2 * @file http_request.cpp
3 * @brief module of HTTP Request
4 * @brief HTTP Request parser
6 * Copyright (C) 2009 NTT COMWARE Corporation.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 **********************************************************************/
26 #include "http_request.h"
29 * HTTP Request constructor.
31 http_request::http_request()
35 /*-------- DEBUG LOG --------*/
36 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
37 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log
38 "in/out_function : Constructor http_request::http_request(void)");
40 /*------ DEBUG LOG END ------*/
44 * HTTP Request constructor.
45 * Parse HTTP request header.
47 * @param[in] header full http request header string
49 http_request::http_request(std::string header)
53 /*-------- DEBUG LOG --------*/
54 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
55 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log
56 "in/out_function : Constructor http_request::http_request(std::string header) : "
57 "header(%s)", header.c_str());
59 /*------ DEBUG LOG END ------*/
64 * HTTP Request destructor.
66 http_request::~http_request()
68 /*-------- DEBUG LOG --------*/
69 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
70 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 2, // XXX log
71 "in/out_function : Destructor http_request::~http_request(void)");
73 /*------ DEBUG LOG END ------*/
77 * Get method function.
81 std::string http_request::method()
83 /*-------- DEBUG LOG --------*/
84 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
85 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
86 "in_function : std::string http_request::method(void)");
87 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
88 "out_function : std::string http_request::method(void) : "
89 "return(%s)", this->_method.c_str());
91 /*------ DEBUG LOG END ------*/
97 * Set method function.
98 * Set new method and return old method.
100 * @param[in] method new method
103 std::string http_request::method(std::string _method)
105 /*-------- DEBUG LOG --------*/
106 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
107 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
108 "in_function : std::string http_request::method(std::string _method) : "
109 "_method(%s)", _method.c_str());
111 /*------ DEBUG LOG END ------*/
113 std::string ret = this->_method;
114 this->_method = _method;
115 this->modified = true;
117 /*-------- DEBUG LOG --------*/
118 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
119 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
120 "out_function : std::string http_request::method(std::string _method) : "
121 "return(%s)", ret.c_str());
123 /*------ DEBUG LOG END ------*/
129 * Get request URI function.
131 * @return request URI
133 std::string http_request::request_uri()
135 /*-------- DEBUG LOG --------*/
136 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
137 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
138 "in_function : std::string http_request::request_uri(void)");
139 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
140 "out_function : std::string http_request::request_uri(void) : "
141 "return(%s)", this->_request_uri.c_str());
143 /*------ DEBUG LOG END ------*/
145 return this->_request_uri;
149 * Set request URI function.
150 * Set new request URI and return old request URI.
152 * @param[in] _request_uri new request URI
153 * @return old request URI
155 std::string http_request::request_uri(std::string _request_uri)
157 /*-------- DEBUG LOG --------*/
158 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
159 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
160 "in_function : std::string http_request::request_uri(std::string _request_uri) : "
161 "_request_uri(%s)", _request_uri.c_str());
163 /*------ DEBUG LOG END ------*/
165 std::string ret = this->_request_uri;
166 this->_request_uri = _request_uri;
167 this->modified = true;
169 /*-------- DEBUG LOG --------*/
170 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
171 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
172 "out_function : std::string http_request::_request_uri(std::string _request_uri) : "
173 "return(%s)", ret.c_str());
175 /*------ DEBUG LOG END ------*/
181 * Get HTTP version function.
183 * @return HTTP version
185 std::string http_request::http_version()
187 /*-------- DEBUG LOG --------*/
188 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
189 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
190 "in_function : std::string http_request::http_version(void)");
191 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
192 "out_function : std::string http_request::http_version(void) : "
193 "return(%s)", this->_http_version.c_str());
195 /*------ DEBUG LOG END ------*/
197 return this->_http_version;
201 * Set HTTP version function.
202 * Set new HTTP version and return old HTTP version.
204 * @param[in] _http_version new HTTP version
205 * @return old HTTP version
207 std::string http_request::http_version(std::string _http_version)
209 /*-------- DEBUG LOG --------*/
210 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
211 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
212 "in_function : std::string http_request::http_version(std::string _http_version) : "
213 "_http_version(%s)", _http_version.c_str());
215 /*------ DEBUG LOG END ------*/
217 std::string ret = this->_http_version;
218 this->_http_version = _http_version;
219 this->modified = true;
221 /*-------- DEBUG LOG --------*/
222 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
223 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
224 "out_function : std::string http_request::http_version(std::string _http_version) : "
225 "return(%s)", ret.c_str());
227 /*------ DEBUG LOG END ------*/
233 * Get HTTP header field function.
235 * @param[in] field_name lookup field name
236 * @return header field value
238 field_range http_request::header(std::string field_name)
240 /*-------- DEBUG LOG --------*/
241 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
242 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
243 "in_function : field_range http_request::header(std::string field_name) : "
244 "field_name(%s)", field_name.c_str());
246 /*------ DEBUG LOG END ------*/
248 field_range ret = this->_header.get<field_map>().equal_range(field_name);
250 /*-------- DEBUG LOG --------*/
251 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
252 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
253 "out_function : field_range http_request::header(std::string field_name)");
255 /*------ DEBUG LOG END ------*/
261 * Set HTTP header field function.
262 * Set new HTTP header field and return old HTTP header field.
264 * @param[in] field_name lookup field name
265 * @param[in] field_value field value
267 void http_request::header(std::string field_name, std::string field_value)
269 /*-------- DEBUG LOG --------*/
270 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
271 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
272 "in_function : field_range http_request::header(std::string field_name, std::string field_value) : "
273 "field_name(%s), field_value(%s)", field_name.c_str(), field_value.c_str());
275 /*------ DEBUG LOG END ------*/
277 bool replaced = false;
278 field_range ret = this->_header.get<field_map>().equal_range(field_name);
279 field_map_iterator it = ret.first;
280 field_map_iterator it_end = ret.second;
281 for (;it != it_end; ++it) {
282 if ( _header.get<field_map>().replace(it, field(field_name, field_value)) ) {
284 this->modified = true;
288 _header.get<field_map>().insert( field(field_name, field_value) );
289 this->modified = true;
292 /*-------- DEBUG LOG --------*/
293 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
294 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
295 "out_function : field_range http_request::header(std::string field_name, std::string field_value)");
297 /*------ DEBUG LOG END ------*/
301 * Get message body function.
303 * @return message body
305 std::string http_request::message()
307 /*-------- DEBUG LOG --------*/
308 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
309 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
310 "in_function : std::string http_request::message(void)");
311 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
312 "out_function : std::string http_request::message(void) : "
313 "return(%s)", this->_message.c_str());
315 /*------ DEBUG LOG END ------*/
317 return this->_message;
321 * Set message body function.
322 * Set new message body and return old message body.
324 * @param[in] _message new message body
325 * @return old message body
327 std::string http_request::message(std::string _message)
329 /*-------- DEBUG LOG --------*/
330 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
331 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
332 "in_function : std::string http_request::http_version(std::string _message) : "
333 "_message(%s)", _message.c_str());
335 /*------ DEBUG LOG END ------*/
337 std::string ret = this->_message;
338 this->_message = _message;
339 this->modified = true;
341 /*-------- DEBUG LOG --------*/
342 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
343 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
344 "out_function : std::string http_request::message(std::string _message) : "
345 "return(%s)", ret.c_str());
347 /*------ DEBUG LOG END ------*/
353 * Get request line function.
355 * @return request line
357 std::string http_request::request_line()
359 /*-------- DEBUG LOG --------*/
360 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
361 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
362 "in_function : std::string http_request::request_line(void)");
364 /*------ DEBUG LOG END ------*/
366 std::string ret = this->method() + " " + this->request_uri() + " " + this->http_version() + "\r\n";
368 /*-------- DEBUG LOG --------*/
369 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
370 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
371 "out_function : std::string http_request::request_line(void) : "
372 "return(%s)", ret.c_str());
374 /*------ DEBUG LOG END ------*/
380 * Get full HTTP request function.
382 * @return HTTP request
384 std::string http_request::as_string()
386 /*-------- DEBUG LOG --------*/
387 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
388 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
389 "in_function : std::string http_request::as_string(void)");
391 /*------ DEBUG LOG END ------*/
396 /*-------- DEBUG LOG --------*/
397 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
398 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
399 "out_function : std::string http_request::as_string(void) : "
400 "return(%s)", this->raw_request.c_str());
402 /*------ DEBUG LOG END ------*/
404 return this->raw_request;
408 * Parse HTTP header function.
410 * @param[in] request full HTTP request header
412 void http_request::parse(std::string request)
414 /*-------- DEBUG LOG --------*/
415 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
416 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
417 "in_function : void http_request::parse(std::string request) : "
418 "request(%s)", request.c_str());
420 /*------ DEBUG LOG END ------*/
423 this->raw_request = request;
426 HTTP_REQUEST_POSITION pos = REQUEST_METHOD;
431 * CHAR : US-ASCII(0-127)
434 * ALPHA : UPALPHA | LOALPHA
436 * HEXDIG : A-F | a-f | DIGIT
438 * HT : Horizontal Tab(9)
439 * CR : Carriage Return(13)
441 * CTL : ConTLol char(0-31,127)
442 * LWS : [CRLF] 1*(SP|HT)
443 * separators : ()<>@,;:\"/[]?={} and SP, HT
444 * token : 1*(CHAR not CTL, separators)
446 std::string::iterator ptr = request.begin();
447 std::string::iterator end = request.end();
448 std::string::iterator start = ptr;
449 std::pair<std::string, std::string> field_pair;
454 * METHOD SP REQUEST-URI SP HTTP-VERSION CRLF
460 if (*ptr == ' ') { // METHOD end with SP
461 this->_method.assign(start, ptr);
462 pos = REQUEST_METHOD_SP;
463 } else if (!isalpha(*ptr) && !isdigit(*ptr)) { // XXX not enough
464 /*-------- DEBUG LOG --------*/
465 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
466 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
467 "out_function : void http_request::parse(std::string request) : Invalid Method");
469 /*------ DEBUG LOG END ------*/
474 * REQUEST-URI : * | absolute-URI | path-absolute | authority
477 * absolute-URI : scheme ":" hier-part [ "?" query ]
478 * path-absolute : "/" [ segment-nz *( "/" segment ) ]
479 * authority : [ userinfo "@" ] host [ ":" port ]
480 * scheme : ALPHA *( ALPHA | DIGIT | "+" | "-" | "." )
481 * hier-part : "//" authority path-abempty
485 * query : *( pchar | "/" | "?" )
486 * path-abempty : *( "/" segment )
487 * path-rootless : segment-nz *( "/" segment )
488 * path-empty : no char
489 * segment-nz : 1*pchar
491 * userinfo : *( unreserved | pct-encoded | sub-delims | ":" )
492 * host : IP-literal | IPv4address | reg-name
494 * unreserved : ALPHA | DIGIT | "-" | "." | "_" | "~"
495 * pct-encoded : "%" HEXDIG HEXDIG
496 * sub-delims : !$&'()*+,;=
497 * pchar : unreserved | pct-encoded | subdelims | ":" | "@"
498 * IP-literal : "[" ( IPv6address | IPvFuture ) "]"
499 * IPvFuture : "v" 1*HEXDIG "." 1*( unreserved | sub-delims | ":" )
500 * IPv6address : 6( h16 ":" ) ls32
501 * / "::" 5( h16 ":" ) ls32
502 * / [ h16 ] "::" 4( h16 ":" ) ls32
503 * / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
504 * / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
505 * / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
506 * / [ *4( h16 ":" ) h16 ] "::" ls32
507 * / [ *5( h16 ":" ) h16 ] "::" h16
508 * / [ *6( h16 ":" ) h16 ] "::"
510 * ls32 : ( h16 ":" h16 ) | IPv4address
511 * IPv4address : dec-octet "." dec-octet "." dec-octet "." dec-octet
513 * reg-name : *( unreserved | pct-encoded | sub-delims )
515 case REQUEST_METHOD_SP:
518 if (*ptr == '/' || isalpha(*ptr) || isdigit(*ptr) || *ptr == '-' ||
519 *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == ':' ||
520 *ptr == '@' || *ptr == '!' || *ptr == '$' || *ptr == '&' ||
521 *ptr == '(' || *ptr == ')' || *ptr == '*' || *ptr == '+' ||
522 *ptr == ',' || *ptr == ';' || *ptr == '=' || *ptr == '%') {
523 pos = REQUEST_REQUEST_URI;
526 /*-------- DEBUG LOG --------*/
527 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
528 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
529 "out_function : void http_request::parse(std::string request) : Invalid Request-URI");
531 /*------ DEBUG LOG END ------*/
536 case REQUEST_REQUEST_URI:
537 if (*ptr == ' ') { // Request-URI end with SP
538 this->_request_uri.assign(start, ptr);
539 pos = REQUEST_REQUEST_URI_SP;
540 } else if (!isalpha(*ptr) && !isdigit(*ptr) && *ptr != '/' && // XXX not enough?
541 *ptr != '.' && *ptr != '=' && *ptr != '%' && *ptr != '?' &&
542 *ptr != '&' && *ptr != '+' && *ptr != '~' && *ptr != ',' &&
543 *ptr != '@' && *ptr != '!' && *ptr != '$' && *ptr != '-' &&
544 *ptr != '(' && *ptr != ')' && *ptr != '*' && *ptr != '_' &&
545 *ptr != ':' && *ptr != ';') {
546 /*-------- DEBUG LOG --------*/
547 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
548 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
549 "out_function : void http_request::parse(std::string request) : Invalid Request-URI");
551 /*------ DEBUG LOG END ------*/
557 * HTTP-VERSION : "HTTP" "/" 1*DIGIT "." 1*DIGIT
559 case REQUEST_REQUEST_URI_SP:
560 // HTTP-VERSION start
562 pos = REQUEST_HTTP_VERSION_H;
565 /*-------- DEBUG LOG --------*/
566 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
567 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
568 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
570 /*------ DEBUG LOG END ------*/
575 case REQUEST_HTTP_VERSION_H:
578 pos = REQUEST_HTTP_VERSION_T1;
580 /*-------- DEBUG LOG --------*/
581 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
582 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
583 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
585 /*------ DEBUG LOG END ------*/
590 case REQUEST_HTTP_VERSION_T1:
593 pos = REQUEST_HTTP_VERSION_T2;
595 /*-------- DEBUG LOG --------*/
596 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
597 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
598 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
600 /*------ DEBUG LOG END ------*/
605 case REQUEST_HTTP_VERSION_T2:
608 pos = REQUEST_HTTP_VERSION_P;
610 /*-------- DEBUG LOG --------*/
611 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
612 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
613 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
615 /*------ DEBUG LOG END ------*/
620 case REQUEST_HTTP_VERSION_P:
623 pos = REQUEST_HTTP_VERSION_SLASH;
625 /*-------- DEBUG LOG --------*/
626 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
627 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
628 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
630 /*------ DEBUG LOG END ------*/
635 case REQUEST_HTTP_VERSION_SLASH:
636 // HTTP-VERSION Mejor number
638 pos = REQUEST_HTTP_VERSION_MAJOR;
640 /*-------- DEBUG LOG --------*/
641 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
642 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
643 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
645 /*------ DEBUG LOG END ------*/
650 case REQUEST_HTTP_VERSION_MAJOR:
651 // HTTP-VERSION next dot
653 pos = REQUEST_HTTP_VERSION_DOT;
654 } else if (!isdigit(*ptr)) {
655 /*-------- DEBUG LOG --------*/
656 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
657 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
658 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
660 /*------ DEBUG LOG END ------*/
665 case REQUEST_HTTP_VERSION_DOT:
666 // HTTP-VERSION Minor number
668 pos = REQUEST_HTTP_VERSION_MINOR;
670 /*-------- DEBUG LOG --------*/
671 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
672 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
673 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
675 /*------ DEBUG LOG END ------*/
680 case REQUEST_HTTP_VERSION_MINOR:
681 // HTTP-VERSION end with CR
684 this->_http_version.assign(start, ptr);
685 } else if (!isdigit(*ptr)) {
686 /*-------- DEBUG LOG --------*/
687 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
688 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
689 "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
691 /*------ DEBUG LOG END ------*/
701 /*-------- DEBUG LOG --------*/
702 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
703 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
704 "out_function : void http_request::parse(std::string request) : not CRLF");
706 /*------ DEBUG LOG END ------*/
712 * MESSAGE-HEADER : field-name ":" [ field-value ]
714 * field-value : *( field-content | LWS )
715 * field-content : <the OCTETs making up the field-value and
716 * consisting of either *TEXT or combinations
717 * of token, separators, and quoted-string>
718 * TEXT : <any OCTET except CTLs, but including LWS>
719 * quoted-string : ( <"> *(qdtext | quoted-pair ) <"> )
720 * qdtext : <any TEXT except <">>
721 * quoted-pair : "\" CHAR
724 if (isalpha(*ptr) || *ptr == '-' || isdigit(*ptr) ||
725 *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == '!' ||
726 *ptr == '$' || *ptr == '&' || *ptr == '*' || *ptr == '+' ||
728 if (field_pair.first.length()) {
729 _header.get<field_map>().insert(field_pair);
730 field_pair.first.clear();
733 pos = REQUEST_FIELD_NAME;
734 } else if (*ptr == ' ' || *ptr == '\t') {
735 pos = REQUEST_FIELD_VALUE;
736 } else if (*ptr == '\r') { // CRLF + CRLF
737 if (field_pair.first.length()) {
738 _header.get<field_map>().insert(field_pair);
739 field_pair.first.clear();
741 pos = REQUEST_LAST_CR;
743 /*-------- DEBUG LOG --------*/
744 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
745 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
746 "out_function : void http_request::parse(std::string request) : not CRLF");
748 /*------ DEBUG LOG END ------*/
753 case REQUEST_FIELD_NAME:
754 // field-name end with ':'
756 pos = REQUEST_FIELD_NAME_COLON;
757 field_pair.first.assign(start, ptr);
758 } else if (!isalpha(*ptr) && *ptr != '-' && !isdigit(*ptr) &&
759 *ptr != '.' && *ptr != '_' && *ptr != '~' && *ptr != '!' &&
760 *ptr != '$' && *ptr != '&' && *ptr != '*' && *ptr != '+' &&
762 /*-------- DEBUG LOG --------*/
763 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
764 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
765 "out_function : void http_request::parse(std::string request) : Invalid header field name.");
767 /*------ DEBUG LOG END ------*/
772 case REQUEST_FIELD_NAME_COLON:
773 if (*ptr == ' ' || isalpha(*ptr) || isdigit(*ptr) || *ptr == '-' ||
774 *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == ':' ||
775 *ptr == '@' || *ptr == '!' || *ptr == '$' || *ptr == '&' ||
776 *ptr == '(' || *ptr == ')' || *ptr == '*' || *ptr == '+' ||
777 *ptr == ',' || *ptr == ';' || *ptr == '=' || *ptr == '%' ||
778 *ptr == '<' || *ptr == '>' || *ptr == '[' || *ptr == ']' ||
779 *ptr == '{' || *ptr == '}' || *ptr == '?' || *ptr == '"' ||
780 *ptr == '|' || *ptr == '/' || *ptr == '\\' || *ptr == '\t') {
782 pos = REQUEST_FIELD_VALUE;
783 } else if (*ptr == '\r') { // omit field value
784 field_pair.second.clear();
786 /*-------- DEBUG LOG --------*/
787 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
788 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
789 "out_function : void http_request::parse(std::string request) : Invalid header field value.('%c')", *ptr);
791 /*------ DEBUG LOG END ------*/
795 case REQUEST_FIELD_VALUE:
796 // field-value end with CR
799 field_pair.second.assign(start, ptr);
800 } else if (*ptr != ' ' && !isalpha(*ptr) && !isdigit(*ptr) && *ptr != '-' &&
801 *ptr != '.' && *ptr != '_' && *ptr != '~' && *ptr != ':' &&
802 *ptr != '@' && *ptr != '!' && *ptr != '$' && *ptr != '&' &&
803 *ptr != '(' && *ptr != ')' && *ptr != '*' && *ptr != '+' &&
804 *ptr != ',' && *ptr != ';' && *ptr != '=' && *ptr != '%' &&
805 *ptr != '<' && *ptr != '>' && *ptr != '[' && *ptr != ']' &&
806 *ptr != '{' && *ptr != '}' && *ptr != '?' && *ptr != '"' &&
807 *ptr != '|' && *ptr != '/' && *ptr != '\\'&& *ptr != '\t' ) {
808 /*-------- DEBUG LOG --------*/
809 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
810 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
811 "out_function : void http_request::parse(std::string request) : Invalid header field value.('%c')", *ptr);
813 /*------ DEBUG LOG END ------*/
818 case REQUEST_LAST_CR:
821 pos = REQUEST_LAST_LF;
823 /*-------- DEBUG LOG --------*/
824 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
825 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
826 "out_function : void http_request::parse(std::string request) : not CRLF");
828 /*------ DEBUG LOG END ------*/
834 * MESSAGE-BODY : *OCTET
836 case REQUEST_LAST_LF:
837 pos = REQUEST_MESSAGE;
841 case REQUEST_MESSAGE:
848 case REQUEST_MESSAGE:
849 this->_message.assign(start, ptr);
852 /*-------- DEBUG LOG --------*/
853 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
854 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
855 "out_function : void http_request::parse(std::string request)");
857 /*------ DEBUG LOG END ------*/
861 * Rebuild HTTP header function.
863 void http_request::rebuild()
865 /*-------- DEBUG LOG --------*/
866 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
867 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
868 "in_function : void http_request::rebuild()");
870 /*------ DEBUG LOG END ------*/
872 this->raw_request = this->request_line();
874 header_container::iterator it = this->_header.begin();
875 header_container::iterator it_end = this->_header.end();
877 while (it != it_end) {
878 this->raw_request += it->first + ": " + it->second + "\r\n";
882 this->raw_request += "\r\n" + this->message();
884 /*-------- DEBUG LOG --------*/
885 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
886 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
887 "out_function : void http_request::rebuild()");
889 /*------ DEBUG LOG END ------*/
892 void printheader(http_request& request, std::string name) {
894 r = request.header(name);
895 while (r.first != r.second) {
896 std::cout << "=======> HEADER(" << r.first->first << "): " << r.first->second<< std::endl;
901 void changeheader(http_request& request, std::string name, std::string value) {
902 request.header(name, value);
903 printheader(request, name);
910 req.parse("GET / HTTP/1.0\n");
911 std::cout << "=======> METHOD: " << req.method() << std::endl;
917 http_request request("POST /index HTTP/1.1\r\nHost: localhost\r\nX-Forwarded-For: localhost\r\n foobar\r\nAccept: */*\r\n\r\nMessageBODY");
918 std::cout << request.as_string() << std::endl;
919 std::cout << "=======> METHOD: " << request.method() << std::endl;
920 std::cout << "=======> URI: " << request.request_uri() << std::endl;
921 std::cout << "=======> VERSION: " << request.http_version() << std::endl;
922 printheader(request, "Host");
923 printheader(request, "X-Forwarded-For");
924 printheader(request, "Accept");
925 printheader(request, "Test");
926 changeheader(request, "Test", "new test");
927 changeheader(request, "Host", "new host");
928 std::cout << request.as_string() << std::endl;
929 std::cout << request.request_line() << std::endl;
930 // std::cout << request.method("TRACE") << std::endl;
931 // std::cout << request.request_uri("/?type=project&id=393") << std::endl;
932 // std::cout << request.http_version("HTTP/1.0") << std::endl;
933 std::cout << request.request_line() << std::endl;
934 std::cout << request.message("type=project&id=303") << std::endl;
935 std::cout << request.message() << std::endl;
936 std::cout << request.as_string() << std::endl;
943 r.request_uri("/index.html");
944 r.http_version("HTTP/1.1");
945 r.header("Host", "img.unitcom.co.jp");
946 r.header("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)");
947 r.header("Accept", "image/png,image/*;q=0.8,*/*;q=0.5");
948 r.header("Accept-Language", "ja,en-us;q=0.7,en;q=0.3");
949 r.header("Accept-Encoding", "gzip,deflate");
950 r.header("Accept-Charset", "Shift_JIS,utf-8;q=0.7,*;q=0.7");
951 r.header("Keep-Alive", "300");
952 r.header("Connection", "keep-alive");
953 r.header("Referer", "http://www.faith-go.co.jp/special/");
954 r.header("Cookie", "ASPSESSIONIDQCCQBQBR=HHKHICIACCKKHPIIECCOBOJG");
955 r.message("TEST__TEST");
956 std::cout << r.as_string() << std::endl;
962 "GET /cgi-bin/env.cgi HTTP/1.1\r\n"
963 "Host: 192.168.0.4:7780\r\n"
964 "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)\r\n"
965 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
966 "Accept-Language: ja,en-us;q=0.7,en;q=0.3\r\n"
967 "Accept-Encoding: gzip,deflate\r\n"
968 "Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r\n"
969 "Keep-Alive: 300\r\n"
970 "Connection: keep-alive\r\n"
971 "Cookie: rh_omni_tc=70160000000H4AoAAK; __utma=225840474.262789985507525570.1236909895.1236909895.1236909895.1; __utmz=225840474.1236909895.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); sch_target=mygroup; sch_d=3; sch_m=5; sch_y=2009; sch_move=weekly; PHPSESSID=pfn9gu39gkfq3cn16cr70q12b5; circular_kwd=; room_target=all; room_move=weekly; room_y=2009; room_m=4; room_d=27\r\n"
972 "Cache-Control: max-age=0\r\n"
974 http_request re(text);
975 std::cout << re.as_string() << std::endl;