From 433dd38d0457be662ba0b4e18d7acbe87b20faf1 Mon Sep 17 00:00:00 2001 From: Kohei TANUMA Date: Mon, 1 Jun 2009 01:52:48 +0900 Subject: [PATCH] Refactoring HTTP parser. --- conf/sslproxy.target.cf | 9 +- include/http_message.cpp | 554 +++++++++++++++++++++ include/{httprequest.h => http_message.h} | 42 +- include/http_message_enum.h | 40 ++ src/httprequest.cpp => include/http_request.cpp | 282 +++++++---- include/http_request.h | 61 +++ include/http_request_enum.h | 46 ++ include/http_response.h | 57 +++ include/http_response_enum.h | 48 ++ logger/logger_enum.h | 3 +- logger/logger_impl.cpp | 3 +- src/Makefile.am | 8 +- src/http_message.cpp | 538 ++++++++++++++++++++ src/http_request.cpp | 621 +++++++++++++++++++++++ src/http_response.cpp | 624 ++++++++++++++++++++++++ src/sslproxysession.cpp | 8 +- 16 files changed, 2812 insertions(+), 132 deletions(-) create mode 100644 include/http_message.cpp rename include/{httprequest.h => http_message.h} (75%) create mode 100644 include/http_message_enum.h rename src/httprequest.cpp => include/http_request.cpp (74%) create mode 100644 include/http_request.h create mode 100644 include/http_request_enum.h create mode 100644 include/http_response.h create mode 100644 include/http_response_enum.h create mode 100644 src/http_message.cpp create mode 100644 src/http_request.cpp create mode 100644 src/http_response.cpp diff --git a/conf/sslproxy.target.cf b/conf/sslproxy.target.cf index df893da..f243774 100644 --- a/conf/sslproxy.target.cf +++ b/conf/sslproxy.target.cf @@ -64,8 +64,10 @@ session_cache_timeout = 300 # Packet edit configuration. edit_client_msg = "off" edit_server_msg = "off" -x_forwarded_for_mode = "none" -custom_field = "" +http_request_header = "add:X-Forwarded-For:%{REMOTE_ADDR}" +http_request_header = "set:X-Forwarded-Proto:https" +http_request_header = "set:Via:%{LOCAL_ADDR}" +http_request_header = "remove:Cookie" [logger] ## SSLProxy log configuration. @@ -116,5 +118,6 @@ sslproxy_common = "warn" sslproxy_server = "warn" sslproxy_session = "warn" sslproxy_connection = "info" -http = "info" +packet_edit = "info" +packet_edit_http = "info" diff --git a/include/http_message.cpp b/include/http_message.cpp new file mode 100644 index 0000000..2d6b39d --- /dev/null +++ b/include/http_message.cpp @@ -0,0 +1,554 @@ +/* + * @file http_message.cpp + * @brief module of HTTP Message + * @brief HTTP Message parser + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#include "http_message.h" + +/*! + * HTTP Message constructor. + */ +http_message::http_message() + : + modified(false) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log + "in/out_function : Constructor http_message::http_message(void)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * HTTP Message constructor. + * Parse HTTP message header. + * + * @param[in] header full http message header string + */ +http_message::http_message(std::string header) + : + modified(false) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log + "in/out_function : Constructor http_message::http_message(std::string header) : " + "header(%s)", header.c_str()); + } + /*------ DEBUG LOG END ------*/ + this->parse(header); +} + +/*! + * HTTP Message destructor. + */ +http_message::~http_message() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 2, // XXX log + "in/out_function : Destructor http_message::~http_message(void)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Get HTTP header field function. + * + * @param[in] field_name lookup field name + * @return header field value + */ +field_range http_message::header(std::string field_name) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : field_range http_message::header(std::string field_name) : " + "field_name(%s)", field_name.c_str()); + } + /*------ DEBUG LOG END ------*/ + + field_range ret = this->_header.get().equal_range(field_name); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : field_range http_message::header(std::string field_name)"); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Set HTTP header field function. + * Set new HTTP header field and return old HTTP header field. + * + * @param[in] field_name lookup field name + * @param[in] field_value field value + */ +void http_message::header(std::string field_name, std::string field_value) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : field_range http_message::header(std::string field_name, std::string field_value) : " + "field_name(%s), field_value(%s)", field_name.c_str(), field_value.c_str()); + } + /*------ DEBUG LOG END ------*/ + + bool replaced = false; + field_range ret = this->_header.get().equal_range(field_name); + field_map_iterator it = ret.first; + field_map_iterator it_end = ret.second; + for (;it != it_end; ++it) { + if ( _header.get().replace(it, field(field_name, field_value)) ) { + replaced = true; + this->modified = true; + } + } + if (!replaced) { + _header.get().insert( field(field_name, field_value) ); + this->modified = true; + } + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : field_range http_message::header(std::string field_name, std::string field_value)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Get message body function. + * + * @return message body + */ +std::string http_message::body() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_message::body(void)"); + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_message::body(void) : " + "return(%s)", this->_body.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->_body; +} + +/*! + * Set message body function. + * Set new message body and return old message body. + * + * @param[in] _body new message body + * @return old message body + */ +std::string http_message::body(std::string _body) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_message::http_version(std::string _message) : " + "_body(%s)", _body.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->_body; + this->_body = _body; + this->modified = true; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_message::body(std::string _body) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get full HTTP message function. + * + * @return HTTP message + */ +std::string http_message::as_string() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_message::as_string(void)"); + } + /*------ DEBUG LOG END ------*/ + + if (this->modified) + this->rebuild(); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_message::as_string(void) : " + "return(%s)", this->raw_message.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->raw_message; +} + +/*! + * Parse HTTP header function. + * + * @param[in] message full HTTP message header + */ +void http_message::parse(std::string message) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : void http_message::parse(std::string message) : " + "message(%s)", message.c_str()); + } + /*------ DEBUG LOG END ------*/ + + // save raw message + this->raw_message = message; + + // parse message + HTTP_MESSAGE_POSITION pos = MESSAGE_TOP; + + /* + * RFC2616 + * OCTET : 8bit data + * CHAR : US-ASCII(0-127) + * UPALPHA : A-Z + * LOALPHA : a-z + * ALPHA : UPALPHA | LOALPHA + * DIGIT : 0-9 + * HEXDIG : A-F | a-f | DIGIT + * SP : SPace(32) + * HT : Horizontal Tab(9) + * CR : Carriage Return(13) + * LF : Line Feed(10) + * CTL : ConTLol char(0-31,127) + * LWS : [CRLF] 1*(SP|HT) + * separators : ()<>@,;:\"/[]?={} and SP, HT + * token : 1*(CHAR not CTL, separators) + */ + std::string::iterator ptr = message.begin(); + std::string::iterator end = message.end(); + std::string::iterator start = ptr; + std::pair field_pair; + while (ptr != end) { + switch(pos) { + /* + * MESSAGE-HEADER : field-name ":" [ field-value ] + * field-name : token + * field-value : *( field-content | LWS ) + * field-content : + * TEXT : + * quoted-string : ( <"> *(qdtext | quoted-pair ) <"> ) + * qdtext : > + * quoted-pair : "\" CHAR + */ + case MESSAGE_TOP: + if (isalpha(*ptr) || *ptr == '-' || isdigit(*ptr) || + *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == '!' || + *ptr == '$' || *ptr == '&' || *ptr == '*' || *ptr == '+' || + *ptr == '%') { + start = ptr; + pos = MESSAGE_FIELD_NAME; + } else if (*ptr == '\r') { // CRLF + CRLF + pos = MESSAGE_LAST_CR; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_CR: + // LF only + if (*ptr == '\n') { + pos = MESSAGE_LF; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_LF: + if (isalpha(*ptr) || *ptr == '-' || isdigit(*ptr) || + *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == '!' || + *ptr == '$' || *ptr == '&' || *ptr == '*' || *ptr == '+' || + *ptr == '%') { + if (field_pair.first.length()) { + _header.get().insert(field_pair); + field_pair.first.clear(); + } + start = ptr; + pos = MESSAGE_FIELD_NAME; + } else if (*ptr == ' ' || *ptr == '\t') { + pos = MESSAGE_FIELD_VALUE; + } else if (*ptr == '\r') { // CRLF + CRLF + if (field_pair.first.length()) { + _header.get().insert(field_pair); + field_pair.first.clear(); + } + pos = MESSAGE_LAST_CR; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_FIELD_NAME: + // field-name end with ':' + if (*ptr == ':') { + pos = MESSAGE_FIELD_NAME_COLON; + field_pair.first.assign(start, ptr); + } else if (!isalpha(*ptr) && *ptr != '-' && !isdigit(*ptr) && + *ptr != '.' && *ptr != '_' && *ptr != '~' && *ptr != '!' && + *ptr != '$' && *ptr != '&' && *ptr != '*' && *ptr != '+' && + *ptr != '%') { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : Invalid header field name."); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_FIELD_NAME_COLON: + if (*ptr == ' ' || isalpha(*ptr) || isdigit(*ptr) || *ptr == '-' || + *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == ':' || + *ptr == '@' || *ptr == '!' || *ptr == '$' || *ptr == '&' || + *ptr == '(' || *ptr == ')' || *ptr == '*' || *ptr == '+' || + *ptr == ',' || *ptr == ';' || *ptr == '=' || *ptr == '%' || + *ptr == '<' || *ptr == '>' || *ptr == '[' || *ptr == ']' || + *ptr == '{' || *ptr == '}' || *ptr == '?' || *ptr == '"' || + *ptr == '|' || *ptr == '/' || *ptr == '\\' || *ptr == '\t') { + start = ptr; + pos = MESSAGE_FIELD_VALUE; + } else if (*ptr == '\r') { // omit field value + field_pair.second.clear(); + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : Invalid header field value.('%c')", *ptr); + } + /*------ DEBUG LOG END ------*/ + } + break; + + case MESSAGE_FIELD_VALUE: + // field-value end with CR + if (*ptr == '\r') { + pos = MESSAGE_CR; + field_pair.second.assign(start, ptr); + } else if (*ptr != ' ' && !isalpha(*ptr) && !isdigit(*ptr) && *ptr != '-' && + *ptr != '.' && *ptr != '_' && *ptr != '~' && *ptr != ':' && + *ptr != '@' && *ptr != '!' && *ptr != '$' && *ptr != '&' && + *ptr != '(' && *ptr != ')' && *ptr != '*' && *ptr != '+' && + *ptr != ',' && *ptr != ';' && *ptr != '=' && *ptr != '%' && + *ptr != '<' && *ptr != '>' && *ptr != '[' && *ptr != ']' && + *ptr != '{' && *ptr != '}' && *ptr != '?' && *ptr != '"' && + *ptr != '|' && *ptr != '/' && *ptr != '\\'&& *ptr != '\t' ) { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : Invalid header field value.('%c')", *ptr); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_LAST_CR: + // LF only + if (*ptr == '\n') { + pos = MESSAGE_LAST_LF; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + /* + * MESSAGE-BODY : *OCTET + */ + case MESSAGE_LAST_LF: + pos = MESSAGE_BODY; + start = ptr; + break; + + case MESSAGE_BODY: + break; + } + ptr++; + } + + switch (pos) { + case MESSAGE_BODY: + this->_body.assign(start, ptr); + } + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Rebuild HTTP header function. + */ +void http_message::rebuild() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : void http_message::rebuild()"); + } + /*------ DEBUG LOG END ------*/ + + // insertion order + header_container::iterator it = this->_header.begin(); + header_container::iterator it_end = this->_header.end(); + + while (it != it_end) { + this->raw_message += it->first + ": " + it->second + "\r\n"; + it++; + } + + this->raw_message += "\r\n" + this->body(); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::rebuild()"); + } + /*------ DEBUG LOG END ------*/ +} + + + +//============================ + +void printheader(http_message& message, std::string name) { + field_range r; + r = message.header(name); + while (r.first != r.second) { + std::cout << "=======> HEADER(" << r.first->first << "): " << r.first->second<< std::endl; + r.first++; + } +} + +void changeheader(http_message& message, std::string name, std::string value) { + message.header(name, value); + printheader(message, name); +} + +int main() { + + try { + http_message message("POST /index HTTP/1.1\r\nHost: localhost\r\nX-Forwarded-For: localhost\r\n foobar\r\nAccept: */*\r\n\r\nMessageBODY"); + std::cout << message.as_string() << std::endl; + printheader(message, "Host"); + printheader(message, "X-Forwarded-For"); + printheader(message, "Accept"); + printheader(message, "Test"); + changeheader(message, "Test", "new test"); + changeheader(message, "Host", "new host"); + std::cout << message.as_string() << std::endl; + std::cout << message.body("type=project&id=303") << std::endl; + std::cout << message.body() << std::endl; + std::cout << message.as_string() << std::endl; + } + catch(...) {} + + try { + http_message r; + r.header("Host", "img.unitcom.co.jp"); + 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)"); + r.header("Accept", "image/png,image/*;q=0.8,*/*;q=0.5"); + r.header("Accept-Language", "ja,en-us;q=0.7,en;q=0.3"); + r.header("Accept-Encoding", "gzip,deflate"); + r.header("Accept-Charset", "Shift_JIS,utf-8;q=0.7,*;q=0.7"); + r.header("Keep-Alive", "300"); + r.header("Connection", "keep-alive"); + r.header("Referer", "http://www.faith-go.co.jp/special/"); + r.header("Cookie", "ASPSESSIONIDQCCQBQBR=HHKHICIACCKKHPIIECCOBOJG"); + r.body("TEST__TEST"); + std::cout << r.as_string() << std::endl; + } + catch(...) {} + + try { +std::string text = +"Host: 192.168.0.4:7780\r\n" +"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" +"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +"Accept-Language: ja,en-us;q=0.7,en;q=0.3\r\n" +"Accept-Encoding: gzip,deflate\r\n" +"Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r\n" +"Keep-Alive: 300\r\n" +"Connection: keep-alive\r\n" +"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" +"Cache-Control: max-age=0\r\n" +"\r\n"; + http_message re(text); + std::cout << re.as_string() << std::endl; + } + catch(...){} + return 0; +} diff --git a/include/httprequest.h b/include/http_message.h similarity index 75% rename from include/httprequest.h rename to include/http_message.h index f100584..b5a1463 100644 --- a/include/httprequest.h +++ b/include/http_message.h @@ -1,5 +1,5 @@ /* - * @file httprequest.h + * @file http_message.h * @brief HTTP Request Message Header * * Copyright (C) 2009 NTT COMWARE Corporation. @@ -21,15 +21,18 @@ * **********************************************************************/ -#ifndef __HTTPREQUEST_H__ -#define __HTTPREQUEST_H__ +#ifndef __HTTP_MESSAGE_H__ +#define __HTTP_MESSAGE_H__ #include #include #include #include +#include +#include +#include #include -#include "httprequest_enum.h" +#include "http_message_enum.h" #include "logger_wrapper.h" using boost::multi_index_container; @@ -47,13 +50,10 @@ typedef multi_index_container< typedef header_container::index_iterator::type field_map_iterator; typedef std::pair field_range; -//! HTTP Request Class (RFC2616) -class http_request +//! HTTP Message Class (RFC2616) +class http_message { protected: - std::string _method; - std::string _request_uri; - std::string _http_version; /* * _header : keep header fields order and fast key lookup. * @@ -64,31 +64,25 @@ protected: * the order of these field values when a message is forwarded. */ header_container _header; - std::string _message; + std::string _body; std::string incomplete; - std::string raw_request; + std::string raw_message; bool modified; + std::string convert_upper_camel_case(std::string); public: - http_request(); - http_request( std::string ); - ~http_request(); + http_message(); + http_message( std::string ); + ~http_message(); - std::string method(); - std::string method( std::string ); - std::string request_uri(); - std::string request_uri( std::string ); - std::string http_version(); - std::string http_version( std::string ); field_range header( std::string ); void header( std::string, std::string ); - std::string message(); - std::string message( std::string ); + std::string body(); + std::string body( std::string ); - std::string request_line(); std::string as_string(); void parse( std::string ); void rebuild(); }; -#endif //__HTTPREQUEST_H__ +#endif //__HTTP_MESSAGE_H__ diff --git a/include/http_message_enum.h b/include/http_message_enum.h new file mode 100644 index 0000000..c5ef324 --- /dev/null +++ b/include/http_message_enum.h @@ -0,0 +1,40 @@ +/* + * @file http_message_enum.h + * @brief HTTP Request Message Enum Header + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#ifndef __HTTP_MESSAGE_ENUM_H__ +#define __HTTP_MESSAGE_ENUM_H__ + +enum HTTP_MESSAGE_POSITION +{ + MESSAGE_TOP = 0, + MESSAGE_FIELD_NAME, + MESSAGE_FIELD_NAME_COLON, + MESSAGE_FIELD_VALUE, + MESSAGE_CR, + MESSAGE_LF, + MESSAGE_LAST_CR, + MESSAGE_LAST_LF, + MESSAGE_BODY, +}; + +#endif //__HTTP_MESSAGE_ENUM_H__ diff --git a/src/httprequest.cpp b/include/http_request.cpp similarity index 74% rename from src/httprequest.cpp rename to include/http_request.cpp index 8ba42e9..ddf97dc 100644 --- a/src/httprequest.cpp +++ b/include/http_request.cpp @@ -1,5 +1,5 @@ /* - * @file httprequest.cpp + * @file http_request.cpp * @brief module of HTTP Request * @brief HTTP Request parser * @@ -22,7 +22,8 @@ * **********************************************************************/ -#include "httprequest.h" +//#define DEBUG +#include "http_request.h" /*! * HTTP Request constructor. @@ -32,8 +33,8 @@ http_request::http_request() modified(false) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 1, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log "in/out_function : Constructor http_request::http_request(void)"); } /*------ DEBUG LOG END ------*/ @@ -50,8 +51,8 @@ http_request::http_request(std::string header) modified(false) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 1, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log "in/out_function : Constructor http_request::http_request(std::string header) : " "header(%s)", header.c_str()); } @@ -65,8 +66,8 @@ http_request::http_request(std::string header) http_request::~http_request() { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 2, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 2, // XXX log "in/out_function : Destructor http_request::~http_request(void)"); } /*------ DEBUG LOG END ------*/ @@ -80,10 +81,10 @@ http_request::~http_request() std::string http_request::method() { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::method(void)"); - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::method(void) : " "return(%s)", this->_method.c_str()); } @@ -102,8 +103,8 @@ std::string http_request::method() std::string http_request::method(std::string _method) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::method(std::string _method) : " "_method(%s)", _method.c_str()); } @@ -114,8 +115,8 @@ std::string http_request::method(std::string _method) this->modified = true; /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::method(std::string _method) : " "return(%s)", ret.c_str()); } @@ -132,10 +133,10 @@ std::string http_request::method(std::string _method) std::string http_request::request_uri() { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::request_uri(void)"); - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::request_uri(void) : " "return(%s)", this->_request_uri.c_str()); } @@ -154,8 +155,8 @@ std::string http_request::request_uri() std::string http_request::request_uri(std::string _request_uri) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::request_uri(std::string _request_uri) : " "_request_uri(%s)", _request_uri.c_str()); } @@ -166,8 +167,8 @@ std::string http_request::request_uri(std::string _request_uri) this->modified = true; /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::_request_uri(std::string _request_uri) : " "return(%s)", ret.c_str()); } @@ -184,10 +185,10 @@ std::string http_request::request_uri(std::string _request_uri) std::string http_request::http_version() { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::http_version(void)"); - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::http_version(void) : " "return(%s)", this->_http_version.c_str()); } @@ -206,8 +207,8 @@ std::string http_request::http_version() std::string http_request::http_version(std::string _http_version) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::http_version(std::string _http_version) : " "_http_version(%s)", _http_version.c_str()); } @@ -218,8 +219,8 @@ std::string http_request::http_version(std::string _http_version) this->modified = true; /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::http_version(std::string _http_version) : " "return(%s)", ret.c_str()); } @@ -237,8 +238,8 @@ std::string http_request::http_version(std::string _http_version) field_range http_request::header(std::string field_name) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : field_range http_request::header(std::string field_name) : " "field_name(%s)", field_name.c_str()); } @@ -247,8 +248,8 @@ field_range http_request::header(std::string field_name) field_range ret = this->_header.get().equal_range(field_name); /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : field_range http_request::header(std::string field_name)"); } /*------ DEBUG LOG END ------*/ @@ -266,8 +267,8 @@ field_range http_request::header(std::string field_name) void http_request::header(std::string field_name, std::string field_value) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : field_range http_request::header(std::string field_name, std::string field_value) : " "field_name(%s), field_value(%s)", field_name.c_str(), field_value.c_str()); } @@ -289,8 +290,8 @@ void http_request::header(std::string field_name, std::string field_value) } /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : field_range http_request::header(std::string field_name, std::string field_value)"); } /*------ DEBUG LOG END ------*/ @@ -304,10 +305,10 @@ void http_request::header(std::string field_name, std::string field_value) std::string http_request::message() { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::message(void)"); - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::message(void) : " "return(%s)", this->_message.c_str()); } @@ -326,8 +327,8 @@ std::string http_request::message() std::string http_request::message(std::string _message) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::http_version(std::string _message) : " "_message(%s)", _message.c_str()); } @@ -338,8 +339,8 @@ std::string http_request::message(std::string _message) this->modified = true; /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::message(std::string _message) : " "return(%s)", ret.c_str()); } @@ -356,8 +357,8 @@ std::string http_request::message(std::string _message) std::string http_request::request_line() { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::request_line(void)"); } /*------ DEBUG LOG END ------*/ @@ -365,8 +366,8 @@ std::string http_request::request_line() std::string ret = this->method() + " " + this->request_uri() + " " + this->http_version() + "\r\n"; /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::request_line(void) : " "return(%s)", ret.c_str()); } @@ -383,8 +384,8 @@ std::string http_request::request_line() std::string http_request::as_string() { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : std::string http_request::as_string(void)"); } /*------ DEBUG LOG END ------*/ @@ -393,8 +394,8 @@ std::string http_request::as_string() this->rebuild(); /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : std::string http_request::as_string(void) : " "return(%s)", this->raw_request.c_str()); } @@ -411,8 +412,8 @@ std::string http_request::as_string() void http_request::parse(std::string request) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : void http_request::parse(std::string request) : " "request(%s)", request.c_str()); } @@ -461,8 +462,8 @@ void http_request::parse(std::string request) pos = REQUEST_METHOD_SP; } else if (!isalpha(*ptr) && !isdigit(*ptr)) { // XXX not enough /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid Method"); } /*------ DEBUG LOG END ------*/ @@ -523,8 +524,8 @@ void http_request::parse(std::string request) start = ptr; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid Request-URI"); } /*------ DEBUG LOG END ------*/ @@ -543,8 +544,8 @@ void http_request::parse(std::string request) *ptr != '(' && *ptr != ')' && *ptr != '*' && *ptr != '_' && *ptr != ':' && *ptr != ';') { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid Request-URI"); } /*------ DEBUG LOG END ------*/ @@ -562,8 +563,8 @@ void http_request::parse(std::string request) start = ptr; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -577,8 +578,8 @@ void http_request::parse(std::string request) pos = REQUEST_HTTP_VERSION_T1; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -592,8 +593,8 @@ void http_request::parse(std::string request) pos = REQUEST_HTTP_VERSION_T2; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -607,8 +608,8 @@ void http_request::parse(std::string request) pos = REQUEST_HTTP_VERSION_P; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -622,8 +623,8 @@ void http_request::parse(std::string request) pos = REQUEST_HTTP_VERSION_SLASH; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -637,8 +638,8 @@ void http_request::parse(std::string request) pos = REQUEST_HTTP_VERSION_MAJOR; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -652,8 +653,8 @@ void http_request::parse(std::string request) pos = REQUEST_HTTP_VERSION_DOT; } else if (!isdigit(*ptr)) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -667,8 +668,8 @@ void http_request::parse(std::string request) pos = REQUEST_HTTP_VERSION_MINOR; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -683,8 +684,8 @@ void http_request::parse(std::string request) this->_http_version.assign(start, ptr); } else if (!isdigit(*ptr)) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); } /*------ DEBUG LOG END ------*/ @@ -698,8 +699,8 @@ void http_request::parse(std::string request) pos = REQUEST_LF; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : not CRLF"); } /*------ DEBUG LOG END ------*/ @@ -740,8 +741,8 @@ void http_request::parse(std::string request) pos = REQUEST_LAST_CR; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : not CRLF"); } /*------ DEBUG LOG END ------*/ @@ -759,8 +760,8 @@ void http_request::parse(std::string request) *ptr != '$' && *ptr != '&' && *ptr != '*' && *ptr != '+' && *ptr != '%') { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid header field name."); } /*------ DEBUG LOG END ------*/ @@ -783,8 +784,8 @@ void http_request::parse(std::string request) field_pair.second.clear(); } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid header field value.('%c')", *ptr); } /*------ DEBUG LOG END ------*/ @@ -805,8 +806,8 @@ void http_request::parse(std::string request) *ptr != '{' && *ptr != '}' && *ptr != '?' && *ptr != '"' && *ptr != '|' && *ptr != '/' && *ptr != '\\'&& *ptr != '\t' ) { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : Invalid header field value.('%c')", *ptr); } /*------ DEBUG LOG END ------*/ @@ -820,8 +821,8 @@ void http_request::parse(std::string request) pos = REQUEST_LAST_LF; } else { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request) : not CRLF"); } /*------ DEBUG LOG END ------*/ @@ -849,8 +850,8 @@ void http_request::parse(std::string request) } /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::parse(std::string request)"); } /*------ DEBUG LOG END ------*/ @@ -862,8 +863,8 @@ void http_request::parse(std::string request) void http_request::rebuild() { /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "in_function : void http_request::rebuild()"); } /*------ DEBUG LOG END ------*/ @@ -881,9 +882,98 @@ void http_request::rebuild() this->raw_request += "\r\n" + this->message(); /*-------- DEBUG LOG --------*/ - if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_HTTP)) { - LOGGER_PUT_LOG_DEBUG(LOG_CAT_HTTP, 3, // XXX log + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log "out_function : void http_request::rebuild()"); } /*------ DEBUG LOG END ------*/ } + +void printheader(http_request& request, std::string name) { + field_range r; + r = request.header(name); + while (r.first != r.second) { + std::cout << "=======> HEADER(" << r.first->first << "): " << r.first->second<< std::endl; + r.first++; + } +} + +void changeheader(http_request& request, std::string name, std::string value) { + request.header(name, value); + printheader(request, name); +} + +int main() { +/* + try { + http_request req; + req.parse("GET / HTTP/1.0\n"); + std::cout << "=======> METHOD: " << req.method() << std::endl; + } + catch(...) {} +*/ + + try { + 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"); + std::cout << request.as_string() << std::endl; + std::cout << "=======> METHOD: " << request.method() << std::endl; + std::cout << "=======> URI: " << request.request_uri() << std::endl; + std::cout << "=======> VERSION: " << request.http_version() << std::endl; + printheader(request, "Host"); + printheader(request, "X-Forwarded-For"); + printheader(request, "Accept"); + printheader(request, "Test"); + changeheader(request, "Test", "new test"); + changeheader(request, "Host", "new host"); + std::cout << request.as_string() << std::endl; + std::cout << request.request_line() << std::endl; +// std::cout << request.method("TRACE") << std::endl; +// std::cout << request.request_uri("/?type=project&id=393") << std::endl; +// std::cout << request.http_version("HTTP/1.0") << std::endl; + std::cout << request.request_line() << std::endl; + std::cout << request.message("type=project&id=303") << std::endl; + std::cout << request.message() << std::endl; + std::cout << request.as_string() << std::endl; + } + catch(...) {} + + try { + http_request r; + r.method("GET"); + r.request_uri("/index.html"); + r.http_version("HTTP/1.1"); + r.header("Host", "img.unitcom.co.jp"); + 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)"); + r.header("Accept", "image/png,image/*;q=0.8,*/*;q=0.5"); + r.header("Accept-Language", "ja,en-us;q=0.7,en;q=0.3"); + r.header("Accept-Encoding", "gzip,deflate"); + r.header("Accept-Charset", "Shift_JIS,utf-8;q=0.7,*;q=0.7"); + r.header("Keep-Alive", "300"); + r.header("Connection", "keep-alive"); + r.header("Referer", "http://www.faith-go.co.jp/special/"); + r.header("Cookie", "ASPSESSIONIDQCCQBQBR=HHKHICIACCKKHPIIECCOBOJG"); + r.message("TEST__TEST"); + std::cout << r.as_string() << std::endl; + } + catch(...) {} + + try { +std::string text = +"GET /cgi-bin/env.cgi HTTP/1.1\r\n" +"Host: 192.168.0.4:7780\r\n" +"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" +"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +"Accept-Language: ja,en-us;q=0.7,en;q=0.3\r\n" +"Accept-Encoding: gzip,deflate\r\n" +"Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r\n" +"Keep-Alive: 300\r\n" +"Connection: keep-alive\r\n" +"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" +"Cache-Control: max-age=0\r\n" +"\r\n"; + http_request re(text); + std::cout << re.as_string() << std::endl; + } + catch(...){} + return 0; +} diff --git a/include/http_request.h b/include/http_request.h new file mode 100644 index 0000000..225b9e2 --- /dev/null +++ b/include/http_request.h @@ -0,0 +1,61 @@ +/* + * @file http_request.h + * @brief HTTP Request Message Header + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#ifndef __HTTP_REQUEST_H__ +#define __HTTP_REQUEST_H__ + +#include +#include +#include +#include +#include +#include "http_message.h" +#include "http_request_enum.h" +#include "logger_wrapper.h" + +//! HTTP Request Class (RFC2616) +class http_request : public http_message +{ +private: + std::string _method; + std::string _request_uri; + std::string _http_version; + +public: + http_request(); + http_request( std::string ); + ~http_request(); + + std::string method(); + std::string method( std::string ); + std::string request_uri(); + std::string request_uri( std::string ); + std::string http_version(); + std::string http_version( std::string ); + std::string request_line(); + std::string as_string(); + void parse( std::string ); + void rebuild(); +}; + +#endif //__HTTP_REQUEST_H__ diff --git a/include/http_request_enum.h b/include/http_request_enum.h new file mode 100644 index 0000000..cf21716 --- /dev/null +++ b/include/http_request_enum.h @@ -0,0 +1,46 @@ +/* + * @file http_request_enum.h + * @brief HTTP Request Message Enum Header + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#ifndef __HTTP_REQUEST_ENUM_H__ +#define __HTTP_REQUEST_ENUM_H__ + +enum HTTP_REQUEST_POSITION +{ + REQUEST_TOP = 0, + REQUEST_METHOD, + REQUEST_METHOD_SP, + REQUEST_REQUEST_URI, + REQUEST_REQUEST_URI_SP, + REQUEST_HTTP_VERSION_H, + REQUEST_HTTP_VERSION_T1, + REQUEST_HTTP_VERSION_T2, + REQUEST_HTTP_VERSION_P, + REQUEST_HTTP_VERSION_SLASH, + REQUEST_HTTP_VERSION_MAJOR, + REQUEST_HTTP_VERSION_DOT, + REQUEST_HTTP_VERSION_MINOR, + REQUEST_CR, + REQUEST_LF, +}; + +#endif //__HTTP_REQUEST_ENUM_H__ diff --git a/include/http_response.h b/include/http_response.h new file mode 100644 index 0000000..5ce5a67 --- /dev/null +++ b/include/http_response.h @@ -0,0 +1,57 @@ +/* + * @file http_response.h + * @brief HTTP Response Message Header + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#ifndef __HTTP_RESPONSE_H__ +#define __HTTP_RESPONSE_H__ + +#include +#include "http_message.h" +#include "http_response_enum.h" +#include "logger_wrapper.h" + +//! HTTP Response Class (RFC2616) +class http_response : public http_message +{ +private: + std::string _http_version; + std::string _status_code; + std::string _reason_phrase; + +public: + http_response(); + http_response( std::string ); + ~http_response(); + + std::string http_version(); + std::string http_version( std::string ); + std::string status_code(); + std::string status_code( std::string ); + std::string reason_phrase(); + std::string reason_phrase( std::string ); + std::string status_line(); + std::string as_string(); + void parse( std::string ); + void rebuild(); +}; + +#endif //__HTTP_RESPONSE_H__ diff --git a/include/http_response_enum.h b/include/http_response_enum.h new file mode 100644 index 0000000..e2e16a7 --- /dev/null +++ b/include/http_response_enum.h @@ -0,0 +1,48 @@ +/* + * @file http_response_enum.h + * @brief HTTP Response Message Enum Header + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#ifndef __HTTP_RESPONSE_ENUM_H__ +#define __HTTP_RESPONSE_ENUM_H__ + +enum HTTP_RESPONSE_POSITION +{ + RESPONSE_TOP = 0, + RESPONSE_HTTP_VERSION_H, + RESPONSE_HTTP_VERSION_T1, + RESPONSE_HTTP_VERSION_T2, + RESPONSE_HTTP_VERSION_P, + RESPONSE_HTTP_VERSION_SLASH, + RESPONSE_HTTP_VERSION_MAJOR, + RESPONSE_HTTP_VERSION_DOT, + RESPONSE_HTTP_VERSION_MINOR, + RESPONSE_HTTP_VERSION_SP, + RESPONSE_STATUS_CODE1, + RESPONSE_STATUS_CODE2, + RESPONSE_STATUS_CODE3, + RESPONSE_STATUS_CODE_SP, + RESPONSE_REASON_PHRASE, + RESPONSE_CR, + RESPONSE_LF, +}; + +#endif //__HTTP_RESPONSE_ENUM_H__ diff --git a/logger/logger_enum.h b/logger/logger_enum.h index 84931f8..8c15614 100644 --- a/logger/logger_enum.h +++ b/logger/logger_enum.h @@ -59,7 +59,8 @@ enum LOG_CATEGORY_TAG LOG_CAT_SSLPROXY_SERVER, LOG_CAT_SSLPROXY_SESSION, LOG_CAT_SSLPROXY_CONNECTION, - LOG_CAT_HTTP, + LOG_CAT_PACKET_EDIT, + LOG_CAT_PACKET_EDIT_HTTP, LOG_CAT_END }; diff --git a/logger/logger_impl.cpp b/logger/logger_impl.cpp index ef42a1a..3803f7d 100644 --- a/logger/logger_impl.cpp +++ b/logger/logger_impl.cpp @@ -72,7 +72,8 @@ char l7vs::LoggerImpl::categoryTable[][LOGGER_CATEGORY_NUM] = { "sslproxy_server", "sslproxy_session", "sslproxy_connection", - "http", + "packet_edit", + "packet_edit_http", "end" }; diff --git a/src/Makefile.am b/src/Makefile.am index eb07130..1a12905 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,12 +14,16 @@ sslproxy_SOURCES = \ ../include/sslproxy.h \ ../include/sslproxyserver.h \ ../include/sslproxysession.h \ - ../include/httprequest.h \ + ../include/http_message.h \ + ../include/http_request.h \ + ../include/http_response.h \ sslproxy.cpp \ sslproxymain.cpp \ sslproxyserver.cpp \ sslproxysession.cpp \ - httprequest.cpp + http_message.cpp \ + http_request.cpp \ + http_response.cpp sslproxy_LDADD = ../logger/libsslproxy_logger.a \ ../parameter/libsslproxy_parameter.a \ diff --git a/src/http_message.cpp b/src/http_message.cpp new file mode 100644 index 0000000..9af3ec3 --- /dev/null +++ b/src/http_message.cpp @@ -0,0 +1,538 @@ +/* + * @file http_message.cpp + * @brief module of HTTP Message + * @brief HTTP Message parser + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#include "http_message.h" + +/*! + * HTTP Message constructor. + */ +http_message::http_message() + : + modified(false) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log + "in/out_function : Constructor http_message::http_message(void)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * HTTP Message constructor. + * Parse HTTP message header. + * + * @param[in] header full http message header string + */ +http_message::http_message(std::string header) + : + modified(false) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log + "in/out_function : Constructor http_message::http_message(std::string header) : " + "header(%s)", header.c_str()); + } + /*------ DEBUG LOG END ------*/ + this->parse(header); +} + +/*! + * HTTP Message destructor. + */ +http_message::~http_message() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 2, // XXX log + "in/out_function : Destructor http_message::~http_message(void)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Get HTTP header field function. + * + * @param[in] field_name lookup field name + * @return header field value + */ +field_range http_message::header(std::string field_name) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : field_range http_message::header(std::string field_name) : " + "field_name(%s)", field_name.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string name = convert_upper_camel_case(field_name); + field_range ret = this->_header.get().equal_range(name); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : field_range http_message::header(std::string field_name)"); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Set HTTP header field function. + * Set new HTTP header field and return old HTTP header field. + * + * @param[in] field_name lookup field name + * @param[in] field_value field value + */ +void http_message::header(std::string field_name, std::string field_value) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : field_range http_message::header(std::string field_name, std::string field_value) : " + "field_name(%s), field_value(%s)", field_name.c_str(), field_value.c_str()); + } + /*------ DEBUG LOG END ------*/ + + bool changed = false; + std::string name = convert_upper_camel_case(field_name); + field_range ret = this->_header.get().equal_range(name); + field_map_iterator it = ret.first; + field_map_iterator it_end = ret.second; + try { + for (;it != it_end; ++it) { + if (field_value != "") { + if ( _header.get().replace(it, field(name, field_value)) ) { + changed = true; + this->modified = true; + } + } + else { + _header.get().erase(it); + changed = true; + this->modified = true; + } + } + if (!changed && field_value != "") { + _header.get().insert( field(name, field_value) ); + this->modified = true; + } + } + catch (...) { + // XXX log: insert, replace (no throw by erase) + } + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : field_range http_message::header(std::string field_name, std::string field_value)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Get message body function. + * + * @return message body + */ +std::string http_message::body() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_message::body(void)"); + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_message::body(void) : " + "return(%s)", this->_body.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->_body; +} + +/*! + * Set message body function. + * Set new message body and return old message body. + * + * @param[in] _body new message body + * @return old message body + */ +std::string http_message::body(std::string _body) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_message::http_version(std::string _message) : " + "_body(%s)", _body.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->_body; + this->_body = _body; + this->modified = true; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_message::body(std::string _body) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get full HTTP message function. + * + * @return HTTP message + */ +std::string http_message::as_string() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_message::as_string(void)"); + } + /*------ DEBUG LOG END ------*/ + + if (this->modified) + this->rebuild(); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_message::as_string(void) : " + "return(%s)", this->raw_message.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->raw_message; +} + +/*! + * Parse HTTP header function. + * + * @param[in] message full HTTP message header + */ +void http_message::parse(std::string message) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : void http_message::parse(std::string message) : " + "message(%s)", message.c_str()); + } + /*------ DEBUG LOG END ------*/ + + // save raw message + if (this->raw_message.length() == 0) + this->raw_message = message; + + // parse message + HTTP_MESSAGE_POSITION pos = MESSAGE_TOP; + + /* + * RFC2616 + * OCTET : 8bit data + * CHAR : US-ASCII(0-127) + * UPALPHA : A-Z + * LOALPHA : a-z + * ALPHA : UPALPHA | LOALPHA + * DIGIT : 0-9 + * HEXDIG : A-F | a-f | DIGIT + * SP : SPace(32) + * HT : Horizontal Tab(9) + * CR : Carriage Return(13) + * LF : Line Feed(10) + * CTL : ConTLol char(0-31,127) + * LWS : [CRLF] 1*(SP|HT) + * separators : ()<>@,;:\"/[]?={} and SP, HT + * token : 1*(CHAR not CTL, separators) + */ + std::string::iterator ptr = message.begin(); + std::string::iterator end = message.end(); + std::string::iterator start = ptr; + std::pair field_pair; + while (ptr != end) { + switch(pos) { + /* + * MESSAGE-HEADER : field-name ":" [ field-value ] + * field-name : token + * field-value : *( field-content | LWS ) + * field-content : + * TEXT : + * quoted-string : ( <"> *(qdtext | quoted-pair ) <"> ) + * qdtext : > + * quoted-pair : "\" CHAR + */ + case MESSAGE_TOP: + if (isalpha(*ptr) || *ptr == '-' || isdigit(*ptr) || + *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == '!' || + *ptr == '$' || *ptr == '&' || *ptr == '*' || *ptr == '+' || + *ptr == '%') { + start = ptr; + pos = MESSAGE_FIELD_NAME; + } else if (*ptr == '\r') { // CRLF + CRLF + pos = MESSAGE_LAST_CR; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_CR: + // LF only + if (*ptr == '\n') { + pos = MESSAGE_LF; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_LF: + if (isalpha(*ptr) || *ptr == '-' || isdigit(*ptr) || + *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == '!' || + *ptr == '$' || *ptr == '&' || *ptr == '*' || *ptr == '+' || + *ptr == '%') { + if (field_pair.first.length()) { + field_pair.first = convert_upper_camel_case(field_pair.first); + boost::trim(field_pair.second); + _header.get().insert(field_pair); + field_pair.first.clear(); + } + start = ptr; + pos = MESSAGE_FIELD_NAME; + } else if (*ptr == ' ' || *ptr == '\t') { + pos = MESSAGE_FIELD_VALUE; + } else if (*ptr == '\r') { // CRLF + CRLF + if (field_pair.first.length()) { + field_pair.first = convert_upper_camel_case(field_pair.first); + boost::trim(field_pair.second); + _header.get().insert(field_pair); + field_pair.first.clear(); + } + pos = MESSAGE_LAST_CR; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_FIELD_NAME: + // field-name end with ':' + if (*ptr == ':') { + pos = MESSAGE_FIELD_NAME_COLON; + field_pair.first.assign(start, ptr); + } else if (!isalpha(*ptr) && *ptr != '-' && !isdigit(*ptr) && + *ptr != '.' && *ptr != '_' && *ptr != '~' && *ptr != '!' && + *ptr != '$' && *ptr != '&' && *ptr != '*' && *ptr != '+' && + *ptr != '%') { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : Invalid header field name."); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_FIELD_NAME_COLON: + if (*ptr == ' ' || isalpha(*ptr) || isdigit(*ptr) || *ptr == '-' || + *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == ':' || + *ptr == '@' || *ptr == '!' || *ptr == '$' || *ptr == '&' || + *ptr == '(' || *ptr == ')' || *ptr == '*' || *ptr == '+' || + *ptr == ',' || *ptr == ';' || *ptr == '=' || *ptr == '%' || + *ptr == '<' || *ptr == '>' || *ptr == '[' || *ptr == ']' || + *ptr == '{' || *ptr == '}' || *ptr == '?' || *ptr == '"' || + *ptr == '|' || *ptr == '/' || *ptr == '\\' || *ptr == '\t') { + start = ptr; + pos = MESSAGE_FIELD_VALUE; + } else if (*ptr == '\r') { // omit field value + field_pair.second.clear(); + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : Invalid header field value.('%c')", *ptr); + } + /*------ DEBUG LOG END ------*/ + } + break; + + case MESSAGE_FIELD_VALUE: + // field-value end with CR + if (*ptr == '\r') { + pos = MESSAGE_CR; + field_pair.second.assign(start, ptr); + } else if (*ptr != ' ' && !isalpha(*ptr) && !isdigit(*ptr) && *ptr != '-' && + *ptr != '.' && *ptr != '_' && *ptr != '~' && *ptr != ':' && + *ptr != '@' && *ptr != '!' && *ptr != '$' && *ptr != '&' && + *ptr != '(' && *ptr != ')' && *ptr != '*' && *ptr != '+' && + *ptr != ',' && *ptr != ';' && *ptr != '=' && *ptr != '%' && + *ptr != '<' && *ptr != '>' && *ptr != '[' && *ptr != ']' && + *ptr != '{' && *ptr != '}' && *ptr != '?' && *ptr != '"' && + *ptr != '|' && *ptr != '/' && *ptr != '\\'&& *ptr != '\t' ) { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : Invalid header field value.('%c')", *ptr); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case MESSAGE_LAST_CR: + // LF only + if (*ptr == '\n') { + pos = MESSAGE_LAST_LF; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + /* + * MESSAGE-BODY : *OCTET + */ + case MESSAGE_LAST_LF: + pos = MESSAGE_BODY; + start = ptr; + break; + + case MESSAGE_BODY: + break; + } + ptr++; + } + + switch (pos) { + case MESSAGE_BODY: + this->_body.assign(start, ptr); + } + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::parse(std::string message)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Rebuild HTTP header function. + */ +void http_message::rebuild() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : void http_message::rebuild()"); + } + /*------ DEBUG LOG END ------*/ + + // insertion order + header_container::iterator it = this->_header.begin(); + header_container::iterator it_end = this->_header.end(); + + while (it != it_end) { + this->raw_message += it->first + ": " + it->second + "\r\n"; + it++; + } + + this->raw_message += "\r\n" + this->body(); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_message::rebuild()"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Field name convert function. + * + * @param[in] field_name field name + * @return converted to camel case + */ +std::string http_message::convert_upper_camel_case(std::string field_name) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_message::upper_camel_case(std::string field_name) : " + "field_name(%s)", field_name.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret; + boost::char_separator sep("-_0123456789", "-_0123456789", boost::keep_empty_tokens); + boost::tokenizer > tokens(field_name, sep); + boost::tokenizer >::iterator tok_it = tokens.begin(); + boost::tokenizer >::iterator tok_end = tokens.end(); + for (; tok_it != tok_end; ++tok_it) { + std::string token(*tok_it); + boost::to_lower(token); + token.at(0) = std::toupper(token.at(0)); + ret += token; + } + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_message::upper_camel_case(std::string field_name) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + return ret; +} diff --git a/src/http_request.cpp b/src/http_request.cpp new file mode 100644 index 0000000..bc84313 --- /dev/null +++ b/src/http_request.cpp @@ -0,0 +1,621 @@ +/* + * @file http_request.cpp + * @brief module of HTTP Request + * @brief HTTP Request parser + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#include "http_request.h" + +/*! + * HTTP Request constructor. + */ +http_request::http_request() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log + "in/out_function : Constructor http_request::http_request(void)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * HTTP Request constructor. + * Parse HTTP request header. + * + * @param[in] header full http request header string + */ +http_request::http_request(std::string header) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log + "in/out_function : Constructor http_request::http_request(std::string header) : " + "header(%s)", header.c_str()); + } + /*------ DEBUG LOG END ------*/ + this->parse(header); +} + +/*! + * HTTP Request destructor. + */ +http_request::~http_request() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 2, // XXX log + "in/out_function : Destructor http_request::~http_request(void)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Get method function. + * + * @return method + */ +std::string http_request::method() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_request::method(void)"); + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_request::method(void) : " + "return(%s)", this->_method.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->_method; +} + +/*! + * Set method function. + * Set new method and return old method. + * + * @param[in] method new method + * @return old method + */ +std::string http_request::method(std::string _method) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_request::method(std::string _method) : " + "_method(%s)", _method.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->_method; + this->_method = _method; + this->modified = true; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_request::method(std::string _method) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get request URI function. + * + * @return request URI + */ +std::string http_request::request_uri() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_request::request_uri(void)"); + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_request::request_uri(void) : " + "return(%s)", this->_request_uri.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->_request_uri; +} + +/*! + * Set request URI function. + * Set new request URI and return old request URI. + * + * @param[in] _request_uri new request URI + * @return old request URI + */ +std::string http_request::request_uri(std::string _request_uri) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_request::request_uri(std::string _request_uri) : " + "_request_uri(%s)", _request_uri.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->_request_uri; + this->_request_uri = _request_uri; + this->modified = true; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_request::_request_uri(std::string _request_uri) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get HTTP version function. + * + * @return HTTP version + */ +std::string http_request::http_version() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_request::http_version(void)"); + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_request::http_version(void) : " + "return(%s)", this->_http_version.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->_http_version; +} + +/*! + * Set HTTP version function. + * Set new HTTP version and return old HTTP version. + * + * @param[in] _http_version new HTTP version + * @return old HTTP version + */ +std::string http_request::http_version(std::string _http_version) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_request::http_version(std::string _http_version) : " + "_http_version(%s)", _http_version.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->_http_version; + this->_http_version = _http_version; + this->modified = true; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_request::http_version(std::string _http_version) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get request line function. + * + * @return request line + */ +std::string http_request::request_line() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_request::request_line(void)"); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->method() + " " + this->request_uri() + " " + this->http_version() + "\r\n"; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_request::request_line(void) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get full HTTP request function. + * + * @return HTTP request + */ +std::string http_request::as_string() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_request::as_string(void)"); + } + /*------ DEBUG LOG END ------*/ + + if (this->modified) + this->rebuild(); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_request::as_string(void) : " + "return(%s)", this->raw_message.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->raw_message; +} + +/*! + * Parse HTTP request header function. + * + * @param[in] request full HTTP request header + */ +void http_request::parse(std::string request) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : void http_request::parse(std::string request) : " + "request(%s)", request.c_str()); + } + /*------ DEBUG LOG END ------*/ + + // save raw request + this->raw_message = request; + + // parse request + HTTP_REQUEST_POSITION pos = REQUEST_METHOD; + + /* + * RFC2616 + * OCTET : 8bit data + * CHAR : US-ASCII(0-127) + * UPALPHA : A-Z + * LOALPHA : a-z + * ALPHA : UPALPHA | LOALPHA + * DIGIT : 0-9 + * HEXDIG : A-F | a-f | DIGIT + * SP : SPace(32) + * HT : Horizontal Tab(9) + * CR : Carriage Return(13) + * LF : Line Feed(10) + * CTL : ConTLol char(0-31,127) + * LWS : [CRLF] 1*(SP|HT) + * separators : ()<>@,;:\"/[]?={} and SP, HT + * token : 1*(CHAR not CTL, separators) + */ + std::string::iterator ptr = request.begin(); + std::string::iterator end = request.end(); + std::string::iterator start = ptr; + std::pair field_pair; + while (ptr != end) { + switch(pos) { + /* + * REQUEST-LINE : + * METHOD SP REQUEST-URI SP HTTP-VERSION CRLF + */ + /* + * METHOD : token + */ + case REQUEST_METHOD: + if (*ptr == ' ') { // METHOD end with SP + this->_method.assign(start, ptr); + pos = REQUEST_METHOD_SP; + } else if (!isalpha(*ptr) && !isdigit(*ptr)) { // XXX not enough + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid Method"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + /* + * REQUEST-URI : * | absolute-URI | path-absolute | authority + * + * RFC3986 + * absolute-URI : scheme ":" hier-part [ "?" query ] + * path-absolute : "/" [ segment-nz *( "/" segment ) ] + * authority : [ userinfo "@" ] host [ ":" port ] + * scheme : ALPHA *( ALPHA | DIGIT | "+" | "-" | "." ) + * hier-part : "//" authority path-abempty + * / path-absolute + * / path-rootless + * / path-empty + * query : *( pchar | "/" | "?" ) + * path-abempty : *( "/" segment ) + * path-rootless : segment-nz *( "/" segment ) + * path-empty : no char + * segment-nz : 1*pchar + * segment : *pchar + * userinfo : *( unreserved | pct-encoded | sub-delims | ":" ) + * host : IP-literal | IPv4address | reg-name + * port : *DIGIT + * unreserved : ALPHA | DIGIT | "-" | "." | "_" | "~" + * pct-encoded : "%" HEXDIG HEXDIG + * sub-delims : !$&'()*+,;= + * pchar : unreserved | pct-encoded | subdelims | ":" | "@" + * IP-literal : "[" ( IPv6address | IPvFuture ) "]" + * IPvFuture : "v" 1*HEXDIG "." 1*( unreserved | sub-delims | ":" ) + * IPv6address : 6( h16 ":" ) ls32 + * / "::" 5( h16 ":" ) ls32 + * / [ h16 ] "::" 4( h16 ":" ) ls32 + * / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + * / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + * / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + * / [ *4( h16 ":" ) h16 ] "::" ls32 + * / [ *5( h16 ":" ) h16 ] "::" h16 + * / [ *6( h16 ":" ) h16 ] "::" + * h16 : 1*4HEXDIG + * ls32 : ( h16 ":" h16 ) | IPv4address + * IPv4address : dec-octet "." dec-octet "." dec-octet "." dec-octet + * dec-octet : 0-255 + * reg-name : *( unreserved | pct-encoded | sub-delims ) + */ + case REQUEST_METHOD_SP: + // Request-URI start + // XXX not enough? + if (*ptr == '/' || isalpha(*ptr) || isdigit(*ptr) || *ptr == '-' || + *ptr == '.' || *ptr == '_' || *ptr == '~' || *ptr == ':' || + *ptr == '@' || *ptr == '!' || *ptr == '$' || *ptr == '&' || + *ptr == '(' || *ptr == ')' || *ptr == '*' || *ptr == '+' || + *ptr == ',' || *ptr == ';' || *ptr == '=' || *ptr == '%') { + pos = REQUEST_REQUEST_URI; + start = ptr; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid Request-URI"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_REQUEST_URI: + if (*ptr == ' ') { // Request-URI end with SP + this->_request_uri.assign(start, ptr); + pos = REQUEST_REQUEST_URI_SP; + } else if (!isalpha(*ptr) && !isdigit(*ptr) && *ptr != '/' && // XXX not enough? + *ptr != '.' && *ptr != '=' && *ptr != '%' && *ptr != '?' && + *ptr != '&' && *ptr != '+' && *ptr != '~' && *ptr != ',' && + *ptr != '@' && *ptr != '!' && *ptr != '$' && *ptr != '-' && + *ptr != '(' && *ptr != ')' && *ptr != '*' && *ptr != '_' && + *ptr != ':' && *ptr != ';') { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid Request-URI"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + /* + * HTTP-VERSION : "HTTP" "/" 1*DIGIT "." 1*DIGIT + */ + case REQUEST_REQUEST_URI_SP: + // HTTP-VERSION start + if (*ptr == 'H') { + pos = REQUEST_HTTP_VERSION_H; + start = ptr; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_HTTP_VERSION_H: + // HTTP-VERSION next + if (*ptr == 'T') { + pos = REQUEST_HTTP_VERSION_T1; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_HTTP_VERSION_T1: + // HTTP-VERSION next + if (*ptr == 'T') { + pos = REQUEST_HTTP_VERSION_T2; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_HTTP_VERSION_T2: + // HTTP-VERSION next + if (*ptr == 'P') { + pos = REQUEST_HTTP_VERSION_P; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_HTTP_VERSION_P: + // HTTP-VERSION next + if (*ptr == '/') { + pos = REQUEST_HTTP_VERSION_SLASH; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_HTTP_VERSION_SLASH: + // HTTP-VERSION Mejor number + if (isdigit(*ptr)) { + pos = REQUEST_HTTP_VERSION_MAJOR; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_HTTP_VERSION_MAJOR: + // HTTP-VERSION next dot + if (*ptr == '.') { + pos = REQUEST_HTTP_VERSION_DOT; + } else if (!isdigit(*ptr)) { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_HTTP_VERSION_DOT: + // HTTP-VERSION Minor number + if (isdigit(*ptr)) { + pos = REQUEST_HTTP_VERSION_MINOR; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_HTTP_VERSION_MINOR: + // HTTP-VERSION end with CR + if (*ptr == '\r') { + pos = REQUEST_CR; + this->_http_version.assign(start, ptr); + } else if (!isdigit(*ptr)) { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case REQUEST_CR: + // LF only + if (*ptr == '\n') { + pos = REQUEST_LF; + http_message::parse(std::string(ptr + 1, end)); + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + } + if (pos == REQUEST_LF) + break; + ptr++; + } + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::parse(std::string request)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Rebuild HTTP request header function. + */ +void http_request::rebuild() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : void http_request::rebuild()"); + } + /*------ DEBUG LOG END ------*/ + + this->raw_message = this->request_line(); + http_message::rebuild(); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_request::rebuild()"); + } + /*------ DEBUG LOG END ------*/ +} diff --git a/src/http_response.cpp b/src/http_response.cpp new file mode 100644 index 0000000..7fea5c0 --- /dev/null +++ b/src/http_response.cpp @@ -0,0 +1,624 @@ +/* + * @file http_response.cpp + * @brief module of HTTP Request + * @brief HTTP Request parser + * + * Copyright (C) 2009 NTT COMWARE Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + **********************************************************************/ + +#include "http_response.h" + +/*! + * HTTP Request constructor. + */ +http_response::http_response() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log + "in/out_function : Constructor http_response::http_response(void)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * HTTP Request constructor. + * Parse HTTP response header. + * + * @param[in] header full http response header string + */ +http_response::http_response(std::string header) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 1, // XXX log + "in/out_function : Constructor http_response::http_response(std::string header) : " + "header(%s)", header.c_str()); + } + /*------ DEBUG LOG END ------*/ + this->parse(header); +} + +/*! + * HTTP Request destructor. + */ +http_response::~http_response() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 2, // XXX log + "in/out_function : Destructor http_response::~http_response(void)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Get HTTP version function. + * + * @return HTTP version + */ +std::string http_response::http_version() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_response::http_version(void)"); + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_response::http_version(void) : " + "return(%s)", this->_http_version.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->_http_version; +} + +/*! + * Set HTTP version function. + * Set new HTTP version and return old HTTP version. + * + * @param[in] _http_version new HTTP version + * @return old HTTP version + */ +std::string http_response::http_version(std::string _http_version) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_response::http_version(std::string _http_version) : " + "_http_version(%s)", _http_version.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->_http_version; + this->_http_version = _http_version; + this->modified = true; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_response::http_version(std::string _http_version) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get status code function. + * + * @return status code + */ +std::string http_response::status_code() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_response::status_code(void)"); + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_response::status_code(void) : " + "return(%s)", this->_status_code.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->_status_code; +} + +/*! + * Set status code function. + * Set new status code and return old status code. + * + * @param[in] _status_code new status code + * @return old status code + */ +std::string http_response::status_code(std::string _status_code) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_response::status_code(std::string _status_code) : " + "_status_code(%s)", _status_code.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->_status_code; + this->_status_code = _status_code; + this->modified = true; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_response::status_code(std::string _status_code) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get reason phrase function. + * + * @return reason phrase + */ +std::string http_response::reason_phrase() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_response::reason_phrase(void)"); + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_response::reason_phrase(void) : " + "return(%s)", this->_reason_phrase.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->_reason_phrase; +} + +/*! + * Set reason phrase function. + * Set new reason phrase and return old reason phrase. + * + * @param[in] _reason_phrase new reason phrase + * @return old reason phrase + */ +std::string http_response::reason_phrase(std::string _reason_phrase) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_response::reason_phrase(std::string _reason_phrase) : " + "_reason_phrase(%s)", _reason_phrase.c_str()); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->_reason_phrase; + this->_reason_phrase = _reason_phrase; + this->modified = true; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_response::reason_phrase(std::string _reason_phrase) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get status line function. + * + * @return status line + */ +std::string http_response::status_line() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_response::status_line(void)"); + } + /*------ DEBUG LOG END ------*/ + + std::string ret = this->http_version() + " " + this->status_code() + " " + this->reason_phrase() + "\r\n"; + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_response::status_line(void) : " + "return(%s)", ret.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return ret; +} + +/*! + * Get full HTTP response function. + * + * @return HTTP response + */ +std::string http_response::as_string() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : std::string http_response::as_string(void)"); + } + /*------ DEBUG LOG END ------*/ + + if (this->modified) + this->rebuild(); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : std::string http_response::as_string(void) : " + "return(%s)", this->raw_message.c_str()); + } + /*------ DEBUG LOG END ------*/ + + return this->raw_message; +} + +/*! + * Parse HTTP response header function. + * + * @param[in] request full HTTP response header + */ +void http_response::parse(std::string response) +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : void http_response::parse(std::string response) : " + "response(%s)", response.c_str()); + } + /*------ DEBUG LOG END ------*/ + + // save raw response + this->raw_message = response; + + // parse response + HTTP_RESPONSE_POSITION pos = RESPONSE_TOP; + + /* + * RFC2616 + * OCTET : 8bit data + * CHAR : US-ASCII(0-127) + * UPALPHA : A-Z + * LOALPHA : a-z + * ALPHA : UPALPHA | LOALPHA + * DIGIT : 0-9 + * HEXDIG : A-F | a-f | DIGIT + * SP : SPace(32) + * HT : Horizontal Tab(9) + * CR : Carriage Return(13) + * LF : Line Feed(10) + * CTL : ConTLol char(0-31,127) + * LWS : [CRLF] 1*(SP|HT) + * separators : ()<>@,;:\"/[]?={} and SP, HT + * token : 1*(CHAR not CTL, separators) + */ + std::string::iterator ptr = response.begin(); + std::string::iterator end = response.end(); + std::string::iterator start = ptr; + std::pair field_pair; + while (ptr != end) { + switch(pos) { + /* + * STATUS-LINE : + * HTTP-VERSION SP STATUS-CODE SP REASON-PHRASE CRLF + */ + /* + * HTTP-VERSION : "HTTP" "/" 1*DIGIT "." 1*DIGIT + */ + case RESPONSE_TOP: + // HTTP-VERSION start + if (*ptr == 'H') { + pos = RESPONSE_HTTP_VERSION_H; + start = ptr; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_HTTP_VERSION_H: + // HTTP-VERSION next + if (*ptr == 'T') { + pos = RESPONSE_HTTP_VERSION_T1; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_HTTP_VERSION_T1: + // HTTP-VERSION next + if (*ptr == 'T') { + pos = RESPONSE_HTTP_VERSION_T2; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_HTTP_VERSION_T2: + // HTTP-VERSION next + if (*ptr == 'P') { + pos = RESPONSE_HTTP_VERSION_P; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_HTTP_VERSION_P: + // HTTP-VERSION next + if (*ptr == '/') { + pos = RESPONSE_HTTP_VERSION_SLASH; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_HTTP_VERSION_SLASH: + // HTTP-VERSION Mejor number + if (isdigit(*ptr)) { + pos = RESPONSE_HTTP_VERSION_MAJOR; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_HTTP_VERSION_MAJOR: + // HTTP-VERSION next dot + if (*ptr == '.') { + pos = RESPONSE_HTTP_VERSION_DOT; + } else if (!isdigit(*ptr)) { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_HTTP_VERSION_DOT: + // HTTP-VERSION Minor number + if (isdigit(*ptr)) { + pos = RESPONSE_HTTP_VERSION_MINOR; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_HTTP_VERSION_MINOR: + // HTTP-VERSION end with SP + if (*ptr == ' ') { + pos = RESPONSE_HTTP_VERSION_SP; + this->_http_version.assign(start, ptr); + } else if (!isdigit(*ptr)) { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid HTTP-Version"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + /* + * Status-Code : 3DIGIT + */ + case RESPONSE_HTTP_VERSION_SP: + // STATUS-CODE start + if (isdigit(*ptr)) { + pos = RESPONSE_STATUS_CODE1; + start = ptr; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid Status-Code"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_STATUS_CODE1: + // STATUS-CODE next + if (isdigit(*ptr)) { + pos = RESPONSE_STATUS_CODE2; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid Status-Code"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_STATUS_CODE2: + // STATUS-CODE next + if (isdigit(*ptr)) { + pos = RESPONSE_STATUS_CODE3; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid Status-Code"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_STATUS_CODE3: + // Status-Code end with SP + if (*ptr == ' ') { + pos = RESPONSE_STATUS_CODE_SP; + this->_status_code.assign(start, ptr); + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid Status-Code"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + /* + * Reason-Phrase : * + */ + case RESPONSE_STATUS_CODE_SP: + // Reason-Phrase is OCTET + if (*ptr == '\r') { // omit reason-phrase + pos = RESPONSE_CR; + this->_reason_phrase.clear(); + } else if (*ptr != '\n') { + pos = RESPONSE_REASON_PHRASE; + start = ptr; + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid Reason-Phrase"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_REASON_PHRASE: + // Reason-Phrase end with CR + if (*ptr == '\r') { + pos = RESPONSE_CR; + this->_reason_phrase.assign(start, ptr); + } else if (*ptr == '\n') { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : Invalid Reason-Phrase"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + + case RESPONSE_CR: + // LF only + if (*ptr == '\n') { + pos = RESPONSE_LF; + http_message::parse(std::string(ptr + 1, end)); + } else { + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response) : not CRLF"); + } + /*------ DEBUG LOG END ------*/ + throw -1; + } + break; + } + if (pos == RESPONSE_LF) + break; + ptr++; + } + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::parse(std::string response)"); + } + /*------ DEBUG LOG END ------*/ +} + +/*! + * Rebuild HTTP response header function. + */ +void http_response::rebuild() +{ + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "in_function : void http_response::rebuild()"); + } + /*------ DEBUG LOG END ------*/ + + this->raw_message = this->status_line(); + http_message::rebuild(); + + /*-------- DEBUG LOG --------*/ + if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) { + LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 3, // XXX log + "out_function : void http_response::rebuild()"); + } + /*------ DEBUG LOG END ------*/ +} diff --git a/src/sslproxysession.cpp b/src/sslproxysession.cpp index e59bed3..f8d4dea 100644 --- a/src/sslproxysession.cpp +++ b/src/sslproxysession.cpp @@ -33,7 +33,9 @@ #include "sslproxyserver.h" #include "sslproxysession.h" -#include "httprequest.h" +#include "http_message.h" +#include "http_request.h" +#include "http_response.h" // sslproxy_session constructor /*! @@ -932,7 +934,6 @@ void sslproxy_session::edit_client_message(size_t& bytes_transferred) if (x_forwarded_for_mode != NONE_X_FORWARDED_FOR || custom_field != "") { -LOGGER_PUT_LOG_FATAL(LOG_CAT_SSLPROXY_SESSION, 41, "============= custom"); try { // Parse HTTP request http_request request(std::string(client_buffer, bytes_transferred)); @@ -972,15 +973,12 @@ LOGGER_PUT_LOG_FATAL(LOG_CAT_SSLPROXY_SESSION, 41, "============= custom"); } std::string new_client_buffer = request.as_string(); -LOGGER_PUT_LOG_FATAL(LOG_CAT_SSLPROXY_SESSION, 41, "=============OLD=============\n%s\n==============NEW=============\n%s\n", client_buffer, new_client_buffer.c_str()); -LOGGER_PUT_LOG_FATAL(LOG_CAT_SSLPROXY_SESSION, 41, "======OLD===== %d\n=======NEW====== %d\n", bytes_transferred, new_client_buffer.length()); if (new_client_buffer.length() <= MAX_BUFFER_SIZE) { memcpy(client_buffer, new_client_buffer.c_str(), new_client_buffer.length()); bytes_transferred = new_client_buffer.length(); } } catch (...) { -LOGGER_PUT_LOG_FATAL(LOG_CAT_SSLPROXY_SESSION, 41, "============= parse fail"); // XXX http request parse error } } -- 2.11.0