2 * @file http_response.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 **********************************************************************/
25 #include "http_response.h"
28 * HTTP Request constructor.
30 http_response::http_response()
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, 43,
35 "in/out_function : Constructor http_response::http_response(void)");
37 /*------ DEBUG LOG END ------*/
41 * HTTP Request constructor.
42 * Parse HTTP response header.
44 * @param[in] header full http response header string
46 http_response::http_response(std::string header)
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, 44,
51 "in/out_function : Constructor http_response::http_response(std::string header) : "
52 "header(%s)", header.c_str());
54 /*------ DEBUG LOG END ------*/
59 * HTTP Request destructor.
61 http_response::~http_response()
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, 45,
66 "in/out_function : Destructor http_response::~http_response(void)");
68 /*------ DEBUG LOG END ------*/
72 * Get HTTP version function.
74 * @return HTTP version
76 std::string http_response::http_version() const
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, 46,
81 "in_function : std::string http_response::http_version(void)");
82 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 47,
83 "out_function : std::string http_response::http_version(void) : "
84 "return(%s)", this->_http_version.c_str());
86 /*------ DEBUG LOG END ------*/
88 return this->_http_version;
92 * Set HTTP version function.
93 * Set new HTTP version and return old HTTP version.
95 * @param[in] _http_version new HTTP version
96 * @return old HTTP version
98 std::string http_response::http_version(std::string _http_version)
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, 48,
103 "in_function : std::string http_response::http_version(std::string _http_version) : "
104 "_http_version(%s)", _http_version.c_str());
106 /*------ DEBUG LOG END ------*/
108 std::string ret = this->_http_version;
109 this->_http_version = _http_version;
110 this->_modified = true;
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, 49,
115 "out_function : std::string http_response::http_version(std::string _http_version) : "
116 "return(%s)", ret.c_str());
118 /*------ DEBUG LOG END ------*/
124 * Get status code function.
126 * @return status code
128 std::string http_response::status_code() const
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, 50,
133 "in_function : std::string http_response::status_code(void)");
134 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 51,
135 "out_function : std::string http_response::status_code(void) : "
136 "return(%s)", this->_status_code.c_str());
138 /*------ DEBUG LOG END ------*/
140 return this->_status_code;
144 * Set status code function.
145 * Set new status code and return old status code.
147 * @param[in] _status_code new status code
148 * @return old status code
150 std::string http_response::status_code(std::string _status_code)
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, 52,
155 "in_function : std::string http_response::status_code(std::string _status_code) : "
156 "_status_code(%s)", _status_code.c_str());
158 /*------ DEBUG LOG END ------*/
160 std::string ret = this->_status_code;
161 this->_status_code = _status_code;
162 this->_modified = true;
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, 53,
167 "out_function : std::string http_response::status_code(std::string _status_code) : "
168 "return(%s)", ret.c_str());
170 /*------ DEBUG LOG END ------*/
176 * Get reason phrase function.
178 * @return reason phrase
180 std::string http_response::reason_phrase() const
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, 54,
185 "in_function : std::string http_response::reason_phrase(void)");
186 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 55,
187 "out_function : std::string http_response::reason_phrase(void) : "
188 "return(%s)", this->_reason_phrase.c_str());
190 /*------ DEBUG LOG END ------*/
192 return this->_reason_phrase;
196 * Set reason phrase function.
197 * Set new reason phrase and return old reason phrase.
199 * @param[in] _reason_phrase new reason phrase
200 * @return old reason phrase
202 std::string http_response::reason_phrase(std::string _reason_phrase)
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, 56,
207 "in_function : std::string http_response::reason_phrase(std::string _reason_phrase) : "
208 "_reason_phrase(%s)", _reason_phrase.c_str());
210 /*------ DEBUG LOG END ------*/
212 std::string ret = this->_reason_phrase;
213 this->_reason_phrase = _reason_phrase;
214 this->_modified = true;
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, 57,
219 "out_function : std::string http_response::reason_phrase(std::string _reason_phrase) : "
220 "return(%s)", ret.c_str());
222 /*------ DEBUG LOG END ------*/
228 * Get status line function.
230 * @return status line
232 std::string http_response::status_line() const
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, 58,
237 "in_function : std::string http_response::status_line(void)");
239 /*------ DEBUG LOG END ------*/
241 std::string ret = this->http_version() + " " + this->status_code() + " " + this->reason_phrase() + "\r\n";
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, 59,
246 "out_function : std::string http_response::status_line(void) : "
247 "return(%s)", ret.c_str());
249 /*------ DEBUG LOG END ------*/
255 * Get full HTTP response function.
257 * @return HTTP response
259 std::string http_response::as_string()
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, 60,
264 "in_function : std::string http_response::as_string(void)");
266 /*------ DEBUG LOG END ------*/
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, 61,
274 "out_function : std::string http_response::as_string(void) : "
275 "return(%s)", this->raw_message.c_str());
277 /*------ DEBUG LOG END ------*/
279 return this->raw_message;
283 * Parse HTTP response header function.
285 * @param[in] request full HTTP response header
287 void http_response::parse(std::string response)
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, 62,
292 "in_function : void http_response::parse(std::string response) : "
293 "response(%s)", response.c_str());
295 /*------ DEBUG LOG END ------*/
298 this->raw_message = response;
301 HTTP_RESPONSE_POSITION pos = RESPONSE_TOP;
306 * CHAR : US-ASCII(0-127)
309 * ALPHA : UPALPHA | LOALPHA
311 * HEXDIG : A-F | a-f | DIGIT
313 * HT : Horizontal Tab(9)
314 * CR : Carriage Return(13)
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)
321 std::string::iterator ptr = response.begin();
322 std::string::iterator end = response.end();
323 std::string::iterator start = ptr;
324 std::pair<std::string, std::string> field_pair;
330 * HTTP-VERSION SP STATUS-CODE SP REASON-PHRASE CRLF
333 * HTTP-VERSION : "HTTP" "/" 1*DIGIT "." 1*DIGIT
336 // HTTP-VERSION start
338 pos = RESPONSE_HTTP_VERSION_H;
341 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 15,
342 "Parse error: Invalid http-version.(%c)", *ptr);
347 case RESPONSE_HTTP_VERSION_H:
350 pos = RESPONSE_HTTP_VERSION_T1;
352 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 16,
353 "Parse error: Invalid http-version.(%c)", *ptr);
358 case RESPONSE_HTTP_VERSION_T1:
361 pos = RESPONSE_HTTP_VERSION_T2;
363 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 17,
364 "Parse error: Invalid http-version.(%c)", *ptr);
369 case RESPONSE_HTTP_VERSION_T2:
372 pos = RESPONSE_HTTP_VERSION_P;
374 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 18,
375 "Parse error: Invalid http-version.(%c)", *ptr);
380 case RESPONSE_HTTP_VERSION_P:
383 pos = RESPONSE_HTTP_VERSION_SLASH;
385 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 19,
386 "Parse error: Invalid http-version.(%c)", *ptr);
391 case RESPONSE_HTTP_VERSION_SLASH:
392 // HTTP-VERSION Mejor number
394 pos = RESPONSE_HTTP_VERSION_MAJOR;
396 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 20,
397 "Parse error: Invalid http-version.(%c)", *ptr);
402 case RESPONSE_HTTP_VERSION_MAJOR:
403 // HTTP-VERSION next dot
405 pos = RESPONSE_HTTP_VERSION_DOT;
406 } else if (!isdigit(*ptr)) {
407 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 21,
408 "Parse error: Invalid http-version.(%c)", *ptr);
413 case RESPONSE_HTTP_VERSION_DOT:
414 // HTTP-VERSION Minor number
416 pos = RESPONSE_HTTP_VERSION_MINOR;
418 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 22,
419 "Parse error: Invalid http-version.(%c)", *ptr);
424 case RESPONSE_HTTP_VERSION_MINOR:
425 // HTTP-VERSION end with SP
427 pos = RESPONSE_HTTP_VERSION_SP;
428 this->_http_version.assign(start, ptr);
429 } else if (!isdigit(*ptr)) {
430 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 23,
431 "Parse error: Invalid http-version.(%c)", *ptr);
437 * Status-Code : 3DIGIT
439 case RESPONSE_HTTP_VERSION_SP:
442 pos = RESPONSE_STATUS_CODE1;
445 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 24,
446 "Parse error: Invalid status-code.(%c)", *ptr);
451 case RESPONSE_STATUS_CODE1:
454 pos = RESPONSE_STATUS_CODE2;
456 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 25,
457 "Parse error: Invalid status-code.(%c)", *ptr);
462 case RESPONSE_STATUS_CODE2:
465 pos = RESPONSE_STATUS_CODE3;
467 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 26,
468 "Parse error: Invalid status-code.(%c)", *ptr);
473 case RESPONSE_STATUS_CODE3:
474 // Status-Code end with SP
476 pos = RESPONSE_STATUS_CODE_SP;
477 this->_status_code.assign(start, ptr);
479 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 27,
480 "Parse error: Invalid status-code.(%c)", *ptr);
486 * Reason-Phrase : *<TEXT, excluding CR, LF>
488 case RESPONSE_STATUS_CODE_SP:
489 // Reason-Phrase is OCTET
490 if (*ptr == '\r') { // omit reason-phrase
492 this->_reason_phrase.clear();
493 } else if (*ptr != '\n') {
494 pos = RESPONSE_REASON_PHRASE;
497 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 28,
498 "Parse error: Invalid reason-phrase.(%c)", *ptr);
503 case RESPONSE_REASON_PHRASE:
504 // Reason-Phrase end with CR
507 this->_reason_phrase.assign(start, ptr);
508 } else if (*ptr == '\n') {
509 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 29,
510 "Parse error: Invalid reason-phrase.(%c)", *ptr);
519 http_message::parse(std::string(ptr + 1, end));
521 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 30,
522 "Parse error: No LF.(%c)", *ptr);
527 if (pos == RESPONSE_LF)
533 LOGGER_PUT_LOG_INFO(LOG_CAT_PACKET_EDIT_HTTP, 31,
534 "Exception occured by parsing HTTP response.");
537 /*-------- DEBUG LOG --------*/
538 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
539 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 63,
540 "out_function : void http_response::parse(std::string response)");
542 /*------ DEBUG LOG END ------*/
546 * Rebuild HTTP response header function.
548 void http_response::rebuild()
550 /*-------- DEBUG LOG --------*/
551 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
552 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 64,
553 "in_function : void http_response::rebuild()");
555 /*------ DEBUG LOG END ------*/
557 this->raw_message = this->status_line();
558 http_message::rebuild();
560 /*-------- DEBUG LOG --------*/
561 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
562 LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 65,
563 "out_function : void http_response::rebuild()");
565 /*------ DEBUG LOG END ------*/