OSDN Git Service

Refactoring HTTP parser.
[ultramonkey-l7/sslproxy.git] / src / http_request.cpp
1 /*
2  * @file  http_request.cpp
3  * @brief module of HTTP Request
4  * @brief HTTP Request parser
5  *
6  * Copyright (C) 2009  NTT COMWARE Corporation.
7  *
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.
12  *
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.
17  *
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
21  * 02110-1301 USA
22  *
23  **********************************************************************/
24
25 #include "http_request.h"
26
27 /*!
28  * HTTP Request constructor.
29  */
30 http_request::http_request()
31 {
32     /*-------- DEBUG LOG --------*/
33     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
34         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log
35         "in/out_function : Constructor http_request::http_request(void)");
36     }
37     /*------ DEBUG LOG END ------*/
38 }
39
40 /*!
41  * HTTP Request constructor.
42  * Parse HTTP request header.
43  *
44  * @param[in]   header  full http request header string
45  */
46 http_request::http_request(std::string header)
47 {
48     /*-------- DEBUG LOG --------*/
49     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
50         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log
51         "in/out_function : Constructor http_request::http_request(std::string header) : "
52         "header(%s)", header.c_str());
53     }
54     /*------ DEBUG LOG END ------*/
55     this->parse(header);
56 }
57
58 /*!
59  * HTTP Request destructor.
60  */
61 http_request::~http_request()
62 {
63     /*-------- DEBUG LOG --------*/
64     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
65         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 2, // XXX log
66         "in/out_function : Destructor http_request::~http_request(void)");
67     }
68     /*------ DEBUG LOG END ------*/
69 }
70
71 /*!
72  * Get method function.
73  *
74  * @return    method
75  */
76 std::string http_request::method()
77 {
78     /*-------- DEBUG LOG --------*/
79     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
80         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
81         "in_function : std::string http_request::method(void)");
82         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
83         "out_function : std::string http_request::method(void) : "
84         "return(%s)", this->_method.c_str());
85     }
86     /*------ DEBUG LOG END ------*/
87
88     return this->_method;
89 }
90
91 /*!
92  * Set method function.
93  * Set new method and return old method.
94  *
95  * @param[in]   method  new method
96  * @return  old method
97  */
98 std::string http_request::method(std::string _method)
99 {
100     /*-------- DEBUG LOG --------*/
101     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
102         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
103         "in_function : std::string http_request::method(std::string _method) : "
104         "_method(%s)", _method.c_str());
105     }
106     /*------ DEBUG LOG END ------*/
107
108     std::string ret = this->_method;
109     this->_method = _method;
110     this->modified = true;
111
112     /*-------- DEBUG LOG --------*/
113     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
114         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
115         "out_function : std::string http_request::method(std::string _method) : "
116         "return(%s)", ret.c_str());
117     }
118     /*------ DEBUG LOG END ------*/
119
120     return ret;
121 }
122
123 /*!
124  * Get request URI function.
125  *
126  * @return    request URI
127  */
128 std::string http_request::request_uri()
129 {
130     /*-------- DEBUG LOG --------*/
131     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
132         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
133         "in_function : std::string http_request::request_uri(void)");
134         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
135         "out_function : std::string http_request::request_uri(void) : "
136         "return(%s)", this->_request_uri.c_str());
137     }
138     /*------ DEBUG LOG END ------*/
139
140     return this->_request_uri;
141 }
142
143 /*!
144  * Set request URI function.
145  * Set new request URI and return old request URI.
146  *
147  * @param[in]   _request_uri    new request URI
148  * @return  old request URI
149  */
150 std::string http_request::request_uri(std::string _request_uri)
151 {
152     /*-------- DEBUG LOG --------*/
153     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
154         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
155         "in_function : std::string http_request::request_uri(std::string _request_uri) : "
156         "_request_uri(%s)", _request_uri.c_str());
157     }
158     /*------ DEBUG LOG END ------*/
159
160     std::string ret = this->_request_uri;
161     this->_request_uri = _request_uri;
162     this->modified = true;
163
164     /*-------- DEBUG LOG --------*/
165     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
166         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
167         "out_function : std::string http_request::_request_uri(std::string _request_uri) : "
168         "return(%s)", ret.c_str());
169     }
170     /*------ DEBUG LOG END ------*/
171
172     return ret;
173 }
174
175 /*!
176  * Get HTTP version function.
177  *
178  * @return    HTTP version
179  */
180 std::string http_request::http_version()
181 {
182     /*-------- DEBUG LOG --------*/
183     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
184         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
185         "in_function : std::string http_request::http_version(void)");
186         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
187         "out_function : std::string http_request::http_version(void) : "
188         "return(%s)", this->_http_version.c_str());
189     }
190     /*------ DEBUG LOG END ------*/
191
192     return this->_http_version;
193 }
194
195 /*!
196  * Set HTTP version function.
197  * Set new HTTP version and return old HTTP version.
198  *
199  * @param[in]   _http_version   new HTTP version
200  * @return  old HTTP version
201  */
202 std::string http_request::http_version(std::string _http_version)
203 {
204     /*-------- DEBUG LOG --------*/
205     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
206         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
207         "in_function : std::string http_request::http_version(std::string _http_version) : "
208         "_http_version(%s)", _http_version.c_str());
209     }
210     /*------ DEBUG LOG END ------*/
211
212     std::string ret = this->_http_version;
213     this->_http_version = _http_version;
214     this->modified = true;
215
216     /*-------- DEBUG LOG --------*/
217     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
218         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
219         "out_function : std::string http_request::http_version(std::string _http_version) : "
220         "return(%s)", ret.c_str());
221     }
222     /*------ DEBUG LOG END ------*/
223
224     return ret;
225 }
226
227 /*!
228  * Get request line function.
229  *
230  * @return    request line
231  */
232 std::string http_request::request_line()
233 {
234     /*-------- DEBUG LOG --------*/
235     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
236         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
237         "in_function : std::string http_request::request_line(void)");
238     }
239     /*------ DEBUG LOG END ------*/
240
241     std::string ret = this->method() + " " + this->request_uri() + " " + this->http_version() + "\r\n";
242
243     /*-------- DEBUG LOG --------*/
244     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
245         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
246         "out_function : std::string http_request::request_line(void) : "
247         "return(%s)", ret.c_str());
248     }
249     /*------ DEBUG LOG END ------*/
250
251     return ret;
252 }
253
254 /*!
255  * Get full HTTP request function.
256  *
257  * @return    HTTP request
258  */
259 std::string http_request::as_string()
260 {
261     /*-------- DEBUG LOG --------*/
262     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
263         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
264         "in_function : std::string http_request::as_string(void)");
265     }
266     /*------ DEBUG LOG END ------*/
267
268     if (this->modified)
269         this->rebuild();
270
271     /*-------- DEBUG LOG --------*/
272     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
273         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
274         "out_function : std::string http_request::as_string(void) : "
275         "return(%s)", this->raw_message.c_str());
276     }
277     /*------ DEBUG LOG END ------*/
278
279     return this->raw_message;
280 }
281
282 /*!
283  * Parse HTTP request header function.
284  *
285  * @param[in]   request     full HTTP request header
286  */
287 void http_request::parse(std::string request)
288 {
289     /*-------- DEBUG LOG --------*/
290     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
291         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
292         "in_function : void http_request::parse(std::string request) : "
293         "request(%s)", request.c_str());
294     }
295     /*------ DEBUG LOG END ------*/
296
297     // save raw request
298     this->raw_message = request;
299
300     // parse request
301     HTTP_REQUEST_POSITION pos = REQUEST_METHOD;
302
303     /*
304      * RFC2616
305      *  OCTET       : 8bit data
306      *  CHAR        : US-ASCII(0-127)
307      *  UPALPHA     : A-Z
308      *  LOALPHA     : a-z
309      *  ALPHA       : UPALPHA | LOALPHA
310      *  DIGIT       : 0-9
311      *  HEXDIG      : A-F | a-f | DIGIT
312      *  SP          : SPace(32)
313      *  HT          : Horizontal Tab(9)
314      *  CR          : Carriage Return(13)
315      *  LF          : Line Feed(10)
316      *  CTL         : ConTLol char(0-31,127)
317      *  LWS         : [CRLF] 1*(SP|HT)
318      *  separators  : ()<>@,;:\"/[]?={} and SP, HT
319      *  token       : 1*(CHAR not CTL, separators)
320      */
321     std::string::iterator ptr = request.begin();
322     std::string::iterator end = request.end();
323     std::string::iterator start = ptr;
324     std::pair<std::string, std::string> field_pair;
325     while (ptr != end) {
326         switch(pos) {
327         /*
328          * REQUEST-LINE :
329          *      METHOD SP REQUEST-URI SP HTTP-VERSION CRLF
330          */
331         /*
332          * METHOD : token
333          */
334         case REQUEST_METHOD:
335             if (*ptr == ' ') { // METHOD end with SP
336                 this->_method.assign(start, ptr);
337                 pos = REQUEST_METHOD_SP;
338             } else if (!isalpha(*ptr) && !isdigit(*ptr)) { // XXX not enough
339                 /*-------- DEBUG LOG --------*/
340                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
341                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
342                     "out_function : void http_request::parse(std::string request) : Invalid Method");
343                 }
344                 /*------ DEBUG LOG END ------*/
345                 throw -1;
346             }
347             break;
348         /*
349          * REQUEST-URI : * | absolute-URI | path-absolute | authority
350          *
351          * RFC3986
352          *  absolute-URI    : scheme ":" hier-part [ "?" query ]
353          *  path-absolute   : "/" [ segment-nz *( "/" segment ) ]
354          *  authority       : [ userinfo "@" ] host [ ":" port ]
355          *  scheme          : ALPHA *( ALPHA | DIGIT | "+" | "-" | "." )
356          *  hier-part       : "//" authority path-abempty
357          *                  / path-absolute
358          *                  / path-rootless
359          *                  / path-empty
360          *  query           : *( pchar | "/" | "?" )
361          *  path-abempty    : *( "/" segment )
362          *  path-rootless   : segment-nz *( "/" segment )
363          *  path-empty      : no char
364          *  segment-nz      : 1*pchar
365          *  segment         : *pchar
366          *  userinfo        : *( unreserved | pct-encoded | sub-delims | ":" )
367          *  host            : IP-literal | IPv4address | reg-name
368          *  port            : *DIGIT
369          *  unreserved      : ALPHA | DIGIT | "-" | "." | "_" | "~"
370          *  pct-encoded     : "%" HEXDIG HEXDIG
371          *  sub-delims      : !$&'()*+,;=
372          *  pchar           : unreserved | pct-encoded | subdelims | ":" | "@"
373          *  IP-literal      : "[" ( IPv6address | IPvFuture ) "]"
374          *  IPvFuture       : "v" 1*HEXDIG "." 1*( unreserved | sub-delims | ":" )
375          *  IPv6address     :                            6( h16 ":" ) ls32
376          *                  /                       "::" 5( h16 ":" ) ls32
377          *                  / [               h16 ] "::" 4( h16 ":" ) ls32
378          *                  / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
379          *                  / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
380          *                  / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
381          *                  / [ *4( h16 ":" ) h16 ] "::"              ls32
382          *                  / [ *5( h16 ":" ) h16 ] "::"              h16
383          *                  / [ *6( h16 ":" ) h16 ] "::"
384          *  h16             : 1*4HEXDIG
385          *  ls32            : ( h16 ":" h16 ) | IPv4address
386          *  IPv4address     : dec-octet "." dec-octet "." dec-octet "." dec-octet
387          *  dec-octet       : 0-255
388          *  reg-name        : *( unreserved | pct-encoded | sub-delims )
389          */
390         case REQUEST_METHOD_SP:
391             // Request-URI start
392             // XXX not enough?
393             if (*ptr == '/' || isalpha(*ptr) || isdigit(*ptr) || *ptr == '-' ||
394                 *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == ':' || 
395                 *ptr == '@' || *ptr == '!' || *ptr == '$' || *ptr == '&' ||
396                 *ptr == '(' || *ptr == ')' || *ptr == '*' || *ptr == '+' ||
397                 *ptr == ',' || *ptr == ';' || *ptr == '=' || *ptr == '%') {
398                 pos = REQUEST_REQUEST_URI;
399                 start = ptr;
400             } else {
401                 /*-------- DEBUG LOG --------*/
402                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
403                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
404                     "out_function : void http_request::parse(std::string request) : Invalid Request-URI");
405                 }
406                 /*------ DEBUG LOG END ------*/
407                 throw -1;
408             }
409             break;
410
411         case REQUEST_REQUEST_URI:
412             if (*ptr == ' ') { // Request-URI end with SP
413                 this->_request_uri.assign(start, ptr);
414                 pos = REQUEST_REQUEST_URI_SP;
415             } else if (!isalpha(*ptr) && !isdigit(*ptr) && *ptr != '/' && // XXX not enough?
416                 *ptr != '.' && *ptr != '=' && *ptr != '%' && *ptr != '?' &&
417                 *ptr != '&' && *ptr != '+' && *ptr != '~' && *ptr != ',' && 
418                 *ptr != '@' && *ptr != '!' && *ptr != '$' && *ptr != '-' &&
419                 *ptr != '(' && *ptr != ')' && *ptr != '*' && *ptr != '_' &&
420                 *ptr != ':' && *ptr != ';') {
421                 /*-------- DEBUG LOG --------*/
422                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
423                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
424                     "out_function : void http_request::parse(std::string request) : Invalid Request-URI");
425                 }
426                 /*------ DEBUG LOG END ------*/
427                 throw -1;
428             }
429             break;
430
431         /*
432          * HTTP-VERSION     : "HTTP" "/" 1*DIGIT "." 1*DIGIT
433          */
434         case REQUEST_REQUEST_URI_SP:
435             // HTTP-VERSION start
436             if (*ptr == 'H') {
437                 pos = REQUEST_HTTP_VERSION_H;
438                 start = ptr;
439             } else {
440                 /*-------- DEBUG LOG --------*/
441                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
442                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
443                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
444                 }
445                 /*------ DEBUG LOG END ------*/
446                 throw -1;
447             }
448             break;
449
450         case REQUEST_HTTP_VERSION_H:
451             // HTTP-VERSION next
452             if (*ptr == 'T') {
453                 pos = REQUEST_HTTP_VERSION_T1;
454             } else {
455                 /*-------- DEBUG LOG --------*/
456                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
457                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
458                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
459                 }
460                 /*------ DEBUG LOG END ------*/
461                 throw -1;
462             }
463             break;
464
465         case REQUEST_HTTP_VERSION_T1:
466             // HTTP-VERSION next
467             if (*ptr == 'T') {
468                 pos = REQUEST_HTTP_VERSION_T2;
469             } else {
470                 /*-------- DEBUG LOG --------*/
471                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
472                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
473                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
474                 }
475                 /*------ DEBUG LOG END ------*/
476                 throw -1;
477             }
478             break;
479
480         case REQUEST_HTTP_VERSION_T2:
481             // HTTP-VERSION next
482             if (*ptr == 'P') {
483                 pos = REQUEST_HTTP_VERSION_P;
484             } else {
485                 /*-------- DEBUG LOG --------*/
486                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
487                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
488                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
489                 }
490                 /*------ DEBUG LOG END ------*/
491                 throw -1;
492             }
493             break;
494
495         case REQUEST_HTTP_VERSION_P:
496             // HTTP-VERSION next
497             if (*ptr == '/') {
498                 pos = REQUEST_HTTP_VERSION_SLASH;
499             } else {
500                 /*-------- DEBUG LOG --------*/
501                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
502                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
503                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
504                 }
505                 /*------ DEBUG LOG END ------*/
506                 throw -1;
507             }
508             break;
509
510         case REQUEST_HTTP_VERSION_SLASH:
511             // HTTP-VERSION Mejor number
512             if (isdigit(*ptr)) {
513                 pos = REQUEST_HTTP_VERSION_MAJOR;
514             } else {
515                 /*-------- DEBUG LOG --------*/
516                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
517                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
518                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
519                 }
520                 /*------ DEBUG LOG END ------*/
521                 throw -1;
522             }
523             break;
524
525         case REQUEST_HTTP_VERSION_MAJOR:
526             // HTTP-VERSION next dot
527             if (*ptr == '.') {
528                 pos = REQUEST_HTTP_VERSION_DOT;
529             } else if (!isdigit(*ptr)) {
530                 /*-------- DEBUG LOG --------*/
531                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
532                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
533                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
534                 }
535                 /*------ DEBUG LOG END ------*/
536                 throw -1;
537             }
538             break;
539
540         case REQUEST_HTTP_VERSION_DOT:
541             // HTTP-VERSION Minor number
542             if (isdigit(*ptr)) {
543                 pos = REQUEST_HTTP_VERSION_MINOR;
544             } else {
545                 /*-------- DEBUG LOG --------*/
546                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
547                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
548                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
549                 }
550                 /*------ DEBUG LOG END ------*/
551                 throw -1;
552             }
553             break;
554
555         case REQUEST_HTTP_VERSION_MINOR:
556             // HTTP-VERSION end with CR
557             if (*ptr == '\r') {
558                 pos = REQUEST_CR;
559                 this->_http_version.assign(start, ptr);
560             } else if (!isdigit(*ptr)) {
561                 /*-------- DEBUG LOG --------*/
562                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
563                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
564                     "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version");
565                 }
566                 /*------ DEBUG LOG END ------*/
567                 throw -1;
568             }
569             break;
570
571         case REQUEST_CR:
572             // LF only
573             if (*ptr == '\n') {
574                 pos = REQUEST_LF;
575                 http_message::parse(std::string(ptr + 1, end));
576             } else {
577                 /*-------- DEBUG LOG --------*/
578                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
579                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
580                     "out_function : void http_request::parse(std::string request) : not CRLF");
581                 }
582                 /*------ DEBUG LOG END ------*/
583                 throw -1;
584             }
585             break;
586         }
587         if (pos == REQUEST_LF)
588             break;
589         ptr++;
590     }
591
592     /*-------- DEBUG LOG --------*/
593     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
594         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
595         "out_function : void http_request::parse(std::string request)");
596     }
597     /*------ DEBUG LOG END ------*/
598 }
599
600 /*!
601  * Rebuild HTTP request header function.
602  */
603 void http_request::rebuild()
604 {
605     /*-------- DEBUG LOG --------*/
606     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
607         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
608         "in_function : void http_request::rebuild()");
609     }
610     /*------ DEBUG LOG END ------*/
611
612     this->raw_message = this->request_line();
613     http_message::rebuild();
614
615     /*-------- DEBUG LOG --------*/
616     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
617         LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log
618         "out_function : void http_request::rebuild()");
619     }
620     /*------ DEBUG LOG END ------*/
621 }