| Home | Libraries | People | FAQ | More

# http::server::request_parser Class Reference

List of all members.

## Detailed Description

Parser for incoming requests.

Definition at line 13 of file request_parser.hpp.

## Public Member Functions

| request_parser ()
| Construct ready to parse the request method.
void | reset ()
| Reset to initial parser state.
template<typename InputIterator>
boost::tuple< boost::tribool, InputIterator > | parse (request &req, InputIterator begin, InputIterator end)
| Parse some data. The tribool return value is true when a complete request has been parsed, false if the data is invalid, indeterminate when more data is required. The InputIterator return value indicates how much of the input has been consumed.

## Private Types

| method_start
| method
| uri_start
| uri
| http_version_h
| http_version_t_1
| http_version_t_2
| http_version_p
| http_version_slash
| http_version_major_start
| http_version_major
| http_version_minor_start
| http_version_minor
| expecting_newline_1
| header_line_start
| header_lws
| header_name
| space_before_header_value
| header_value
| expecting_newline_2
| expecting_newline_3
enum | state { method_start, method, uri_start, uri, http_version_h, http_version_t_1, http_version_t_2, http_version_p, http_version_slash, http_version_major_start, http_version_major, http_version_minor_start, http_version_minor, expecting_newline_1, header_line_start, header_lws, header_name, space_before_header_value, header_value, expecting_newline_2, expecting_newline_3 }
| The current state of the parser. More...

## Private Member Functions

boost::tribool | consume (request &req, char input)
| Handle the next character of input.

## Static Private Member Functions

static bool | is_char (int c)
| Check if a byte is an HTTP character.
static bool | is_ctl (int c)
| Check if a byte is an HTTP control character.
static bool | is_tspecial (int c)
| Check if a byte is defined as an HTTP tspecial character.
static bool | is_digit (int c)
| Check if a byte is a digit.

## Private Attributes

enum http::server::request_parser::state | state_
| The current state of the parser.

## Member Enumeration Documentation

enum http::server::request_parser::state `[private]`

The current state of the parser.

Enumerator:

  method_start |
  method |
  uri_start |
  uri |
  http_version_h |
  http_version_t_1 |
  http_version_t_2 |
  http_version_p |
  http_version_slash |
  http_version_major_start |
  http_version_major |
  http_version_minor_start |
  http_version_minor |
  expecting_newline_1 |
  header_line_start |
  header_lws |
  header_name |
  space_before_header_value |
  header_value |
  expecting_newline_2 |
  expecting_newline_3 |

Definition at line 54 of file request_parser.hpp.

    00058   {
    00059     method_start,
    00060     method,
    00061     uri_start,
    00062     uri,
    00063     http_version_h,
    00064     http_version_t_1,
    00065     http_version_t_2,
    00066     http_version_p,
    00067     http_version_slash,
    00068     http_version_major_start,
    00069     http_version_major,
    00070     http_version_minor_start,
    00071     http_version_minor,
    00072     expecting_newline_1,
    00073     header_line_start,
    00074     header_lws,
    00075     header_name,
    00076     space_before_header_value,
    00077     header_value,

## Constructor & Destructor Documentation

http::server::request_parser::request_parser | ( |  | ) |

Construct ready to parse the request method.

Definition at line 7 of file request_parser.cpp.

    00008   : state_(method_start)
    00009 {
    00010 }

## Member Function Documentation

void http::server::request_parser::reset | ( |  | ) |

Reset to initial parser state.

Definition at line 12 of file request_parser.cpp.

    00013 {
    00014   state_ = method_start;
    00015 }

template<typename InputIterator>

boost::tuple<boost::tribool, InputIterator> http::server::request_parser::parse | ( | request & | req,
|  | InputIterator | begin,
|  | InputIterator | end |
| ) |  |  |

Parse some data. The tribool return value is true when a complete request has been parsed, false if the data is invalid, indeterminate when more data is required. The InputIterator return value indicates how much of the input has been consumed.

Definition at line 24 of file request_parser.hpp.

Referenced by http::server::connection::handle_read().

    00029   {
    00030     while (begin != end)
    00031     {
    00032       boost::tribool result = consume(req, *begin++);
    00033       if (result || !result)
    00034         return boost::make_tuple(result, begin);
    00035     }

boost::tribool http::server::request_parser::consume | ( | request & | req,
|  | char | input |
| ) |  |  | `[private]`

Handle the next character of input.

Definition at line 17 of file request_parser.cpp.

    00018 {
    00019   switch (state_)
    00020   {
    00021   case method_start:
    00022     if (!is_char(input) || is_ctl(input) || is_tspecial(input))
    00023     {
    00024       return false;
    00025     }
    00026     else
    00027     {
    00028       state_ = method;
    00029       req.method.push_back(input);
    00030       return boost::indeterminate;
    00031     }
    00032   case method:
    00033     if (input == ' ')
    00034     {
    00035       state_ = uri;
    00036       return boost::indeterminate;
    00037     }
    00038     else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
    00039     {
    00040       return false;
    00041     }
    00042     else
    00043     {
    00044       req.method.push_back(input);
    00045       return boost::indeterminate;
    00046     }
    00047   case uri_start:
    00048     if (is_ctl(input))
    00049     {
    00050       return false;
    00051     }
    00052     else
    00053     {
    00054       state_ = uri;
    00055       req.uri.push_back(input);
    00056       return boost::indeterminate;
    00057     }
    00058   case uri:
    00059     if (input == ' ')
    00060     {
    00061       state_ = http_version_h;
    00062       return boost::indeterminate;
    00063     }
    00064     else if (is_ctl(input))
    00065     {
    00066       return false;
    00067     }
    00068     else
    00069     {
    00070       req.uri.push_back(input);
    00071       return boost::indeterminate;
    00072     }
    00073   case http_version_h:
    00074     if (input == 'H')
    00075     {
    00076       state_ = http_version_t_1;
    00077       return boost::indeterminate;
    00078     }
    00079     else
    00080     {
    00081       return false;
    00082     }
    00083   case http_version_t_1:
    00084     if (input == 'T')
    00085     {
    00086       state_ = http_version_t_2;
    00087       return boost::indeterminate;
    00088     }
    00089     else
    00090     {
    00091       return false;
    00092     }
    00093   case http_version_t_2:
    00094     if (input == 'T')
    00095     {
    00096       state_ = http_version_p;
    00097       return boost::indeterminate;
    00098     }
    00099     else
    00100     {
    00101       return false;
    00102     }
    00103   case http_version_p:
    00104     if (input == 'P')
    00105     {
    00106       state_ = http_version_slash;
    00107       return boost::indeterminate;
    00108     }
    00109     else
    00110     {
    00111       return false;
    00112     }
    00113   case http_version_slash:
    00114     if (input == '/')
    00115     {
    00116       req.http_version_major = 0;
    00117       req.http_version_minor = 0;
    00118       state_ = http_version_major_start;
    00119       return boost::indeterminate;
    00120     }
    00121     else
    00122     {
    00123       return false;
    00124     }
    00125   case http_version_major_start:
    00126     if (is_digit(input))
    00127     {
    00128       req.http_version_major = req.http_version_major * 10 + input - '0';
    00129       state_ = http_version_major;
    00130       return boost::indeterminate;
    00131     }
    00132     else
    00133     {
    00134       return false;
    00135     }
    00136   case http_version_major:
    00137     if (input == '.')
    00138     {
    00139       state_ = http_version_minor_start;
    00140       return boost::indeterminate;
    00141     }
    00142     else if (is_digit(input))
    00143     {
    00144       req.http_version_major = req.http_version_major * 10 + input - '0';
    00145       return boost::indeterminate;
    00146     }
    00147     else
    00148     {
    00149       return false;
    00150     }
    00151   case http_version_minor_start:
    00152     if (is_digit(input))
    00153     {
    00154       req.http_version_minor = req.http_version_minor * 10 + input - '0';
    00155       state_ = http_version_minor;
    00156       return boost::indeterminate;
    00157     }
    00158     else
    00159     {
    00160       return false;
    00161     }
    00162   case http_version_minor:
    00163     if (input == '\r')
    00164     {
    00165       state_ = expecting_newline_1;
    00166       return boost::indeterminate;
    00167     }
    00168     else if (is_digit(input))
    00169     {
    00170       req.http_version_minor = req.http_version_minor * 10 + input - '0';
    00171       return boost::indeterminate;
    00172     }
    00173     else
    00174     {
    00175       return false;
    00176     }
    00177   case expecting_newline_1:
    00178     if (input == '\n')
    00179     {
    00180       state_ = header_line_start;
    00181       return boost::indeterminate;
    00182     }
    00183     else
    00184     {
    00185       return false;
    00186     }
    00187   case header_line_start:
    00188     if (input == '\r')
    00189     {
    00190       state_ = expecting_newline_3;
    00191       return boost::indeterminate;
    00192     }
    00193     else if (!req.headers.empty() && (input == ' ' || input == '\t'))
    00194     {
    00195       state_ = header_lws;
    00196       return boost::indeterminate;
    00197     }
    00198     else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
    00199     {
    00200       return false;
    00201     }
    00202     else
    00203     {
    00204       req.headers.push_back(header());
    00205       req.headers.back().name.push_back(input);
    00206       state_ = header_name;
    00207       return boost::indeterminate;
    00208     }
    00209   case header_lws:
    00210     if (input == '\r')
    00211     {
    00212       state_ = expecting_newline_2;
    00213       return boost::indeterminate;
    00214     }
    00215     else if (input == ' ' || input == '\t')
    00216     {
    00217       return boost::indeterminate;
    00218     }
    00219     else if (is_ctl(input))
    00220     {
    00221       return false;
    00222     }
    00223     else
    00224     {
    00225       state_ = header_value;
    00226       req.headers.back().value.push_back(input);
    00227       return boost::indeterminate;
    00228     }
    00229   case header_name:
    00230     if (input == ':')
    00231     {
    00232       state_ = space_before_header_value;
    00233       return boost::indeterminate;
    00234     }
    00235     else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
    00236     {
    00237       return false;
    00238     }
    00239     else
    00240     {
    00241       req.headers.back().name.push_back(input);
    00242       return boost::indeterminate;
    00243     }
    00244   case space_before_header_value:
    00245     if (input == ' ')
    00246     {
    00247       state_ = header_value;
    00248       return boost::indeterminate;
    00249     }
    00250     else
    00251     {
    00252       return false;
    00253     }
    00254   case header_value:
    00255     if (input == '\r')
    00256     {
    00257       state_ = expecting_newline_2;
    00258       return boost::indeterminate;
    00259     }
    00260     else if (is_ctl(input))
    00261     {
    00262       return false;
    00263     }
    00264     else
    00265     {
    00266       req.headers.back().value.push_back(input);
    00267       return boost::indeterminate;
    00268     }
    00269   case expecting_newline_2:
    00270     if (input == '\n')
    00271     {
    00272       state_ = header_line_start;
    00273       return boost::indeterminate;
    00274     }
    00275     else
    00276     {
    00277       return false;
    00278     }
    00279   case expecting_newline_3:
    00280     return (input == '\n');
    00281   default:
    00282     return false;
    00283   }
    00284 }

bool http::server::request_parser::is_char | ( | int | c | ) | `[static, private]`

Check if a byte is an HTTP character.

Definition at line 286 of file request_parser.cpp.

Referenced by consume().

    00287 {
    00288   return c >= 0 && c <= 127;
    00289 }

bool http::server::request_parser::is_ctl | ( | int | c | ) | `[static, private]`

Check if a byte is an HTTP control character.

Definition at line 291 of file request_parser.cpp.

Referenced by consume().

    00292 {
    00293   return c >= 0 && c <= 31 || c == 127;
    00294 }

bool http::server::request_parser::is_tspecial | ( | int | c | ) | `[static, private]`

Check if a byte is defined as an HTTP tspecial character.

Definition at line 296 of file request_parser.cpp.

Referenced by consume().

    00297 {
    00298   switch (c)
    00299   {
    00300   case '(': case ')': case '<': case '>': case '@':
    00301   case ',': case ';': case ':': case '\\': case '"':
    00302   case '/': case '[': case ']': case '?': case '=':
    00303   case '{': case '}': case ' ': case '\t':
    00304     return true;
    00305   default:
    00306     return false;
    00307   }
    00308 }

bool http::server::request_parser::is_digit | ( | int | c | ) | `[static, private]`

Check if a byte is a digit.

Definition at line 310 of file request_parser.cpp.

Referenced by consume().

    00311 {
    00312   return c >= '0' && c <= '9';
    00313 }

## Member Data Documentation

enum http::server::request_parser::state http::server::request_parser::state_ `[private]`

The current state of the parser.

Referenced by consume(), and reset().

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

- http/server/request_parser.hpp
- http/server/request_parser.cpp

| Copyright © 2003 - 2006 Christopher M. Kohlhoff