SNode.C
Loading...
Searching...
No Matches
web::http::decoder::Fields Class Reference

#include <Fields.h>

Collaboration diagram for web::http::decoder::Fields:

Public Member Functions

 Fields (core::socket::stream::SocketContext *socketContext, std::set< std::string > fieldsExpected={})
 
 Fields (Fields &)=delete
 
 Fields (Fields &&)=delete
 
Fieldsoperator= (Fields &)=delete
 
Fieldsoperator= (Fields &&)=delete
 
void setFieldsExpected (std::set< std::string > fieldsExpected)
 
std::size_t read ()
 
web::http::CiStringMap< std::string > && getHeader ()
 
bool isComplete () const
 
bool isError () const
 
int getErrorCode () const
 
std::string getErrorReason ()
 

Private Member Functions

void splitLine (const std::string &line)
 

Private Attributes

core::socket::stream::SocketContextsocketContext
 
web::http::CiStringMap< std::string > fields
 
std::set< std::string > fieldsExpected
 
std::string line
 
std::size_t maxLineLength
 
bool completed = false
 
int errorCode = 0
 
std::string errorReason
 
char lastButOne = '\0'
 
char last = '\0'
 

Detailed Description

Definition at line 39 of file Fields.h.

Constructor & Destructor Documentation

◆ Fields() [1/3]

web::http::decoder::Fields::Fields ( core::socket::stream::SocketContext * socketContext,
std::set< std::string > fieldsExpected = {} )
explicit

Definition at line 38 of file Fields.cpp.

40 , fieldsExpected(std::move(fieldsExpected))
42 }
#define MAX_LINE_LENGTH
Definition Fields.cpp:33
core::socket::stream::SocketContext * socketContext
Definition Fields.h:63
std::size_t maxLineLength
Definition Fields.h:69
std::set< std::string > fieldsExpected
Definition Fields.h:66

References Fields(), maxLineLength, and socketContext.

Referenced by Fields().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Fields() [2/3]

web::http::decoder::Fields::Fields ( Fields & )
delete

◆ Fields() [3/3]

web::http::decoder::Fields::Fields ( Fields && )
delete

Member Function Documentation

◆ getErrorCode()

int web::http::decoder::Fields::getErrorCode ( ) const

Definition at line 149 of file Fields.cpp.

149 {
150 return errorCode;
151 }

References errorCode.

◆ getErrorReason()

std::string web::http::decoder::Fields::getErrorReason ( )

Definition at line 153 of file Fields.cpp.

153 {
154 return errorReason;
155 }
std::string errorReason
Definition Fields.h:73

References errorReason.

◆ getHeader()

web::http::CiStringMap< std::string > && web::http::decoder::Fields::getHeader ( )

Definition at line 137 of file Fields.cpp.

137 {
138 return std::move(fields);
139 }
web::http::CiStringMap< std::string > fields
Definition Fields.h:65

◆ isComplete()

bool web::http::decoder::Fields::isComplete ( ) const

Definition at line 141 of file Fields.cpp.

141 {
142 return completed;
143 }

References completed.

◆ isError()

bool web::http::decoder::Fields::isError ( ) const

Definition at line 145 of file Fields.cpp.

145 {
146 return errorCode != 0;
147 }

References errorCode.

◆ operator=() [1/2]

Fields & web::http::decoder::Fields::operator= ( Fields && )
delete

◆ operator=() [2/2]

Fields & web::http::decoder::Fields::operator= ( Fields & )
delete

◆ read()

std::size_t web::http::decoder::Fields::read ( )

Definition at line 48 of file Fields.cpp.

48 {
49 std::size_t consumed = 0;
50
51 if (completed || errorCode != 0) {
52 completed = false;
53 fields.clear();
54 errorCode = 0;
55 errorReason = "";
56 }
57
58 std::size_t ret = 0;
59 do {
60 char ch = '\0';
61
62 ret = socketContext->readFromPeer(&ch, 1);
63 consumed += ret;
64
65 if (ret > 0) {
66 if (!line.empty() || ch != ' ') {
67 line += ch;
68
69 if (maxLineLength == 0 || line.size() <= maxLineLength) {
71 last = ch;
72
73 if (lastButOne == '\r' && last == '\n') {
74 line.pop_back(); // Remove \n
75 line.pop_back(); // Remove \r
76
77 completed = line.empty();
78 if (!completed) {
80
81 if (!fieldsExpected.empty() && fields.size() > fieldsExpected.size()) {
82 errorCode = 400;
83 errorReason = "Too many fields";
84 }
85 } else if (!fieldsExpected.empty() && fields.size() < fieldsExpected.size()) {
86 errorCode = 400;
87 errorReason = "Too view fields";
88
89 completed = false;
90 }
91 line.clear();
92 lastButOne = '\0';
93 last = '\0';
94 }
95 } else {
96 errorCode = 431;
97 errorReason = "Line too long: " + line;
98 }
99 } else {
100 errorCode = 400;
101 errorReason = "Header Folding";
102 }
103 }
104 } while (ret > 0 && !completed && errorCode == 0);
105
106 return consumed;
107 }
std::size_t readFromPeer(char *chunk, std::size_t chunklen) const final
void splitLine(const std::string &line)
Definition Fields.cpp:109

References completed, errorCode, errorReason, last, lastButOne, line, maxLineLength, core::socket::stream::SocketContext::readFromPeer(), socketContext, and splitLine().

Here is the call graph for this function:

◆ setFieldsExpected()

void web::http::decoder::Fields::setFieldsExpected ( std::set< std::string > fieldsExpected)

Definition at line 44 of file Fields.cpp.

44 {
45 this->fieldsExpected = std::move(fieldsExpected);
46 }

◆ splitLine()

void web::http::decoder::Fields::splitLine ( const std::string & line)
private

Definition at line 109 of file Fields.cpp.

109 {
110 auto [headerFieldName, value] = httputils::str_split(line, ':');
111
112 if (headerFieldName.empty()) {
113 errorCode = 400;
114 errorReason = "Header field empty";
115 } else if ((std::isblank(headerFieldName.back()) != 0) || (std::isblank(headerFieldName.front()) != 0)) {
116 errorCode = 400;
117 errorReason = "White space before or after field";
118 } else if (value.empty()) {
119 errorCode = 400;
120 errorReason = "Value of field \"" + headerFieldName + "\" empty";
121 } else {
122 if (fieldsExpected.empty() || fieldsExpected.contains(headerFieldName)) {
124
125 if (!fields.contains(headerFieldName)) {
126 fields.emplace(headerFieldName, value);
127 } else {
128 fields[headerFieldName] += "," + value;
129 }
130 } else if (!fieldsExpected.empty() && !fieldsExpected.contains(headerFieldName)) {
131 errorCode = 400;
132 errorReason = "Field '" + headerFieldName + "' not in expected fields";
133 }
134 }
135 }
std::pair< std::string, std::string > str_split(const std::string &base, char c_middle)
std::string & str_trimm(std::string &text)

References errorCode, and errorReason.

Referenced by read().

Here is the caller graph for this function:

Member Data Documentation

◆ completed

bool web::http::decoder::Fields::completed = false
private

Definition at line 71 of file Fields.h.

Referenced by isComplete(), and read().

◆ errorCode

int web::http::decoder::Fields::errorCode = 0
private

Definition at line 72 of file Fields.h.

Referenced by getErrorCode(), isError(), read(), and splitLine().

◆ errorReason

std::string web::http::decoder::Fields::errorReason
private

Definition at line 73 of file Fields.h.

Referenced by getErrorReason(), read(), and splitLine().

◆ fields

web::http::CiStringMap<std::string> web::http::decoder::Fields::fields
private

Definition at line 65 of file Fields.h.

◆ fieldsExpected

std::set<std::string> web::http::decoder::Fields::fieldsExpected
private

Definition at line 66 of file Fields.h.

◆ last

char web::http::decoder::Fields::last = '\0'
private

Definition at line 76 of file Fields.h.

Referenced by read().

◆ lastButOne

char web::http::decoder::Fields::lastButOne = '\0'
private

Definition at line 75 of file Fields.h.

Referenced by read().

◆ line

std::string web::http::decoder::Fields::line
private

Definition at line 68 of file Fields.h.

Referenced by read().

◆ maxLineLength

std::size_t web::http::decoder::Fields::maxLineLength
private

Definition at line 69 of file Fields.h.

Referenced by Fields(), and read().

◆ socketContext

core::socket::stream::SocketContext* web::http::decoder::Fields::socketContext
private

Definition at line 63 of file Fields.h.

Referenced by Fields(), and read().


The documentation for this class was generated from the following files: