38 const std::function<
void()>& onResponseStart,
39 const std::function<
void(Response&&)>& onResponseParsed,
40 const std::function<
void(
int,
const std::string&)>& onResponseParseError)
41 : Parser(socketContext)
42 , onResponseStart(onResponseStart)
43 , onResponseParsed(onResponseParsed)
44 , onResponseParseError(onResponseParseError) {
63 std::string remaining;
65 std::tie(response.httpVersion, remaining) = httputils::str_split(line,
' ');
67 std::smatch httpVersionMatch;
68 if (!std::regex_match(response.httpVersion, httpVersionMatch, httpVersionRegex)) {
69 parseError(400,
"Wrong protocol version: " + response.httpVersion);
71 httpMajor = std::stoi(httpVersionMatch.str(1));
72 httpMinor = std::stoi(httpVersionMatch.str(2));
74 std::tie(response.statusCode, response.reason) = httputils::str_split(remaining,
' ');
75 if (StatusCode::contains(std::stoi(response.statusCode))) {
76 if (response.reason.empty()) {
77 parseError(400,
"No reason phrase");
80 parseError(400,
"Unknown status code");
84 parseError(400,
"Response line empty");
91 if (headers.contains(
"Connection")) {
92 const std::string& connection = headers[
"Connection"];
93 if (web::http::ciContains(connection,
"keep-alive")) {
94 response.connectionState = ConnectionState::Keep;
95 }
else if (web::http::ciContains(connection,
"close")) {
96 response.connectionState = ConnectionState::Close;
99 if (headers.contains(
"Set-Cookie")) {
100 std::string cookiesLine = headers[
"Set-Cookie"];
102 while (!cookiesLine.empty()) {
103 std::string cookieLine;
104 std::tie(cookieLine, cookiesLine) = httputils::str_split(cookiesLine,
',');
106 std::string cookieOptions;
108 std::tie(cookie, cookieOptions) = httputils::str_split(cookieLine,
';');
110 std::string cookieName;
111 std::string cookieValue;
112 std::tie(cookieName, cookieValue) = httputils::str_split(cookie,
'=');
114 httputils::str_trimm(cookieName);
115 httputils::str_trimm(cookieValue);
117 std::map<std::string, CookieOptions>::iterator cookieElement;
118 bool inserted =
false;
119 std::tie(cookieElement, inserted) = response.cookies.insert({cookieName, CookieOptions(cookieValue)});
121 while (!cookieOptions.empty()) {
123 std::tie(option, cookieOptions) = httputils::str_split(cookieOptions,
';');
125 std::string optionName;
126 std::string optionValue;
127 std::tie(optionName, optionValue) = httputils::str_split(option,
'=');
129 httputils::str_trimm(optionName);
130 httputils::str_trimm(optionValue);
132 cookieElement->second.setOption(optionName, optionValue);
136 Parser::headers.erase(
"Set-Cookie");
139 if (transferEncoding == TransferEncoding::Identity && contentLength == 0) {