utility::string_t flatten_http_headers(const http_headers& headers) { utility::string_t flattened_headers; for (auto iter = headers.begin(); iter != headers.end(); ++iter) { flattened_headers.append(iter->first); flattened_headers.push_back(':'); flattened_headers.append(iter->second); flattened_headers.append(CRLF); } return flattened_headers; }
// // Helper function to generate a wstring from given http_headers and message body. // static utility::string_t http_headers_body_to_string(const http_headers &headers, concurrency::streams::istream instream) { utility::ostringstream_t buffer; for (auto iter = headers.begin(); iter != headers.end(); ++iter) { buffer << iter->first << _XPLATSTR(": ") << iter->second << CRLF; } buffer << CRLF; utility::string_t content_type; if(headers.match(http::header_names::content_type, content_type)) { buffer << convert_body_to_string_t(content_type, instream); } return buffer.str(); }
void parse_headers_string(_Inout_z_ utf16char* headersStr, http_headers& headers) { utf16char* context = nullptr; utf16char* line = wcstok_s(headersStr, CRLF, &context); while (line != nullptr) { const utility::string_t header_line(line); const size_t colonIndex = header_line.find_first_of(_XPLATSTR(":")); if (colonIndex != utility::string_t::npos) { utility::string_t key = header_line.substr(0, colonIndex); utility::string_t value = header_line.substr(colonIndex + 1, header_line.length() - colonIndex - 1); http::details::trim_whitespace(key); http::details::trim_whitespace(value); headers.add(key, value); } line = wcstok_s(nullptr, CRLF, &context); } }
// // Helper function to generate a wstring from given http_headers and message body. // static utility::string_t http_headers_body_to_string(const http_headers& headers, concurrency::streams::istream instream) { utility::string_t result; for (const auto& header : headers) { result += header.first; result += _XPLATSTR(": "); result += header.second; result += CRLF; } result += CRLF; utility::string_t content_type; if (headers.match(http::header_names::content_type, content_type)) { result += convert_body_to_string_t(content_type, instream); } return result; }
bool parse_http_headers(Iterator begin, Iterator end, std::string &content_type, boost::int64_t &content_length, std::string &location, http_headers &headers) { enum { first_header_line_start, header_line_start, header_lws, header_name, space_before_header_value, header_value, linefeed, final_linefeed, fail } state = first_header_line_start; Iterator iter = begin; std::string reason; std::string name; std::string value; while (iter != end && state != fail) { char c = *iter++; switch (state) { case first_header_line_start: if (c == '\r') state = final_linefeed; else if (!is_char(c) || is_ctl(c) || is_tspecial(c)) state = fail; else { name.push_back(c); state = header_name; } break; case header_line_start: if (c == '\r') { boost::trim(name); boost::trim(value); check_header(name, value, content_type, content_length, location); headers.push_back(std::make_pair(name, value)); name.clear(); value.clear(); state = final_linefeed; } else if (c == ' ' || c == '\t') state = header_lws; else if (!is_char(c) || is_ctl(c) || is_tspecial(c)) state = fail; else { boost::trim(name); boost::trim(value); check_header(name, value, content_type, content_length, location); headers.push_back(std::make_pair(name, value)); name.clear(); value.clear(); name.push_back(c); state = header_name; } break; case header_lws: if (c == '\r') state = linefeed; else if (c == ' ' || c == '\t') ; // Discard character. else if (is_ctl(c)) state = fail; else { state = header_value; value.push_back(c); } break; case header_name: if (c == ':') state = space_before_header_value; else if (!is_char(c) || is_ctl(c) || is_tspecial(c)) state = fail; else name.push_back(c); break; case space_before_header_value: if (c == ' ') state = header_value; else if (is_ctl(c)) state = fail; else { value.push_back(c); state = header_value; } break; case header_value: if (c == '\r') state = linefeed; else if (is_ctl(c)) state = fail; else value.push_back(c); break; case linefeed: state = (c == '\n') ? header_line_start : fail; break; case final_linefeed: return (c == '\n'); default: return false; } } return false; }