28 #ifndef HTTP_PARSER_HPP
29 #define HTTP_PARSER_HPP
36 #include <websocketpp/utilities.hpp>
37 #include <websocketpp/http/constants.hpp>
52 namespace body_encoding {
60 typedef std::map<std::string, std::string, utility::ci_less > header_list;
72 template <
typename InputIterator>
73 std::pair<std::string,InputIterator> extract_token(InputIterator begin,
76 InputIterator it = std::find_if(begin,end,&is_not_token_char);
77 return std::make_pair(std::string(begin,it),it);
91 template <
typename InputIterator>
92 std::pair<std::string,InputIterator> extract_quoted_string(InputIterator begin,
98 return std::make_pair(s,begin);
102 return std::make_pair(s,begin);
105 InputIterator cursor = begin+1;
106 InputIterator marker = cursor;
108 cursor = std::find(cursor,end,
'"');
110 while (cursor != end) {
112 if (*(cursor-1) ==
'\\') {
113 s.append(marker,cursor-1);
118 s.append(marker,cursor);
120 return std::make_pair(s,cursor);
123 cursor = std::find(cursor,end,
'"');
126 return std::make_pair(
"",begin);
138 template <
typename InputIterator>
139 InputIterator extract_lws(InputIterator begin, InputIterator end) {
140 InputIterator it = begin;
143 if (end-begin > 2 && *begin ==
'\r' && *(begin+1) ==
'\n' &&
144 is_whitespace_char(
static_cast<
unsigned char>(*(begin+2))))
149 it = std::find_if(it,end,&is_not_whitespace_char);
163 template <
typename InputIterator>
164 InputIterator extract_all_lws(InputIterator begin, InputIterator end) {
165 InputIterator old_it;
166 InputIterator new_it = begin;
173 new_it = extract_lws(old_it,end);
174 }
while (new_it != end && old_it != new_it);
194 template <
typename InputIterator>
195 InputIterator extract_attributes(InputIterator begin, InputIterator end,
196 attribute_list & attributes)
198 InputIterator cursor;
206 std::pair<std::string,InputIterator> ret;
208 while (cursor != end) {
211 cursor =
http::parser::extract_all_lws(cursor,end);
220 if (*cursor ==
';') {
230 cursor =
http::parser::extract_all_lws(cursor,end);
231 ret = http::parser::extract_token(cursor,end);
233 if (ret.first.empty()) {
241 cursor =
http::parser::extract_all_lws(cursor,end);
242 if (cursor == end || *cursor !=
'=') {
245 attributes[name].clear();
252 cursor =
http::parser::extract_all_lws(cursor,end);
258 ret = http::parser::extract_quoted_string(cursor,end);
259 if (ret.second != cursor) {
260 attributes[name] = ret.first;
265 ret = http::parser::extract_token(cursor,end);
266 if (ret.first.empty()) {
270 attributes[name] = ret.first;
292 template <
typename InputIterator>
293 InputIterator extract_parameters(InputIterator begin, InputIterator end,
294 parameter_list ¶meters)
296 InputIterator cursor;
304 std::pair<std::string,InputIterator> ret;
314 while (cursor != end) {
315 std::string parameter_name;
316 attribute_list attributes;
319 cursor =
http::parser::extract_all_lws(cursor,end);
320 if (cursor == end) {
break;}
322 ret = http::parser::extract_token(cursor,end);
324 if (ret.first.empty()) {
328 parameter_name = ret.first;
333 cursor =
http::parser::extract_all_lws(cursor,end);
336 parameters.push_back(std::make_pair(parameter_name,attributes));
341 if (*cursor ==
';') {
342 InputIterator acursor;
345 acursor = http::parser::extract_attributes(cursor,end,attributes);
347 if (acursor == cursor) {
357 parameters.push_back(std::make_pair(parameter_name,attributes));
359 cursor =
http::parser::extract_all_lws(cursor,end);
360 if (cursor == end) {
break;}
363 if (*cursor !=
',') {
379 inline std::string strip_lws(std::string
const & input) {
380 std::string::const_iterator begin = extract_all_lws(input.begin(),input.end());
381 if (begin == input.end()) {
382 return std::string();
385 std::string::const_reverse_iterator rbegin = extract_all_lws(input.rbegin(),input.rend());
386 if (rbegin == input.rend()) {
387 return std::string();
390 return std::string(begin,rbegin.base());
402 , m_body_bytes_needed(0)
403 , m_body_bytes_max(max_body_size)
404 , m_body_encoding(body_encoding::unknown) {}
470 void append_header(std::string
const & key, std::string
const & val,
471 lib::error_code & ec);
487 void replace_header(std::string
const & key, std::string
const & val,
488 lib::error_code & ec);
500 void remove_header(std::string
const & key, lib::error_code & ec);
524 void set_body(std::string
const & value, lib::error_code & ec);
536 return m_body_bytes_max;
549 m_body_bytes_max = value;
568 void process_header(std::string::iterator begin, std::string::iterator end);
608 return (m_body_bytes_needed == 0);
620 std::string m_version;
621 header_list m_headers;
623 size_t m_header_bytes;
626 size_t m_body_bytes_needed;
627 size_t m_body_bytes_max;
628 body_encoding::value m_body_encoding;
635 #include <websocketpp/http/impl/parser.hpp>