OSDN Git Service

Merge branch 'packet_edit' into autotools-fix(releng)
authorKohei TANUMA <tanuma@users.sourceforge.jp>
Mon, 10 Aug 2009 16:31:01 +0000 (01:31 +0900)
committerKohei TANUMA <tanuma@users.sourceforge.jp>
Mon, 10 Aug 2009 16:31:01 +0000 (01:31 +0900)
42 files changed:
CHANGES
README
conf/Makefile.am
conf/sslproxy.target.cf [moved from conf/sslproxy.target_1.cf with 55% similarity]
conf/sslproxy.target_2.cf [deleted file]
conf/sslproxyadm.cf
include/http_message.h [new file with mode: 0644]
include/http_message_enum.h [new file with mode: 0644]
include/http_request.h [new file with mode: 0644]
include/http_request_enum.h [new file with mode: 0644]
include/http_response.h [new file with mode: 0644]
include/http_response_enum.h [new file with mode: 0644]
include/httprequest_enum.h [new file with mode: 0644]
include/packet_editor.h [new file with mode: 0644]
include/sslproxy.h
include/sslproxyserver.h
include/sslproxysession.h
logger/lexical_cast.h
logger/logger.cpp
logger/logger.h
logger/logger_enum.h
logger/logger_impl.cpp
logger/logger_impl.h
logger/logger_wrapper.h
logger/strict_time_based_rolling_policy.cpp
logger/strict_time_based_rolling_policy.h
logger/time_and_size_based_rolling_policy.cpp
logger/time_and_size_based_rolling_policy.h
parameter/parameter.cpp
parameter/parameter.h
parameter/parameter_enum.h
parameter/parameter_impl.cpp
parameter/parameter_impl.h
parameter/parameter_wrapper.h
src/Makefile.am
src/http_message.cpp [new file with mode: 0644]
src/http_request.cpp [new file with mode: 0644]
src/http_response.cpp [new file with mode: 0644]
src/packet_editor.cpp [new file with mode: 0644]
src/sslproxy.cpp
src/sslproxymain.cpp
src/sslproxysession.cpp

diff --git a/CHANGES b/CHANGES
index 8e3242b..ffc1e03 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+[Aug. 24, 2009] 1.0.2-0 Kohei TANUMA
+  - New feature: Allows to modify HTTP header messages.
+                 See example of http_request_header, http_response_header
+                 settings in conf/sslproxy.target.cf.
+
 [Mar. 25, 2009] 1.0.1-1 Shinya TAKEBAYASHI
   - Fixed initialization routine
 
diff --git a/README b/README
index 38cde92..4a4e3c9 100644 (file)
--- a/README
+++ b/README
@@ -9,7 +9,7 @@ System requirements
 ===================
 
            OS : Linux 2.6.9(or later)on x86 and x86_64 architecture
-                We recommend to use Redhat Enterprise Linux.
+                We recommend to use Red Hat Enterprise Linux.
 
           CPU : Intel x86 and x86_64 or compatible architecture processors
 
index 1266dbd..ffcbe6c 100644 (file)
@@ -4,6 +4,5 @@ sysconf_sslproxydir = $(sysconfdir)/l7vs/sslproxy
 
 dist_sysconf_sslproxy_DATA = \
        sslproxy.logger_init.cf \
-       sslproxy.target_1.cf \
-       sslproxy.target_2.cf \
+       sslproxy.target.cf \
        sslproxyadm.cf
similarity index 55%
rename from conf/sslproxy.target_1.cf
rename to conf/sslproxy.target.cf
index 766e191..8be6ba4 100644 (file)
@@ -3,8 +3,8 @@
 
 [sslproxy]
 # Global configuration.
-recv_endpoint = "10.144.169.70:33333"
-target_endpoint = "10.144.169.70:11111"
+recv_endpoint = "0.0.0.0:443"
+target_endpoint = "208.77.188.166:80"
 num_thread = 10
 timeout_sec = 30
 
@@ -22,8 +22,8 @@ private_key_passwd_from = "file"
 private_key_passwd_dir = "/etc/l7vs/sslproxy/"
 private_key_passwd_file = "passwd.txt"
 verify_options = "SSL_VERIFY_NONE"
-verify_options = "SSL_VERIFY_PEER"
-verify_options = "SSL_VERIFY_FAIL_IF_NO_PEER_CERT"
+#verify_options = "SSL_VERIFY_PEER"
+#verify_options = "SSL_VERIFY_FAIL_IF_NO_PEER_CERT"
 #verify_options = "SSL_VERIFY_CLIENT_ONCE"
 verify_cert_depth = 9
 #ssl_options = "SSL_OP_MICROSOFT_SESS_ID_BUG"
@@ -41,7 +41,7 @@ ssl_options = "SSL_OP_ALL"
 #ssl_options = "SSL_OP_COOKIE_EXCHANGE"
 #ssl_options = "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION"
 #ssl_options = "SSL_OP_SINGLE_ECDH_USE"
-ssl_options = "SSL_OP_SINGLE_DH_USE"
+#ssl_options = "SSL_OP_SINGLE_DH_USE"
 #ssl_options = "SSL_OP_EPHEMERAL_RSA"
 #ssl_options = "SSL_OP_CIPHER_SERVER_PREFERENCE"
 #ssl_options = "SSL_OP_TLS_ROLLBACK_BUG"
@@ -52,8 +52,8 @@ ssl_options = "SSL_OP_NO_SSLv2"
 #ssl_options = "SSL_OP_PKCS1_CHECK_2"
 #ssl_options = "SSL_OP_NETSCAPE_CA_DN_BUG"
 #ssl_options = "SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG"
-tmp_dh_dir = "/etc/l7vs/sslproxy/"
-tmp_dh_file = "dh512.pem"
+#tmp_dh_dir = "/etc/l7vs/sslproxy/"
+#tmp_dh_file = "dh512.pem"
 cipher_list = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
 
 # SSL session cache configuration.
@@ -61,10 +61,43 @@ session_cache = "on"
 session_cache_size = 20480
 session_cache_timeout = 300
 
+# Packet edit configuration.
+# http_request_header:  Edit HTTP client request header message.
+# http_response_header: Edit HTTP server response header message.
+#   Format: "mode:header-field-name[:header-field-value[:replace-value]]
+#   Mode:   'set', 'unset', 'add' or 'replace'
+#   Macro:  %{CLIENT_ADDR} -> client IP address
+#           %{CLIENT_PORT} -> client port number
+#           %{SERVER_ADDR} -> server IP address
+#           %{SERVER_PORT} -> server port number
+#           %{RECV_ADDR}   -> sslproxy IP address
+#           %{RECV_PORT}   -> sslproxy port number
+#   Example: Insert or overwrite "X-Forwarded-Proto: https"
+#http_request_header = "set:X-Forwarded-Proto:https"
+#   Example: Change Host to real address
+#http_request_header = "set:Host:%{SERVER_ADDR}:%{SERVER_PORT}"
+#   Example: Remove "Cookie" field
+#http_request_header = "unset:Cookie"
+#   Example: Add "X-Forwarded-For: old-value,new-value"
+#            or insert "X-Forwarded-For: new-value"
+#http_request_header = "add:X-Forwarded-For:%{CLIENT_ADDR}"
+#   Example: Add or insert "Via"
+#http_request_header = "add:Via:HTTP/1.1 myserver (sslproxy/1.0)"
+#   Example: Replace keep-alive to close
+#http_request_header = "replace:Connection:keep-alive:close"
+#   Example: Replace MSIE User-Agent to Firefox (regex)
+#http_request_header = "replace:User-Agent:^.*MSIE.*$:Mozilla/5.0 (Windows; U; Windows NT 5.1) Firefox/3.0.0"
+#   Example: Add "Set-Cookie"
+#http_response_header = "add:Set-Cookie:sslproxy=on; path=/; secure"
+#   Example: Remove "Server"
+#http_response_header = "unset:Server"
+#   Example: Change "Content-Type" text/html to text/plain
+#http_response_header = "replace:Content-Type:html:plain"
+
 [logger]
 ## SSLProxy log configuration.
 # sslproxy logfile base name
-sslproxy_log_filename = "/var/log/l7vs/sslproxy/sslproxy.target_1.log"
+sslproxy_log_filename = "/var/log/l7vs/sslproxy/sslproxy.target.log"
 
 # sslproxy log rotate pattern
 sslproxy_rotation = "size"
@@ -86,7 +119,7 @@ sslproxy_max_filesize = "10M"
 conn_log_flag = "on"
 
 # connection logfile base name
-conn_log_filename = "/var/log/l7vs/sslproxy/sslproxy.target_1.conn_log"
+conn_log_filename = "/var/log/l7vs/sslproxy/sslproxy.target.conn_log"
 
 # connection log rotate pattern
 #conn_rotation = "size"
@@ -104,10 +137,12 @@ conn_rotation_timing = "month"
 conn_rotation_timing_value = "1 0:01"
 
 # Log categories level
-sslproxy_logger                        = "warn"
-sslproxy_parameter             = "warn"
-sslproxy_common                        = "warn"
-sslproxy_server                        = "warn"
-sslproxy_session               = "warn"
-sslproxy_connection            = "info"
+sslproxy_logger     = "warn"
+sslproxy_parameter  = "warn"
+sslproxy_common     = "warn"
+sslproxy_server     = "warn"
+sslproxy_session    = "warn"
+sslproxy_connection = "info"
+packet_edit         = "info"
+packet_edit_http    = "info"
 
diff --git a/conf/sslproxy.target_2.cf b/conf/sslproxy.target_2.cf
deleted file mode 100644 (file)
index 42a09ed..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-# sslproxy configuration file.
-# /etc/l7vs/sslproxy/sslproxy.<target_id>.cf
-
-[sslproxy]
-# Global configuration.
-recv_endpoint = "10.144.169.70:44444"
-target_endpoint = "10.144.169.70:22222"
-num_thread = 10
-timeout_sec = 30
-
-# SSL configuration.
-ca_dir = "/etc/l7vs/sslproxy/"
-ca_file = "root.pem"
-cert_chain_dir = "/etc/l7vs/sslproxy/"
-cert_chain_file = "server.pem"
-private_key_dir = "/etc/l7vs/sslproxy/"
-private_key_file = "server.pem"
-private_key_filetype = "SSL_FILETYPE_PEM"
-#private_key_filetype = "SSL_FILETYPE_ASN1"
-#private_key_passwd_from = "console"
-private_key_passwd_from = "file"
-private_key_passwd_dir = "/etc/l7vs/sslproxy/"
-private_key_passwd_file = "passwd.txt"
-verify_options = "SSL_VERIFY_NONE"
-verify_options = "SSL_VERIFY_PEER"
-verify_options = "SSL_VERIFY_FAIL_IF_NO_PEER_CERT"
-#verify_options = "SSL_VERIFY_CLIENT_ONCE"
-verify_cert_depth = 9
-#ssl_options = "SSL_OP_MICROSOFT_SESS_ID_BUG"
-#ssl_options = "SSL_OP_NETSCAPE_CHALLENGE_BUG"
-#ssl_options = "SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG"
-#ssl_options = "SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG"
-#ssl_options = "SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER"
-#ssl_options = "SSL_OP_MSIE_SSLV2_RSA_PADDING"
-#ssl_options = "SSL_OP_SSLEAY_080_CLIENT_DH_BUG"
-#ssl_options = "SSL_OP_TLS_D5_BUG"
-#ssl_options = "SSL_OP_TLS_BLOCK_PADDING_BUG"
-#ssl_options = "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS"
-ssl_options = "SSL_OP_ALL"
-#ssl_options = "SSL_OP_NO_QUERY_MTU"
-#ssl_options = "SSL_OP_COOKIE_EXCHANGE"
-#ssl_options = "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION"
-#ssl_options = "SSL_OP_SINGLE_ECDH_USE"
-ssl_options = "SSL_OP_SINGLE_DH_USE"
-#ssl_options = "SSL_OP_EPHEMERAL_RSA"
-#ssl_options = "SSL_OP_CIPHER_SERVER_PREFERENCE"
-#ssl_options = "SSL_OP_TLS_ROLLBACK_BUG"
-ssl_options = "SSL_OP_NO_SSLv2"
-#ssl_options = "SSL_OP_NO_SSLv3"
-#ssl_options = "SSL_OP_NO_TLSv1"
-#ssl_options = "SSL_OP_PKCS1_CHECK_1"
-#ssl_options = "SSL_OP_PKCS1_CHECK_2"
-#ssl_options = "SSL_OP_NETSCAPE_CA_DN_BUG"
-#ssl_options = "SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG"
-tmp_dh_dir = "/etc/l7vs/sslproxy/"
-tmp_dh_file = "dh512.pem"
-cipher_list = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
-
-# SSL session cache configuration.
-session_cache = "on"
-session_cache_size = 20480
-session_cache_timeout = 300
-
-[logger]
-## SSLProxy log configuration.
-# sslproxy logfile base name
-sslproxy_log_filename = "/var/log/l7vs/sslproxy/sslproxy.target_2.log"
-
-# sslproxy log rotate pattern
-sslproxy_rotation = "size"
-#sslproxy_rotation = "date"
-#sslproxy_rotation = "datesize"
-
-# sslproxy rotate max backup number
-sslproxy_max_backup_index = "10"
-
-# sslproxy rotate file size
-sslproxy_max_filesize = "10M"
-
-# sslproxy rotation timing
-#sslproxy_rotation_timing = "month"
-#sslproxy_rotation_timing_value = "1 0:01"
-
-## Connection log configuration.
-# connection log ON/OFF
-conn_log_flag = "on"
-
-# connection logfile base name
-conn_log_filename = "/var/log/l7vs/sslproxy/sslproxy.target_2.conn_log"
-
-# connection log rotate pattern
-#conn_rotation = "size"
-conn_rotation = "date"
-#conn_rotation = "datesize"
-
-# connection rotate max backup number
-conn_max_backup_index = "10"
-
-# connection rotate file size
-#conn_max_filesize = "10M"
-
-# sslproxy rotation timing
-conn_rotation_timing = "month"
-conn_rotation_timing_value = "1 0:01"
-
-# Log categories level
-sslproxy_logger                        = "warn"
-sslproxy_parameter             = "warn"
-sslproxy_common                        = "warn"
-sslproxy_server                        = "warn"
-sslproxy_session               = "warn"
-sslproxy_connection            = "info"
-
index 10302fa..1216549 100644 (file)
@@ -8,7 +8,7 @@ log_level = "warn"
 
 # SSLProxy process (Target endpoint) configuration.
 [target_1]
-conf_file = "/etc/l7vs/sslproxy/sslproxy.target_1.cf"
+conf_file = "/etc/l7vs/sslproxy/sslproxy.target.cf"
 
-[target_2]
-conf_file = "/etc/l7vs/sslproxy/sslproxy.target_2.cf"
+#[target_2]
+#conf_file = "/etc/l7vs/sslproxy/sslproxy.target2.cf"
diff --git a/include/http_message.h b/include/http_message.h
new file mode 100644 (file)
index 0000000..85064c5
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * @file  http_message.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_MESSAGE_H__
+#define __HTTP_MESSAGE_H__
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/detail/case_conv.hpp>
+#include <boost/tokenizer.hpp>
+#include <string>
+#include "http_message_enum.h"
+#include "logger_wrapper.h"
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+struct field_map; // tag
+typedef std::pair<std::string, std::string> field; // header field
+typedef multi_index_container<
+  field,
+  indexed_by<
+    sequenced<>, // header field order
+    hashed_non_unique< tag<field_map>, member<field, std::string, &field::first> >
+  >
+> header_container;
+typedef header_container::index_iterator<field_map>::type field_map_iterator;
+typedef std::pair<field_map_iterator, field_map_iterator> field_range;
+
+//! HTTP Message Class (RFC2616)
+class http_message
+{
+protected:
+    /*
+     * _header : keep header fields order and fast key lookup.
+     *
+     * RFC2616 Sec 4.2
+     * The order in which header fields with the same field-name are
+     * received is therefore significant to the interpretation of
+     * the combined field value, and thus a proxy MUST NOT change
+     * the order of these field values when a message is forwarded.
+     */
+    header_container    _header;
+    std::string     _body;
+    std::string     incomplete;
+    std::string     raw_message;
+    bool            modified;
+    std::string convert_upper_camel_case(std::string) const;
+
+public:
+    http_message();
+    http_message( std::string );
+    ~http_message();
+
+    field_range header( std::string ) const;
+    void header( std::string, std::string );
+    std::string body() const;
+    std::string body( std::string );
+
+    std::string as_string();
+    void parse( std::string );
+    void rebuild();
+};
+
+#endif //__HTTP_MESSAGE_H__
diff --git a/include/http_message_enum.h b/include/http_message_enum.h
new file mode 100644 (file)
index 0000000..c5ef324
--- /dev/null
@@ -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/include/http_request.h b/include/http_request.h
new file mode 100644 (file)
index 0000000..3dcce4b
--- /dev/null
@@ -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 <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <string>
+#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() const;
+    std::string method( std::string );
+    std::string request_uri() const;
+    std::string request_uri( std::string );
+    std::string http_version() const;
+    std::string http_version( std::string );
+    std::string request_line() const;
+    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 (file)
index 0000000..cf21716
--- /dev/null
@@ -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 (file)
index 0000000..ac323f9
--- /dev/null
@@ -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 <string>
+#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() const;
+    std::string http_version( std::string );
+    std::string status_code() const;
+    std::string status_code( std::string );
+    std::string reason_phrase() const;
+    std::string reason_phrase( std::string );
+    std::string status_line() const;
+    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 (file)
index 0000000..e2e16a7
--- /dev/null
@@ -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/include/httprequest_enum.h b/include/httprequest_enum.h
new file mode 100644 (file)
index 0000000..d263903
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * @file  httprequest_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 __HTTPREQUEST_ENUM_H__
+#define __HTTPREQUEST_ENUM_H__
+
+enum HTTP_REQUEST_POSITION
+{
+    REQUEST_METHOD = 0,
+    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,
+    REQUEST_FIELD_NAME,
+    REQUEST_FIELD_NAME_COLON,
+    REQUEST_FIELD_VALUE,
+    REQUEST_LAST_CR,
+    REQUEST_LAST_LF,
+    REQUEST_MESSAGE,
+};
+
+#endif //__HTTPREQUEST_ENUM_H__
diff --git a/include/packet_editor.h b/include/packet_editor.h
new file mode 100644 (file)
index 0000000..c9d6478
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * @file  packet_editor.h
+ * @brief Packet Editor 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 __PACKET_EDITOR_H__
+#define __PACKET_EDITOR_H__
+
+#include <vector>
+#include "logger_wrapper.h"
+#include "sslproxy.h"
+#include "sslproxysession.h"
+#include "http_message.h"
+#include "http_request.h"
+#include "http_response.h"
+
+class packet_editor
+{
+private:
+    const sslproxy_session* session;
+    void expand_macro(std::string&);
+    std::vector<std::string> split(const std::string&, const std::string&, int);
+
+public:
+    packet_editor(const sslproxy_session*);
+    ~packet_editor();
+    void edit_client(char*, size_t&);
+    void edit_server(char*, size_t&);
+};
+
+#endif //__PACKET_EDITOR_H__
index 9619452..a7f0aa3 100644 (file)
 #define DEFAULT_CONN_LOG_FLAG          "on"
 
 #define DEFAULT_SSL_METHOD             boost::asio::ssl::context::sslv23       //! SSLv23_method
+#define DEFAULT_CLIENT_EDIT            false
+#define DEFAULT_SERVER_EDIT            false
 #define MAX_PASSWD_SIZE                        256
-#define MAX_BUFFER_SIZE                        4096
+#define MAX_READ_SIZE                  4096
+#define MAX_EDIT_SIZE                  MAX_READ_SIZE
+#define MAX_BUFFER_SIZE                        (MAX_READ_SIZE + MAX_EDIT_SIZE)
 #define MAX_TARGET_ID_SIZE             256
 #define TARGET_ID_CHECK_STRING         "/bin/ps -C sslproxy -o args --no-headers | /bin/cut -d\" \" -f2"
 
@@ -94,5 +98,9 @@ extern long session_cache_mode;
 extern long session_cache_size;
 extern long session_cache_timeout;
 extern std::string conn_log_flag;
+extern bool client_packet_edit;
+extern bool server_packet_edit;
+extern std::list<std::pair<std::string, std::string > > http_request_header;
+extern std::list<std::pair<std::string, std::string > > http_response_header;
 
 #endif //__SSLPROXY_H__
index b6a73c0..fbb7576 100644 (file)
@@ -1,60 +1,60 @@
-/*\r
- * @file  sslproxyserver.h\r
- * @brief SSLproxy server Header\r
- *\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************\r
- *\r
- * Distributed under the Boost Software Licence, Version 1.0\r
- * http://www.boost.org/LICENSE_1_0.txt\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef __SSLPROXYSERVER_H__\r
-#define __SSLPROXYSERVER_H__\r
-\r
-#include "sslproxy.h"\r
-#include "sslproxysession.h"\r
-\r
-//! SSLproxy session management table.\r
-extern std::map<long, int> sessionTable;\r
-extern pthread_mutex_t sessionTable_mutex;\r
-\r
-class sslproxy_server\r
-{\r
-protected:\r
-       boost::asio::io_service&                        sslservice;\r
-       boost::asio::ip::tcp::acceptor                  sslacceptor;\r
-       boost::asio::ssl::context                       sslcontext;\r
-       boost::asio::ip::tcp::resolver::iterator        target_endpoint_iterator;\r
-       std::string                                     private_key_passwd;\r
-public:\r
-       // constructor\r
-       sslproxy_server(boost::asio::io_service& io_service,\r
-                       boost::asio::ip::tcp::resolver::iterator target_itr,\r
-                       boost::asio::ip::tcp::endpoint recv_endpoint);\r
-       // destructor\r
-       ~sslproxy_server();\r
-       // Get password callback function.\r
-       std::string get_password();\r
-       // Acception handling function.\r
-       void handle_accept(sslproxy_session* session, const boost::system::error_code& error);\r
-};\r
-\r
-#endif //__SSLPROXYSERVER_H__\r
+/*
+ * @file  sslproxyserver.h
+ * @brief SSLproxy server Header
+ *
+ * Copyright (C) 2008  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
+ *
+ **********************************************************************
+ *
+ * Distributed under the Boost Software Licence, Version 1.0
+ * http://www.boost.org/LICENSE_1_0.txt
+ *
+ **********************************************************************/
+
+#ifndef __SSLPROXYSERVER_H__
+#define __SSLPROXYSERVER_H__
+
+#include "sslproxy.h"
+#include "sslproxysession.h"
+
+//! SSLproxy session management table.
+extern std::map<long, int> sessionTable;
+extern pthread_mutex_t sessionTable_mutex;
+
+class sslproxy_server
+{
+protected:
+       boost::asio::io_service&                        sslservice;
+       boost::asio::ip::tcp::acceptor                  sslacceptor;
+       boost::asio::ssl::context                       sslcontext;
+       boost::asio::ip::tcp::resolver::iterator        target_endpoint_iterator;
+       std::string                                     private_key_passwd;
+public:
+       // constructor
+       sslproxy_server(boost::asio::io_service& io_service,
+                       boost::asio::ip::tcp::resolver::iterator target_itr,
+                       boost::asio::ip::tcp::endpoint recv_endpoint);
+       // destructor
+       ~sslproxy_server();
+       // Get password callback function.
+       std::string get_password();
+       // Acception handling function.
+       void handle_accept(sslproxy_session* session, const boost::system::error_code& error);
+};
+
+#endif //__SSLPROXYSERVER_H__
index db6ca12..edfba37 100644 (file)
@@ -1,95 +1,99 @@
-/*\r
- * @file  sslproxysession.h\r
- * @brief SSLproxy session Header\r
- *\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************\r
- *\r
- * Distributed under the Boost Software Licence, Version 1.0\r
- * http://www.boost.org/LICENSE_1_0.txt\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef __SSLPROXYSESSION_H__\r
-#define __SSLPROXYSESSION_H__\r
-\r
-#include <boost/asio.hpp>\r
-#include <boost/asio/ssl.hpp>\r
-#include <boost/thread.hpp>\r
-\r
-//! SSL socket for client.\r
-typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;\r
-\r
-//! TCP socket for server. (target)\r
-typedef boost::asio::ip::tcp::socket   nomal_socket;\r
-\r
-class sslproxy_session\r
-{\r
-protected:\r
-       nomal_socket                                    server_socket;\r
-       ssl_socket                                      client_socket;\r
-       boost::asio::ip::tcp::resolver::iterator        endpoint_iterator;\r
-       boost::asio::deadline_timer                     timer;\r
-       int                                             cancel_time;\r
-       char                                            client_buffer[MAX_BUFFER_SIZE];\r
-       char                                            server_buffer[MAX_BUFFER_SIZE];\r
-       bool                                            handshaked;\r
-       bool                                            istimeout;\r
-       bool                                            c_r_event;\r
-       bool                                            c_w_event;\r
-       bool                                            s_r_event;\r
-       bool                                            s_w_event;\r
-       bool                                            finishing;\r
-       pthread_mutex_t                                 client_socket_mutex;\r
-       boost::asio::deadline_timer                     cache_timer;\r
-\r
-public:\r
-       // constructor\r
-       sslproxy_session(boost::asio::io_service& ioservice,\r
-                        boost::asio::ssl::context& context,\r
-                        boost::asio::ip::tcp::resolver::iterator itr);\r
-       // destructor\r
-       ~sslproxy_session();\r
-       // Low level socket getting function.\r
-       ssl_socket::lowest_layer_type& low_socket();\r
-       // Get remote endpoint (client address:port) function.\r
-       std::string get_remote_endpoint(ssl_socket& socket);\r
-       // Session start function\r
-       void start();\r
-       // Timer cancel function.\r
-       void cancel(const boost::system::error_code& error);\r
-       // Cache expire function.\r
-       void cache_expire(const boost::system::error_code& error);\r
-       // Session destroy function.\r
-       void destroy_session(sslproxy_session* session);\r
-       // Handshake handling function.\r
-       void handle_handshake(const boost::system::error_code& error);\r
-       // Connect handling function.\r
-       void handle_connect(const boost::system::error_code& error);\r
-       // Client read handling function.\r
-       void handle_client_read(const boost::system::error_code& error, size_t bytes_transferred);\r
-       // Server write handling function.\r
-       void handle_server_write(const boost::system::error_code& error, size_t bytes_transferred);\r
-       // Server read handling function.\r
-       void handle_server_read(const boost::system::error_code& error, size_t bytes_transferred);\r
-       // Client write handling function.\r
-       void handle_client_write(const boost::system::error_code& error, size_t bytes_transferred);\r
-};\r
-\r
-#endif //__SSLPROXYSESSION_H__\r
+/*
+ * @file  sslproxysession.h
+ * @brief SSLproxy session Header
+ *
+ * Copyright (C) 2008  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
+ *
+ **********************************************************************
+ *
+ * Distributed under the Boost Software Licence, Version 1.0
+ * http://www.boost.org/LICENSE_1_0.txt
+ *
+ **********************************************************************/
+
+#ifndef __SSLPROXYSESSION_H__
+#define __SSLPROXYSESSION_H__
+
+#include <boost/asio.hpp>
+#include <boost/asio/ssl.hpp>
+#include <boost/thread.hpp>
+
+//! SSL socket for client.
+typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
+
+//! TCP socket for server. (target)
+typedef boost::asio::ip::tcp::socket   nomal_socket;
+
+class sslproxy_session
+{
+protected:
+       nomal_socket                                    server_socket;
+       ssl_socket                                      client_socket;
+       boost::asio::ip::tcp::resolver::iterator        endpoint_iterator;
+       boost::asio::deadline_timer                     timer;
+       int                                             cancel_time;
+       char                                            client_buffer[MAX_BUFFER_SIZE];
+       char                                            server_buffer[MAX_BUFFER_SIZE];
+       bool                                            handshaked;
+       bool                                            istimeout;
+       bool                                            c_r_event;
+       bool                                            c_w_event;
+       bool                                            s_r_event;
+       bool                                            s_w_event;
+       bool                                            finishing;
+       pthread_mutex_t                                 client_socket_mutex;
+       boost::asio::deadline_timer                     cache_timer;
+
+public:
+       // constructor
+       sslproxy_session(boost::asio::io_service& ioservice,
+                        boost::asio::ssl::context& context,
+                        boost::asio::ip::tcp::resolver::iterator itr);
+       // destructor
+       ~sslproxy_session();
+       // Low level socket getting function.
+       ssl_socket::lowest_layer_type& low_socket();
+       // Get remote endpoint (client address:port) function.
+       std::string get_remote_endpoint() const;
+       // Session start function
+       void start();
+       // Timer cancel function.
+       void cancel(const boost::system::error_code& error);
+       // Cache expire function.
+       void cache_expire(const boost::system::error_code& error);
+       // Session destroy function.
+       void destroy_session(sslproxy_session* session);
+       // Handshake handling function.
+       void handle_handshake(const boost::system::error_code& error);
+       // Connect handling function.
+       void handle_connect(const boost::system::error_code& error);
+       // Client read handling function.
+       void handle_client_read(const boost::system::error_code& error, size_t bytes_transferred);
+       // Server write handling function.
+       void handle_server_write(const boost::system::error_code& error, size_t bytes_transferred);
+       // Server read handling function.
+       void handle_server_read(const boost::system::error_code& error, size_t bytes_transferred);
+       // Client write handling function.
+       void handle_client_write(const boost::system::error_code& error, size_t bytes_transferred);
+    // Edit client message function.
+       void edit_client_message(size_t& bytes_transferred);
+    // Edit server message function.
+       void edit_server_message(size_t& bytes_transferred);
+};
+
+#endif //__SSLPROXYSESSION_H__
index 26d4b90..54c92c7 100644 (file)
@@ -1,54 +1,54 @@
-/*\r
- * @file  lexical_cast.h\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *      \r
- **********************************************************************/\r
-\r
-#ifndef __LEXICAL_CAST_H__\r
-#define __LEXICAL_CAST_H__\r
-\r
-#include <string>\r
-#include <sstream>\r
-\r
-namespace l7vs\r
-{\r
-       class bad_lexical_cast : public std::bad_cast\r
-       {\r
-       public:\r
-               bad_lexical_cast() {}\r
-       };\r
-\r
-       template <typename T>\r
-       T lexical_cast(const std::string& s)\r
-       {\r
-               std::stringstream ss;\r
-               T d;\r
-               ss << s.c_str();\r
-               while( !ss.eof() ){\r
-                       ss >> d;\r
-                       if(ss.fail()) {\r
-                               throw bad_lexical_cast();\r
-                       }\r
-               }\r
-               return d;\r
-       }\r
-}\r
-\r
-#endif //__LEXICAL_CAST_H__\r
+/*
+ * @file  lexical_cast.h
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __LEXICAL_CAST_H__
+#define __LEXICAL_CAST_H__
+
+#include <string>
+#include <sstream>
+
+namespace l7vs
+{
+       class bad_lexical_cast : public std::bad_cast
+       {
+       public:
+               bad_lexical_cast() {}
+       };
+
+       template <typename T>
+       T lexical_cast(const std::string& s)
+       {
+               std::stringstream ss;
+               T d;
+               ss << s.c_str();
+               while( !ss.eof() ){
+                       ss >> d;
+                       if(ss.fail()) {
+                               throw bad_lexical_cast();
+                       }
+               }
+               return d;
+       }
+}
+
+#endif //__LEXICAL_CAST_H__
index 29d38a7..f76dfa2 100644 (file)
-/*\r
- * @file  logger.cpp\r
- * @brief logger module creation class.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#include <logger.h>\r
-#include <logger_impl.h>\r
-\r
-/*!\r
- * default constructor.\r
- * get instance of implement class, and initialize\r
- * @param   void\r
- * @return  void\r
- */\r
-l7vs::Logger::Logger()\r
-{\r
-       if (!LoggerImpl::getInstance().init()) {\r
-               exit(1);\r
-       }\r
-}\r
-\r
-/*!\r
- * destructor.\r
- * @param   void\r
- * @return  void\r
- */\r
-l7vs::Logger::~Logger()\r
-{\r
-}\r
-\r
-/*!\r
- * retrieve category's log level.\r
- * this is only wrapper to implement method.\r
- * @param   category that want to know\r
- * @return  log level\r
- */\r
-LOG_LEVEL_TAG l7vs::Logger::getLogLevel(LOG_CATEGORY_TAG cat)\r
-{\r
-       return LoggerImpl::getInstance().getLogLevel(cat);\r
-}\r
-\r
-/*!\r
- * set category's log level.\r
- * this is only wrapper to implement method.\r
- * @param   category to set log level\r
- * @param   level\r
- * @retval  true  succeed\r
- * @retval  false failed\r
- */\r
-bool l7vs::Logger::setLogLevel(LOG_CATEGORY_TAG cat, LOG_LEVEL_TAG level)\r
-{\r
-       return LoggerImpl::getInstance().setLogLevel(cat, level);\r
-}\r
-\r
-/*!\r
- * output fatal log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   log message \r
- * @param   current file \r
- * @param   current line\r
- * @retrun  void\r
- */\r
-void l7vs::Logger::putLogFatal(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-{\r
-       LoggerImpl::getInstance().putLogFatal(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * output errorl log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   log message \r
- * @param   current file \r
- * @param   current line\r
- * @retrun  void\r
- */\r
-void l7vs::Logger::putLogError(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-{\r
-       LoggerImpl::getInstance().putLogError(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * output warn log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   log message \r
- * @param   current file \r
- * @param   current line\r
- * @retrun  void\r
- */\r
-void l7vs::Logger::putLogWarn(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-{\r
-       LoggerImpl::getInstance().putLogWarn(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * output info log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   log message \r
- * @param   current file \r
- * @param   current line\r
- * @retrun  void\r
- */\r
-void l7vs::Logger::putLogInfo(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-{\r
-       LoggerImpl::getInstance().putLogInfo(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * output debug log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   log message \r
- * @param   current file \r
- * @param   current line\r
- * @retrun  void\r
- */\r
-void l7vs::Logger::putLogDebug(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-{\r
-       LoggerImpl::getInstance().putLogDebug(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * reload configuration.\r
- * this is only wrapper to implement method.\r
- * @param   void\r
- * @return  void\r
- */\r
-void l7vs::Logger::loadConf()\r
-{\r
-       LoggerImpl::getInstance().loadConf();\r
-}\r
+/*
+ * @file  logger.cpp
+ * @brief logger module creation class.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 <logger.h>
+#include <logger_impl.h>
+
+/*!
+ * default constructor.
+ * get instance of implement class, and initialize
+ * @param   void
+ * @return  void
+ */
+l7vs::Logger::Logger()
+{
+       if (!LoggerImpl::getInstance().init()) {
+               exit(1);
+       }
+}
+
+/*!
+ * destructor.
+ * @param   void
+ * @return  void
+ */
+l7vs::Logger::~Logger()
+{
+}
+
+/*!
+ * retrieve category's log level.
+ * this is only wrapper to implement method.
+ * @param   category that want to know
+ * @return  log level
+ */
+LOG_LEVEL_TAG l7vs::Logger::getLogLevel(LOG_CATEGORY_TAG cat)
+{
+       return LoggerImpl::getInstance().getLogLevel(cat);
+}
+
+/*!
+ * set category's log level.
+ * this is only wrapper to implement method.
+ * @param   category to set log level
+ * @param   level
+ * @retval  true  succeed
+ * @retval  false failed
+ */
+bool l7vs::Logger::setLogLevel(LOG_CATEGORY_TAG cat, LOG_LEVEL_TAG level)
+{
+       return LoggerImpl::getInstance().setLogLevel(cat, level);
+}
+
+/*!
+ * output fatal log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   log message 
+ * @param   current file 
+ * @param   current line
+ * @retrun  void
+ */
+void l7vs::Logger::putLogFatal(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+{
+       LoggerImpl::getInstance().putLogFatal(cat, message_id, message, file, line);
+}
+
+/*!
+ * output errorl log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   log message 
+ * @param   current file 
+ * @param   current line
+ * @retrun  void
+ */
+void l7vs::Logger::putLogError(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+{
+       LoggerImpl::getInstance().putLogError(cat, message_id, message, file, line);
+}
+
+/*!
+ * output warn log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   log message 
+ * @param   current file 
+ * @param   current line
+ * @retrun  void
+ */
+void l7vs::Logger::putLogWarn(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+{
+       LoggerImpl::getInstance().putLogWarn(cat, message_id, message, file, line);
+}
+
+/*!
+ * output info log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   log message 
+ * @param   current file 
+ * @param   current line
+ * @retrun  void
+ */
+void l7vs::Logger::putLogInfo(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+{
+       LoggerImpl::getInstance().putLogInfo(cat, message_id, message, file, line);
+}
+
+/*!
+ * output debug log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   log message 
+ * @param   current file 
+ * @param   current line
+ * @retrun  void
+ */
+void l7vs::Logger::putLogDebug(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+{
+       LoggerImpl::getInstance().putLogDebug(cat, message_id, message, file, line);
+}
+
+/*!
+ * reload configuration.
+ * this is only wrapper to implement method.
+ * @param   void
+ * @return  void
+ */
+void l7vs::Logger::loadConf()
+{
+       LoggerImpl::getInstance().loadConf();
+}
index 0586531..1ea56fc 100644 (file)
@@ -1,82 +1,82 @@
-/*\r
- * @file  logger.h\r
- * @brief logger module creation class.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef __LOGGER_H__\r
-#define __LOGGER_H__\r
-\r
-#include <string>\r
-#include <logger_enum.h>\r
-\r
-#define BUF_LEN (4096)\r
-#define DEBUG_STR_LEN (4096)\r
-\r
-namespace l7vs\r
-{\r
-       /*!\r
-        *  Logger creation class.\r
-        *  this class create Logger Inmlement class and mediate function.\r
-        */\r
-       class Logger\r
-       {\r
-       public:\r
-               //! default constructor creates implement class.\r
-               Logger();\r
-               //! destructor.\r
-               ~Logger();\r
-               /*!\r
-                * returns single instance.\r
-                *\r
-                * @param   void\r
-                * @return  instance\r
-                */             \r
-               static Logger& getInstance() {\r
-                       return instance;\r
-               }\r
-               //! load Configuration.\r
-               void loadConf();\r
-               //! retrieve category's log level.\r
-               LOG_LEVEL_TAG getLogLevel(LOG_CATEGORY_TAG cat);\r
-               //! set category's log level.\r
-               bool setLogLevel(LOG_CATEGORY_TAG cat, LOG_LEVEL_TAG level);\r
-               //! output fatal log.\r
-               void putLogFatal(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);\r
-               //! output error log.\r
-               void putLogError(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);\r
-               //! output warn log.\r
-               void putLogWarn(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);\r
-               //! output info log.\r
-               void putLogInfo(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);\r
-               //! output debug log.\r
-               void putLogDebug(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);\r
-\r
-       protected:\r
-               /*!\r
-                * static instance initialize before main. \r
-                * instance will defined in main program.\r
-                */\r
-               static Logger instance;\r
-       };\r
-}      //namespace l7vs\r
-\r
-#endif //__LOGGER_H__\r
+/*
+ * @file  logger.h
+ * @brief logger module creation class.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __LOGGER_H__
+#define __LOGGER_H__
+
+#include <string>
+#include <logger_enum.h>
+
+#define BUF_LEN (4096)
+#define DEBUG_STR_LEN (4096)
+
+namespace l7vs
+{
+       /*!
+        *  Logger creation class.
+        *  this class create Logger Inmlement class and mediate function.
+        */
+       class Logger
+       {
+       public:
+               //! default constructor creates implement class.
+               Logger();
+               //! destructor.
+               ~Logger();
+               /*!
+                * returns single instance.
+                *
+                * @param   void
+                * @return  instance
+                */             
+               static Logger& getInstance() {
+                       return instance;
+               }
+               //! load Configuration.
+               void loadConf();
+               //! retrieve category's log level.
+               LOG_LEVEL_TAG getLogLevel(LOG_CATEGORY_TAG cat);
+               //! set category's log level.
+               bool setLogLevel(LOG_CATEGORY_TAG cat, LOG_LEVEL_TAG level);
+               //! output fatal log.
+               void putLogFatal(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);
+               //! output error log.
+               void putLogError(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);
+               //! output warn log.
+               void putLogWarn(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);
+               //! output info log.
+               void putLogInfo(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);
+               //! output debug log.
+               void putLogDebug(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line);
+
+       protected:
+               /*!
+                * static instance initialize before main. 
+                * instance will defined in main program.
+                */
+               static Logger instance;
+       };
+}      //namespace l7vs
+
+#endif //__LOGGER_H__
index 7fd17c1..8c15614 100644 (file)
@@ -1,91 +1,93 @@
-/*\r
- * @file  logger_enum.h\r
- * @brief logger module constants enumeration.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *      \r
- **********************************************************************/\r
-\r
-#ifndef __LOGGER_ENUM_H__\r
-#define __LOGGER_ENUM_H__\r
-\r
-#include <string>\r
-#include <log4cxx/level.h>\r
-\r
-/*!\r
- * LogLevel enumeration.\r
- */\r
-enum LOG_LEVEL_TAG\r
-{\r
-       LOG_LV_NONE = 0,\r
-       LOG_LV_DEBUG,\r
-       LOG_LV_INFO,\r
-       LOG_LV_WARN,\r
-       LOG_LV_ERROR,\r
-       LOG_LV_FATAL\r
-};\r
-\r
-inline LOG_LEVEL_TAG& operator++(LOG_LEVEL_TAG& level) {\r
-       level = static_cast<LOG_LEVEL_TAG>(level + 1);\r
-       return level;\r
-}\r
-\r
-/*!\r
- * Category enumeration.\r
- * LOG_CAT_SSLPROXY_LOGGER should be first for logger log.\r
- */\r
-enum LOG_CATEGORY_TAG\r
-{\r
-       LOG_CAT_NONE = 0,\r
-       LOG_CAT_SSLPROXY_LOGGER = 1,\r
-       LOG_CAT_SSLPROXY_PARAMETER,\r
-       LOG_CAT_SSLPROXY_COMMON,\r
-       LOG_CAT_SSLPROXY_SERVER,\r
-       LOG_CAT_SSLPROXY_SESSION,\r
-       LOG_CAT_SSLPROXY_CONNECTION,\r
-       LOG_CAT_END\r
-};\r
-\r
-\r
-inline LOG_CATEGORY_TAG& operator++(LOG_CATEGORY_TAG& cat) {\r
-       cat = static_cast<LOG_CATEGORY_TAG>(cat + 1);\r
-       return cat;\r
-}\r
-\r
-/*!\r
- * Rotation enumeration.\r
- */\r
-enum LOG_ROTATION_TAG {\r
-       LOG_ROT_SIZE,\r
-       LOG_ROT_DATE,\r
-       LOG_ROT_DATESIZE\r
-};\r
-\r
-/*!\r
- * RotationTiming enumeration.\r
- */\r
-enum LOG_ROTATION_TIMING_TAG {\r
-       LOG_TIM_YEAR,\r
-       LOG_TIM_MONTH,\r
-       LOG_TIM_WEEK,\r
-       LOG_TIM_DATE,\r
-       LOG_TIM_HOUR\r
-};\r
-       \r
-#endif //__LOGGER_ENUM_H__\r
+/*
+ * @file  logger_enum.h
+ * @brief logger module constants enumeration.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __LOGGER_ENUM_H__
+#define __LOGGER_ENUM_H__
+
+#include <string>
+#include <log4cxx/level.h>
+
+/*!
+ * LogLevel enumeration.
+ */
+enum LOG_LEVEL_TAG
+{
+       LOG_LV_NONE = 0,
+       LOG_LV_DEBUG,
+       LOG_LV_INFO,
+       LOG_LV_WARN,
+       LOG_LV_ERROR,
+       LOG_LV_FATAL
+};
+
+inline LOG_LEVEL_TAG& operator++(LOG_LEVEL_TAG& level) {
+       level = static_cast<LOG_LEVEL_TAG>(level + 1);
+       return level;
+}
+
+/*!
+ * Category enumeration.
+ * LOG_CAT_SSLPROXY_LOGGER should be first for logger log.
+ */
+enum LOG_CATEGORY_TAG
+{
+       LOG_CAT_NONE = 0,
+       LOG_CAT_SSLPROXY_LOGGER = 1,
+       LOG_CAT_SSLPROXY_PARAMETER,
+       LOG_CAT_SSLPROXY_COMMON,
+       LOG_CAT_SSLPROXY_SERVER,
+       LOG_CAT_SSLPROXY_SESSION,
+       LOG_CAT_SSLPROXY_CONNECTION,
+       LOG_CAT_PACKET_EDIT,
+       LOG_CAT_PACKET_EDIT_HTTP,
+       LOG_CAT_END
+};
+
+
+inline LOG_CATEGORY_TAG& operator++(LOG_CATEGORY_TAG& cat) {
+       cat = static_cast<LOG_CATEGORY_TAG>(cat + 1);
+       return cat;
+}
+
+/*!
+ * Rotation enumeration.
+ */
+enum LOG_ROTATION_TAG {
+       LOG_ROT_SIZE,
+       LOG_ROT_DATE,
+       LOG_ROT_DATESIZE
+};
+
+/*!
+ * RotationTiming enumeration.
+ */
+enum LOG_ROTATION_TIMING_TAG {
+       LOG_TIM_YEAR,
+       LOG_TIM_MONTH,
+       LOG_TIM_WEEK,
+       LOG_TIM_DATE,
+       LOG_TIM_HOUR
+};
+       
+#endif //__LOGGER_ENUM_H__
index 1474602..3803f7d 100644 (file)
-/*\r
- * @file  logger_impl.cpp\r
- * @brief logger module implementation class.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#include <sstream>\r
-#include <iomanip>\r
-#include <limits.h>\r
-#include <log4cxx/logmanager.h>\r
-#include <log4cxx/helpers/loglog.h>\r
-#include <log4cxx/rolling/rollingfileappender.h>\r
-#include <log4cxx/rolling/fixedwindowrollingpolicy.h>\r
-#include <log4cxx/rolling/sizebasedtriggeringpolicy.h>\r
-#include <log4cxx/rolling/timebasedrollingpolicy.h>\r
-#include <log4cxx/consoleappender.h>\r
-#include <errno.h>\r
-#include <stdexcept>\r
-\r
-#include "logger_impl.h"\r
-#include "parameter.h"\r
-#include "lexical_cast.h"\r
-#include "strict_time_based_rolling_policy.h"\r
-#include "time_and_size_based_rolling_policy.h"\r
-\r
-#define LOGGER_LAYOUT "%d{%Y/%m/%d %H:%M:%S} [%p] %c %m %t %F:%L%n"\r
-#define LOGGER_DEFAULT_BUFFER_SIZE (8 * 1024)\r
-#define LOGGER_SYSLOG_FACILITY "USER"\r
-#define LOGGER_BACKUP_INDEX_LOWER_LIMIT (1)\r
-#define LOGGER_BACKUP_INDEX_LIMIT (12)\r
-#define LOGGER_FILESIZE_LOWER_LIMIT (65535)\r
-#define LOGGER_FILE_PATTERN "%i"\r
-\r
-#define LOGGER_LOG_FILENAME_KEY "sslproxy_log_filename"\r
-#define LOGGER_ROTATION_KEY "sslproxy_rotation"\r
-#define LOGGER_MAX_BACKUP_INDEX_KEY "sslproxy_max_backup_index"\r
-#define LOGGER_MAX_FILE_SIZE_KEY "sslproxy_max_filesize"\r
-#define LOGGER_ROTATION_TIMING_KEY "sslproxy_rotation_timing"\r
-#define LOGGER_ROTATION_TIMING_VALUE_KEY "sslproxy_rotation_timing_value"\r
-\r
-#define LOGGER_CONN_LOG_FILENAME_KEY "conn_log_filename"\r
-#define LOGGER_CONN_ROTATION_KEY "conn_rotation"\r
-#define LOGGER_CONN_MAX_BACKUP_INDEX_KEY "conn_max_backup_index"\r
-#define LOGGER_CONN_MAX_FILE_SIZE_KEY "conn_max_filesize"\r
-#define LOGGER_CONN_ROTATION_TIMING_KEY "conn_rotation_timing"\r
-#define LOGGER_CONN_ROTATION_TIMING_VALUE_KEY "conn_rotation_timing_value"\r
-\r
-//! for transration between log4cxx::LevelPtr and LOGER_LEVEL_TAG\r
-char l7vs::LoggerImpl::categoryTable[][LOGGER_CATEGORY_NUM] = { \r
-       "none",\r
-       "sslproxy_logger",\r
-       "sslproxy_parameter",\r
-       "sslproxy_common",\r
-       "sslproxy_server",\r
-       "sslproxy_session",\r
-       "sslproxy_connection",\r
-       "end"\r
-       };\r
-\r
-//! for transration between string and LOGGER_CATEGORY_TAG\r
-log4cxx::LevelPtr l7vs::LoggerImpl::levelTable[LOGGER_LEVEL_NUM];\r
-\r
-/*!\r
- * returns single instance.\r
- *\r
- * @param   void\r
- * @return  instance\r
- */\r
-l7vs::LoggerImpl& l7vs::LoggerImpl::getInstance()\r
-{\r
-       if (!instance) {\r
-               instance = new LoggerImpl;\r
-       }\r
-       return *instance;\r
-}\r
-\r
-//! static Logger instance pointer initialized by 0.\r
-l7vs::LoggerImpl* l7vs::LoggerImpl::instance = 0;\r
-\r
-/*!\r
- * initialize function.\r
- * logger initialized to use syslogappender and fileappender(/dev/console)\r
- *\r
- * @param   void\r
- * @retval  true succeed\r
- * @retval  false failed\r
- */\r
-bool l7vs::LoggerImpl::init()\r
-{\r
-       int ret = 0;\r
-       if (initialized) return false;\r
-\r
-       try {\r
-               log4cxx::LoggerPtr root = log4cxx::Logger::getRootLogger();\r
-               if (0 == root) {\r
-                       return false;\r
-               }\r
-               log4cxx::LayoutPtr layout =\r
-                       new log4cxx::PatternLayout(LOGGER_LAYOUT);\r
-               log4cxx::net::SyslogAppenderPtr syslogAppender =\r
-                       new log4cxx::net::SyslogAppender(layout, log4cxx::net::SyslogAppender::getFacility(LOGGER_SYSLOG_FACILITY));\r
-               root->addAppender(syslogAppender);\r
-               log4cxx::WriterAppender* consoleAppender =\r
-                       new log4cxx::ConsoleAppender( layout, log4cxx::ConsoleAppender::getSystemErr() );\r
-               root->addAppender(consoleAppender);\r
-\r
-               for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {\r
-                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-               }\r
-       }\r
-       catch (const std::exception& e) {\r
-               std::ostringstream oss;\r
-               oss <<  "Logger Initialization Failed : " << e.what();\r
-               errorConf(6, oss.str(), __FILE__, __LINE__);\r
-               return false;\r
-       }\r
-       \r
-       ret = gethostname(hostname, HOST_NAME_LEN);\r
-       if (0 > ret) {\r
-               if (LOG_LV_WARN >= this->getLogLevel(loggerCategory)) {\r
-                       this->putLogWarn(loggerCategory,1, "Fail to get Hostname", __FILE__, __LINE__);\r
-               }\r
-       }       \r
-\r
-       if (LOG_LV_INFO >= this->getLogLevel(loggerCategory)) {\r
-               this->putLogInfo(loggerCategory,1, "Logger Initialized.", __FILE__, __LINE__);\r
-       }\r
-\r
-       initialized = true;\r
-       return true;\r
-}\r
-\r
-/*!\r
- * error handling function.\r
- * if error occured, switch appenders to syslogappender and fileappender(/dev/console)\r
- * message will output to syslog/fileappender appender\r
- * \r
- * @param   log message id \r
- * @param   log message \r
- * @param   current file \r
- * @param   current line\r
- * @return  void\r
- */\r
-void l7vs::LoggerImpl::errorConf(unsigned int message_id, const std::string& errorMessage, const char* file, int line)\r
-{\r
-       try {\r
-               log4cxx::LogManager::resetConfiguration();\r
-               log4cxx::LoggerPtr root = log4cxx::Logger::getRootLogger();\r
-               if (0 == root)\r
-                       return;\r
-               log4cxx::LayoutPtr layout =\r
-                       new log4cxx::PatternLayout(LOGGER_LAYOUT);\r
-               log4cxx::net::SyslogAppenderPtr syslogAppender =\r
-                       new log4cxx::net::SyslogAppender(layout, log4cxx::net::SyslogAppender::getFacility(LOGGER_SYSLOG_FACILITY));\r
-               log4cxx::ConsoleAppender* consoleAppender = new log4cxx::ConsoleAppender(layout, log4cxx::ConsoleAppender::getSystemErr() );\r
-                root->addAppender(consoleAppender);\r
-               root->addAppender(syslogAppender);\r
-\r
-               for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {\r
-                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-               }\r
-\r
-               char buf[BUF_LEN];\r
-               snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_FATAL, loggerCategory, message_id, errorMessage.c_str(), hostname);\r
-               log4cxx::Logger::getLogger(categoryTable[loggerCategory])->forcedLog(log4cxx::Level::getFatal(), buf, log4cxx::spi::LocationInfo(file, "", line));\r
-       }\r
-       catch (const std::exception& e) {\r
-               std::ostringstream oss;\r
-               oss <<  "Logger Error Output Failed : " << e.what() << "\n";\r
-               fputs(oss.str().c_str(), stderr);\r
-       }\r
-}\r
-\r
-/*!\r
- * load the logger parameter.\r
- * get settings from parameter component, and configure log4cxx property\r
- *\r
- * @param   void\r
- * @return  void\r
- */\r
-void l7vs::LoggerImpl::loadConf()\r
-{\r
-       for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {\r
-               if (cat == LOG_CAT_SSLPROXY_CONNECTION) {\r
-                       // Connection category Logger setting.\r
-                       log_filename_key          = LOGGER_CONN_LOG_FILENAME_KEY;\r
-                       rotation_key              = LOGGER_CONN_ROTATION_KEY;\r
-                       max_backup_index_key      = LOGGER_CONN_MAX_BACKUP_INDEX_KEY;\r
-                       max_file_size_key         = LOGGER_CONN_MAX_FILE_SIZE_KEY;\r
-                       rotation_timing_key       = LOGGER_CONN_ROTATION_TIMING_KEY;\r
-                       rotation_timing_value_key = LOGGER_CONN_ROTATION_TIMING_VALUE_KEY;\r
-                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                       if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory)) {\r
-                               std::ostringstream oss;\r
-                               oss << "function : void l7vs::LoggerImpl::loadConf() : "\r
-                                   << "Connection category Logger setting. "\r
-                                   << "cat = " << cat;\r
-                               this->putLogDebug(loggerCategory, 1, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-                       /*------ DEBUG LOG END for sslproxy ------*/\r
-               } else {\r
-                       // Other category Logger setting.\r
-                       log_filename_key          = LOGGER_LOG_FILENAME_KEY;\r
-                       rotation_key              = LOGGER_ROTATION_KEY;\r
-                       max_backup_index_key      = LOGGER_MAX_BACKUP_INDEX_KEY;\r
-                       max_file_size_key         = LOGGER_MAX_FILE_SIZE_KEY;\r
-                       rotation_timing_key       = LOGGER_ROTATION_TIMING_KEY;\r
-                       rotation_timing_value_key = LOGGER_ROTATION_TIMING_VALUE_KEY;\r
-                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                       if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory) &&\r
-                           cat != LOG_CAT_SSLPROXY_LOGGER) {\r
-                               std::ostringstream oss;\r
-                               oss << "function : void l7vs::LoggerImpl::loadConf() : "\r
-                                   << "Other category Logger setting. "\r
-                                   << "cat = " << cat;\r
-                               this->putLogDebug(loggerCategory, 2, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-                       /*------ DEBUG LOG END for sslproxy ------*/\r
-               }\r
-               loadCategoryLoggerConf(cat);\r
-       }\r
-       if (LOG_LV_INFO >= this->getLogLevel(loggerCategory)) {\r
-               std::ostringstream oss;\r
-               oss << "Logger Configuration Succeed.";\r
-               this->putLogInfo(loggerCategory,2, oss.str(), __FILE__, __LINE__);\r
-       }\r
-\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory)) {\r
-               std::ostringstream oss;\r
-               oss << "out_function : void l7vs::LoggerImpl::loadConf() : "\r
-                   << "loadCategoryLoggerConf() END.";\r
-               this->putLogDebug(loggerCategory, 3, oss.str(), __FILE__, __LINE__);\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-}\r
-\r
-/*!\r
- * load the category logger parameter.\r
- * get settings from parameter component of each category, and configure log4cxx property\r
- *\r
- * @param[in]  catnum  LOG_CATEGORY_TAG\r
- * @return  void\r
- */\r
-void l7vs::LoggerImpl::loadCategoryLoggerConf(LOG_CATEGORY_TAG catnum)\r
-{\r
-       std::string ret;\r
-\r
-       //get log filename\r
-       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, log_filename_key)) {\r
-               logFilename = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, log_filename_key);\r
-       }\r
-       else {\r
-               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                       this->putLogError(loggerCategory,1, "Not Exist Log Filename Setting.", __FILE__, __LINE__);\r
-               }\r
-               throw std::logic_error("Not Exist Log Filename Setting.");\r
-       }\r
-       \r
-       //get rotation\r
-       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_key)) {\r
-               std::string rotationStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_key);\r
-               if ("size" == rotationStr) rotation = LOG_ROT_SIZE;\r
-               else if ("date" == rotationStr) rotation = LOG_ROT_DATE;\r
-               else if ("datesize" == rotationStr) rotation = LOG_ROT_DATESIZE;\r
-               else {\r
-                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                               this->putLogError(loggerCategory,2, "Invalid Log Rotation Setting.", __FILE__, __LINE__);\r
-                       }\r
-                       throw std::logic_error("Invalid Log Rotation Setting.");\r
-               }\r
-       }\r
-       else {\r
-               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                       this->putLogError(loggerCategory,3, "Not Exist Log Rotation Setting.", __FILE__, __LINE__);\r
-               }\r
-               throw std::logic_error("Not Exist Log Rotation Setting.");\r
-       }\r
-\r
-       //get max backup index\r
-       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, max_backup_index_key)) {\r
-               std::string maxBackupIndexStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, max_backup_index_key);\r
-               try {\r
-                       maxBackupIndex = lexical_cast<unsigned int>(maxBackupIndexStr);\r
-               }\r
-               catch (const l7vs::bad_lexical_cast& bc) {\r
-                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                               this->putLogError(loggerCategory,4, "Invalid MaxBackupIndex Value.", __FILE__, __LINE__);\r
-                       }\r
-                       throw std::logic_error("Invalid MaxBackupIndex Value.");\r
-               }\r
-               if (LOGGER_BACKUP_INDEX_LOWER_LIMIT > maxBackupIndex) {\r
-                       std::ostringstream oss;\r
-                       oss << "Max Backup Index must at least " << LOGGER_BACKUP_INDEX_LOWER_LIMIT << ".";\r
-                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                               this->putLogError(loggerCategory,5, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-                       throw std::logic_error(oss.str());\r
-               }               \r
-               if (LOGGER_BACKUP_INDEX_LIMIT < maxBackupIndex) {\r
-                       std::ostringstream oss;\r
-                       oss << "Max Backup Index must at most " << LOGGER_BACKUP_INDEX_LIMIT << ".";\r
-                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                               this->putLogError(loggerCategory,6, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-                       throw std::logic_error(oss.str());\r
-               }               \r
-       }\r
-       else {\r
-               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                       this->putLogError(loggerCategory,7, "Not Exist Log MaxBackupIndex Setting.", __FILE__, __LINE__);\r
-               }\r
-               throw std::logic_error("Not Exist Log MaxBackupIndex Setting.");\r
-       }\r
-\r
-       if (LOG_ROT_SIZE == rotation || LOG_ROT_DATESIZE == rotation) {\r
-               // get max file size\r
-               std::string maxFileSizeStr;\r
-               if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, max_file_size_key)) {\r
-                       maxFileSizeStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, max_file_size_key);\r
-               }\r
-               else {\r
-                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                               this->putLogError(loggerCategory,8, "Not Exist Log MaxFileSize Setting.", __FILE__, __LINE__);\r
-                       }\r
-                       throw std::logic_error("Not Exist Log MaxFileSize Setting.");\r
-               }\r
-               \r
-               std::string size_val;\r
-               std::string last_str = maxFileSizeStr.substr(maxFileSizeStr.length() - 1, 1);\r
-               // when unit was specified\r
-               if (("K" == last_str) || ("M" == last_str) || ("G" == last_str)) {\r
-                       size_val = maxFileSizeStr.substr(0, maxFileSizeStr.length() - 1);\r
-               }\r
-               else {\r
-                       size_val = maxFileSizeStr;\r
-               }\r
-                       \r
-               try {\r
-                       maxFileSize = lexical_cast<size_t>(size_val);\r
-               }\r
-               catch (const l7vs::bad_lexical_cast& bc) {\r
-                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                               this->putLogError(loggerCategory,9, "Invalid FileSize Value.", __FILE__, __LINE__);\r
-                       }\r
-                       throw std::logic_error("Invalid FileSize Value.");\r
-               }\r
-\r
-               if ("K" == last_str) {\r
-                       if ((ULLONG_MAX / 1024) < maxFileSize) {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,10, "Invalid FileSize Value.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Invalid FileSize Value.");\r
-                       }\r
-                       maxFileSize = maxFileSize * 1024;\r
-               }\r
-               else if ("M" == last_str) {\r
-                       if ((ULLONG_MAX / 1024 / 1024) < maxFileSize) {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,11, "Invalid FileSize Value.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Invalid FileSize Value.");\r
-                       }\r
-                       maxFileSize = maxFileSize * 1024 * 1024;\r
-               }\r
-               else if ("G" == last_str) {\r
-                       if ((ULLONG_MAX / 1024 / 1024 / 1024) < maxFileSize) {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,12, "Invalid FileSize Value.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Invalid FileSize Value.");\r
-                       }\r
-                       maxFileSize = maxFileSize * 1024 * 1024 * 1024;\r
-               }\r
-               if (LOGGER_FILESIZE_LOWER_LIMIT > maxFileSize) {\r
-                       int limit = LOGGER_FILESIZE_LOWER_LIMIT;\r
-                       std::ostringstream oss;\r
-                       oss << "FileSize must at least " << limit << " bytes.";\r
-                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                               this->putLogError(loggerCategory,13, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-                       throw std::logic_error(oss.str());\r
-               }\r
-       }\r
-\r
-       if (LOG_ROT_DATE == rotation || LOG_ROT_DATESIZE == rotation) {\r
-               // get rotation timing\r
-               if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_key)) {\r
-                       std::string rotationTimingStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_key);\r
-                       if ("year" == rotationTimingStr) rotationTiming = LOG_TIM_YEAR;\r
-                       else if ("month" == rotationTimingStr) rotationTiming = LOG_TIM_MONTH;\r
-                       else if ("week" == rotationTimingStr) rotationTiming = LOG_TIM_WEEK;\r
-                       else if ("date" == rotationTimingStr) rotationTiming = LOG_TIM_DATE;\r
-                       else if ("hour" == rotationTimingStr) rotationTiming = LOG_TIM_HOUR;\r
-                       else {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,14, "Invalid Log RotationTiming Setting.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Invalid Log RotationTiming Setting.");\r
-                       }\r
-               }\r
-               else {\r
-                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                               this->putLogError(loggerCategory,15, "Not Exist Log RotaionTiming Setting.", __FILE__, __LINE__);\r
-                       }\r
-                       throw std::logic_error("Not Exist Log RotaionTiming Setting.");\r
-               }\r
-\r
-               if (LOG_TIM_YEAR == rotationTiming) {\r
-                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {\r
-                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);\r
-\r
-                               std::string::size_type fpos = 0;\r
-                               std::string::size_type rpos = 0;\r
-                               int month = 0;\r
-                               int date = 0;\r
-                               int hour = 0;\r
-                               int minute = 0;\r
-                               // find month\r
-                               rpos = ret.find_first_of('/', fpos);\r
-                               if (std::string::npos != rpos) {\r
-                                       std::string monthStr = ret.substr(fpos, rpos - fpos);\r
-                                       try {\r
-                                               month = lexical_cast<int>(monthStr);\r
-                                       }\r
-                                       catch (const l7vs::bad_lexical_cast& bc) {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,16, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Year Error.");\r
-                                       }\r
-                                       if (1 > month || month > 12) {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,17, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Year Error.");\r
-                                       }\r
-                                       fpos = rpos + 1;\r
-                                       // find date\r
-                                       rpos = ret.find_first_of(' ', fpos);\r
-                                       if (std::string::npos != rpos) {\r
-                                               std::string dateStr = ret.substr(fpos, rpos - fpos);\r
-                                               try {\r
-                                                       date = lexical_cast<int>(dateStr);\r
-                                               }\r
-                                               catch (const l7vs::bad_lexical_cast& bc) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,18, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Year Error.");\r
-                                               }\r
-                                               if (1 > date || date > 31) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,19, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Year Error.");\r
-                                               }\r
-                                               int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\r
-                                               if (date > dates[month - 1]) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,20, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Year Error.");\r
-                                               }\r
-                                               fpos = rpos + 1;\r
-                                               // find hour \r
-                                               rpos = ret.find_first_of(':', fpos);\r
-                                               if (std::string::npos != rpos) {\r
-                                                       std::string hourStr = ret.substr(fpos, rpos - fpos);\r
-                                                       try {\r
-                                                               hour = lexical_cast<int>(hourStr);\r
-                                                       }\r
-                                                       catch (const l7vs::bad_lexical_cast& bc) {\r
-                                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                                       this->putLogError(loggerCategory,21, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                                               }\r
-                                                               throw std::logic_error("Parse Timing Year Error.");\r
-                                                       }\r
-                                                       if (0 > hour || hour > 23) {\r
-                                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                                       this->putLogError(loggerCategory,22, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                                               }\r
-                                                               throw std::logic_error("Parse Timing Year Error.");\r
-                                                       }\r
-                                                       // minute\r
-                                                       std::string minuteStr = ret.substr(rpos + 1);\r
-                                                       try {\r
-                                                               minute = lexical_cast<int>(minuteStr);\r
-                                                       }\r
-                                                       catch (const l7vs::bad_lexical_cast& bc) {\r
-                                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                                       this->putLogError(loggerCategory,23, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                                               }\r
-                                                               throw std::logic_error("Parse Timing Year Error.");\r
-                                                       }\r
-                                                       if (0 > minute || minute > 59) {\r
-                                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                                       this->putLogError(loggerCategory,24, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                                               }\r
-                                                               throw std::logic_error("Parse Timing Year Error.");\r
-                                                       }\r
-                                               }\r
-                                               else {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,25, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Year Error.");\r
-                                               }\r
-                                       }\r
-                                       else {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {        \r
-                                                       this->putLogError(loggerCategory,26, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Year Error.");\r
-                                       }\r
-                               }\r
-                               else {\r
-                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                               this->putLogError(loggerCategory,27, "Parse Timing Year Error.", __FILE__, __LINE__);\r
-                                       }\r
-                                       throw std::logic_error("Parse Timing Year Error.");\r
-                               }\r
-\r
-                               // format to internal rotation timing value expresson\r
-                               std::ostringstream oss;\r
-                               oss << std::setfill('0') << std::setw(2) << month\r
-                                       << std::setfill('0') << std::setw(2) << date\r
-                                       << std::setfill('0') << std::setw(2) << hour\r
-                                       << std::setfill('0') << std::setw(2) << minute;\r
-                               \r
-                               rotationTimingValue = oss.str();\r
-\r
-                       }\r
-                       else {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,28, "Not Exist Log RotaionTiming Year Setting.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Not Exist Log RotaionTiming Year Setting.");\r
-                       }\r
-               }\r
-\r
-               if (LOG_TIM_MONTH == rotationTiming) {\r
-                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {\r
-                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);\r
-\r
-                               std::string::size_type fpos = 0;\r
-                               std::string::size_type rpos = 0;\r
-                               int date = 0;\r
-                               int hour = 0;\r
-                               int minute = 0;\r
-                               // find day\r
-                               rpos = ret.find_first_of(' ', fpos);\r
-                               if (std::string::npos != rpos) {\r
-                                       std::string dateStr = ret.substr(fpos, rpos - fpos);\r
-                                       try {\r
-                                               date = lexical_cast<int>(dateStr);\r
-                                       }\r
-                                       catch (const l7vs::bad_lexical_cast& bc) {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,29, "Parse Timing Month Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Month Error.");\r
-                                       }\r
-                                       if (1 > date || date > 31) {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,30, "Parse Timing Month Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Month Error.");\r
-                                       }\r
-                                       fpos = rpos + 1;\r
-                                       // find hour\r
-                                       rpos = ret.find_first_of(':', fpos);\r
-                                       if (std::string::npos != rpos) {\r
-                                               std::string hourStr = ret.substr(fpos, rpos - fpos);\r
-                                               try {\r
-                                                       hour = lexical_cast<int>(hourStr);\r
-                                               }\r
-                                               catch (const l7vs::bad_lexical_cast& bc) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,31, "Parse Timing Month Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Month Error.");\r
-                                               }\r
-                                               if (0 > hour || hour > 23) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,32, "Parse Timing Month Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Month Error.");\r
-                                               }\r
-                                               // minute\r
-                                               std::string minuteStr = ret.substr(rpos + 1);\r
-                                               try {\r
-                                                       minute = lexical_cast<int>(minuteStr);\r
-                                               }\r
-                                               catch (const l7vs::bad_lexical_cast& bc) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,33, "Parse Timing Month Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Month Error.");\r
-                                               }\r
-                                               if (0 > minute || minute > 59) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,34, "Parse Timing Month Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Month Error.");\r
-                                               }\r
-                                       }\r
-                                       else {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,35, "Parse Timing Month Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Month Error.");\r
-                                       }\r
-                               }\r
-                               else {\r
-                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                               this->putLogError(loggerCategory,36, "Parse Timing Month Error.", __FILE__, __LINE__);\r
-                                       }\r
-                                       throw std::logic_error("Parse Timing Month Error.");\r
-                               }\r
-\r
-                               // format to internal rotation timing value expresson\r
-                               std::ostringstream oss;\r
-                               oss << std::setfill('0') << std::setw(2) << date\r
-                                       << std::setfill('0') << std::setw(2) << hour\r
-                                       << std::setfill('0') << std::setw(2) << minute;\r
-                               \r
-                               rotationTimingValue = oss.str();\r
-\r
-                       }\r
-                       else {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,37, "Not Exist Log RotaionTiming Month Setting.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Not Exist Log RotaionTiming Month Setting.");\r
-                       }\r
-               }\r
-\r
-               if (LOG_TIM_WEEK == rotationTiming) {\r
-                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {\r
-                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);\r
-\r
-                               std::string::size_type fpos = 0;\r
-                               std::string::size_type rpos = 0;\r
-                               int week = 0;\r
-                               int hour = 0;\r
-                               int minute = 0;\r
-                               rpos = ret.find_first_of(' ', fpos);\r
-                               //find week\r
-                               if (std::string::npos != rpos) {\r
-                                       std::string weekStr = ret.substr(fpos, rpos - fpos);\r
-\r
-                                       if ("sun" == weekStr) week = 0;\r
-                                       else if ("mon" == weekStr) week = 1;\r
-                                       else if ("tue" == weekStr) week = 2;\r
-                                       else if ("wed" == weekStr) week = 3;\r
-                                       else if ("thu" == weekStr) week = 4;\r
-                                       else if ("fri" == weekStr) week = 5;\r
-                                       else if ("sat" == weekStr) week = 6;\r
-                                       else {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,38, "Parse Timing Week Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Week Error.");\r
-                                       }\r
-                                       fpos = rpos + 1;\r
-                                       // find hour\r
-                                       rpos = ret.find_first_of(':', fpos);\r
-                                       if (std::string::npos != rpos) {\r
-                                               std::string hourStr = ret.substr(fpos, rpos - fpos);\r
-                                               try {\r
-                                                       hour = lexical_cast<int>(hourStr);\r
-                                               }\r
-                                               catch (const l7vs::bad_lexical_cast& bc) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,39, "Parse Timing Week Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Week Error.");\r
-                                               }\r
-                                               if (0 > hour || hour > 23) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,40, "Parse Timing Week Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Week Error.");\r
-                                               }\r
-                                               // minute\r
-                                               std::string minuteStr = ret.substr(rpos + 1);\r
-                                               try {\r
-                                                       minute = lexical_cast<int>(minuteStr);\r
-                                               }\r
-                                               catch (const l7vs::bad_lexical_cast& bc) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,41, "Parse Timing Week Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Week Error.");\r
-                                               }\r
-                                               if (0 > minute || minute > 59) {\r
-                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                               this->putLogError(loggerCategory,42, "Parse Timing Week Error.", __FILE__, __LINE__);\r
-                                                       }\r
-                                                       throw std::logic_error("Parse Timing Week Error.");\r
-                                               }\r
-                                       }\r
-                                       else {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {        \r
-                                                       this->putLogError(loggerCategory,43, "Parse Timing Week Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Week Error.");\r
-                                       }\r
-                               }\r
-                               else {\r
-                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                               this->putLogError(loggerCategory,44, "Parse Timing Week Error.", __FILE__, __LINE__);\r
-                                       }\r
-                                       throw std::logic_error("Parse Timing Week Error.");\r
-                               }\r
-\r
-                               // format to internal rotation timing value expresson\r
-                               std::ostringstream oss;\r
-                               oss << std::setfill('0') << std::setw(1) << week\r
-                                       << std::setfill('0') << std::setw(2) << hour\r
-                                       << std::setfill('0') << std::setw(2) << minute;\r
-                               \r
-                               rotationTimingValue = oss.str();\r
-\r
-                       }\r
-                       else {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,45, "Not Exist Log RotaionTiming Week Setting.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Not Exist Log RotaionTiming Week Setting.");\r
-                       }\r
-               }\r
-\r
-               if (LOG_TIM_DATE == rotationTiming) {\r
-                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {\r
-                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);\r
-\r
-                               std::string::size_type fpos = 0;\r
-                               std::string::size_type rpos = 0;\r
-                               int hour = 0;\r
-                               int minute = 0;\r
-                               //find time\r
-                               rpos = ret.find_first_of(':', fpos);\r
-                               if (std::string::npos != rpos) {\r
-                                       std::string hourStr = ret.substr(fpos, rpos - fpos);\r
-                                       try {\r
-                                               hour = lexical_cast<int>(hourStr);\r
-                                       }\r
-                                       catch (const l7vs::bad_lexical_cast& bc) {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,46, "Parse Timing Date Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Date Error.");\r
-                                       }\r
-                                       if (0 > hour || hour > 23) {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,47, "Parse Timing Date Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Date Error.");\r
-                                       }\r
-                                       // minute\r
-                                       std::string minuteStr = ret.substr(rpos + 1);\r
-                                       try {\r
-                                               minute = lexical_cast<int>(minuteStr);\r
-                                       }\r
-                                       catch (const l7vs::bad_lexical_cast& bc) {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,48, "Parse Timing Date Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Date Error.");\r
-                                       }\r
-                                       if (0 > minute || minute > 59) {\r
-                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                                       this->putLogError(loggerCategory,49, "Parse Timing Date Error.", __FILE__, __LINE__);\r
-                                               }\r
-                                               throw std::logic_error("Parse Timing Date Error.");\r
-                                       }\r
-                               }\r
-                               else {\r
-                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                               this->putLogError(loggerCategory,50, "Parse Timing Date Error.", __FILE__, __LINE__);\r
-                                       }\r
-                                       throw std::logic_error("Parse Timing Date Error.");\r
-                               }\r
-\r
-                               // format to internal rotation timing value expresson\r
-                               std::ostringstream oss;\r
-                               oss << std::setfill('0') << std::setw(2) << hour\r
-                                       << std::setfill('0') << std::setw(2) << minute;\r
-                               \r
-                               rotationTimingValue = oss.str();\r
-\r
-                       }\r
-                       else {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,51, "Not Exist Log RotaionTiming Date Setting.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Not Exist Log RotaionTiming Date Setting.");\r
-                       }\r
-               }\r
-\r
-               if (LOG_TIM_HOUR == rotationTiming) {\r
-                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {\r
-                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);\r
-\r
-                               // minute\r
-                               int minute = 0;\r
-                               try {\r
-                                       minute = lexical_cast<int>(ret);\r
-                               }\r
-                               catch (const l7vs::bad_lexical_cast& bc) {\r
-                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                               this->putLogError(loggerCategory,52, "Parse Timing Hour Error.", __FILE__, __LINE__);\r
-                                       }\r
-                                       throw std::logic_error("Parse Timing Hour Error.");\r
-                               }\r
-                               if (0 > minute || minute > 59) {\r
-                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                               this->putLogError(loggerCategory,53, "Parse Timing Hour Error.", __FILE__, __LINE__);\r
-                                       }\r
-                                       throw std::logic_error("Parse Timing Hour Error.");\r
-                               }\r
-\r
-                               // format to internal rotation timing value expresson\r
-                               std::ostringstream oss;\r
-                               oss << std::setfill('0') << std::setw(2) << minute;\r
-                               \r
-                               rotationTimingValue = oss.str();\r
-\r
-                       }\r
-                       else {\r
-                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogError(loggerCategory,54, "Not Exist Log RotaionTiming Hour Setting.", __FILE__, __LINE__);\r
-                               }\r
-                               throw std::logic_error("Not Exist Log RotaionTiming Hour Setting.");\r
-                       }\r
-               }\r
-       }\r
-\r
-       try {\r
-               /*-------- DEBUG LOG for sslproxy --------*/\r
-               if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory) &&\r
-                   catnum != LOG_CAT_SSLPROXY_LOGGER) {\r
-                       std::ostringstream oss;\r
-                       oss << "function : void l7vs::LoggerImpl::loadCategoryLoggerConf("\r
-                           << "LOG_CATEGORY_TAG catnum) : "\r
-                           << "Set category Logger appender. "\r
-                           << "catnum = " << catnum;\r
-                       this->putLogDebug(loggerCategory, 4, oss.str(), __FILE__, __LINE__);\r
-               }\r
-               /*------ DEBUG LOG END for sslproxy ------*/\r
-\r
-               // reset current configuration\r
-               // when category is LOG_CAT_NONE (first category)\r
-               log4cxx::helpers::Pool pool;\r
-               if (catnum == LOG_CAT_NONE) {\r
-                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                       if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory) &&\r
-                           catnum != LOG_CAT_SSLPROXY_LOGGER) {\r
-                               std::ostringstream oss;\r
-                               oss << "function : l7vs::LoggerImpl::loadCategoryLoggerConf() : "\r
-                                   << "Reset all Logger configuration. "\r
-                                   << "catnum = " << catnum;\r
-                               this->putLogDebug(loggerCategory, 5, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-                       /*------ DEBUG LOG END for sslproxy ------*/\r
-                       log4cxx::LogManager::resetConfiguration();\r
-               }\r
-               log4cxx::LoggerPtr catlogger = log4cxx::Logger::getLogger(categoryTable[catnum]);\r
-               if (0 == catlogger) {\r
-                       throw std::logic_error("getLogger Failed.");\r
-               }\r
-               log4cxx::LayoutPtr layout =\r
-                       new log4cxx::PatternLayout(LOGGER_LAYOUT);\r
-\r
-               switch (rotation) {\r
-               case LOG_ROT_SIZE:\r
-                       {\r
-                               // create FixedWindowRollingPolicy\r
-                               log4cxx::rolling::FixedWindowRollingPolicyPtr fixedRollingPolicy =\r
-                                       new log4cxx::rolling::FixedWindowRollingPolicy();\r
-       \r
-                               // setting minIndex\r
-                               fixedRollingPolicy->setMinIndex(1);\r
-       \r
-                               // setting maxIndex\r
-                               fixedRollingPolicy->setMaxIndex(maxBackupIndex);\r
-\r
-                               // setting FileNamePattern\r
-                               std::ostringstream sizeFile;\r
-                               sizeFile << logFilename << "." << LOGGER_FILE_PATTERN;\r
-                               fixedRollingPolicy->setFileNamePattern(sizeFile.str());\r
-       \r
-                               // create SizeBasedTriggeringPolicy\r
-                               log4cxx::rolling::SizeBasedTriggeringPolicyPtr sizeTriggeringPolicy =\r
-                                       new log4cxx::rolling::SizeBasedTriggeringPolicy();\r
-\r
-                               // setting maxFileSize\r
-                               sizeTriggeringPolicy->setMaxFileSize(maxFileSize);\r
-       \r
-                               // create RollingFileAppender\r
-                               log4cxx::rolling::RollingFileAppenderPtr sizeAppender =\r
-                                       new log4cxx::rolling::RollingFileAppender();\r
-       \r
-                               // set layout\r
-                               sizeAppender->setLayout(layout);\r
-       \r
-                               // set RollingPolicy\r
-                               sizeAppender->setRollingPolicy(fixedRollingPolicy);\r
-       \r
-                               // set TriggeringPolicy\r
-                               sizeAppender->setTriggeringPolicy(sizeTriggeringPolicy);\r
-\r
-                               // set Log Filename\r
-                               sizeAppender->setFile(logFilename, true, false, LOGGER_DEFAULT_BUFFER_SIZE, pool);\r
-       \r
-                               // activate appender options\r
-                               sizeAppender->activateOptions(pool);\r
-       \r
-                               // add size_base_appender to CategoryLogger\r
-                               catlogger->addAppender(sizeAppender);\r
-\r
-                               break;\r
-                       }\r
-               case LOG_ROT_DATE:\r
-                       {\r
-                               // create StrictTimeBasedRollingPolicy\r
-                               log4cxx::rolling::StrictTimeBasedRollingPolicyPtr strictRollingPolicy =\r
-                                       new log4cxx::rolling::StrictTimeBasedRollingPolicy();\r
-       \r
-                               // setting minIndex\r
-                               strictRollingPolicy->setMinIndex(1);\r
-       \r
-                               // setting maxIndex\r
-                               strictRollingPolicy->setMaxIndex(maxBackupIndex);\r
-\r
-                               // setting FileNamePattern\r
-                               std::ostringstream dateFile;\r
-                               dateFile << logFilename << "." << LOGGER_FILE_PATTERN;\r
-                               strictRollingPolicy->setFileNamePattern(dateFile.str());\r
-\r
-                               // setting Rotation Timing\r
-                               strictRollingPolicy->setRotationTiming(rotationTiming);\r
-       \r
-                               // setting Rotation Timing Value\r
-                               strictRollingPolicy->setRotationTimingValue(rotationTimingValue);\r
-       \r
-                               //create RollingFileAppender\r
-                               log4cxx::rolling::RollingFileAppenderPtr dateAppender =\r
-                                       new log4cxx::rolling::RollingFileAppender();\r
-                       \r
-                               // set layout\r
-                               dateAppender->setLayout(layout);\r
-\r
-                               // set RollingPolicy (TriggeringPolicy also included RollingPolicy)\r
-                               dateAppender->setRollingPolicy(strictRollingPolicy);\r
-       \r
-                               // set Log Filename\r
-                               dateAppender->setFile(logFilename, true, false, LOGGER_DEFAULT_BUFFER_SIZE, pool);\r
-       \r
-                               // activate appender options\r
-                               dateAppender->activateOptions(pool);\r
-       \r
-                               // add date_based_appender to CategoryLogger\r
-                               catlogger->addAppender(dateAppender);\r
-\r
-                               break;\r
-                       }\r
-               default:        //LOG_ROT_DATESIZE:\r
-                       {\r
-                               // create TimeAndSizeBasedRollingPolicy\r
-                               log4cxx::rolling::TimeAndSizeBasedRollingPolicyPtr timeSizeRollingPolicy =\r
-                                       new log4cxx::rolling::TimeAndSizeBasedRollingPolicy();\r
-       \r
-                               // setting minIndex\r
-                               timeSizeRollingPolicy->setMinIndex(1);\r
-       \r
-                               // setting maxIndex\r
-                               timeSizeRollingPolicy->setMaxIndex(maxBackupIndex);\r
-\r
-                               // setting FileNamePattern\r
-                               std::ostringstream dateSizeFile;\r
-                               dateSizeFile << logFilename << "." << LOGGER_FILE_PATTERN;\r
-                               timeSizeRollingPolicy->setFileNamePattern(dateSizeFile.str());\r
-       \r
-                               // setting Rotation Timing\r
-                               timeSizeRollingPolicy->setRotationTiming(rotationTiming);\r
-       \r
-                               // setting Rotation Timing Value\r
-                               timeSizeRollingPolicy->setRotationTimingValue(rotationTimingValue);\r
-       \r
-                               // setting MaxFileSize\r
-                               timeSizeRollingPolicy->setMaxFileSize(maxFileSize);\r
-       \r
-                               // create Rolling FileAppender\r
-                               log4cxx::rolling::RollingFileAppenderPtr dateSizeAppender =\r
-                                       new log4cxx::rolling::RollingFileAppender();\r
-       \r
-                               // set layout\r
-                               dateSizeAppender->setLayout(layout);\r
-       \r
-                               // set RollingPolicy (TriggeringPolicy also included RollingPolicy)\r
-                               dateSizeAppender->setRollingPolicy(timeSizeRollingPolicy);\r
-       \r
-                               // set Log Filename\r
-                               dateSizeAppender->setFile(logFilename, true, false, LOGGER_DEFAULT_BUFFER_SIZE, pool);\r
-       \r
-                               // activate appender options\r
-                               dateSizeAppender->activateOptions(pool);\r
-       \r
-                               // add time_and_size_based_appender to CategoryLogger\r
-                               catlogger->addAppender(dateSizeAppender);\r
-                       }\r
-               }\r
-\r
-               //set default log level\r
-               for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {\r
-                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-               }\r
-\r
-               //get category level\r
-               for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {\r
-                       if (cat == LOG_CAT_NONE) continue;\r
-                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, categoryTable[cat])) {\r
-                               std::string levelStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, categoryTable[cat]);\r
-                               if ("debug" == levelStr) {\r
-                                       categoryLevel[cat] = log4cxx::Level::getDebug();\r
-                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-                               }\r
-                               else if ("info" == levelStr) {\r
-                                       categoryLevel[cat] = log4cxx::Level::getInfo();\r
-                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-                               }\r
-                               else if ("warn" == levelStr) {\r
-                                       categoryLevel[cat] = log4cxx::Level::getWarn();\r
-                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-                               }\r
-                               else if ("error" == levelStr) {\r
-                                       categoryLevel[cat] = log4cxx::Level::getError();\r
-                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-                               }\r
-                               else if ("fatal" == levelStr) {\r
-                                       categoryLevel[cat] = log4cxx::Level::getFatal();\r
-                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-                               }\r
-                               else {\r
-                                       std::ostringstream oss;\r
-                                       oss << "Invalid Log Category Setting : " << categoryTable[cat];\r
-                                       if (LOG_LV_WARN >= this->getLogLevel(loggerCategory)) {\r
-                                               this->putLogWarn(loggerCategory,2, oss.str(), __FILE__, __LINE__);\r
-                                       }\r
-                                       categoryLevel[cat] = log4cxx::Level::getInfo();\r
-                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-                               }\r
-                       }\r
-                       else {\r
-                               std::ostringstream oss;\r
-                               oss << "Not Exist Log Category Setting : " << categoryTable[cat];\r
-                               if (LOG_LV_WARN >= this->getLogLevel(loggerCategory)) {\r
-                                       this->putLogWarn(loggerCategory,3, oss.str(), __FILE__, __LINE__);\r
-                               }\r
-                               categoryLevel[cat] = log4cxx::Level::getInfo();\r
-                               log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);\r
-                       }\r
-               }\r
-       }\r
-       catch (const std::exception& e) {\r
-               std::ostringstream oss;\r
-               oss <<  "Logger Reload Config Failed : " << e.what();\r
-               errorConf(7, oss.str(), __FILE__, __LINE__);\r
-               throw std::logic_error(oss.str());\r
-       }\r
-\r
-       initLogLevelTable();\r
-}\r
-\r
-/*!\r
- * initialize LogLevel table.\r
- * initialize the LogLevel table.\r
- *\r
- * @param   void\r
- * @return  void\r
- */\r
-void l7vs::LoggerImpl::initLogLevelTable(void)\r
-{\r
-       int nCounter = 0;\r
-\r
-       for (;nCounter < LOGGER_CATEGORY_NUM; nCounter++) {\r
-               loglevel[nCounter] = LOG_LV_NONE;\r
-       }\r
-\r
-       return;\r
-}\r
+/*
+ * @file  logger_impl.cpp
+ * @brief logger module implementation class.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 <sstream>
+#include <iomanip>
+#include <limits.h>
+#include <log4cxx/logmanager.h>
+#include <log4cxx/helpers/loglog.h>
+#include <log4cxx/rolling/rollingfileappender.h>
+#include <log4cxx/rolling/fixedwindowrollingpolicy.h>
+#include <log4cxx/rolling/sizebasedtriggeringpolicy.h>
+#include <log4cxx/rolling/timebasedrollingpolicy.h>
+#include <log4cxx/consoleappender.h>
+#include <errno.h>
+#include <stdexcept>
+
+#include "logger_impl.h"
+#include "parameter.h"
+#include "lexical_cast.h"
+#include "strict_time_based_rolling_policy.h"
+#include "time_and_size_based_rolling_policy.h"
+
+#define LOGGER_LAYOUT "%d{%Y/%m/%d %H:%M:%S} [%p] %c %m %t %F:%L%n"
+#define LOGGER_DEFAULT_BUFFER_SIZE (8 * 1024)
+#define LOGGER_SYSLOG_FACILITY "USER"
+#define LOGGER_BACKUP_INDEX_LOWER_LIMIT (1)
+#define LOGGER_BACKUP_INDEX_LIMIT (12)
+#define LOGGER_FILESIZE_LOWER_LIMIT (65535)
+#define LOGGER_FILE_PATTERN "%i"
+
+#define LOGGER_LOG_FILENAME_KEY "sslproxy_log_filename"
+#define LOGGER_ROTATION_KEY "sslproxy_rotation"
+#define LOGGER_MAX_BACKUP_INDEX_KEY "sslproxy_max_backup_index"
+#define LOGGER_MAX_FILE_SIZE_KEY "sslproxy_max_filesize"
+#define LOGGER_ROTATION_TIMING_KEY "sslproxy_rotation_timing"
+#define LOGGER_ROTATION_TIMING_VALUE_KEY "sslproxy_rotation_timing_value"
+
+#define LOGGER_CONN_LOG_FILENAME_KEY "conn_log_filename"
+#define LOGGER_CONN_ROTATION_KEY "conn_rotation"
+#define LOGGER_CONN_MAX_BACKUP_INDEX_KEY "conn_max_backup_index"
+#define LOGGER_CONN_MAX_FILE_SIZE_KEY "conn_max_filesize"
+#define LOGGER_CONN_ROTATION_TIMING_KEY "conn_rotation_timing"
+#define LOGGER_CONN_ROTATION_TIMING_VALUE_KEY "conn_rotation_timing_value"
+
+//! for transration between log4cxx::LevelPtr and LOGER_LEVEL_TAG
+char l7vs::LoggerImpl::categoryTable[][LOGGER_CATEGORY_NUM] = { 
+       "none",
+       "sslproxy_logger",
+       "sslproxy_parameter",
+       "sslproxy_common",
+       "sslproxy_server",
+       "sslproxy_session",
+       "sslproxy_connection",
+       "packet_edit",
+       "packet_edit_http",
+       "end"
+       };
+
+//! for transration between string and LOGGER_CATEGORY_TAG
+log4cxx::LevelPtr l7vs::LoggerImpl::levelTable[LOGGER_LEVEL_NUM];
+
+/*!
+ * returns single instance.
+ *
+ * @param   void
+ * @return  instance
+ */
+l7vs::LoggerImpl& l7vs::LoggerImpl::getInstance()
+{
+       if (!instance) {
+               instance = new LoggerImpl;
+       }
+       return *instance;
+}
+
+//! static Logger instance pointer initialized by 0.
+l7vs::LoggerImpl* l7vs::LoggerImpl::instance = 0;
+
+/*!
+ * initialize function.
+ * logger initialized to use syslogappender and fileappender(/dev/console)
+ *
+ * @param   void
+ * @retval  true succeed
+ * @retval  false failed
+ */
+bool l7vs::LoggerImpl::init()
+{
+       int ret = 0;
+       if (initialized) return false;
+
+       try {
+               log4cxx::LoggerPtr root = log4cxx::Logger::getRootLogger();
+               if (0 == root) {
+                       return false;
+               }
+               log4cxx::LayoutPtr layout =
+                       new log4cxx::PatternLayout(LOGGER_LAYOUT);
+               log4cxx::net::SyslogAppenderPtr syslogAppender =
+                       new log4cxx::net::SyslogAppender(layout, log4cxx::net::SyslogAppender::getFacility(LOGGER_SYSLOG_FACILITY));
+               root->addAppender(syslogAppender);
+               log4cxx::WriterAppender* consoleAppender =
+                       new log4cxx::ConsoleAppender( layout, log4cxx::ConsoleAppender::getSystemErr() );
+               root->addAppender(consoleAppender);
+
+               for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {
+                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+               }
+       }
+       catch (const std::exception& e) {
+               std::ostringstream oss;
+               oss <<  "Logger Initialization Failed : " << e.what();
+               errorConf(6, oss.str(), __FILE__, __LINE__);
+               return false;
+       }
+       
+       ret = gethostname(hostname, HOST_NAME_LEN);
+       if (0 > ret) {
+               if (LOG_LV_WARN >= this->getLogLevel(loggerCategory)) {
+                       this->putLogWarn(loggerCategory,1, "Fail to get Hostname", __FILE__, __LINE__);
+               }
+       }       
+
+       if (LOG_LV_INFO >= this->getLogLevel(loggerCategory)) {
+               this->putLogInfo(loggerCategory,1, "Logger Initialized.", __FILE__, __LINE__);
+       }
+
+       initialized = true;
+       return true;
+}
+
+/*!
+ * error handling function.
+ * if error occured, switch appenders to syslogappender and fileappender(/dev/console)
+ * message will output to syslog/fileappender appender
+ * 
+ * @param   log message id 
+ * @param   log message 
+ * @param   current file 
+ * @param   current line
+ * @return  void
+ */
+void l7vs::LoggerImpl::errorConf(unsigned int message_id, const std::string& errorMessage, const char* file, int line)
+{
+       try {
+               log4cxx::LogManager::resetConfiguration();
+               log4cxx::LoggerPtr root = log4cxx::Logger::getRootLogger();
+               if (0 == root)
+                       return;
+               log4cxx::LayoutPtr layout =
+                       new log4cxx::PatternLayout(LOGGER_LAYOUT);
+               log4cxx::net::SyslogAppenderPtr syslogAppender =
+                       new log4cxx::net::SyslogAppender(layout, log4cxx::net::SyslogAppender::getFacility(LOGGER_SYSLOG_FACILITY));
+               log4cxx::ConsoleAppender* consoleAppender = new log4cxx::ConsoleAppender(layout, log4cxx::ConsoleAppender::getSystemErr() );
+                root->addAppender(consoleAppender);
+               root->addAppender(syslogAppender);
+
+               for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {
+                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+               }
+
+               char buf[BUF_LEN];
+               snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_FATAL, loggerCategory, message_id, errorMessage.c_str(), hostname);
+               log4cxx::Logger::getLogger(categoryTable[loggerCategory])->forcedLog(log4cxx::Level::getFatal(), buf, log4cxx::spi::LocationInfo(file, "", line));
+       }
+       catch (const std::exception& e) {
+               std::ostringstream oss;
+               oss <<  "Logger Error Output Failed : " << e.what() << "\n";
+               fputs(oss.str().c_str(), stderr);
+       }
+}
+
+/*!
+ * load the logger parameter.
+ * get settings from parameter component, and configure log4cxx property
+ *
+ * @param   void
+ * @return  void
+ */
+void l7vs::LoggerImpl::loadConf()
+{
+       for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {
+               if (cat == LOG_CAT_SSLPROXY_CONNECTION) {
+                       // Connection category Logger setting.
+                       log_filename_key          = LOGGER_CONN_LOG_FILENAME_KEY;
+                       rotation_key              = LOGGER_CONN_ROTATION_KEY;
+                       max_backup_index_key      = LOGGER_CONN_MAX_BACKUP_INDEX_KEY;
+                       max_file_size_key         = LOGGER_CONN_MAX_FILE_SIZE_KEY;
+                       rotation_timing_key       = LOGGER_CONN_ROTATION_TIMING_KEY;
+                       rotation_timing_value_key = LOGGER_CONN_ROTATION_TIMING_VALUE_KEY;
+                       /*-------- DEBUG LOG for sslproxy --------*/
+                       if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory)) {
+                               std::ostringstream oss;
+                               oss << "function : void l7vs::LoggerImpl::loadConf() : "
+                                   << "Connection category Logger setting. "
+                                   << "cat = " << cat;
+                               this->putLogDebug(loggerCategory, 1, oss.str(), __FILE__, __LINE__);
+                       }
+                       /*------ DEBUG LOG END for sslproxy ------*/
+               } else {
+                       // Other category Logger setting.
+                       log_filename_key          = LOGGER_LOG_FILENAME_KEY;
+                       rotation_key              = LOGGER_ROTATION_KEY;
+                       max_backup_index_key      = LOGGER_MAX_BACKUP_INDEX_KEY;
+                       max_file_size_key         = LOGGER_MAX_FILE_SIZE_KEY;
+                       rotation_timing_key       = LOGGER_ROTATION_TIMING_KEY;
+                       rotation_timing_value_key = LOGGER_ROTATION_TIMING_VALUE_KEY;
+                       /*-------- DEBUG LOG for sslproxy --------*/
+                       if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory) &&
+                           cat != LOG_CAT_SSLPROXY_LOGGER) {
+                               std::ostringstream oss;
+                               oss << "function : void l7vs::LoggerImpl::loadConf() : "
+                                   << "Other category Logger setting. "
+                                   << "cat = " << cat;
+                               this->putLogDebug(loggerCategory, 2, oss.str(), __FILE__, __LINE__);
+                       }
+                       /*------ DEBUG LOG END for sslproxy ------*/
+               }
+               loadCategoryLoggerConf(cat);
+       }
+       if (LOG_LV_INFO >= this->getLogLevel(loggerCategory)) {
+               std::ostringstream oss;
+               oss << "Logger Configuration Succeed.";
+               this->putLogInfo(loggerCategory,2, oss.str(), __FILE__, __LINE__);
+       }
+
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory)) {
+               std::ostringstream oss;
+               oss << "out_function : void l7vs::LoggerImpl::loadConf() : "
+                   << "loadCategoryLoggerConf() END.";
+               this->putLogDebug(loggerCategory, 3, oss.str(), __FILE__, __LINE__);
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+}
+
+/*!
+ * load the category logger parameter.
+ * get settings from parameter component of each category, and configure log4cxx property
+ *
+ * @param[in]  catnum  LOG_CATEGORY_TAG
+ * @return  void
+ */
+void l7vs::LoggerImpl::loadCategoryLoggerConf(LOG_CATEGORY_TAG catnum)
+{
+       std::string ret;
+
+       //get log filename
+       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, log_filename_key)) {
+               logFilename = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, log_filename_key);
+       }
+       else {
+               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                       this->putLogError(loggerCategory,1, "Not Exist Log Filename Setting.", __FILE__, __LINE__);
+               }
+               throw std::logic_error("Not Exist Log Filename Setting.");
+       }
+       
+       //get rotation
+       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_key)) {
+               std::string rotationStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_key);
+               if ("size" == rotationStr) rotation = LOG_ROT_SIZE;
+               else if ("date" == rotationStr) rotation = LOG_ROT_DATE;
+               else if ("datesize" == rotationStr) rotation = LOG_ROT_DATESIZE;
+               else {
+                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                               this->putLogError(loggerCategory,2, "Invalid Log Rotation Setting.", __FILE__, __LINE__);
+                       }
+                       throw std::logic_error("Invalid Log Rotation Setting.");
+               }
+       }
+       else {
+               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                       this->putLogError(loggerCategory,3, "Not Exist Log Rotation Setting.", __FILE__, __LINE__);
+               }
+               throw std::logic_error("Not Exist Log Rotation Setting.");
+       }
+
+       //get max backup index
+       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, max_backup_index_key)) {
+               std::string maxBackupIndexStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, max_backup_index_key);
+               try {
+                       maxBackupIndex = lexical_cast<unsigned int>(maxBackupIndexStr);
+               }
+               catch (const l7vs::bad_lexical_cast& bc) {
+                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                               this->putLogError(loggerCategory,4, "Invalid MaxBackupIndex Value.", __FILE__, __LINE__);
+                       }
+                       throw std::logic_error("Invalid MaxBackupIndex Value.");
+               }
+               if (LOGGER_BACKUP_INDEX_LOWER_LIMIT > maxBackupIndex) {
+                       std::ostringstream oss;
+                       oss << "Max Backup Index must at least " << LOGGER_BACKUP_INDEX_LOWER_LIMIT << ".";
+                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                               this->putLogError(loggerCategory,5, oss.str(), __FILE__, __LINE__);
+                       }
+                       throw std::logic_error(oss.str());
+               }               
+               if (LOGGER_BACKUP_INDEX_LIMIT < maxBackupIndex) {
+                       std::ostringstream oss;
+                       oss << "Max Backup Index must at most " << LOGGER_BACKUP_INDEX_LIMIT << ".";
+                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                               this->putLogError(loggerCategory,6, oss.str(), __FILE__, __LINE__);
+                       }
+                       throw std::logic_error(oss.str());
+               }               
+       }
+       else {
+               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                       this->putLogError(loggerCategory,7, "Not Exist Log MaxBackupIndex Setting.", __FILE__, __LINE__);
+               }
+               throw std::logic_error("Not Exist Log MaxBackupIndex Setting.");
+       }
+
+       if (LOG_ROT_SIZE == rotation || LOG_ROT_DATESIZE == rotation) {
+               // get max file size
+               std::string maxFileSizeStr;
+               if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, max_file_size_key)) {
+                       maxFileSizeStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, max_file_size_key);
+               }
+               else {
+                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                               this->putLogError(loggerCategory,8, "Not Exist Log MaxFileSize Setting.", __FILE__, __LINE__);
+                       }
+                       throw std::logic_error("Not Exist Log MaxFileSize Setting.");
+               }
+               
+               std::string size_val;
+               std::string last_str = maxFileSizeStr.substr(maxFileSizeStr.length() - 1, 1);
+               // when unit was specified
+               if (("K" == last_str) || ("M" == last_str) || ("G" == last_str)) {
+                       size_val = maxFileSizeStr.substr(0, maxFileSizeStr.length() - 1);
+               }
+               else {
+                       size_val = maxFileSizeStr;
+               }
+                       
+               try {
+                       maxFileSize = lexical_cast<size_t>(size_val);
+               }
+               catch (const l7vs::bad_lexical_cast& bc) {
+                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                               this->putLogError(loggerCategory,9, "Invalid FileSize Value.", __FILE__, __LINE__);
+                       }
+                       throw std::logic_error("Invalid FileSize Value.");
+               }
+
+               if ("K" == last_str) {
+                       if ((ULLONG_MAX / 1024) < maxFileSize) {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,10, "Invalid FileSize Value.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Invalid FileSize Value.");
+                       }
+                       maxFileSize = maxFileSize * 1024;
+               }
+               else if ("M" == last_str) {
+                       if ((ULLONG_MAX / 1024 / 1024) < maxFileSize) {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,11, "Invalid FileSize Value.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Invalid FileSize Value.");
+                       }
+                       maxFileSize = maxFileSize * 1024 * 1024;
+               }
+               else if ("G" == last_str) {
+                       if ((ULLONG_MAX / 1024 / 1024 / 1024) < maxFileSize) {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,12, "Invalid FileSize Value.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Invalid FileSize Value.");
+                       }
+                       maxFileSize = maxFileSize * 1024 * 1024 * 1024;
+               }
+               if (LOGGER_FILESIZE_LOWER_LIMIT > maxFileSize) {
+                       int limit = LOGGER_FILESIZE_LOWER_LIMIT;
+                       std::ostringstream oss;
+                       oss << "FileSize must at least " << limit << " bytes.";
+                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                               this->putLogError(loggerCategory,13, oss.str(), __FILE__, __LINE__);
+                       }
+                       throw std::logic_error(oss.str());
+               }
+       }
+
+       if (LOG_ROT_DATE == rotation || LOG_ROT_DATESIZE == rotation) {
+               // get rotation timing
+               if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_key)) {
+                       std::string rotationTimingStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_key);
+                       if ("year" == rotationTimingStr) rotationTiming = LOG_TIM_YEAR;
+                       else if ("month" == rotationTimingStr) rotationTiming = LOG_TIM_MONTH;
+                       else if ("week" == rotationTimingStr) rotationTiming = LOG_TIM_WEEK;
+                       else if ("date" == rotationTimingStr) rotationTiming = LOG_TIM_DATE;
+                       else if ("hour" == rotationTimingStr) rotationTiming = LOG_TIM_HOUR;
+                       else {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,14, "Invalid Log RotationTiming Setting.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Invalid Log RotationTiming Setting.");
+                       }
+               }
+               else {
+                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                               this->putLogError(loggerCategory,15, "Not Exist Log RotaionTiming Setting.", __FILE__, __LINE__);
+                       }
+                       throw std::logic_error("Not Exist Log RotaionTiming Setting.");
+               }
+
+               if (LOG_TIM_YEAR == rotationTiming) {
+                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {
+                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);
+
+                               std::string::size_type fpos = 0;
+                               std::string::size_type rpos = 0;
+                               int month = 0;
+                               int date = 0;
+                               int hour = 0;
+                               int minute = 0;
+                               // find month
+                               rpos = ret.find_first_of('/', fpos);
+                               if (std::string::npos != rpos) {
+                                       std::string monthStr = ret.substr(fpos, rpos - fpos);
+                                       try {
+                                               month = lexical_cast<int>(monthStr);
+                                       }
+                                       catch (const l7vs::bad_lexical_cast& bc) {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,16, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Year Error.");
+                                       }
+                                       if (1 > month || month > 12) {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,17, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Year Error.");
+                                       }
+                                       fpos = rpos + 1;
+                                       // find date
+                                       rpos = ret.find_first_of(' ', fpos);
+                                       if (std::string::npos != rpos) {
+                                               std::string dateStr = ret.substr(fpos, rpos - fpos);
+                                               try {
+                                                       date = lexical_cast<int>(dateStr);
+                                               }
+                                               catch (const l7vs::bad_lexical_cast& bc) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,18, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Year Error.");
+                                               }
+                                               if (1 > date || date > 31) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,19, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Year Error.");
+                                               }
+                                               int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+                                               if (date > dates[month - 1]) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,20, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Year Error.");
+                                               }
+                                               fpos = rpos + 1;
+                                               // find hour 
+                                               rpos = ret.find_first_of(':', fpos);
+                                               if (std::string::npos != rpos) {
+                                                       std::string hourStr = ret.substr(fpos, rpos - fpos);
+                                                       try {
+                                                               hour = lexical_cast<int>(hourStr);
+                                                       }
+                                                       catch (const l7vs::bad_lexical_cast& bc) {
+                                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                                       this->putLogError(loggerCategory,21, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                                               }
+                                                               throw std::logic_error("Parse Timing Year Error.");
+                                                       }
+                                                       if (0 > hour || hour > 23) {
+                                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                                       this->putLogError(loggerCategory,22, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                                               }
+                                                               throw std::logic_error("Parse Timing Year Error.");
+                                                       }
+                                                       // minute
+                                                       std::string minuteStr = ret.substr(rpos + 1);
+                                                       try {
+                                                               minute = lexical_cast<int>(minuteStr);
+                                                       }
+                                                       catch (const l7vs::bad_lexical_cast& bc) {
+                                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                                       this->putLogError(loggerCategory,23, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                                               }
+                                                               throw std::logic_error("Parse Timing Year Error.");
+                                                       }
+                                                       if (0 > minute || minute > 59) {
+                                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                                       this->putLogError(loggerCategory,24, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                                               }
+                                                               throw std::logic_error("Parse Timing Year Error.");
+                                                       }
+                                               }
+                                               else {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,25, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Year Error.");
+                                               }
+                                       }
+                                       else {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {        
+                                                       this->putLogError(loggerCategory,26, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Year Error.");
+                                       }
+                               }
+                               else {
+                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                               this->putLogError(loggerCategory,27, "Parse Timing Year Error.", __FILE__, __LINE__);
+                                       }
+                                       throw std::logic_error("Parse Timing Year Error.");
+                               }
+
+                               // format to internal rotation timing value expresson
+                               std::ostringstream oss;
+                               oss << std::setfill('0') << std::setw(2) << month
+                                       << std::setfill('0') << std::setw(2) << date
+                                       << std::setfill('0') << std::setw(2) << hour
+                                       << std::setfill('0') << std::setw(2) << minute;
+                               
+                               rotationTimingValue = oss.str();
+
+                       }
+                       else {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,28, "Not Exist Log RotaionTiming Year Setting.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Not Exist Log RotaionTiming Year Setting.");
+                       }
+               }
+
+               if (LOG_TIM_MONTH == rotationTiming) {
+                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {
+                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);
+
+                               std::string::size_type fpos = 0;
+                               std::string::size_type rpos = 0;
+                               int date = 0;
+                               int hour = 0;
+                               int minute = 0;
+                               // find day
+                               rpos = ret.find_first_of(' ', fpos);
+                               if (std::string::npos != rpos) {
+                                       std::string dateStr = ret.substr(fpos, rpos - fpos);
+                                       try {
+                                               date = lexical_cast<int>(dateStr);
+                                       }
+                                       catch (const l7vs::bad_lexical_cast& bc) {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,29, "Parse Timing Month Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Month Error.");
+                                       }
+                                       if (1 > date || date > 31) {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,30, "Parse Timing Month Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Month Error.");
+                                       }
+                                       fpos = rpos + 1;
+                                       // find hour
+                                       rpos = ret.find_first_of(':', fpos);
+                                       if (std::string::npos != rpos) {
+                                               std::string hourStr = ret.substr(fpos, rpos - fpos);
+                                               try {
+                                                       hour = lexical_cast<int>(hourStr);
+                                               }
+                                               catch (const l7vs::bad_lexical_cast& bc) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,31, "Parse Timing Month Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Month Error.");
+                                               }
+                                               if (0 > hour || hour > 23) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,32, "Parse Timing Month Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Month Error.");
+                                               }
+                                               // minute
+                                               std::string minuteStr = ret.substr(rpos + 1);
+                                               try {
+                                                       minute = lexical_cast<int>(minuteStr);
+                                               }
+                                               catch (const l7vs::bad_lexical_cast& bc) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,33, "Parse Timing Month Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Month Error.");
+                                               }
+                                               if (0 > minute || minute > 59) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,34, "Parse Timing Month Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Month Error.");
+                                               }
+                                       }
+                                       else {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,35, "Parse Timing Month Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Month Error.");
+                                       }
+                               }
+                               else {
+                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                               this->putLogError(loggerCategory,36, "Parse Timing Month Error.", __FILE__, __LINE__);
+                                       }
+                                       throw std::logic_error("Parse Timing Month Error.");
+                               }
+
+                               // format to internal rotation timing value expresson
+                               std::ostringstream oss;
+                               oss << std::setfill('0') << std::setw(2) << date
+                                       << std::setfill('0') << std::setw(2) << hour
+                                       << std::setfill('0') << std::setw(2) << minute;
+                               
+                               rotationTimingValue = oss.str();
+
+                       }
+                       else {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,37, "Not Exist Log RotaionTiming Month Setting.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Not Exist Log RotaionTiming Month Setting.");
+                       }
+               }
+
+               if (LOG_TIM_WEEK == rotationTiming) {
+                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {
+                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);
+
+                               std::string::size_type fpos = 0;
+                               std::string::size_type rpos = 0;
+                               int week = 0;
+                               int hour = 0;
+                               int minute = 0;
+                               rpos = ret.find_first_of(' ', fpos);
+                               //find week
+                               if (std::string::npos != rpos) {
+                                       std::string weekStr = ret.substr(fpos, rpos - fpos);
+
+                                       if ("sun" == weekStr) week = 0;
+                                       else if ("mon" == weekStr) week = 1;
+                                       else if ("tue" == weekStr) week = 2;
+                                       else if ("wed" == weekStr) week = 3;
+                                       else if ("thu" == weekStr) week = 4;
+                                       else if ("fri" == weekStr) week = 5;
+                                       else if ("sat" == weekStr) week = 6;
+                                       else {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,38, "Parse Timing Week Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Week Error.");
+                                       }
+                                       fpos = rpos + 1;
+                                       // find hour
+                                       rpos = ret.find_first_of(':', fpos);
+                                       if (std::string::npos != rpos) {
+                                               std::string hourStr = ret.substr(fpos, rpos - fpos);
+                                               try {
+                                                       hour = lexical_cast<int>(hourStr);
+                                               }
+                                               catch (const l7vs::bad_lexical_cast& bc) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,39, "Parse Timing Week Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Week Error.");
+                                               }
+                                               if (0 > hour || hour > 23) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,40, "Parse Timing Week Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Week Error.");
+                                               }
+                                               // minute
+                                               std::string minuteStr = ret.substr(rpos + 1);
+                                               try {
+                                                       minute = lexical_cast<int>(minuteStr);
+                                               }
+                                               catch (const l7vs::bad_lexical_cast& bc) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,41, "Parse Timing Week Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Week Error.");
+                                               }
+                                               if (0 > minute || minute > 59) {
+                                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                               this->putLogError(loggerCategory,42, "Parse Timing Week Error.", __FILE__, __LINE__);
+                                                       }
+                                                       throw std::logic_error("Parse Timing Week Error.");
+                                               }
+                                       }
+                                       else {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {        
+                                                       this->putLogError(loggerCategory,43, "Parse Timing Week Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Week Error.");
+                                       }
+                               }
+                               else {
+                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                               this->putLogError(loggerCategory,44, "Parse Timing Week Error.", __FILE__, __LINE__);
+                                       }
+                                       throw std::logic_error("Parse Timing Week Error.");
+                               }
+
+                               // format to internal rotation timing value expresson
+                               std::ostringstream oss;
+                               oss << std::setfill('0') << std::setw(1) << week
+                                       << std::setfill('0') << std::setw(2) << hour
+                                       << std::setfill('0') << std::setw(2) << minute;
+                               
+                               rotationTimingValue = oss.str();
+
+                       }
+                       else {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,45, "Not Exist Log RotaionTiming Week Setting.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Not Exist Log RotaionTiming Week Setting.");
+                       }
+               }
+
+               if (LOG_TIM_DATE == rotationTiming) {
+                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {
+                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);
+
+                               std::string::size_type fpos = 0;
+                               std::string::size_type rpos = 0;
+                               int hour = 0;
+                               int minute = 0;
+                               //find time
+                               rpos = ret.find_first_of(':', fpos);
+                               if (std::string::npos != rpos) {
+                                       std::string hourStr = ret.substr(fpos, rpos - fpos);
+                                       try {
+                                               hour = lexical_cast<int>(hourStr);
+                                       }
+                                       catch (const l7vs::bad_lexical_cast& bc) {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,46, "Parse Timing Date Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Date Error.");
+                                       }
+                                       if (0 > hour || hour > 23) {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,47, "Parse Timing Date Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Date Error.");
+                                       }
+                                       // minute
+                                       std::string minuteStr = ret.substr(rpos + 1);
+                                       try {
+                                               minute = lexical_cast<int>(minuteStr);
+                                       }
+                                       catch (const l7vs::bad_lexical_cast& bc) {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,48, "Parse Timing Date Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Date Error.");
+                                       }
+                                       if (0 > minute || minute > 59) {
+                                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                                       this->putLogError(loggerCategory,49, "Parse Timing Date Error.", __FILE__, __LINE__);
+                                               }
+                                               throw std::logic_error("Parse Timing Date Error.");
+                                       }
+                               }
+                               else {
+                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                               this->putLogError(loggerCategory,50, "Parse Timing Date Error.", __FILE__, __LINE__);
+                                       }
+                                       throw std::logic_error("Parse Timing Date Error.");
+                               }
+
+                               // format to internal rotation timing value expresson
+                               std::ostringstream oss;
+                               oss << std::setfill('0') << std::setw(2) << hour
+                                       << std::setfill('0') << std::setw(2) << minute;
+                               
+                               rotationTimingValue = oss.str();
+
+                       }
+                       else {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,51, "Not Exist Log RotaionTiming Date Setting.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Not Exist Log RotaionTiming Date Setting.");
+                       }
+               }
+
+               if (LOG_TIM_HOUR == rotationTiming) {
+                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, rotation_timing_value_key)) {
+                               ret = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, rotation_timing_value_key);
+
+                               // minute
+                               int minute = 0;
+                               try {
+                                       minute = lexical_cast<int>(ret);
+                               }
+                               catch (const l7vs::bad_lexical_cast& bc) {
+                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                               this->putLogError(loggerCategory,52, "Parse Timing Hour Error.", __FILE__, __LINE__);
+                                       }
+                                       throw std::logic_error("Parse Timing Hour Error.");
+                               }
+                               if (0 > minute || minute > 59) {
+                                       if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                               this->putLogError(loggerCategory,53, "Parse Timing Hour Error.", __FILE__, __LINE__);
+                                       }
+                                       throw std::logic_error("Parse Timing Hour Error.");
+                               }
+
+                               // format to internal rotation timing value expresson
+                               std::ostringstream oss;
+                               oss << std::setfill('0') << std::setw(2) << minute;
+                               
+                               rotationTimingValue = oss.str();
+
+                       }
+                       else {
+                               if (LOG_LV_ERROR >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogError(loggerCategory,54, "Not Exist Log RotaionTiming Hour Setting.", __FILE__, __LINE__);
+                               }
+                               throw std::logic_error("Not Exist Log RotaionTiming Hour Setting.");
+                       }
+               }
+       }
+
+       try {
+               /*-------- DEBUG LOG for sslproxy --------*/
+               if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory) &&
+                   catnum != LOG_CAT_SSLPROXY_LOGGER) {
+                       std::ostringstream oss;
+                       oss << "function : void l7vs::LoggerImpl::loadCategoryLoggerConf("
+                           << "LOG_CATEGORY_TAG catnum) : "
+                           << "Set category Logger appender. "
+                           << "catnum = " << catnum;
+                       this->putLogDebug(loggerCategory, 4, oss.str(), __FILE__, __LINE__);
+               }
+               /*------ DEBUG LOG END for sslproxy ------*/
+
+               // reset current configuration
+               // when category is LOG_CAT_NONE (first category)
+               log4cxx::helpers::Pool pool;
+               if (catnum == LOG_CAT_NONE) {
+                       /*-------- DEBUG LOG for sslproxy --------*/
+                       if (LOG_LV_DEBUG >= this->getLogLevel(loggerCategory) &&
+                           catnum != LOG_CAT_SSLPROXY_LOGGER) {
+                               std::ostringstream oss;
+                               oss << "function : l7vs::LoggerImpl::loadCategoryLoggerConf() : "
+                                   << "Reset all Logger configuration. "
+                                   << "catnum = " << catnum;
+                               this->putLogDebug(loggerCategory, 5, oss.str(), __FILE__, __LINE__);
+                       }
+                       /*------ DEBUG LOG END for sslproxy ------*/
+                       log4cxx::LogManager::resetConfiguration();
+               }
+               log4cxx::LoggerPtr catlogger = log4cxx::Logger::getLogger(categoryTable[catnum]);
+               if (0 == catlogger) {
+                       throw std::logic_error("getLogger Failed.");
+               }
+               log4cxx::LayoutPtr layout =
+                       new log4cxx::PatternLayout(LOGGER_LAYOUT);
+
+               switch (rotation) {
+               case LOG_ROT_SIZE:
+                       {
+                               // create FixedWindowRollingPolicy
+                               log4cxx::rolling::FixedWindowRollingPolicyPtr fixedRollingPolicy =
+                                       new log4cxx::rolling::FixedWindowRollingPolicy();
+       
+                               // setting minIndex
+                               fixedRollingPolicy->setMinIndex(1);
+       
+                               // setting maxIndex
+                               fixedRollingPolicy->setMaxIndex(maxBackupIndex);
+
+                               // setting FileNamePattern
+                               std::ostringstream sizeFile;
+                               sizeFile << logFilename << "." << LOGGER_FILE_PATTERN;
+                               fixedRollingPolicy->setFileNamePattern(sizeFile.str());
+       
+                               // create SizeBasedTriggeringPolicy
+                               log4cxx::rolling::SizeBasedTriggeringPolicyPtr sizeTriggeringPolicy =
+                                       new log4cxx::rolling::SizeBasedTriggeringPolicy();
+
+                               // setting maxFileSize
+                               sizeTriggeringPolicy->setMaxFileSize(maxFileSize);
+       
+                               // create RollingFileAppender
+                               log4cxx::rolling::RollingFileAppenderPtr sizeAppender =
+                                       new log4cxx::rolling::RollingFileAppender();
+       
+                               // set layout
+                               sizeAppender->setLayout(layout);
+       
+                               // set RollingPolicy
+                               sizeAppender->setRollingPolicy(fixedRollingPolicy);
+       
+                               // set TriggeringPolicy
+                               sizeAppender->setTriggeringPolicy(sizeTriggeringPolicy);
+
+                               // set Log Filename
+                               sizeAppender->setFile(logFilename, true, false, LOGGER_DEFAULT_BUFFER_SIZE, pool);
+       
+                               // activate appender options
+                               sizeAppender->activateOptions(pool);
+       
+                               // add size_base_appender to CategoryLogger
+                               catlogger->addAppender(sizeAppender);
+
+                               break;
+                       }
+               case LOG_ROT_DATE:
+                       {
+                               // create StrictTimeBasedRollingPolicy
+                               log4cxx::rolling::StrictTimeBasedRollingPolicyPtr strictRollingPolicy =
+                                       new log4cxx::rolling::StrictTimeBasedRollingPolicy();
+       
+                               // setting minIndex
+                               strictRollingPolicy->setMinIndex(1);
+       
+                               // setting maxIndex
+                               strictRollingPolicy->setMaxIndex(maxBackupIndex);
+
+                               // setting FileNamePattern
+                               std::ostringstream dateFile;
+                               dateFile << logFilename << "." << LOGGER_FILE_PATTERN;
+                               strictRollingPolicy->setFileNamePattern(dateFile.str());
+
+                               // setting Rotation Timing
+                               strictRollingPolicy->setRotationTiming(rotationTiming);
+       
+                               // setting Rotation Timing Value
+                               strictRollingPolicy->setRotationTimingValue(rotationTimingValue);
+       
+                               //create RollingFileAppender
+                               log4cxx::rolling::RollingFileAppenderPtr dateAppender =
+                                       new log4cxx::rolling::RollingFileAppender();
+                       
+                               // set layout
+                               dateAppender->setLayout(layout);
+
+                               // set RollingPolicy (TriggeringPolicy also included RollingPolicy)
+                               dateAppender->setRollingPolicy(strictRollingPolicy);
+       
+                               // set Log Filename
+                               dateAppender->setFile(logFilename, true, false, LOGGER_DEFAULT_BUFFER_SIZE, pool);
+       
+                               // activate appender options
+                               dateAppender->activateOptions(pool);
+       
+                               // add date_based_appender to CategoryLogger
+                               catlogger->addAppender(dateAppender);
+
+                               break;
+                       }
+               default:        //LOG_ROT_DATESIZE:
+                       {
+                               // create TimeAndSizeBasedRollingPolicy
+                               log4cxx::rolling::TimeAndSizeBasedRollingPolicyPtr timeSizeRollingPolicy =
+                                       new log4cxx::rolling::TimeAndSizeBasedRollingPolicy();
+       
+                               // setting minIndex
+                               timeSizeRollingPolicy->setMinIndex(1);
+       
+                               // setting maxIndex
+                               timeSizeRollingPolicy->setMaxIndex(maxBackupIndex);
+
+                               // setting FileNamePattern
+                               std::ostringstream dateSizeFile;
+                               dateSizeFile << logFilename << "." << LOGGER_FILE_PATTERN;
+                               timeSizeRollingPolicy->setFileNamePattern(dateSizeFile.str());
+       
+                               // setting Rotation Timing
+                               timeSizeRollingPolicy->setRotationTiming(rotationTiming);
+       
+                               // setting Rotation Timing Value
+                               timeSizeRollingPolicy->setRotationTimingValue(rotationTimingValue);
+       
+                               // setting MaxFileSize
+                               timeSizeRollingPolicy->setMaxFileSize(maxFileSize);
+       
+                               // create Rolling FileAppender
+                               log4cxx::rolling::RollingFileAppenderPtr dateSizeAppender =
+                                       new log4cxx::rolling::RollingFileAppender();
+       
+                               // set layout
+                               dateSizeAppender->setLayout(layout);
+       
+                               // set RollingPolicy (TriggeringPolicy also included RollingPolicy)
+                               dateSizeAppender->setRollingPolicy(timeSizeRollingPolicy);
+       
+                               // set Log Filename
+                               dateSizeAppender->setFile(logFilename, true, false, LOGGER_DEFAULT_BUFFER_SIZE, pool);
+       
+                               // activate appender options
+                               dateSizeAppender->activateOptions(pool);
+       
+                               // add time_and_size_based_appender to CategoryLogger
+                               catlogger->addAppender(dateSizeAppender);
+                       }
+               }
+
+               //set default log level
+               for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {
+                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+               }
+
+               //get category level
+               for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {
+                       if (cat == LOG_CAT_NONE) continue;
+                       if (l7vs::Parameter::getInstance().isStringExist(PARAM_COMP_LOGGER, categoryTable[cat])) {
+                               std::string levelStr = l7vs::Parameter::getInstance().getStringValue(PARAM_COMP_LOGGER, categoryTable[cat]);
+                               if ("debug" == levelStr) {
+                                       categoryLevel[cat] = log4cxx::Level::getDebug();
+                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+                               }
+                               else if ("info" == levelStr) {
+                                       categoryLevel[cat] = log4cxx::Level::getInfo();
+                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+                               }
+                               else if ("warn" == levelStr) {
+                                       categoryLevel[cat] = log4cxx::Level::getWarn();
+                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+                               }
+                               else if ("error" == levelStr) {
+                                       categoryLevel[cat] = log4cxx::Level::getError();
+                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+                               }
+                               else if ("fatal" == levelStr) {
+                                       categoryLevel[cat] = log4cxx::Level::getFatal();
+                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+                               }
+                               else {
+                                       std::ostringstream oss;
+                                       oss << "Invalid Log Category Setting : " << categoryTable[cat];
+                                       if (LOG_LV_WARN >= this->getLogLevel(loggerCategory)) {
+                                               this->putLogWarn(loggerCategory,2, oss.str(), __FILE__, __LINE__);
+                                       }
+                                       categoryLevel[cat] = log4cxx::Level::getInfo();
+                                       log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+                               }
+                       }
+                       else {
+                               std::ostringstream oss;
+                               oss << "Not Exist Log Category Setting : " << categoryTable[cat];
+                               if (LOG_LV_WARN >= this->getLogLevel(loggerCategory)) {
+                                       this->putLogWarn(loggerCategory,3, oss.str(), __FILE__, __LINE__);
+                               }
+                               categoryLevel[cat] = log4cxx::Level::getInfo();
+                               log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(categoryLevel[cat]);
+                       }
+               }
+       }
+       catch (const std::exception& e) {
+               std::ostringstream oss;
+               oss <<  "Logger Reload Config Failed : " << e.what();
+               errorConf(7, oss.str(), __FILE__, __LINE__);
+               throw std::logic_error(oss.str());
+       }
+
+       initLogLevelTable();
+}
+
+/*!
+ * initialize LogLevel table.
+ * initialize the LogLevel table.
+ *
+ * @param   void
+ * @return  void
+ */
+void l7vs::LoggerImpl::initLogLevelTable(void)
+{
+       int nCounter = 0;
+
+       for (;nCounter < LOGGER_CATEGORY_NUM; nCounter++) {
+               loglevel[nCounter] = LOG_LV_NONE;
+       }
+
+       return;
+}
index 3e6756a..fb78462 100644 (file)
-/*\r
- * @file  logger_impl.h\r
- * @brief logger module implementation class.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef __LOGGER_IMPL_H__\r
-#define __LOGGER_IMPL_H__\r
-\r
-#include <string>\r
-#include <map>\r
-#include <log4cxx/logger.h>\r
-#include <log4cxx/level.h>\r
-#include <log4cxx/net/syslogappender.h>\r
-#include <log4cxx/fileappender.h>\r
-#include <log4cxx/rollingfileappender.h>\r
-#include <log4cxx/patternlayout.h>\r
-#include "logger_enum.h"\r
-\r
-#define BUF_LEN (4096)\r
-#define LOGGER_LEVEL_NUM (6)\r
-#define LOGGER_CATEGORY_NUM (40)\r
-\r
-#define LOGGER_PROCESS_ID "SLP"\r
-\r
-#define LOGGER_NULL "/dev/null"\r
-\r
-#define HOST_NAME_LEN (256)\r
-\r
-namespace log4cxx\r
-{\r
-       typedef helpers::ObjectPtrT<RollingFileAppender> RollingFileAppenderPtr;\r
-}\r
-\r
-namespace l7vs\r
-{\r
-       /*!\r
-        *  Logger implement class.\r
-        *  operate log4cxx library. \r
-        *  this is singleton class. \r
-        */\r
-       class LoggerImpl\r
-       {\r
-       public:\r
-               //! returns current instance.\r
-               static LoggerImpl& getInstance();\r
-       protected:\r
-               //! default constructor initialize member variables.\r
-               LoggerImpl() : initialized(false), logFilename(""), rotation(LOG_ROT_SIZE), maxBackupIndex(0), maxFileSize(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")\r
-               {\r
-                       levelTable[LOG_LV_NONE] = log4cxx::Level::getDebug();\r
-                       levelTable[LOG_LV_DEBUG] = log4cxx::Level::getDebug();\r
-                       levelTable[LOG_LV_INFO] = log4cxx::Level::getInfo();\r
-                       levelTable[LOG_LV_WARN] = log4cxx::Level::getWarn();\r
-                       levelTable[LOG_LV_ERROR] = log4cxx::Level::getError();\r
-                       levelTable[LOG_LV_FATAL] = log4cxx::Level::getFatal();\r
-\r
-                       loggerCategory = LOG_CAT_SSLPROXY_LOGGER;\r
-                       //set default log level\r
-                       for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {\r
-                               categoryLevel[cat] = log4cxx::Level::getError();\r
-                       }\r
-               }\r
-               //! cpoy constructor disable\r
-               LoggerImpl( const LoggerImpl& );\r
-               //! operator= disable\r
-               LoggerImpl& operator=( const LoggerImpl& );\r
-               //! destructor.\r
-               virtual ~LoggerImpl() {}\r
-               //! static Logger instance\r
-               static LoggerImpl* instance;\r
-               //! initialized flag\r
-               bool initialized;\r
-               //! logger category\r
-               LOG_CATEGORY_TAG loggerCategory;\r
-               //! hostname\r
-               char hostname[HOST_NAME_LEN];\r
-\r
-               //! if error occured, switch appenders to syslogappender and fileappender(/dev/console)\r
-               virtual void errorConf(unsigned int messageId, const std::string& errorMessage, const char* file, int line);\r
-\r
-               //! base logFileanme\r
-               std::string logFilename;\r
-               //! rotation way (size base, date base, or both size and date base)\r
-               LOG_ROTATION_TAG rotation;\r
-               //! number of backup log file\r
-               unsigned int maxBackupIndex;\r
-               //! max size of log file\r
-               unsigned long long maxFileSize;\r
-               /*!\r
-                *  rotation timing\r
-                *  "year"   = yearly\r
-                *  "monthr" = monthly\r
-                *  "week"   = weekly\r
-                *  "date"   = daily\r
-                *  "hour"   = hourly\r
-                */\r
-               LOG_ROTATION_TIMING_TAG rotationTiming;\r
-               /*!\r
-                *  rotation timing value \r
-                *\r
-                *  rotation timing     value\r
-                *  -------------------------------------------------\r
-                *  year                "03051500"      (3/5 15:00)\r
-                *  month               "051100"        (5 11:00)\r
-                *  week                "12000"         (mon 20:00) sun = 0, sat = 6\r
-                *  date                "1500"          (15:00)\r
-                *  hour                "45"            (45)\r
-                */\r
-               std::string rotationTimingValue;\r
-\r
-               //! key strings for logger\r
-               std::string log_filename_key;\r
-               std::string rotation_key;\r
-               std::string max_backup_index_key;\r
-               std::string max_file_size_key;\r
-               std::string rotation_timing_key;\r
-               std::string rotation_timing_value_key;\r
-\r
-\r
-               //! for transration between log4cxx::LevelPtr and LOGER_LEVEL_TAG\r
-               static log4cxx::LevelPtr levelTable[LOGGER_LEVEL_NUM];\r
-               //! for transration between string and LOGGER_CATEGORY_TAG\r
-               static char categoryTable[][LOGGER_CATEGORY_NUM];\r
-               //! holds category-loglevel\r
-               log4cxx::LevelPtr categoryLevel[LOGGER_CATEGORY_NUM];\r
-       \r
-               //! LOG_LEVEL_TAG to log4cxx::LevelPtr transrator\r
-               virtual inline const log4cxx::LevelPtr toLevel(LOG_LEVEL_TAG level)\r
-               {\r
-                       return levelTable[level];\r
-               }\r
-               //! log4cxx::LevelPtr to LOG_LEVEL_TAG transrator\r
-               virtual inline LOG_LEVEL_TAG toLevelTag(const log4cxx::LevelPtr level)\r
-               {\r
-                       int levelInt = level->toInt();\r
-                       switch (levelInt) {\r
-                       case log4cxx::Level::DEBUG_INT:\r
-                               return LOG_LV_DEBUG;\r
-                       case log4cxx::Level::INFO_INT:\r
-                               return LOG_LV_INFO;\r
-                       case log4cxx::Level::WARN_INT:\r
-                               return LOG_LV_WARN;\r
-                       case log4cxx::Level::ERROR_INT:\r
-                               return LOG_LV_ERROR;\r
-                       case log4cxx::Level::FATAL_INT:\r
-                               return LOG_LV_FATAL;\r
-                       default: \r
-                               return LOG_LV_DEBUG;\r
-                       }\r
-               }\r
-       private:\r
-               //! loglevel tagle\r
-               LOG_LEVEL_TAG loglevel[LOGGER_CATEGORY_NUM];\r
-\r
-       public:\r
-               //! initialze function\r
-               virtual bool init();\r
-               //! Configuration function\r
-               virtual void loadConf();\r
-               //! Category logger configuration function\r
-               virtual void loadCategoryLoggerConf(LOG_CATEGORY_TAG cat);\r
-               //1 initialize loglevel table\r
-               void initLogLevelTable();\r
-\r
-               /*!\r
-                * retrieve category's log level.\r
-                *\r
-                * @param   category that want to know\r
-                * @return  log level\r
-                */\r
-               virtual inline LOG_LEVEL_TAG getLogLevel(LOG_CATEGORY_TAG cat)\r
-               {\r
-                       if (LOG_LV_NONE == loglevel[cat]) {\r
-                               this->loglevel[cat] = toLevelTag(log4cxx::Logger::getLogger(categoryTable[cat])->getLevel());\r
-                       }\r
-\r
-                       return loglevel[cat];\r
-               }\r
-\r
-               /*!\r
-                * set category's log level.\r
-                *\r
-                * @param   category to set log level\r
-                * @param   level\r
-                * @retval  true  succeed\r
-                * @retval  false failed\r
-                */\r
-               virtual inline bool setLogLevel(LOG_CATEGORY_TAG cat, LOG_LEVEL_TAG level)\r
-               {\r
-                       try {\r
-                               log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(toLevel(level));\r
-                       }\r
-                       catch (const std::exception& ex) {\r
-                               return false;   \r
-                       }\r
-\r
-                       loglevel[cat] = level;\r
-                       return true;\r
-               }\r
-\r
-               /*!\r
-                * output fatal log.\r
-                *\r
-                * @param   category that logging matter occured\r
-                * @param   log message id \r
-                * @param   log message \r
-                * @param   current file \r
-                * @param   current line\r
-                * @retrun  void\r
-                */\r
-               virtual inline void putLogFatal(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-               {\r
-                       char buf[BUF_LEN];\r
-                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_FATAL, cat, message_id, message.c_str(), hostname);\r
-                       try {\r
-                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getFatal(), buf, log4cxx::spi::LocationInfo(file, "", line));\r
-                       }\r
-                       catch (const std::exception& ex) {\r
-                               std::ostringstream oss;\r
-                               oss << "Logging Error (Fatal Log) : " << ex.what();\r
-                               errorConf(1, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-               }\r
-               /*!\r
-                * output error log.\r
-                *\r
-                * @param   category that logging matter occured\r
-                * @param   log message id \r
-                * @param   log message \r
-                * @param   current file \r
-                * @param   current line\r
-                * @retrun  void\r
-                */\r
-               //! output fatal log.\r
-               virtual inline void putLogError(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-               {\r
-                       char buf[BUF_LEN];\r
-                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_ERROR, cat, message_id, message.c_str(), hostname);\r
-                       try {\r
-                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getError(), buf, log4cxx::spi::LocationInfo(file, "", line));\r
-                       }\r
-                       catch (const std::exception& ex) {\r
-                               std::ostringstream oss;\r
-                               oss << "Logging Error (Error Log) : " << ex.what();\r
-                               errorConf(2, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-               }\r
-               /*!\r
-                * output warn log.\r
-                *\r
-                * @param   category that logging matter occured\r
-                * @param   log message id \r
-                * @param   log message \r
-                * @param   current file \r
-                * @param   current line\r
-                * @retrun  void\r
-                */\r
-               //! output fatal log.\r
-               virtual inline void putLogWarn(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-               {\r
-                       char buf[BUF_LEN];\r
-                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_WARN, cat, message_id, message.c_str(), hostname);\r
-                       try {\r
-                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getWarn(), buf, log4cxx::spi::LocationInfo(file, "", line));\r
-                       }\r
-                       catch (const std::exception& ex) {\r
-                               std::ostringstream oss;\r
-                               oss << "Logging Error (Warn Log) : " << ex.what();\r
-                               errorConf(3, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-               }\r
-               /*!\r
-                * output info log.\r
-                *\r
-                * @param   category that logging matter occured\r
-                * @param   log message id \r
-                * @param   log message \r
-                * @param   current file \r
-                * @param   current line\r
-                * @retrun  void\r
-                */\r
-               //! output fatal log.\r
-               virtual inline void putLogInfo(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-               {\r
-                       char buf[BUF_LEN];\r
-                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_INFO, cat, message_id, message.c_str(), hostname);\r
-                       try {\r
-                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getInfo(), buf, log4cxx::spi::LocationInfo(file, "", line));\r
-                       }\r
-                       catch (const std::exception& ex) {\r
-                               std::ostringstream oss;\r
-                               oss << "Logging Error (Info Log) : " << ex.what();\r
-                               errorConf(4, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-               }\r
-               /*!\r
-                * output debug log.\r
-                *\r
-                * @param   category that logging matter occured\r
-                * @param   log message id \r
-                * @param   log message \r
-                * @param   current file \r
-                * @param   current line\r
-                * @retrun  void\r
-                */\r
-               virtual inline void putLogDebug(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)\r
-               {\r
-                       char buf[BUF_LEN];\r
-                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_DEBUG, cat, message_id, message.c_str(), hostname);\r
-                       try {\r
-                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getDebug(), buf, log4cxx::spi::LocationInfo(file, "", line));\r
-                       }\r
-                       catch (const std::exception& ex) {\r
-                               std::ostringstream oss;\r
-                               oss << "Logging Error (Debug Log) : " << ex.what();\r
-                               errorConf(5, oss.str(), __FILE__, __LINE__);\r
-                       }\r
-               }\r
-       };\r
-}      //namespace l7vs\r
-#endif //__LOGGER_IMPL_H__\r
+/*
+ * @file  logger_impl.h
+ * @brief logger module implementation class.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __LOGGER_IMPL_H__
+#define __LOGGER_IMPL_H__
+
+#include <string>
+#include <map>
+#include <log4cxx/logger.h>
+#include <log4cxx/level.h>
+#include <log4cxx/net/syslogappender.h>
+#include <log4cxx/fileappender.h>
+#include <log4cxx/rollingfileappender.h>
+#include <log4cxx/patternlayout.h>
+#include "logger_enum.h"
+
+#define BUF_LEN (4096)
+#define LOGGER_LEVEL_NUM (6)
+#define LOGGER_CATEGORY_NUM (40)
+
+#define LOGGER_PROCESS_ID "SLP"
+
+#define LOGGER_NULL "/dev/null"
+
+#define HOST_NAME_LEN (256)
+
+namespace log4cxx
+{
+       typedef helpers::ObjectPtrT<RollingFileAppender> RollingFileAppenderPtr;
+}
+
+namespace l7vs
+{
+       /*!
+        *  Logger implement class.
+        *  operate log4cxx library. 
+        *  this is singleton class. 
+        */
+       class LoggerImpl
+       {
+       public:
+               //! returns current instance.
+               static LoggerImpl& getInstance();
+       protected:
+               //! default constructor initialize member variables.
+               LoggerImpl() : initialized(false), logFilename(""), rotation(LOG_ROT_SIZE), maxBackupIndex(0), maxFileSize(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")
+               {
+                       levelTable[LOG_LV_NONE] = log4cxx::Level::getDebug();
+                       levelTable[LOG_LV_DEBUG] = log4cxx::Level::getDebug();
+                       levelTable[LOG_LV_INFO] = log4cxx::Level::getInfo();
+                       levelTable[LOG_LV_WARN] = log4cxx::Level::getWarn();
+                       levelTable[LOG_LV_ERROR] = log4cxx::Level::getError();
+                       levelTable[LOG_LV_FATAL] = log4cxx::Level::getFatal();
+
+                       loggerCategory = LOG_CAT_SSLPROXY_LOGGER;
+                       //set default log level
+                       for (LOG_CATEGORY_TAG cat = LOG_CAT_NONE; cat < LOG_CAT_END; ++cat) {
+                               categoryLevel[cat] = log4cxx::Level::getError();
+                       }
+               }
+               //! cpoy constructor disable
+               LoggerImpl( const LoggerImpl& );
+               //! operator= disable
+               LoggerImpl& operator=( const LoggerImpl& );
+               //! destructor.
+               virtual ~LoggerImpl() {}
+               //! static Logger instance
+               static LoggerImpl* instance;
+               //! initialized flag
+               bool initialized;
+               //! logger category
+               LOG_CATEGORY_TAG loggerCategory;
+               //! hostname
+               char hostname[HOST_NAME_LEN];
+
+               //! if error occured, switch appenders to syslogappender and fileappender(/dev/console)
+               virtual void errorConf(unsigned int messageId, const std::string& errorMessage, const char* file, int line);
+
+               //! base logFileanme
+               std::string logFilename;
+               //! rotation way (size base, date base, or both size and date base)
+               LOG_ROTATION_TAG rotation;
+               //! number of backup log file
+               unsigned int maxBackupIndex;
+               //! max size of log file
+               unsigned long long maxFileSize;
+               /*!
+                *  rotation timing
+                *  "year"   = yearly
+                *  "monthr" = monthly
+                *  "week"   = weekly
+                *  "date"   = daily
+                *  "hour"   = hourly
+                */
+               LOG_ROTATION_TIMING_TAG rotationTiming;
+               /*!
+                *  rotation timing value 
+                *
+                *  rotation timing     value
+                *  -------------------------------------------------
+                *  year                "03051500"      (3/5 15:00)
+                *  month               "051100"        (5 11:00)
+                *  week                "12000"         (mon 20:00) sun = 0, sat = 6
+                *  date                "1500"          (15:00)
+                *  hour                "45"            (45)
+                */
+               std::string rotationTimingValue;
+
+               //! key strings for logger
+               std::string log_filename_key;
+               std::string rotation_key;
+               std::string max_backup_index_key;
+               std::string max_file_size_key;
+               std::string rotation_timing_key;
+               std::string rotation_timing_value_key;
+
+
+               //! for transration between log4cxx::LevelPtr and LOGER_LEVEL_TAG
+               static log4cxx::LevelPtr levelTable[LOGGER_LEVEL_NUM];
+               //! for transration between string and LOGGER_CATEGORY_TAG
+               static char categoryTable[][LOGGER_CATEGORY_NUM];
+               //! holds category-loglevel
+               log4cxx::LevelPtr categoryLevel[LOGGER_CATEGORY_NUM];
+       
+               //! LOG_LEVEL_TAG to log4cxx::LevelPtr transrator
+               virtual inline const log4cxx::LevelPtr toLevel(LOG_LEVEL_TAG level)
+               {
+                       return levelTable[level];
+               }
+               //! log4cxx::LevelPtr to LOG_LEVEL_TAG transrator
+               virtual inline LOG_LEVEL_TAG toLevelTag(const log4cxx::LevelPtr level)
+               {
+                       int levelInt = level->toInt();
+                       switch (levelInt) {
+                       case log4cxx::Level::DEBUG_INT:
+                               return LOG_LV_DEBUG;
+                       case log4cxx::Level::INFO_INT:
+                               return LOG_LV_INFO;
+                       case log4cxx::Level::WARN_INT:
+                               return LOG_LV_WARN;
+                       case log4cxx::Level::ERROR_INT:
+                               return LOG_LV_ERROR;
+                       case log4cxx::Level::FATAL_INT:
+                               return LOG_LV_FATAL;
+                       default: 
+                               return LOG_LV_DEBUG;
+                       }
+               }
+       private:
+               //! loglevel tagle
+               LOG_LEVEL_TAG loglevel[LOGGER_CATEGORY_NUM];
+
+       public:
+               //! initialze function
+               virtual bool init();
+               //! Configuration function
+               virtual void loadConf();
+               //! Category logger configuration function
+               virtual void loadCategoryLoggerConf(LOG_CATEGORY_TAG cat);
+               //1 initialize loglevel table
+               void initLogLevelTable();
+
+               /*!
+                * retrieve category's log level.
+                *
+                * @param   category that want to know
+                * @return  log level
+                */
+               virtual inline LOG_LEVEL_TAG getLogLevel(LOG_CATEGORY_TAG cat)
+               {
+                       if (LOG_LV_NONE == loglevel[cat]) {
+                               this->loglevel[cat] = toLevelTag(log4cxx::Logger::getLogger(categoryTable[cat])->getLevel());
+                       }
+
+                       return loglevel[cat];
+               }
+
+               /*!
+                * set category's log level.
+                *
+                * @param   category to set log level
+                * @param   level
+                * @retval  true  succeed
+                * @retval  false failed
+                */
+               virtual inline bool setLogLevel(LOG_CATEGORY_TAG cat, LOG_LEVEL_TAG level)
+               {
+                       try {
+                               log4cxx::Logger::getLogger(categoryTable[cat])->setLevel(toLevel(level));
+                       }
+                       catch (const std::exception& ex) {
+                               return false;   
+                       }
+
+                       loglevel[cat] = level;
+                       return true;
+               }
+
+               /*!
+                * output fatal log.
+                *
+                * @param   category that logging matter occured
+                * @param   log message id 
+                * @param   log message 
+                * @param   current file 
+                * @param   current line
+                * @retrun  void
+                */
+               virtual inline void putLogFatal(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+               {
+                       char buf[BUF_LEN];
+                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_FATAL, cat, message_id, message.c_str(), hostname);
+                       try {
+                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getFatal(), buf, log4cxx::spi::LocationInfo(file, "", line));
+                       }
+                       catch (const std::exception& ex) {
+                               std::ostringstream oss;
+                               oss << "Logging Error (Fatal Log) : " << ex.what();
+                               errorConf(1, oss.str(), __FILE__, __LINE__);
+                       }
+               }
+               /*!
+                * output error log.
+                *
+                * @param   category that logging matter occured
+                * @param   log message id 
+                * @param   log message 
+                * @param   current file 
+                * @param   current line
+                * @retrun  void
+                */
+               //! output fatal log.
+               virtual inline void putLogError(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+               {
+                       char buf[BUF_LEN];
+                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_ERROR, cat, message_id, message.c_str(), hostname);
+                       try {
+                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getError(), buf, log4cxx::spi::LocationInfo(file, "", line));
+                       }
+                       catch (const std::exception& ex) {
+                               std::ostringstream oss;
+                               oss << "Logging Error (Error Log) : " << ex.what();
+                               errorConf(2, oss.str(), __FILE__, __LINE__);
+                       }
+               }
+               /*!
+                * output warn log.
+                *
+                * @param   category that logging matter occured
+                * @param   log message id 
+                * @param   log message 
+                * @param   current file 
+                * @param   current line
+                * @retrun  void
+                */
+               //! output fatal log.
+               virtual inline void putLogWarn(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+               {
+                       char buf[BUF_LEN];
+                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_WARN, cat, message_id, message.c_str(), hostname);
+                       try {
+                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getWarn(), buf, log4cxx::spi::LocationInfo(file, "", line));
+                       }
+                       catch (const std::exception& ex) {
+                               std::ostringstream oss;
+                               oss << "Logging Error (Warn Log) : " << ex.what();
+                               errorConf(3, oss.str(), __FILE__, __LINE__);
+                       }
+               }
+               /*!
+                * output info log.
+                *
+                * @param   category that logging matter occured
+                * @param   log message id 
+                * @param   log message 
+                * @param   current file 
+                * @param   current line
+                * @retrun  void
+                */
+               //! output fatal log.
+               virtual inline void putLogInfo(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+               {
+                       char buf[BUF_LEN];
+                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_INFO, cat, message_id, message.c_str(), hostname);
+                       try {
+                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getInfo(), buf, log4cxx::spi::LocationInfo(file, "", line));
+                       }
+                       catch (const std::exception& ex) {
+                               std::ostringstream oss;
+                               oss << "Logging Error (Info Log) : " << ex.what();
+                               errorConf(4, oss.str(), __FILE__, __LINE__);
+                       }
+               }
+               /*!
+                * output debug log.
+                *
+                * @param   category that logging matter occured
+                * @param   log message id 
+                * @param   log message 
+                * @param   current file 
+                * @param   current line
+                * @retrun  void
+                */
+               virtual inline void putLogDebug(LOG_CATEGORY_TAG cat, const unsigned int message_id, const std::string& message, const char *file, int line)
+               {
+                       char buf[BUF_LEN];
+                       snprintf(buf, BUF_LEN, "%s%d%03d%04d %s %s", LOGGER_PROCESS_ID, LOG_LV_DEBUG, cat, message_id, message.c_str(), hostname);
+                       try {
+                               log4cxx::Logger::getLogger(categoryTable[cat])->forcedLog(log4cxx::Level::getDebug(), buf, log4cxx::spi::LocationInfo(file, "", line));
+                       }
+                       catch (const std::exception& ex) {
+                               std::ostringstream oss;
+                               oss << "Logging Error (Debug Log) : " << ex.what();
+                               errorConf(5, oss.str(), __FILE__, __LINE__);
+                       }
+               }
+       };
+}      //namespace l7vs
+#endif //__LOGGER_IMPL_H__
index 79394f1..ce745f1 100644 (file)
-/*\r
- * @file  logger_wapprer.h\r
- * @brief logger module c wrapper.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *      \r
- **********************************************************************/\r
-\r
-#ifndef __LOGGER_WRAPPER_H__\r
-#define __LOGGER_WRAPPER_H__\r
-\r
-#include "logger.h"\r
-\r
-/*!\r
- * retrieve category's log level.\r
- * this is only wrapper to implement method.\r
- * @param   category that want to know\r
- * @return  log level\r
- */\r
-inline enum LOG_LEVEL_TAG logger_get_log_level(const enum LOG_CATEGORY_TAG cat)\r
-{\r
-       return l7vs::Logger::getInstance().getLogLevel(cat);\r
-}\r
-\r
-/*!\r
- * set category's log level.\r
- * this is only wrapper to implement method.\r
- * @param   category to set log level\r
- * @param   level\r
- * @retval  0  succeed\r
- * @retval  -1 failed\r
- */\r
-inline int     logger_set_log_level(const enum LOG_CATEGORY_TAG cat, const enum LOG_LEVEL_TAG level)\r
-{\r
-       if (l7vs::Logger::getInstance().setLogLevel(cat, level)) {\r
-               return 0;\r
-       }\r
-       return -1;\r
-}\r
-\r
-/*!\r
- * output fatal log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   current file \r
- * @param   current line\r
- * @param   log message \r
- * @retrun  void\r
- */\r
-inline void    logger_put_log_fatal(const enum LOG_CATEGORY_TAG cat, const unsigned int message_id, char* file, int line, const char* message)\r
-{\r
-       l7vs::Logger::getInstance().putLogFatal(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * output error log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   current file \r
- * @param   current line\r
- * @param   log message \r
- * @retrun  void\r
- */\r
-inline void    logger_put_log_error(const enum LOG_CATEGORY_TAG cat, const unsigned int message_id, char* file, int line, const char* message)\r
-{\r
-       l7vs::Logger::getInstance().putLogError(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * output warn log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   current file \r
- * @param   current line\r
- * @param   log message \r
- * @retrun  void\r
- */\r
-inline void    logger_put_log_warn(const enum LOG_CATEGORY_TAG cat, const unsigned int  message_id, char* file, int line, const char* message)\r
-{\r
-       l7vs::Logger::getInstance().putLogWarn(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * output info log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   current file \r
- * @param   current line\r
- * @param   log message \r
- * @retrun  void\r
- */\r
-inline void    logger_put_log_info(const enum LOG_CATEGORY_TAG cat, const unsigned int message_id, char* file, int line, const char* message)\r
-{\r
-       l7vs::Logger::getInstance().putLogInfo(cat, message_id, message, file, line);\r
-}\r
-\r
-/*!\r
- * output debug log.\r
- * this is only wrapper to implement method.\r
- * @param   category that logging matter occured\r
- * @param   log message id \r
- * @param   current file \r
- * @param   current line\r
- * @param   log message \r
- * @retrun  void\r
- */\r
-inline void    logger_put_log_debug(const enum LOG_CATEGORY_TAG cat, const unsigned int message_id, char* file, int line, const char* message)\r
-{\r
-       l7vs::Logger::getInstance().putLogDebug(cat, message_id, message, file, line);\r
-}\r
-\r
-#define LOGGER_PUT_LOG_FATAL(cat, message_id, message, arg...) { \\r
-       if (LOG_LV_FATAL >= logger_get_log_level(cat)) { \\r
-       char buf[BUF_LEN]; \\r
-       snprintf(buf, BUF_LEN, message, ##arg); \\r
-       logger_put_log_fatal(cat, message_id, __FILE__, __LINE__, buf); }}\r
-       \r
-#define LOGGER_PUT_LOG_ERROR(cat, message_id, message, arg...) { \\r
-       if (LOG_LV_ERROR >= logger_get_log_level(cat)) { \\r
-       char buf[BUF_LEN]; \\r
-       snprintf(buf, BUF_LEN, message, ##arg); \\r
-       logger_put_log_error(cat, message_id, __FILE__, __LINE__, buf); }}\r
-\r
-#define LOGGER_PUT_LOG_WARN(cat, message_id, message, arg...) { \\r
-       if (LOG_LV_WARN >= logger_get_log_level(cat)) { \\r
-       char buf[BUF_LEN]; \\r
-       snprintf(buf, BUF_LEN, message, ##arg); \\r
-       logger_put_log_warn(cat, message_id, __FILE__, __LINE__, buf); }}\r
-\r
-#define LOGGER_PUT_LOG_INFO(cat, message_id, message, arg...) { \\r
-       if (LOG_LV_INFO >= logger_get_log_level(cat)) { \\r
-       char buf[BUF_LEN]; \\r
-       snprintf(buf, BUF_LEN, message, ##arg); \\r
-       logger_put_log_info(cat, message_id, __FILE__, __LINE__, buf); }}\r
-\r
-#define LOGGER_PUT_LOG_DEBUG(cat, message_id, message, arg...) { \\r
-       char buf[BUF_LEN]; \\r
-       snprintf(buf, BUF_LEN, message, ##arg); \\r
-       logger_put_log_debug(cat, message_id, __FILE__, __LINE__, buf); }\r
-\r
-#endif //__LOGGER_WRAPPER_H__\r
+/*
+ * @file  logger_wapprer.h
+ * @brief logger module c wrapper.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __LOGGER_WRAPPER_H__
+#define __LOGGER_WRAPPER_H__
+
+#include "logger.h"
+
+/*!
+ * retrieve category's log level.
+ * this is only wrapper to implement method.
+ * @param   category that want to know
+ * @return  log level
+ */
+inline enum LOG_LEVEL_TAG logger_get_log_level(const enum LOG_CATEGORY_TAG cat)
+{
+       return l7vs::Logger::getInstance().getLogLevel(cat);
+}
+
+/*!
+ * set category's log level.
+ * this is only wrapper to implement method.
+ * @param   category to set log level
+ * @param   level
+ * @retval  0  succeed
+ * @retval  -1 failed
+ */
+inline int     logger_set_log_level(const enum LOG_CATEGORY_TAG cat, const enum LOG_LEVEL_TAG level)
+{
+       if (l7vs::Logger::getInstance().setLogLevel(cat, level)) {
+               return 0;
+       }
+       return -1;
+}
+
+/*!
+ * output fatal log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   current file 
+ * @param   current line
+ * @param   log message 
+ * @retrun  void
+ */
+inline void    logger_put_log_fatal(const enum LOG_CATEGORY_TAG cat, const unsigned int message_id, char* file, int line, const char* message)
+{
+       l7vs::Logger::getInstance().putLogFatal(cat, message_id, message, file, line);
+}
+
+/*!
+ * output error log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   current file 
+ * @param   current line
+ * @param   log message 
+ * @retrun  void
+ */
+inline void    logger_put_log_error(const enum LOG_CATEGORY_TAG cat, const unsigned int message_id, char* file, int line, const char* message)
+{
+       l7vs::Logger::getInstance().putLogError(cat, message_id, message, file, line);
+}
+
+/*!
+ * output warn log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   current file 
+ * @param   current line
+ * @param   log message 
+ * @retrun  void
+ */
+inline void    logger_put_log_warn(const enum LOG_CATEGORY_TAG cat, const unsigned int  message_id, char* file, int line, const char* message)
+{
+       l7vs::Logger::getInstance().putLogWarn(cat, message_id, message, file, line);
+}
+
+/*!
+ * output info log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   current file 
+ * @param   current line
+ * @param   log message 
+ * @retrun  void
+ */
+inline void    logger_put_log_info(const enum LOG_CATEGORY_TAG cat, const unsigned int message_id, char* file, int line, const char* message)
+{
+       l7vs::Logger::getInstance().putLogInfo(cat, message_id, message, file, line);
+}
+
+/*!
+ * output debug log.
+ * this is only wrapper to implement method.
+ * @param   category that logging matter occured
+ * @param   log message id 
+ * @param   current file 
+ * @param   current line
+ * @param   log message 
+ * @retrun  void
+ */
+inline void    logger_put_log_debug(const enum LOG_CATEGORY_TAG cat, const unsigned int message_id, char* file, int line, const char* message)
+{
+       l7vs::Logger::getInstance().putLogDebug(cat, message_id, message, file, line);
+}
+
+#define LOGGER_PUT_LOG_FATAL(cat, message_id, message, arg...) { \
+       if (LOG_LV_FATAL >= logger_get_log_level(cat)) { \
+       char buf[BUF_LEN]; \
+       snprintf(buf, BUF_LEN, message, ##arg); \
+       logger_put_log_fatal(cat, message_id, __FILE__, __LINE__, buf); }}
+       
+#define LOGGER_PUT_LOG_ERROR(cat, message_id, message, arg...) { \
+       if (LOG_LV_ERROR >= logger_get_log_level(cat)) { \
+       char buf[BUF_LEN]; \
+       snprintf(buf, BUF_LEN, message, ##arg); \
+       logger_put_log_error(cat, message_id, __FILE__, __LINE__, buf); }}
+
+#define LOGGER_PUT_LOG_WARN(cat, message_id, message, arg...) { \
+       if (LOG_LV_WARN >= logger_get_log_level(cat)) { \
+       char buf[BUF_LEN]; \
+       snprintf(buf, BUF_LEN, message, ##arg); \
+       logger_put_log_warn(cat, message_id, __FILE__, __LINE__, buf); }}
+
+#define LOGGER_PUT_LOG_INFO(cat, message_id, message, arg...) { \
+       if (LOG_LV_INFO >= logger_get_log_level(cat)) { \
+       char buf[BUF_LEN]; \
+       snprintf(buf, BUF_LEN, message, ##arg); \
+       logger_put_log_info(cat, message_id, __FILE__, __LINE__, buf); }}
+
+#define LOGGER_PUT_LOG_DEBUG(cat, message_id, message, arg...) { \
+       char buf[BUF_LEN]; \
+       snprintf(buf, BUF_LEN, message, ##arg); \
+       logger_put_log_debug(cat, message_id, __FILE__, __LINE__, buf); }
+
+#endif //__LOGGER_WRAPPER_H__
index 4511b17..8349b3a 100644 (file)
-/*\r
- * @file  strict_time_based_rolling_policy.cpp\r
- * @brief log4cxx's rolling policy class. (time)\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#include <log4cxx/logstring.h>\r
-#include <log4cxx/rolling/filerenameaction.h>\r
-#include <log4cxx/helpers/loglog.h>\r
-#include <log4cxx/helpers/exception.h>\r
-#include <log4cxx/helpers/stringhelper.h>\r
-#include <log4cxx/helpers/optionconverter.h>\r
-#include <time.h>\r
-#include "strict_time_based_rolling_policy.h"\r
-#include "lexical_cast.h"\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <unistd.h>\r
-\r
-using namespace log4cxx;\r
-using namespace log4cxx::rolling;\r
-using namespace log4cxx::helpers;\r
-using namespace log4cxx::pattern;\r
-\r
-#define TIME_BUF_LEN (256)\r
-#define LOG_DATE_FORMAT "%Y%m%d%H%M"\r
-#define LOG_DATE_FORMAT_WEEK "%Y%m%d%w%H%M"\r
-\r
-IMPLEMENT_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)\r
-\r
-/*!\r
- * default constructor.\r
- * initialize member valiables\r
- * @param   void\r
- * @return  void\r
- */\r
-StrictTimeBasedRollingPolicy::StrictTimeBasedRollingPolicy() :\r
-       nextCheck(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")\r
-{\r
-}\r
-\r
-/*!\r
- * increase reffernce count\r
- * @param   void\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::addRef() const\r
-{\r
-       TriggeringPolicy::addRef();\r
-}\r
-\r
-/*!\r
- * decrease reffernce count\r
- * @param   void\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::releaseRef() const\r
-{\r
-       TriggeringPolicy::releaseRef();\r
-}\r
-\r
-/*!\r
- * evaluate and activate options\r
- * @param   memory pool\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)\r
-{\r
-       // check for rotationTimingValue\r
-       if (0 >= rotationTimingValue.length()) {\r
-               LogLog::warn(\r
-               LOG4CXX_STR("The RotationTimingValue option must be set before using StrictTimeBasedRollingPolicy. "));\r
-               throw IllegalStateException();\r
-       }\r
-\r
-       // call super class's activateOptions\r
-       FixedWindowRollingPolicy::activateOptions(pool);\r
-}\r
-\r
-/*!\r
- * rotationTimingValue getter\r
- * @param   void\r
- * @return  rotationTimingValue\r
- */\r
-std::string StrictTimeBasedRollingPolicy::getRotationTimingValue()\r
-{\r
-       return rotationTimingValue;\r
-}\r
\r
-/*!\r
- * rotationTimingValue setter\r
- * @param   rotationTimingValue\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::setRotationTimingValue(const std::string& val)\r
-{\r
-       rotationTimingValue = val;\r
-}\r
-\r
-/*!\r
- * rotationTiming getter\r
- * @param   void\r
- * @return  rotationTiming\r
- */\r
-LOG_ROTATION_TIMING_TAG StrictTimeBasedRollingPolicy::getRotationTiming()\r
-{\r
-       return rotationTiming;\r
-}\r
\r
-/*!\r
- * rotationTiming setter\r
- * @param   rotationTiming\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::setRotationTiming(const LOG_ROTATION_TIMING_TAG val)\r
-{\r
-       rotationTiming = val;\r
-}\r
-\r
-/*!\r
- * option setter\r
- * @param   option name\r
- * @param   value\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)\r
-{\r
-       if (StringHelper::equalsIgnoreCase(option,\r
-               LOG4CXX_STR("ROTATIONTIMINGVALUE"),\r
-               LOG4CXX_STR("rotationtimingvalue"))) {\r
-               rotationTimingValue = value;\r
-       }\r
-       else if (StringHelper::equalsIgnoreCase(option,\r
-               LOG4CXX_STR("ROTATIONTIMING"),\r
-               LOG4CXX_STR("rotationtiming"))) {\r
-               rotationTiming = (LOG_ROTATION_TIMING_TAG)OptionConverter::toInt(value, 0);\r
-       }\r
-       else {\r
-               FixedWindowRollingPolicy::setOption(option, value);\r
-       }\r
-}\r
-\r
-/*!\r
- * rolling policy initialize\r
- * @param   filename of current use\r
- * @param   append or overWrite\r
- * @param   memory pool\r
- * @return  Rollover information\r
- */\r
-RolloverDescriptionPtr StrictTimeBasedRollingPolicy::initialize(\r
-       const LogString& currentActiveFile,\r
-       const bool append,\r
-       Pool& pool) \r
-{\r
-       // get current time\r
-       time_t now_time;\r
-       time_t ret_time = time(&now_time);\r
-       if (-1 == ret_time) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));\r
-               RolloverDescriptionPtr desc;\r
-               return desc;\r
-       }\r
-\r
-       // get next rotation timing\r
-       nextCheck = getNextCheck(now_time);\r
-       if (-1 == nextCheck) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));\r
-               RolloverDescriptionPtr desc;\r
-               return desc;\r
-       }       \r
-\r
-       // call super class's initialize\r
-       return FixedWindowRollingPolicy::initialize(currentActiveFile, append, pool);\r
-}\r
-\r
-/*!\r
- * calculate next rollover timing\r
- * @param   now time\r
- * @return  next rollover time\r
- */\r
-time_t StrictTimeBasedRollingPolicy::getNextCheck(time_t now_time)\r
-{\r
-       struct tm now_tm;\r
-       struct tm *ret_tm;\r
-       ret_tm = localtime_r(&now_time, &now_tm);\r
-       if (0 == ret_tm) {\r
-               return -1;\r
-       }\r
-       \r
-       char buf[TIME_BUF_LEN];\r
-       size_t ret_sz = 0;\r
-       if (LOG_TIM_WEEK == rotationTiming) {\r
-               ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT_WEEK, &now_tm);\r
-       }\r
-       else {\r
-               ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT, &now_tm);\r
-       }\r
-       if (0 == ret_sz) {\r
-               return -1;\r
-       }\r
-       std::string now(buf);\r
-\r
-       int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; \r
-       unsigned long long numNowDate = 0;;\r
-       unsigned long long numTimingDate = 0;\r
-\r
-       int numYear = 0;\r
-       int numMonth = 0;\r
-       int numDate = 0;\r
-       int numNowWeek = 0;\r
-       int numTimingWeek = 0;\r
-       int numHour = 0;\r
-       int numMinute = 0;\r
-\r
-       struct tm t;\r
-       memset(&t, 0, sizeof(struct tm));\r
-\r
-       time_t next = 0;\r
-\r
-       try {\r
-               switch (rotationTiming) {\r
-               case LOG_TIM_YEAR:\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(4));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));\r
-                       numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));\r
-                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(4, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(6));\r
-       \r
-                       if (numTimingDate > numNowDate) {\r
-                               t.tm_year = numYear - 1900;\r
-                       }\r
-                       else {\r
-                               t.tm_year = numYear + 1 - 1900;\r
-                       }\r
-                       t.tm_mon = numMonth - 1;\r
-                       t.tm_mday = numDate;\r
-                       t.tm_hour = numHour;\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-                       break;\r
-       \r
-               case LOG_TIM_MONTH:\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(6));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));\r
-                       numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));\r
-                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(4));\r
-       \r
-                       if (numTimingDate > numNowDate) {\r
-                               t.tm_year = numYear - 1900;\r
-                               t.tm_mon = numMonth - 1;\r
-                       }\r
-                       else {\r
-                               if (12 == numMonth) {\r
-                                       t.tm_year = numYear + 1 - 1900;\r
-                                       t.tm_mon = 0;\r
-                               }\r
-                               else {\r
-                                       t.tm_year = numYear - 1900;\r
-                                       t.tm_mon = numMonth + 1 - 1;\r
-                               }\r
-                       }\r
-       \r
-                       if (numDate > dates[t.tm_mon]) {\r
-                               t.tm_mday = dates[t.tm_mon];\r
-                       }\r
-                       else {\r
-                               t.tm_mday = numDate;\r
-                       }\r
-\r
-                       t.tm_hour = numHour;\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-       \r
-                       break;\r
-               case LOG_TIM_WEEK:\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));\r
-                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));\r
-                       numNowWeek = l7vs::lexical_cast<int>(now.substr(8, 1));\r
-                       numTimingWeek = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 1));\r
-                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(1, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(3));\r
-       \r
-                       t.tm_year = numYear - 1900;\r
-                       t.tm_mon = numMonth - 1;\r
-                       if (numTimingDate > numNowDate) {       \r
-                               t.tm_mday = numDate + (numTimingWeek - numNowWeek); \r
-                       }\r
-                       else {\r
-                               t.tm_mday = numDate + (7 - (numNowWeek - numTimingWeek));\r
-                       }\r
-                       t.tm_hour = numHour;\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-       \r
-                       break;\r
-       \r
-               case LOG_TIM_DATE:\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));\r
-                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));\r
-                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(2));\r
-       \r
-                       t.tm_year = numYear - 1900;\r
-                       t.tm_mon = numMonth - 1;\r
-                       if (numTimingDate > numNowDate) {       \r
-                               t.tm_mday = numDate;\r
-                       }\r
-                       else {\r
-                               t.tm_mday = numDate + 1; \r
-                       }\r
-                       t.tm_hour = numHour;\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-                       break;\r
-       \r
-               default:        //HOUR\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(10));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));\r
-                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));\r
-                       numHour = l7vs::lexical_cast<int>(now.substr(8, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue);\r
-       \r
-                       t.tm_year = numYear - 1900;\r
-                       t.tm_mon = numMonth - 1;\r
-                       t.tm_mday = numDate;\r
-                       if (numTimingDate > numNowDate) {\r
-                               t.tm_hour = numHour;\r
-                       }\r
-                       else {\r
-                               t.tm_hour = numHour + 1;\r
-                       }\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-               }\r
-       }\r
-       catch (const std::exception& ex) {\r
-               return -1;\r
-       }\r
-       return next;\r
-\r
-}\r
-\r
-/*!\r
- * log file rollover opration\r
- * @param   name of current log file\r
- * @param   memory pool\r
- * @return  Rollover infomation\r
- */\r
-RolloverDescriptionPtr StrictTimeBasedRollingPolicy::rollover(\r
-       const LogString& currentActiveFile,\r
-       Pool& pool) \r
-{\r
-       // get current time\r
-       time_t now_time;\r
-       time_t ret_time = time(&now_time);\r
-       if (-1 == ret_time) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));\r
-               RolloverDescriptionPtr desc;\r
-               return desc;\r
-       }\r
-\r
-       // get next rotation timing\r
-       nextCheck = getNextCheck(now_time);\r
-       if (-1 == nextCheck) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));\r
-               RolloverDescriptionPtr desc;\r
-               return desc;\r
-       }       \r
-\r
-       // call super class's rollover\r
-       return FixedWindowRollingPolicy::rollover(currentActiveFile, pool);\r
-\r
-}\r
-\r
-/*!\r
- * returns do rollover or not\r
- * @param   appender (not use)\r
- * @param   event (not use)\r
- * @param   filename\r
- * @param   fileLength (not use)\r
- * @retval  true do rollover\r
- * @retval  false not rollover yet\r
- */\r
-bool StrictTimeBasedRollingPolicy::isTriggeringEvent(\r
-       Appender* /* appender */,\r
-       const log4cxx::spi::LoggingEventPtr& /* event */,\r
-       const LogString& filename,\r
-       size_t /* fileLength */)  \r
-{\r
-       time_t now_time;\r
-       time_t ret_time = time(&now_time);\r
-       if (-1 == ret_time) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get time. "));\r
-               return false;\r
-       }\r
-       return now_time > nextCheck;\r
-}\r
+/*
+ * @file  strict_time_based_rolling_policy.cpp
+ * @brief log4cxx's rolling policy class. (time)
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 <log4cxx/logstring.h>
+#include <log4cxx/rolling/filerenameaction.h>
+#include <log4cxx/helpers/loglog.h>
+#include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/optionconverter.h>
+#include <time.h>
+#include "strict_time_based_rolling_policy.h"
+#include "lexical_cast.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace log4cxx;
+using namespace log4cxx::rolling;
+using namespace log4cxx::helpers;
+using namespace log4cxx::pattern;
+
+#define TIME_BUF_LEN (256)
+#define LOG_DATE_FORMAT "%Y%m%d%H%M"
+#define LOG_DATE_FORMAT_WEEK "%Y%m%d%w%H%M"
+
+IMPLEMENT_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)
+
+/*!
+ * default constructor.
+ * initialize member valiables
+ * @param   void
+ * @return  void
+ */
+StrictTimeBasedRollingPolicy::StrictTimeBasedRollingPolicy() :
+       nextCheck(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")
+{
+}
+
+/*!
+ * increase reffernce count
+ * @param   void
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::addRef() const
+{
+       TriggeringPolicy::addRef();
+}
+
+/*!
+ * decrease reffernce count
+ * @param   void
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::releaseRef() const
+{
+       TriggeringPolicy::releaseRef();
+}
+
+/*!
+ * evaluate and activate options
+ * @param   memory pool
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)
+{
+       // check for rotationTimingValue
+       if (0 >= rotationTimingValue.length()) {
+               LogLog::warn(
+               LOG4CXX_STR("The RotationTimingValue option must be set before using StrictTimeBasedRollingPolicy. "));
+               throw IllegalStateException();
+       }
+
+       // call super class's activateOptions
+       FixedWindowRollingPolicy::activateOptions(pool);
+}
+
+/*!
+ * rotationTimingValue getter
+ * @param   void
+ * @return  rotationTimingValue
+ */
+std::string StrictTimeBasedRollingPolicy::getRotationTimingValue()
+{
+       return rotationTimingValue;
+}
+/*!
+ * rotationTimingValue setter
+ * @param   rotationTimingValue
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::setRotationTimingValue(const std::string& val)
+{
+       rotationTimingValue = val;
+}
+
+/*!
+ * rotationTiming getter
+ * @param   void
+ * @return  rotationTiming
+ */
+LOG_ROTATION_TIMING_TAG StrictTimeBasedRollingPolicy::getRotationTiming()
+{
+       return rotationTiming;
+}
+/*!
+ * rotationTiming setter
+ * @param   rotationTiming
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::setRotationTiming(const LOG_ROTATION_TIMING_TAG val)
+{
+       rotationTiming = val;
+}
+
+/*!
+ * option setter
+ * @param   option name
+ * @param   value
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)
+{
+       if (StringHelper::equalsIgnoreCase(option,
+               LOG4CXX_STR("ROTATIONTIMINGVALUE"),
+               LOG4CXX_STR("rotationtimingvalue"))) {
+               rotationTimingValue = value;
+       }
+       else if (StringHelper::equalsIgnoreCase(option,
+               LOG4CXX_STR("ROTATIONTIMING"),
+               LOG4CXX_STR("rotationtiming"))) {
+               rotationTiming = (LOG_ROTATION_TIMING_TAG)OptionConverter::toInt(value, 0);
+       }
+       else {
+               FixedWindowRollingPolicy::setOption(option, value);
+       }
+}
+
+/*!
+ * rolling policy initialize
+ * @param   filename of current use
+ * @param   append or overWrite
+ * @param   memory pool
+ * @return  Rollover information
+ */
+RolloverDescriptionPtr StrictTimeBasedRollingPolicy::initialize(
+       const LogString& currentActiveFile,
+       const bool append,
+       Pool& pool) 
+{
+       // get current time
+       time_t now_time;
+       time_t ret_time = time(&now_time);
+       if (-1 == ret_time) {
+               LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));
+               RolloverDescriptionPtr desc;
+               return desc;
+       }
+
+       // get next rotation timing
+       nextCheck = getNextCheck(now_time);
+       if (-1 == nextCheck) {
+               LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));
+               RolloverDescriptionPtr desc;
+               return desc;
+       }       
+
+       // call super class's initialize
+       return FixedWindowRollingPolicy::initialize(currentActiveFile, append, pool);
+}
+
+/*!
+ * calculate next rollover timing
+ * @param   now time
+ * @return  next rollover time
+ */
+time_t StrictTimeBasedRollingPolicy::getNextCheck(time_t now_time)
+{
+       struct tm now_tm;
+       struct tm *ret_tm;
+       ret_tm = localtime_r(&now_time, &now_tm);
+       if (0 == ret_tm) {
+               return -1;
+       }
+       
+       char buf[TIME_BUF_LEN];
+       size_t ret_sz = 0;
+       if (LOG_TIM_WEEK == rotationTiming) {
+               ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT_WEEK, &now_tm);
+       }
+       else {
+               ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT, &now_tm);
+       }
+       if (0 == ret_sz) {
+               return -1;
+       }
+       std::string now(buf);
+
+       int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
+       unsigned long long numNowDate = 0;;
+       unsigned long long numTimingDate = 0;
+
+       int numYear = 0;
+       int numMonth = 0;
+       int numDate = 0;
+       int numNowWeek = 0;
+       int numTimingWeek = 0;
+       int numHour = 0;
+       int numMinute = 0;
+
+       struct tm t;
+       memset(&t, 0, sizeof(struct tm));
+
+       time_t next = 0;
+
+       try {
+               switch (rotationTiming) {
+               case LOG_TIM_YEAR:
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(4));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
+                       numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));
+                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(4, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(6));
+       
+                       if (numTimingDate > numNowDate) {
+                               t.tm_year = numYear - 1900;
+                       }
+                       else {
+                               t.tm_year = numYear + 1 - 1900;
+                       }
+                       t.tm_mon = numMonth - 1;
+                       t.tm_mday = numDate;
+                       t.tm_hour = numHour;
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+                       break;
+       
+               case LOG_TIM_MONTH:
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(6));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
+                       numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
+                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(4));
+       
+                       if (numTimingDate > numNowDate) {
+                               t.tm_year = numYear - 1900;
+                               t.tm_mon = numMonth - 1;
+                       }
+                       else {
+                               if (12 == numMonth) {
+                                       t.tm_year = numYear + 1 - 1900;
+                                       t.tm_mon = 0;
+                               }
+                               else {
+                                       t.tm_year = numYear - 1900;
+                                       t.tm_mon = numMonth + 1 - 1;
+                               }
+                       }
+       
+                       if (numDate > dates[t.tm_mon]) {
+                               t.tm_mday = dates[t.tm_mon];
+                       }
+                       else {
+                               t.tm_mday = numDate;
+                       }
+
+                       t.tm_hour = numHour;
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+       
+                       break;
+               case LOG_TIM_WEEK:
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
+                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
+                       numNowWeek = l7vs::lexical_cast<int>(now.substr(8, 1));
+                       numTimingWeek = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 1));
+                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(1, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(3));
+       
+                       t.tm_year = numYear - 1900;
+                       t.tm_mon = numMonth - 1;
+                       if (numTimingDate > numNowDate) {       
+                               t.tm_mday = numDate + (numTimingWeek - numNowWeek); 
+                       }
+                       else {
+                               t.tm_mday = numDate + (7 - (numNowWeek - numTimingWeek));
+                       }
+                       t.tm_hour = numHour;
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+       
+                       break;
+       
+               case LOG_TIM_DATE:
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
+                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
+                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(2));
+       
+                       t.tm_year = numYear - 1900;
+                       t.tm_mon = numMonth - 1;
+                       if (numTimingDate > numNowDate) {       
+                               t.tm_mday = numDate;
+                       }
+                       else {
+                               t.tm_mday = numDate + 1; 
+                       }
+                       t.tm_hour = numHour;
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+                       break;
+       
+               default:        //HOUR
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(10));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
+                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
+                       numHour = l7vs::lexical_cast<int>(now.substr(8, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue);
+       
+                       t.tm_year = numYear - 1900;
+                       t.tm_mon = numMonth - 1;
+                       t.tm_mday = numDate;
+                       if (numTimingDate > numNowDate) {
+                               t.tm_hour = numHour;
+                       }
+                       else {
+                               t.tm_hour = numHour + 1;
+                       }
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+               }
+       }
+       catch (const std::exception& ex) {
+               return -1;
+       }
+       return next;
+
+}
+
+/*!
+ * log file rollover opration
+ * @param   name of current log file
+ * @param   memory pool
+ * @return  Rollover infomation
+ */
+RolloverDescriptionPtr StrictTimeBasedRollingPolicy::rollover(
+       const LogString& currentActiveFile,
+       Pool& pool) 
+{
+       // get current time
+       time_t now_time;
+       time_t ret_time = time(&now_time);
+       if (-1 == ret_time) {
+               LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));
+               RolloverDescriptionPtr desc;
+               return desc;
+       }
+
+       // get next rotation timing
+       nextCheck = getNextCheck(now_time);
+       if (-1 == nextCheck) {
+               LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));
+               RolloverDescriptionPtr desc;
+               return desc;
+       }       
+
+       // call super class's rollover
+       return FixedWindowRollingPolicy::rollover(currentActiveFile, pool);
+
+}
+
+/*!
+ * returns do rollover or not
+ * @param   appender (not use)
+ * @param   event (not use)
+ * @param   filename
+ * @param   fileLength (not use)
+ * @retval  true do rollover
+ * @retval  false not rollover yet
+ */
+bool StrictTimeBasedRollingPolicy::isTriggeringEvent(
+       Appender* /* appender */,
+       const log4cxx::spi::LoggingEventPtr& /* event */,
+       const LogString& filename,
+       size_t /* fileLength */)  
+{
+       time_t now_time;
+       time_t ret_time = time(&now_time);
+       if (-1 == ret_time) {
+               LogLog::warn(LOG4CXX_STR("Fail to get time. "));
+               return false;
+       }
+       return now_time > nextCheck;
+}
index 1446642..c12d953 100644 (file)
-/*\r
- * @file  strict_time_based_rolling_policy.h\r
- * @brief log4cxx's rolling policy class. (time)\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef __STRICT_TIME_BASED_ROLLING_POLICY_H__\r
-#define __STRICT_TIME_BASED_ROLLING_POLICY_H__\r
-\r
-#include <log4cxx/portability.h>\r
-#include <log4cxx/rolling/rollingpolicybase.h>\r
-#include <log4cxx/rolling/triggeringpolicy.h>\r
-#include <log4cxx/rolling/fixedwindowrollingpolicy.h>\r
-#include "logger_enum.h"\r
-\r
-namespace log4cxx {\r
-       namespace rolling {\r
-               /*!\r
-                *  log4cxx time based rolling policy class.\r
-                *  this policy class can specify rolling time more strictly\r
-                *  than normal TimeBasedRollingPolicy.\r
-                */\r
-               class LOG4CXX_EXPORT StrictTimeBasedRollingPolicy :\r
-                       public FixedWindowRollingPolicy,\r
-                       public TriggeringPolicy\r
-               {\r
-                       DECLARE_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)\r
-                       BEGIN_LOG4CXX_CAST_MAP()\r
-                               LOG4CXX_CAST_ENTRY(StrictTimeBasedRollingPolicy)\r
-                               LOG4CXX_CAST_ENTRY_CHAIN(FixedWindowRollingPolicy)\r
-                               LOG4CXX_CAST_ENTRY_CHAIN(TriggeringPolicy)\r
-                       END_LOG4CXX_CAST_MAP()\r
-\r
-               protected:\r
-                       //! time of next rollover\r
-                       time_t nextCheck;\r
-                       /*!\r
-                        *  rotation timing\r
-                        *  LOG_TIM_YEAR   = yearly\r
-                        *  LOG_TIM_MONTH  = monthly\r
-                        *  LOG_TIM_WEEK   = weekly\r
-                        *  LOG_TIM_DATE   = daily\r
-                        *  LOG_TIM_HOUR   = hourly\r
-                        */\r
-                       LOG_ROTATION_TIMING_TAG rotationTiming;\r
-                       /*!\r
-                        *  rotation timing value \r
-                        *\r
-                        *  rotation timing     value\r
-                        *  -------------------------------------------------\r
-                        *  LOG_TIM_YEAR        "03051500"      (3/5 15:00)\r
-                        *  LOG_TIM_MONTH       "051100"        (5 11:00)\r
-                        *  LOG_TIM_WEEK        "12000"         (mon 20:00) sun = 0, sat = 6\r
-                        *  LOG_TIM_DATE        "1500"          (15:00)\r
-                        *  LOG_TIM_HOUR        "45"            (45)\r
-                        */\r
-                       std::string rotationTimingValue;\r
-                       //! calculate next rollover timing\r
-                       time_t getNextCheck(time_t now_time);\r
-                       \r
-               public:\r
-                       //! default constructor\r
-                       StrictTimeBasedRollingPolicy();\r
-                       //! increase reffernce count\r
-                       void addRef() const;\r
-                       //! decrease reffernce count\r
-                       void releaseRef() const;\r
-                       //! option setter\r
-                       void setOption(const LogString&, const LogString&);\r
-                       //! evaluate and activate options\r
-                       void activateOptions(log4cxx::helpers::Pool& );\r
-\r
-                       //! rotationTiming getter\r
-                       LOG_ROTATION_TIMING_TAG getRotationTiming();\r
-                       //! rotationTiming setter\r
-                       void setRotationTiming(const LOG_ROTATION_TIMING_TAG);\r
-                       //! rotatioTimingValue getter\r
-                       std::string getRotationTimingValue();\r
-                       //! rotatioTimingValue setter\r
-                       void setRotationTimingValue(const std::string&);\r
-                       \r
-                       //! rolling policy initialize\r
-                       RolloverDescriptionPtr initialize(\r
-                               const LogString& file,\r
-                               const bool append,\r
-                               log4cxx::helpers::Pool& pool);\r
-                       //! invoke when rollover event\r
-                       RolloverDescriptionPtr rollover(const LogString& activeFile,\r
-                               log4cxx::helpers::Pool& pool);\r
-                       \r
-                       //! returns do rollover or not \r
-                       virtual bool isTriggeringEvent(\r
-                               Appender* appender,\r
-                               const log4cxx::spi::LoggingEventPtr& event,\r
-                               const LogString& filename,\r
-                               size_t fileLength);\r
-                       \r
-               };\r
-               LOG4CXX_PTR_DEF(StrictTimeBasedRollingPolicy);\r
-       }\r
-}\r
-\r
-#endif //__STRICT_TIME_BASED_ROLLING_POLICY_H__\r
-\r
+/*
+ * @file  strict_time_based_rolling_policy.h
+ * @brief log4cxx's rolling policy class. (time)
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __STRICT_TIME_BASED_ROLLING_POLICY_H__
+#define __STRICT_TIME_BASED_ROLLING_POLICY_H__
+
+#include <log4cxx/portability.h>
+#include <log4cxx/rolling/rollingpolicybase.h>
+#include <log4cxx/rolling/triggeringpolicy.h>
+#include <log4cxx/rolling/fixedwindowrollingpolicy.h>
+#include "logger_enum.h"
+
+namespace log4cxx {
+       namespace rolling {
+               /*!
+                *  log4cxx time based rolling policy class.
+                *  this policy class can specify rolling time more strictly
+                *  than normal TimeBasedRollingPolicy.
+                */
+               class LOG4CXX_EXPORT StrictTimeBasedRollingPolicy :
+                       public FixedWindowRollingPolicy,
+                       public TriggeringPolicy
+               {
+                       DECLARE_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)
+                       BEGIN_LOG4CXX_CAST_MAP()
+                               LOG4CXX_CAST_ENTRY(StrictTimeBasedRollingPolicy)
+                               LOG4CXX_CAST_ENTRY_CHAIN(FixedWindowRollingPolicy)
+                               LOG4CXX_CAST_ENTRY_CHAIN(TriggeringPolicy)
+                       END_LOG4CXX_CAST_MAP()
+
+               protected:
+                       //! time of next rollover
+                       time_t nextCheck;
+                       /*!
+                        *  rotation timing
+                        *  LOG_TIM_YEAR   = yearly
+                        *  LOG_TIM_MONTH  = monthly
+                        *  LOG_TIM_WEEK   = weekly
+                        *  LOG_TIM_DATE   = daily
+                        *  LOG_TIM_HOUR   = hourly
+                        */
+                       LOG_ROTATION_TIMING_TAG rotationTiming;
+                       /*!
+                        *  rotation timing value 
+                        *
+                        *  rotation timing     value
+                        *  -------------------------------------------------
+                        *  LOG_TIM_YEAR        "03051500"      (3/5 15:00)
+                        *  LOG_TIM_MONTH       "051100"        (5 11:00)
+                        *  LOG_TIM_WEEK        "12000"         (mon 20:00) sun = 0, sat = 6
+                        *  LOG_TIM_DATE        "1500"          (15:00)
+                        *  LOG_TIM_HOUR        "45"            (45)
+                        */
+                       std::string rotationTimingValue;
+                       //! calculate next rollover timing
+                       time_t getNextCheck(time_t now_time);
+                       
+               public:
+                       //! default constructor
+                       StrictTimeBasedRollingPolicy();
+                       //! increase reffernce count
+                       void addRef() const;
+                       //! decrease reffernce count
+                       void releaseRef() const;
+                       //! option setter
+                       void setOption(const LogString&, const LogString&);
+                       //! evaluate and activate options
+                       void activateOptions(log4cxx::helpers::Pool& );
+
+                       //! rotationTiming getter
+                       LOG_ROTATION_TIMING_TAG getRotationTiming();
+                       //! rotationTiming setter
+                       void setRotationTiming(const LOG_ROTATION_TIMING_TAG);
+                       //! rotatioTimingValue getter
+                       std::string getRotationTimingValue();
+                       //! rotatioTimingValue setter
+                       void setRotationTimingValue(const std::string&);
+                       
+                       //! rolling policy initialize
+                       RolloverDescriptionPtr initialize(
+                               const LogString& file,
+                               const bool append,
+                               log4cxx::helpers::Pool& pool);
+                       //! invoke when rollover event
+                       RolloverDescriptionPtr rollover(const LogString& activeFile,
+                               log4cxx::helpers::Pool& pool);
+                       
+                       //! returns do rollover or not 
+                       virtual bool isTriggeringEvent(
+                               Appender* appender,
+                               const log4cxx::spi::LoggingEventPtr& event,
+                               const LogString& filename,
+                               size_t fileLength);
+                       
+               };
+               LOG4CXX_PTR_DEF(StrictTimeBasedRollingPolicy);
+       }
+}
+
+#endif //__STRICT_TIME_BASED_ROLLING_POLICY_H__
+
index bbf6e60..3b149a2 100644 (file)
-/*\r
- * @file  time_and_size_based_rolling_policy.cpp\r
- * @brief log4cxx's rolling policy class. (time + size)\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#include <log4cxx/logstring.h>\r
-#include <log4cxx/pattern/filedatepatternconverter.h>\r
-#include <log4cxx/helpers/date.h>\r
-#include <log4cxx/rolling/filerenameaction.h>\r
-#include <log4cxx/helpers/loglog.h>\r
-#include <log4cxx/helpers/exception.h>\r
-#include <log4cxx/helpers/stringhelper.h>\r
-#include <log4cxx/helpers/optionconverter.h>\r
-#include <time.h>\r
-#include "time_and_size_based_rolling_policy.h"\r
-#include "lexical_cast.h"\r
-\r
-#define DEFAULT_MAX_FILE_SIZE (10 * 1024 * 1024)\r
-\r
-using namespace log4cxx;\r
-using namespace log4cxx::rolling;\r
-using namespace log4cxx::helpers;\r
-using namespace log4cxx::pattern;\r
-\r
-IMPLEMENT_LOG4CXX_OBJECT(TimeAndSizeBasedRollingPolicy)\r
-\r
-/*!\r
- * default constructor.\r
- * initialize member valiables\r
- * @param   void\r
- * @return  void\r
- */\r
-TimeAndSizeBasedRollingPolicy::TimeAndSizeBasedRollingPolicy() :\r
-       maxFileSize(DEFAULT_MAX_FILE_SIZE)\r
-{\r
-}\r
-\r
-/*!\r
- * maxFileSize getter\r
- * @param   void\r
- * @return  maxFileSize\r
- */\r
-size_t TimeAndSizeBasedRollingPolicy::getMaxFileSize()\r
-{\r
-       return maxFileSize;\r
-}\r
-\r
-/*!\r
- * maxFileSize setter\r
- * @param   maxFileSize\r
- * @return  void\r
- */ \r
-void TimeAndSizeBasedRollingPolicy::setMaxFileSize(size_t size)\r
-{\r
-       maxFileSize = size;\r
-}\r
-\r
-/*!\r
- * option setter\r
- * @param   option name\r
- * @param   value\r
- * @return  void\r
- */\r
-void TimeAndSizeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)\r
-{\r
-       if (StringHelper::equalsIgnoreCase(option,\r
-               LOG4CXX_STR("MAXFILESIZE"),\r
-               LOG4CXX_STR("maxfilesize"))) {\r
-               maxFileSize = OptionConverter::toFileSize(value, DEFAULT_MAX_FILE_SIZE);\r
-       }\r
-       else {\r
-               StrictTimeBasedRollingPolicy::setOption(option, value);\r
-       }\r
-}\r
-\r
-/*!\r
- * returns do rollover or not\r
- * @param   appender (not use)\r
- * @param   event (not use)\r
- * @param   filename (not use)\r
- * @param   fileLength\r
- * @retval  true do rollover\r
- * @retval  false not rollover yet\r
- */\r
-bool TimeAndSizeBasedRollingPolicy::isTriggeringEvent(\r
-       Appender* appender,\r
-       const log4cxx::spi::LoggingEventPtr& event,\r
-       const LogString& filename,\r
-       size_t fileLength)  \r
-{\r
-\r
-       return (fileLength >= maxFileSize || \r
-               StrictTimeBasedRollingPolicy::isTriggeringEvent(appender, event, filename, fileLength));\r
-}\r
+/*
+ * @file  time_and_size_based_rolling_policy.cpp
+ * @brief log4cxx's rolling policy class. (time + size)
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 <log4cxx/logstring.h>
+#include <log4cxx/pattern/filedatepatternconverter.h>
+#include <log4cxx/helpers/date.h>
+#include <log4cxx/rolling/filerenameaction.h>
+#include <log4cxx/helpers/loglog.h>
+#include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/optionconverter.h>
+#include <time.h>
+#include "time_and_size_based_rolling_policy.h"
+#include "lexical_cast.h"
+
+#define DEFAULT_MAX_FILE_SIZE (10 * 1024 * 1024)
+
+using namespace log4cxx;
+using namespace log4cxx::rolling;
+using namespace log4cxx::helpers;
+using namespace log4cxx::pattern;
+
+IMPLEMENT_LOG4CXX_OBJECT(TimeAndSizeBasedRollingPolicy)
+
+/*!
+ * default constructor.
+ * initialize member valiables
+ * @param   void
+ * @return  void
+ */
+TimeAndSizeBasedRollingPolicy::TimeAndSizeBasedRollingPolicy() :
+       maxFileSize(DEFAULT_MAX_FILE_SIZE)
+{
+}
+
+/*!
+ * maxFileSize getter
+ * @param   void
+ * @return  maxFileSize
+ */
+size_t TimeAndSizeBasedRollingPolicy::getMaxFileSize()
+{
+       return maxFileSize;
+}
+
+/*!
+ * maxFileSize setter
+ * @param   maxFileSize
+ * @return  void
+ */ 
+void TimeAndSizeBasedRollingPolicy::setMaxFileSize(size_t size)
+{
+       maxFileSize = size;
+}
+
+/*!
+ * option setter
+ * @param   option name
+ * @param   value
+ * @return  void
+ */
+void TimeAndSizeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)
+{
+       if (StringHelper::equalsIgnoreCase(option,
+               LOG4CXX_STR("MAXFILESIZE"),
+               LOG4CXX_STR("maxfilesize"))) {
+               maxFileSize = OptionConverter::toFileSize(value, DEFAULT_MAX_FILE_SIZE);
+       }
+       else {
+               StrictTimeBasedRollingPolicy::setOption(option, value);
+       }
+}
+
+/*!
+ * returns do rollover or not
+ * @param   appender (not use)
+ * @param   event (not use)
+ * @param   filename (not use)
+ * @param   fileLength
+ * @retval  true do rollover
+ * @retval  false not rollover yet
+ */
+bool TimeAndSizeBasedRollingPolicy::isTriggeringEvent(
+       Appender* appender,
+       const log4cxx::spi::LoggingEventPtr& event,
+       const LogString& filename,
+       size_t fileLength)  
+{
+
+       return (fileLength >= maxFileSize || 
+               StrictTimeBasedRollingPolicy::isTriggeringEvent(appender, event, filename, fileLength));
+}
index 307dd2d..698baa8 100644 (file)
@@ -1,75 +1,75 @@
-/*\r
- * @file  time_and_size_based_rolling_policy.h\r
- * @brief log4cxx's rolling policy class. (time + size)\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef __TIME_AND_SIZE_BASED_ROLLING_POLICY_H__\r
-#define __TIME_AND_SIZE_BASED_ROLLING_POLICY_H__\r
-\r
-#include <log4cxx/portability.h>\r
-#include "strict_time_based_rolling_policy.h"\r
-#include "logger_enum.h"\r
-\r
-namespace log4cxx {\r
-       namespace rolling {\r
-               /*!\r
-                *  log4cxx time and size based rolling policy class.\r
-                *  this policy class is delivered from StrictTimeBasedRollingPolicy.\r
-                *  so it can size specify in addition to strict time specify.\r
-                */\r
-               class LOG4CXX_EXPORT TimeAndSizeBasedRollingPolicy :\r
-                       public StrictTimeBasedRollingPolicy\r
-               {\r
-                       DECLARE_LOG4CXX_OBJECT(TimeAndSizeBasedRollingPolicy)\r
-                       BEGIN_LOG4CXX_CAST_MAP()\r
-                               LOG4CXX_CAST_ENTRY(TimeAndSizeBasedRollingPolicy)\r
-                               LOG4CXX_CAST_ENTRY_CHAIN(StrictTimeBasedRollingPolicy)\r
-                       END_LOG4CXX_CAST_MAP()\r
-\r
-               protected:\r
-                       //! maximum size of file\r
-                       size_t maxFileSize;\r
-                       \r
-               public:\r
-                       //! default constructor\r
-                       TimeAndSizeBasedRollingPolicy();\r
-                       //! option setter\r
-                       void setOption(const LogString&, const LogString&);\r
-                       //! maxFileSize getter\r
-                       size_t getMaxFileSize();\r
-                       //! maxFileSize setter\r
-                       void setMaxFileSize(size_t);\r
-                       \r
-                       //! returns do rollover or not\r
-                       virtual bool isTriggeringEvent(\r
-                               Appender* appender,\r
-                               const log4cxx::spi::LoggingEventPtr& event,\r
-                               const LogString& filename,\r
-                               size_t fileLength);\r
-                       \r
-               };\r
-               LOG4CXX_PTR_DEF(TimeAndSizeBasedRollingPolicy);\r
-       }\r
-}\r
-\r
-#endif //__TIME_AND_SIZE_BASED_ROLLING_POLICY_H__\r
-\r
+/*
+ * @file  time_and_size_based_rolling_policy.h
+ * @brief log4cxx's rolling policy class. (time + size)
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __TIME_AND_SIZE_BASED_ROLLING_POLICY_H__
+#define __TIME_AND_SIZE_BASED_ROLLING_POLICY_H__
+
+#include <log4cxx/portability.h>
+#include "strict_time_based_rolling_policy.h"
+#include "logger_enum.h"
+
+namespace log4cxx {
+       namespace rolling {
+               /*!
+                *  log4cxx time and size based rolling policy class.
+                *  this policy class is delivered from StrictTimeBasedRollingPolicy.
+                *  so it can size specify in addition to strict time specify.
+                */
+               class LOG4CXX_EXPORT TimeAndSizeBasedRollingPolicy :
+                       public StrictTimeBasedRollingPolicy
+               {
+                       DECLARE_LOG4CXX_OBJECT(TimeAndSizeBasedRollingPolicy)
+                       BEGIN_LOG4CXX_CAST_MAP()
+                               LOG4CXX_CAST_ENTRY(TimeAndSizeBasedRollingPolicy)
+                               LOG4CXX_CAST_ENTRY_CHAIN(StrictTimeBasedRollingPolicy)
+                       END_LOG4CXX_CAST_MAP()
+
+               protected:
+                       //! maximum size of file
+                       size_t maxFileSize;
+                       
+               public:
+                       //! default constructor
+                       TimeAndSizeBasedRollingPolicy();
+                       //! option setter
+                       void setOption(const LogString&, const LogString&);
+                       //! maxFileSize getter
+                       size_t getMaxFileSize();
+                       //! maxFileSize setter
+                       void setMaxFileSize(size_t);
+                       
+                       //! returns do rollover or not
+                       virtual bool isTriggeringEvent(
+                               Appender* appender,
+                               const log4cxx::spi::LoggingEventPtr& event,
+                               const LogString& filename,
+                               size_t fileLength);
+                       
+               };
+               LOG4CXX_PTR_DEF(TimeAndSizeBasedRollingPolicy);
+       }
+}
+
+#endif //__TIME_AND_SIZE_BASED_ROLLING_POLICY_H__
+
index 2673958..8883cb2 100644 (file)
-/*\r
- * @file  parameter.cpp\r
- * @brief parameter module creation class.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#include "parameter_enum.h"\r
-#include "parameter.h"\r
-#include "parameter_impl.h"\r
-#include "logger_wrapper.h"\r
-\r
-LOG_CATEGORY_TAG param_cat = LOG_CAT_SSLPROXY_PARAMETER;\r
-\r
-/*!\r
- * Constructor of Parameter class\r
- */\r
-l7vs::Parameter::Parameter()\r
-{\r
-       if( !ParameterImpl::getInstance().init() ){\r
-               LOGGER_PUT_LOG_FATAL( param_cat, 1, "Parameter initialize failure" );\r
-               /*-------- DEBUG LOG for sslproxy --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(param_cat)) {\r
-                       LOGGER_PUT_LOG_DEBUG(param_cat, 1,\r
-                               "function : Constructor l7vs::Parameter::Parameter() : "\r
-                               "Initialize error.");\r
-               }\r
-               /*------ DEBUG LOG END for sslproxy ------*/\r
-               exit(1);\r
-       }\r
-}\r
-\r
-/*!\r
- * Destructor of Parameter class\r
- */\r
-l7vs::Parameter::~Parameter()\r
-{\r
-}\r
-\r
-/*!\r
- * reload config file\r
- * @param[in]   comp    section TAG\r
- * @param[in]   filename    config file name\r
- * @return     true = success read file / false = failure read file\r
- */\r
-bool\r
-l7vs::Parameter::rereadFile(PARAMETER_COMPONENT_TAG comp, const std::string& filename)\r
-{\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(param_cat)) {\r
-               LOGGER_PUT_LOG_DEBUG(param_cat, 2,\r
-                       "function : bool l7vs::Parameter::rereadFile("\r
-                       "PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& filename) : "\r
-                       "Call ParameterImpl.rereadFile("\r
-                       "comp = %d, "\r
-                       "filename = %s)",\r
-                       comp,\r
-                       filename.c_str());\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-       return ParameterImpl::getInstance().rereadFile(comp, filename);\r
-}\r
-\r
-/*!\r
- * check whether integer data exists.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  key     key string\r
- * @return     true = exist setting value / false = non exist setting value\r
- */\r
-bool\r
-l7vs::Parameter::isIntExist(const PARAMETER_COMPONENT_TAG comp, const std::string& key)\r
-{\r
-       return ParameterImpl::getInstance().isIntExist(comp, key);\r
-}\r
-\r
-/*!\r
- * check whether character data exists.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  key     key string\r
- * @return     true = exist setting value / false = non exist setting value\r
- */\r
-bool\r
-l7vs::Parameter::isStringExist(const PARAMETER_COMPONENT_TAG comp, const std::string& key)\r
-{\r
-       return ParameterImpl::getInstance().isStringExist(comp, key);\r
-}\r
-\r
-/*!\r
- * get integer data.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  key     key string\r
- * @return     value\r
- */\r
-int\r
-l7vs::Parameter::getIntValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key)\r
-{\r
-       return ParameterImpl::getInstance().getIntValue(comp, key);\r
-}\r
-\r
-/*!\r
- * get character data.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  key     key string\r
- * @return     value\r
- */\r
-std::string\r
-l7vs::Parameter::getStringValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key)\r
-{\r
-       return ParameterImpl::getInstance().getStringValue(comp, key);\r
-}\r
-\r
-/*!\r
- * get character map data.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  key     key string\r
- * @param[out] retMap  map data\r
- * @return     value\r
- */\r
-void\r
-l7vs::Parameter::getStringMapValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key, std::multimap<std::string, std::string>& retMap)\r
-{\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(param_cat)) {\r
-               LOGGER_PUT_LOG_DEBUG(param_cat, 3,\r
-                       "function : void l7vs::Parameter::getStringMapValue("\r
-                       "const PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& key, "\r
-                       "std::multimap<std::string, std::string>& retMap) : "\r
-                       "Call ParameterImpl.getStringMapValue("\r
-                       "comp = %d, "\r
-                       "key = %s)",\r
-                       comp,\r
-                       key.c_str());\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-       return ParameterImpl::getInstance().getStringMapValue(comp, key, retMap);\r
-}\r
-\r
-/*!\r
- * set-parameter function pointer relates component-tag\r
- * @param[in]  comp    section TAG\r
- * @param[in]  p_func  function pointer\r
- */\r
-void\r
-l7vs::Parameter::registerFunctionPointer(const PARAMETER_COMPONENT_TAG comp, void(*p_func)())\r
-{\r
-       ParameterImpl::getInstance().registerFunctionPointer(comp, p_func);\r
-}\r
-\r
+/*
+ * @file  parameter.cpp
+ * @brief parameter module creation class.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 "parameter_enum.h"
+#include "parameter.h"
+#include "parameter_impl.h"
+#include "logger_wrapper.h"
+
+LOG_CATEGORY_TAG param_cat = LOG_CAT_SSLPROXY_PARAMETER;
+
+/*!
+ * Constructor of Parameter class
+ */
+l7vs::Parameter::Parameter()
+{
+       if( !ParameterImpl::getInstance().init() ){
+               LOGGER_PUT_LOG_FATAL( param_cat, 1, "Parameter initialize failure" );
+               /*-------- DEBUG LOG for sslproxy --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(param_cat)) {
+                       LOGGER_PUT_LOG_DEBUG(param_cat, 1,
+                               "function : Constructor l7vs::Parameter::Parameter() : "
+                               "Initialize error.");
+               }
+               /*------ DEBUG LOG END for sslproxy ------*/
+               exit(1);
+       }
+}
+
+/*!
+ * Destructor of Parameter class
+ */
+l7vs::Parameter::~Parameter()
+{
+}
+
+/*!
+ * reload config file
+ * @param[in]   comp    section TAG
+ * @param[in]   filename    config file name
+ * @return     true = success read file / false = failure read file
+ */
+bool
+l7vs::Parameter::rereadFile(PARAMETER_COMPONENT_TAG comp, const std::string& filename)
+{
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(param_cat)) {
+               LOGGER_PUT_LOG_DEBUG(param_cat, 2,
+                       "function : bool l7vs::Parameter::rereadFile("
+                       "PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& filename) : "
+                       "Call ParameterImpl.rereadFile("
+                       "comp = %d, "
+                       "filename = %s)",
+                       comp,
+                       filename.c_str());
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+       return ParameterImpl::getInstance().rereadFile(comp, filename);
+}
+
+/*!
+ * check whether integer data exists.
+ * @param[in]  comp    section TAG
+ * @param[in]  key     key string
+ * @return     true = exist setting value / false = non exist setting value
+ */
+bool
+l7vs::Parameter::isIntExist(const PARAMETER_COMPONENT_TAG comp, const std::string& key)
+{
+       return ParameterImpl::getInstance().isIntExist(comp, key);
+}
+
+/*!
+ * check whether character data exists.
+ * @param[in]  comp    section TAG
+ * @param[in]  key     key string
+ * @return     true = exist setting value / false = non exist setting value
+ */
+bool
+l7vs::Parameter::isStringExist(const PARAMETER_COMPONENT_TAG comp, const std::string& key)
+{
+       return ParameterImpl::getInstance().isStringExist(comp, key);
+}
+
+/*!
+ * get integer data.
+ * @param[in]  comp    section TAG
+ * @param[in]  key     key string
+ * @return     value
+ */
+int
+l7vs::Parameter::getIntValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key)
+{
+       return ParameterImpl::getInstance().getIntValue(comp, key);
+}
+
+/*!
+ * get character data.
+ * @param[in]  comp    section TAG
+ * @param[in]  key     key string
+ * @return     value
+ */
+std::string
+l7vs::Parameter::getStringValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key)
+{
+       return ParameterImpl::getInstance().getStringValue(comp, key);
+}
+
+/*!
+ * get character map data.
+ * @param[in]  comp    section TAG
+ * @param[in]  key     key string
+ * @param[out] retMap  map data
+ * @return     value
+ */
+void
+l7vs::Parameter::getStringMapValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key, std::multimap<std::string, std::string>& retMap)
+{
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(param_cat)) {
+               LOGGER_PUT_LOG_DEBUG(param_cat, 3,
+                       "function : void l7vs::Parameter::getStringMapValue("
+                       "const PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& key, "
+                       "std::multimap<std::string, std::string>& retMap) : "
+                       "Call ParameterImpl.getStringMapValue("
+                       "comp = %d, "
+                       "key = %s)",
+                       comp,
+                       key.c_str());
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+       return ParameterImpl::getInstance().getStringMapValue(comp, key, retMap);
+}
+
+/*!
+ * set-parameter function pointer relates component-tag
+ * @param[in]  comp    section TAG
+ * @param[in]  p_func  function pointer
+ */
+void
+l7vs::Parameter::registerFunctionPointer(const PARAMETER_COMPONENT_TAG comp, void(*p_func)())
+{
+       ParameterImpl::getInstance().registerFunctionPointer(comp, p_func);
+}
+
index 2a5777c..d0401ff 100644 (file)
@@ -1,61 +1,61 @@
-/*\r
- * @file  parameter.h\r
- * @brief parameter module creation class.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef __PARAMETER_H__\r
-#define __PARAMETER_H__\r
-\r
-#include <iostream>\r
-#include <map>\r
-#include "parameter_enum.h"\r
-\r
-namespace l7vs\r
-{\r
-       class ParameterImpl;\r
-       class Parameter\r
-       {\r
-       private:\r
-               static Parameter instance;\r
-               \r
-       protected:\r
-               Parameter();\r
-               Parameter( const Parameter& );\r
-               Parameter&      operator=( const Parameter& );\r
-               ~Parameter();\r
-               \r
-       public:\r
-               bool    rereadFile(const PARAMETER_COMPONENT_TAG, const std::string&);\r
-       \r
-               static  Parameter& getInstance(){\r
-                       return  instance;\r
-               }\r
-               bool    isIntExist(const PARAMETER_COMPONENT_TAG, const std::string&);\r
-               bool    isStringExist(const PARAMETER_COMPONENT_TAG, const std::string&);\r
-               int     getIntValue(const PARAMETER_COMPONENT_TAG, const std::string&);\r
-               std::string     getStringValue(const PARAMETER_COMPONENT_TAG, const std::string&);\r
-               void    getStringMapValue( const PARAMETER_COMPONENT_TAG, const std::string&, std::multimap<std::string, std::string>&);\r
-               void    registerFunctionPointer(const PARAMETER_COMPONENT_TAG, void(*)());\r
-       };\r
-}\r
-       \r
-#endif //__PARAMETER_H__\r
+/*
+ * @file  parameter.h
+ * @brief parameter module creation class.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __PARAMETER_H__
+#define __PARAMETER_H__
+
+#include <iostream>
+#include <map>
+#include "parameter_enum.h"
+
+namespace l7vs
+{
+       class ParameterImpl;
+       class Parameter
+       {
+       private:
+               static Parameter instance;
+               
+       protected:
+               Parameter();
+               Parameter( const Parameter& );
+               Parameter&      operator=( const Parameter& );
+               ~Parameter();
+               
+       public:
+               bool    rereadFile(const PARAMETER_COMPONENT_TAG, const std::string&);
+       
+               static  Parameter& getInstance(){
+                       return  instance;
+               }
+               bool    isIntExist(const PARAMETER_COMPONENT_TAG, const std::string&);
+               bool    isStringExist(const PARAMETER_COMPONENT_TAG, const std::string&);
+               int     getIntValue(const PARAMETER_COMPONENT_TAG, const std::string&);
+               std::string     getStringValue(const PARAMETER_COMPONENT_TAG, const std::string&);
+               void    getStringMapValue( const PARAMETER_COMPONENT_TAG, const std::string&, std::multimap<std::string, std::string>&);
+               void    registerFunctionPointer(const PARAMETER_COMPONENT_TAG, void(*)());
+       };
+}
+       
+#endif //__PARAMETER_H__
index 1c705ed..b48cd2a 100644 (file)
@@ -1,39 +1,39 @@
-/*\r
- * @file  parameter_enum.h\r
- * @brief parameter module constants enumeration.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *      \r
- **********************************************************************/\r
-\r
-#ifndef __PARAMETER_ENUM_H__\r
-#define __PARAMETER_ENUM_H__\r
-\r
-/*!\r
- * enumerate section\r
- */\r
-enum PARAMETER_COMPONENT_TAG\r
-{\r
-       PARAM_COMP_ALL,\r
-       PARAM_COMP_NOCAT,\r
-       PARAM_COMP_LOGGER,\r
-       PARAM_COMP_SSLPROXY\r
-};\r
-       \r
-#endif //__PARAMETER_ENUM_H__\r
+/*
+ * @file  parameter_enum.h
+ * @brief parameter module constants enumeration.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __PARAMETER_ENUM_H__
+#define __PARAMETER_ENUM_H__
+
+/*!
+ * enumerate section
+ */
+enum PARAMETER_COMPONENT_TAG
+{
+       PARAM_COMP_ALL,
+       PARAM_COMP_NOCAT,
+       PARAM_COMP_LOGGER,
+       PARAM_COMP_SSLPROXY
+};
+       
+#endif //__PARAMETER_ENUM_H__
index cf1404a..71a8cc8 100644 (file)
-/*\r
- * @file  parameter_impl.cpp\r
- * @brief parameter module implementation class.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#include <vector>\r
-#include <fstream>\r
-#include <stdexcept>\r
-#include "parameter_impl.h"\r
-#include "logger_wrapper.h"\r
-\r
-#include <boost/lexical_cast.hpp>\r
-\r
-#ifndef INIT_PARAMETER_FILE\r
-#define INIT_PARAMETER_FILE "/etc/l7vs/sslproxy/sslproxy.logger_init.cf"\r
-#endif //INIT_PARAMETER_FILE\r
-\r
-#define        LINE_LENGTH     4096\r
-\r
-LOG_CATEGORY_TAG parameter_cat = LOG_CAT_SSLPROXY_PARAMETER;\r
-\r
-void   loadLoggerConf(){\r
-       l7vs::Logger::getInstance().loadConf();\r
-}\r
-\r
-/*!\r
- * ParameterImpl class Constructor\r
- */\r
-l7vs::ParameterImpl::ParameterImpl()\r
-{\r
-}\r
-\r
-/*!\r
- * Initialize ParameterImpl class\r
- */\r
-bool   l7vs::ParameterImpl::init()\r
-{\r
-       bool    retbool = true;\r
-       //clrear map objects\r
-       compTable.clear();\r
-       stringMap.clear();\r
-       intMap.clear();\r
-\r
-       //add member to component table\r
-       compTable[PARAM_COMP_ALL]       = component("all", NULL);\r
-       compTable[PARAM_COMP_NOCAT]     = component("nocategory", NULL);\r
-       compTable[PARAM_COMP_LOGGER]    = component("logger", loadLoggerConf);\r
-       compTable[PARAM_COMP_SSLPROXY]  = component("sslproxy", NULL);\r
-\r
-       //read all parameters\r
-       retbool = rereadFile( PARAM_COMP_ALL, INIT_PARAMETER_FILE);\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {\r
-               LOGGER_PUT_LOG_DEBUG(parameter_cat, 4,\r
-                       "function : bool l7vs::ParameterImpl::init() : "\r
-                       "rereadFile() END. "\r
-                       "retbool = %d",\r
-                       retbool);\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-\r
-       return  retbool;\r
-}\r
-\r
-/*!\r
- * checks that an argument is a numeric.\r
- * @param[in]  const std::string\r
- * @return             is numeric = true / not numeric = false\r
- */\r
-bool   l7vs::ParameterImpl::isNumeric(const std::string& val)\r
-{\r
-       try {\r
-               boost::lexical_cast<int>(val);\r
-       }\r
-       catch (boost::bad_lexical_cast& ex) {\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-/*!\r
- * delete blank before and behind a sentence\r
- * @param[in]  const std::string\r
- * @return             std::string\r
- */\r
-std::string    l7vs::ParameterImpl::removebrank( const std::string& val )\r
-{\r
-       std::string     str = val;\r
-       //remove brank(head of the sentence and end of the sentence)\r
-       std::string::iterator its;\r
-       its = str.begin();\r
-       while( its != str.end() ){\r
-               if( ( ' ' == *its ) || ( '\t' == *its ) ){\r
-                       str.erase(its);\r
-               }else break;\r
-       }\r
-       if( "" == str )return str;\r
-       //remove brank(head of the sentence and end of the sentence)\r
-       its = str.end() - 1;\r
-       while( its != str.begin() ){\r
-               if( ( ' ' == *its ) || ( '\t' == *its ) ){\r
-                       str.erase(its);\r
-                       its--;\r
-               }else break;\r
-       }\r
-       return str;\r
-}\r
-\r
-/*!\r
- * Read Parameter from file\r
- * @param[in]  const std::string\r
- * @return             success = true / fail = false\r
- */\r
-bool   l7vs::ParameterImpl::readParameterFile( const std::string& val )\r
-{\r
-       bool    retval = true;\r
-       char    readbuf[LINE_LENGTH];\r
-\r
-       LOGGER_PUT_LOG_INFO( parameter_cat,1, "read parameter file : %s", val.c_str() );\r
-\r
-       std::vector<std::string>        paramlines;\r
-       try{\r
-               paramlines.clear();\r
-               preparse.clear();\r
-\r
-               std::ifstream   ifs( val.c_str() );\r
-               if( ifs.fail() ){\r
-                       return false;\r
-               }\r
-               while( !ifs.eof() ){\r
-                       memset( readbuf, 0, LINE_LENGTH );\r
-                       ifs.getline( readbuf, ( LINE_LENGTH - 1 ) );\r
-                       std::string     str = readbuf;\r
-                       str = removebrank( str );\r
-                       //remove coment line\r
-                       if( '#' == str[0] )continue;\r
-                       //remove brank\r
-                       if( !str.empty() )paramlines.push_back( str );\r
-               }\r
-               std::string     sectionname = compTable[PARAM_COMP_NOCAT].section;\r
-               for( std::vector<std::string>::iterator it = paramlines.begin();\r
-                       it != paramlines.end(); it++ ){\r
-                       //pre-parse\r
-                       std::string str = *it;\r
-                       if( '[' == str[0] ){\r
-                               std::string     tmpstr = str.substr( str.rfind("]")+1 );\r
-                               tmpstr = removebrank( tmpstr.substr( 0, tmpstr.find( "#" ) ) );\r
-                               if( !tmpstr.empty() )continue;\r
-                               //section string validity check\r
-                               //invalid "#","[","]","\" character\r
-                               tmpstr = removebrank( str.substr( str.find( "[" )+1, str.rfind( "]", str.length() )-1 ) );\r
-                               if( std::string::npos != tmpstr.find( "[" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;\r
-                               if( std::string::npos != tmpstr.find( "]" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;\r
-                               if( std::string::npos != tmpstr.find( "\\" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;\r
-                               if( std::string::npos != tmpstr.find( "#" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;\r
-                               if( std::string::npos != tmpstr.find( "=" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;\r
-                               sectionname = tmpstr;\r
-                       }else{\r
-                               preparse.insert( std::pair<std::string,std::string>( sectionname,str ) );\r
-                       }\r
-               }\r
-       }\r
-       catch( ... ){\r
-               preparse.clear();\r
-               retval  = false;\r
-       }\r
-       if( preparse.empty() )retval = false;\r
-       return  retval;\r
-}\r
-\r
-/*!\r
- * read parameter and parse\r
- * @param[in]  comp    PARAMETER_COMPONENT_TAG\r
- * @param[in]  filename        config file name\r
- * @return             success = true / fail = false\r
- */\r
-bool   l7vs::ParameterImpl::rereadFile(PARAMETER_COMPONENT_TAG comp, const std::string& filename)\r
-{\r
-       bool    retbool = true;\r
-\r
-       LOGGER_PUT_LOG_INFO( parameter_cat,2, "read parameter : COMPONENT = %s", compTable[comp].section.c_str() );\r
-\r
-       if( !readParameterFile( filename ) )return false;\r
-\r
-       stringMap.clear();\r
-       intMap.clear();\r
-\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {\r
-               LOGGER_PUT_LOG_DEBUG(parameter_cat, 5,\r
-                       "function : bool l7vs::ParameterImpl::rereadFile("\r
-                       "PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& filename) : "\r
-                       "comp = %s, "\r
-                       "filename = %s",\r
-                       compTable[comp].section.c_str(),\r
-                       filename.c_str());\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-\r
-       std::multimap<std::string,std::string>::iterator        it;\r
-       std::multimap<std::string,std::string>::iterator        ite;\r
-       if( PARAM_COMP_ALL == comp ){\r
-               it = preparse.begin();\r
-       }else{\r
-               it = preparse.find( compTable[comp].section );\r
-       }\r
-       ite = preparse.end();\r
-               \r
-       for( std::multimap<std::string,std::string>::iterator its = it; its !=ite; its++ ){\r
-               //be made an invalid line if there is no = in a setting line.\r
-               if( std::string::npos == its->second.find( "=" ) )continue;\r
-               std::string     key = removebrank( its->second.substr( 0, its->second.find( "=" ) ) );\r
-               //Key string validity check\r
-               if( key.empty() )continue;\r
-               //invalid "#","[","]","\" character\r
-               if( std::string::npos != key.find( "[" ))continue;\r
-               if( std::string::npos != key.find( "]" ))continue;\r
-               if( std::string::npos != key.find( "\\" ))continue;\r
-               if( std::string::npos != key.find( "#" ) )continue;\r
-\r
-               key     = its->first + "." + key;\r
-\r
-               std::string     value = removebrank( its->second.substr( its->second.find( "=" )+1, std::string::npos ) );\r
-               //Value string validity check\r
-               if( '"' == value[0] ) {\r
-                       if( std::string::npos == value.find( "\"", 1 ) )continue;\r
-                       std::string tmpstr = removebrank( value.substr( value.find( "\"", 1 )+1, value.find( "#", value.find( "\"", 1 )+1  ) ) );\r
-                       if( !tmpstr.empty() )continue;\r
-                       tmpstr = removebrank( value.substr( 1, value.find( "\"", 1 )-1 ) );\r
-                       stringMap.insert( std::pair<std::string, std::string>( key, tmpstr ) );\r
-                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {\r
-                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 6,\r
-                                       "function : bool l7vs::ParameterImpl::rereadFile() : "\r
-                                       "stringMap.insert("\r
-                                       "key = %s, "\r
-                                       "tmpstr = %s)",\r
-                                       key.c_str(),\r
-                                       tmpstr.c_str());\r
-                       }\r
-                       /*------ DEBUG LOG END for sslproxy ------*/\r
-               }else{\r
-                       value = value.substr( 0, value.find_first_of( "#", 0 ) );\r
-                       if( std::string::npos != value.find( "\\" ))continue;\r
-                       if( std::string::npos != value.find( "=" ))continue;\r
-                       if( value.empty() )continue;\r
-                       if( isNumeric( value ) ){\r
-                               try{\r
-                                       intMap.insert( std::pair<std::string, int>( key, boost::lexical_cast<int>( value ) ) );\r
-                                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {\r
-                                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 7,\r
-                                                       "function : bool l7vs::ParameterImpl::rereadFile() : "\r
-                                                       "intMap.insert("\r
-                                                       "key = %s, "\r
-                                                       "value = %s)",\r
-                                                       key.c_str(),\r
-                                                       value.c_str());\r
-                                       }\r
-                                       /*------ DEBUG LOG END for sslproxy ------*/\r
-                               }\r
-                               catch (boost::bad_lexical_cast& ex) {\r
-                                       stringMap.insert( std::pair<std::string, std::string>( key, value ) );\r
-                                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {\r
-                                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 8,\r
-                                                       "function : bool l7vs::ParameterImpl::rereadFile() : "\r
-                                                       "stringMap.insert("\r
-                                                       "key = %s, "\r
-                                                       "value = %s)",\r
-                                                       key.c_str(),\r
-                                                       value.c_str());\r
-                                       }\r
-                                       /*------ DEBUG LOG END for sslproxy ------*/\r
-                               }\r
-                       }else{\r
-                               stringMap.insert( std::pair<std::string, std::string>( key, value ) );\r
-                               /*-------- DEBUG LOG for sslproxy --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(parameter_cat, 9,\r
-                                               "function : bool l7vs::ParameterImpl::rereadFile() : "\r
-                                               "stringMap.insert("\r
-                                               "key = %s, "\r
-                                               "value = %s)",\r
-                                               key.c_str(),\r
-                                               value.c_str());\r
-                               }\r
-                               /*------ DEBUG LOG END for sslproxy ------*/\r
-                       }\r
-               }\r
-       }\r
-       //set parameter\r
-       std::map<PARAMETER_COMPONENT_TAG, component>::iterator itr = compTable.find( comp );\r
-       if( itr != compTable.end() ){\r
-               try{\r
-                       if( NULL != itr->second.function )itr->second.function();\r
-               }\r
-               catch( const std::logic_error& err ){\r
-                       LOGGER_PUT_LOG_ERROR( parameter_cat,1, "set parameter function failure at category: %s", itr->second.section.c_str() );\r
-                       retbool = false;\r
-               }\r
-       }\r
-       if( PARAM_COMP_ALL == comp ){\r
-               for( itr = compTable.begin(); itr != compTable.end(); ++itr ){\r
-                       try{\r
-                               if( NULL != itr->second.function )itr->second.function();\r
-                       }\r
-                       catch( const std::logic_error& err ){\r
-                               LOGGER_PUT_LOG_ERROR( parameter_cat,2, "set parameter function failure at category: %s", itr->second.section.c_str() );\r
-                               retbool = false;\r
-                       }\r
-               }\r
-       }\r
-\r
-       return  retbool;\r
-}\r
-\r
-/*!\r
- * Existence of a integer parameter is checked\r
- * @param[in]  comp    PARAMETER_COMPONENT_TAG\r
- * @param[in]  key     key string\r
- * @return             exist = true / not exist = false\r
- */\r
-bool   l7vs::ParameterImpl::isIntExist(const PARAMETER_COMPONENT_TAG comp, const std::string& key)\r
-{\r
-       bool    retval = false;\r
-       std::string comp_key = compTable[comp].section + "." + key;\r
-       if( intMap.end() != intMap.find( comp_key ) ){\r
-               retval = true;\r
-       }\r
-       return  retval;\r
-}\r
-\r
-/*!\r
- * Existence of a string parameter is checked\r
- * @param[in]  comp    PARAMETER_COMPONENT_TAG\r
- * @param[in]  key     key string\r
- * @return             exist = true / not exist = false\r
- */\r
-bool   l7vs::ParameterImpl::isStringExist(const PARAMETER_COMPONENT_TAG comp, const std::string& key)\r
-{\r
-       bool    retval = false;\r
-       std::string comp_key = compTable[comp].section + "." + key;\r
-       if( stringMap.end() != stringMap.find( comp_key ) ){\r
-               retval = true;\r
-       }\r
-       return  retval;\r
-}\r
-\r
-/*!\r
- * get a integer parameter\r
- * @param[in]  comp    PARAMETER_COMPONENT_TAG\r
- * @param[in]  key     key string\r
- * @return             integer data\r
- */\r
-int    l7vs::ParameterImpl::getIntValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key)\r
-{\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-           comp != PARAM_COMP_LOGGER) {\r
-               LOGGER_PUT_LOG_DEBUG(parameter_cat, 10,\r
-                       "in_function : int l7vs::ParameterImpl::getIntValue("\r
-                       "const PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& key) : "\r
-                       "comp = %s, "\r
-                       "key = %s",\r
-                       compTable[comp].section.c_str(),\r
-                       key.c_str());\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-\r
-       int retint = 0;\r
-       std::string comp_key = compTable[comp].section + "." + key;\r
-       std::multimap<std::string, int>::iterator it = intMap.begin();\r
-       std::multimap<std::string, int>::iterator ite = intMap.end();\r
-\r
-       for( std::multimap<std::string, int>::iterator its = it; its !=ite; its++ ) {\r
-               /*-------- DEBUG LOG for sslproxy --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-                   comp != PARAM_COMP_LOGGER) {\r
-                       LOGGER_PUT_LOG_DEBUG(parameter_cat, 11,\r
-                               "function : int l7vs::ParameterImpl::getIntValue() : "\r
-                               "Search intMap [%s][%d]",\r
-                               its->first.c_str(),\r
-                               its->second);\r
-               }\r
-               /*------ DEBUG LOG END for sslproxy ------*/\r
-               if (its->first == comp_key) {\r
-                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-                           comp != PARAM_COMP_LOGGER) {\r
-                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 12,\r
-                                       "function : int l7vs::ParameterImpl::getIntValue() : "\r
-                                       "Key matched.");\r
-                       }\r
-                       /*------ DEBUG LOG END for sslproxy ------*/\r
-                       retint = its->second;\r
-               }\r
-       }\r
-\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-           comp != PARAM_COMP_LOGGER) {\r
-               LOGGER_PUT_LOG_DEBUG(parameter_cat, 13,\r
-                       "out_function : int l7vs::ParameterImpl::getIntValue("\r
-                       "const PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& key) : "\r
-                       "retint = %d",\r
-                       retint);\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-       return retint;\r
-}\r
-\r
-/*!\r
- * get a string parameter\r
- * @param[in]  comp    PARAMETER_COMPONENT_TAG\r
- * @param[in]  key     key string\r
- * @return             string data\r
- */\r
-std::string    l7vs::ParameterImpl::getStringValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key)\r
-{\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-           comp != PARAM_COMP_LOGGER) {\r
-               LOGGER_PUT_LOG_DEBUG(parameter_cat, 14,\r
-                       "in_function : std::string l7vs::ParameterImpl::getStringValue("\r
-                       "const PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& key) : "\r
-                       "comp = %s, "\r
-                       "key = %s",\r
-                       compTable[comp].section.c_str(),\r
-                       key.c_str());\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-\r
-       std::string     retstr = "";\r
-       std::string     comp_key = compTable[comp].section + "." + key;\r
-       std::multimap<std::string, std::string>::iterator it = stringMap.begin();\r
-       std::multimap<std::string, std::string>::iterator ite = stringMap.end();\r
-\r
-       for( std::multimap<std::string, std::string>::iterator its = it; its !=ite; its++ ) {\r
-               /*-------- DEBUG LOG for sslproxy --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-                   comp != PARAM_COMP_LOGGER) {\r
-                       LOGGER_PUT_LOG_DEBUG(parameter_cat, 15,\r
-                               "function : std::string l7vs::ParameterImpl::getStringValue() : "\r
-                               "Search stringMap [%s][%s]",\r
-                               its->first.c_str(),\r
-                               its->second.c_str());\r
-               }\r
-               /*------ DEBUG LOG END for sslproxy ------*/\r
-               if (its->first == comp_key) {\r
-                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-                           comp != PARAM_COMP_LOGGER) {\r
-                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 16,\r
-                                       "function : std::string l7vs::ParameterImpl::getStringValue() : "\r
-                                       "Key matched.");\r
-                       }\r
-                       /*------ DEBUG LOG END for sslproxy ------*/\r
-                       retstr = its->second;\r
-               }\r
-       }\r
-\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-           comp != PARAM_COMP_LOGGER) {\r
-               LOGGER_PUT_LOG_DEBUG(parameter_cat, 17,\r
-                       "out_function : std::string l7vs::ParameterImpl::getStringValue("\r
-                       "const PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& key) : "\r
-                       "retstr = %s",\r
-                       retstr.c_str());\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-       return retstr;\r
-}\r
-\r
-/*!\r
- * get map parameter\r
- * @param[in]  comp    PARAMETER_COMPONENT_TAG\r
- * @param[in]  key     key string\r
- * @param[out] retMap  map data\r
- */\r
-void   l7vs::ParameterImpl::getStringMapValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key, std::multimap<std::string, std::string>& retMap)\r
-{\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-           comp != PARAM_COMP_LOGGER) {\r
-               LOGGER_PUT_LOG_DEBUG(parameter_cat, 18,\r
-                       "in_function : void l7vs::ParameterImpl::getStringMapValue("\r
-                       "const PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& key, "\r
-                       "std::multimap<std::string, std::string>& retMap) : "\r
-                       "comp = %s, "\r
-                       "key = %s",\r
-                       compTable[comp].section.c_str(),\r
-                       key.c_str());\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-\r
-       std::string     comp_key = compTable[comp].section + "." + key;\r
-       std::multimap<std::string, std::string>::iterator it = stringMap.begin();\r
-       std::multimap<std::string, std::string>::iterator ite = stringMap.end();\r
-\r
-       for( std::multimap<std::string, std::string>::iterator its = it; its !=ite; its++ ) {\r
-               /*-------- DEBUG LOG for sslproxy --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-                   comp != PARAM_COMP_LOGGER) {\r
-                       LOGGER_PUT_LOG_DEBUG(parameter_cat, 19,\r
-                               "function : void l7vs::ParameterImpl::getStringMapValue() : "\r
-                               "Search stringMap [%s][%s]",\r
-                               its->first.c_str(),\r
-                               its->second.c_str());\r
-               }\r
-               /*------ DEBUG LOG END for sslproxy ------*/\r
-               if (its->first == comp_key) {\r
-                       /*-------- DEBUG LOG for sslproxy --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-                           comp != PARAM_COMP_LOGGER) {\r
-                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 20,\r
-                                       "function : void l7vs::ParameterImpl::getStringMapValue() : "\r
-                                       "Key matched. Insert map.");\r
-                       }\r
-                       /*------ DEBUG LOG END for sslproxy ------*/\r
-                       retMap.insert( std::pair<std::string, std::string>( key, its->second ) );\r
-               }\r
-       }\r
-\r
-       /*-------- DEBUG LOG for sslproxy --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&\r
-           comp != PARAM_COMP_LOGGER) {\r
-               LOGGER_PUT_LOG_DEBUG(parameter_cat, 21,\r
-                       "out_function : void l7vs::ParameterImpl::getStringMapValue("\r
-                       "const PARAMETER_COMPONENT_TAG comp, "\r
-                       "const std::string& key, "\r
-                       "std::multimap<std::string, std::string>& retMap)");\r
-       }\r
-       /*------ DEBUG LOG END for sslproxy ------*/\r
-}\r
-\r
-/*!\r
- * set-parameter function pointer relates component-tag\r
- * @param[in]  comp    section TAG\r
- * @param[in]  p_func  function pointer\r
- */\r
-void   l7vs::ParameterImpl::registerFunctionPointer( const PARAMETER_COMPONENT_TAG comp, void (*p_func)() )\r
-{\r
-       compTable[comp].function = p_func;\r
-}\r
-\r
+/*
+ * @file  parameter_impl.cpp
+ * @brief parameter module implementation class.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 <vector>
+#include <fstream>
+#include <stdexcept>
+#include "parameter_impl.h"
+#include "logger_wrapper.h"
+
+#include <boost/lexical_cast.hpp>
+
+#ifndef INIT_PARAMETER_FILE
+#define INIT_PARAMETER_FILE "/etc/l7vs/sslproxy/sslproxy.logger_init.cf"
+#endif //INIT_PARAMETER_FILE
+
+#define        LINE_LENGTH     4096
+
+LOG_CATEGORY_TAG parameter_cat = LOG_CAT_SSLPROXY_PARAMETER;
+
+void   loadLoggerConf(){
+       l7vs::Logger::getInstance().loadConf();
+}
+
+/*!
+ * ParameterImpl class Constructor
+ */
+l7vs::ParameterImpl::ParameterImpl()
+{
+}
+
+/*!
+ * Initialize ParameterImpl class
+ */
+bool   l7vs::ParameterImpl::init()
+{
+       bool    retbool = true;
+       //clrear map objects
+       compTable.clear();
+       stringMap.clear();
+       intMap.clear();
+
+       //add member to component table
+       compTable[PARAM_COMP_ALL]       = component("all", NULL);
+       compTable[PARAM_COMP_NOCAT]     = component("nocategory", NULL);
+       compTable[PARAM_COMP_LOGGER]    = component("logger", loadLoggerConf);
+       compTable[PARAM_COMP_SSLPROXY]  = component("sslproxy", NULL);
+
+       //read all parameters
+       retbool = rereadFile( PARAM_COMP_ALL, INIT_PARAMETER_FILE);
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {
+               LOGGER_PUT_LOG_DEBUG(parameter_cat, 4,
+                       "function : bool l7vs::ParameterImpl::init() : "
+                       "rereadFile() END. "
+                       "retbool = %d",
+                       retbool);
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+
+       return  retbool;
+}
+
+/*!
+ * checks that an argument is a numeric.
+ * @param[in]  const std::string
+ * @return             is numeric = true / not numeric = false
+ */
+bool   l7vs::ParameterImpl::isNumeric(const std::string& val)
+{
+       try {
+               boost::lexical_cast<int>(val);
+       }
+       catch (boost::bad_lexical_cast& ex) {
+               return false;
+       }
+       return true;
+}
+
+/*!
+ * delete blank before and behind a sentence
+ * @param[in]  const std::string
+ * @return             std::string
+ */
+std::string    l7vs::ParameterImpl::removebrank( const std::string& val )
+{
+       std::string     str = val;
+       //remove brank(head of the sentence and end of the sentence)
+       std::string::iterator its;
+       its = str.begin();
+       while( its != str.end() ){
+               if( ( ' ' == *its ) || ( '\t' == *its ) ){
+                       str.erase(its);
+               }else break;
+       }
+       if( "" == str )return str;
+       //remove brank(head of the sentence and end of the sentence)
+       its = str.end() - 1;
+       while( its != str.begin() ){
+               if( ( ' ' == *its ) || ( '\t' == *its ) ){
+                       str.erase(its);
+                       its--;
+               }else break;
+       }
+       return str;
+}
+
+/*!
+ * Read Parameter from file
+ * @param[in]  const std::string
+ * @return             success = true / fail = false
+ */
+bool   l7vs::ParameterImpl::readParameterFile( const std::string& val )
+{
+       bool    retval = true;
+       char    readbuf[LINE_LENGTH];
+
+       LOGGER_PUT_LOG_INFO( parameter_cat,1, "read parameter file : %s", val.c_str() );
+
+       std::vector<std::string>        paramlines;
+       try{
+               paramlines.clear();
+               preparse.clear();
+
+               std::ifstream   ifs( val.c_str() );
+               if( ifs.fail() ){
+                       return false;
+               }
+               while( !ifs.eof() ){
+                       memset( readbuf, 0, LINE_LENGTH );
+                       ifs.getline( readbuf, ( LINE_LENGTH - 1 ) );
+                       std::string     str = readbuf;
+                       str = removebrank( str );
+                       //remove coment line
+                       if( '#' == str[0] )continue;
+                       //remove brank
+                       if( !str.empty() )paramlines.push_back( str );
+               }
+               std::string     sectionname = compTable[PARAM_COMP_NOCAT].section;
+               for( std::vector<std::string>::iterator it = paramlines.begin();
+                       it != paramlines.end(); it++ ){
+                       //pre-parse
+                       std::string str = *it;
+                       if( '[' == str[0] ){
+                               std::string     tmpstr = str.substr( str.rfind("]")+1 );
+                               tmpstr = removebrank( tmpstr.substr( 0, tmpstr.find( "#" ) ) );
+                               if( !tmpstr.empty() )continue;
+                               //section string validity check
+                               //invalid "#","[","]","\" character
+                               tmpstr = removebrank( str.substr( str.find( "[" )+1, str.rfind( "]", str.length() )-1 ) );
+                               if( std::string::npos != tmpstr.find( "[" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;
+                               if( std::string::npos != tmpstr.find( "]" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;
+                               if( std::string::npos != tmpstr.find( "\\" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;
+                               if( std::string::npos != tmpstr.find( "#" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;
+                               if( std::string::npos != tmpstr.find( "=" ) )tmpstr = compTable[PARAM_COMP_NOCAT].section;
+                               sectionname = tmpstr;
+                       }else{
+                               preparse.insert( std::pair<std::string,std::string>( sectionname,str ) );
+                       }
+               }
+       }
+       catch( ... ){
+               preparse.clear();
+               retval  = false;
+       }
+       if( preparse.empty() )retval = false;
+       return  retval;
+}
+
+/*!
+ * read parameter and parse
+ * @param[in]  comp    PARAMETER_COMPONENT_TAG
+ * @param[in]  filename        config file name
+ * @return             success = true / fail = false
+ */
+bool   l7vs::ParameterImpl::rereadFile(PARAMETER_COMPONENT_TAG comp, const std::string& filename)
+{
+       bool    retbool = true;
+
+       LOGGER_PUT_LOG_INFO( parameter_cat,2, "read parameter : COMPONENT = %s", compTable[comp].section.c_str() );
+
+       if( !readParameterFile( filename ) )return false;
+
+       stringMap.clear();
+       intMap.clear();
+
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {
+               LOGGER_PUT_LOG_DEBUG(parameter_cat, 5,
+                       "function : bool l7vs::ParameterImpl::rereadFile("
+                       "PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& filename) : "
+                       "comp = %s, "
+                       "filename = %s",
+                       compTable[comp].section.c_str(),
+                       filename.c_str());
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+
+       std::multimap<std::string,std::string>::iterator        it;
+       std::multimap<std::string,std::string>::iterator        ite;
+       if( PARAM_COMP_ALL == comp ){
+               it = preparse.begin();
+       }else{
+               it = preparse.find( compTable[comp].section );
+       }
+       ite = preparse.end();
+               
+       for( std::multimap<std::string,std::string>::iterator its = it; its !=ite; its++ ){
+               //be made an invalid line if there is no = in a setting line.
+               if( std::string::npos == its->second.find( "=" ) )continue;
+               std::string     key = removebrank( its->second.substr( 0, its->second.find( "=" ) ) );
+               //Key string validity check
+               if( key.empty() )continue;
+               //invalid "#","[","]","\" character
+               if( std::string::npos != key.find( "[" ))continue;
+               if( std::string::npos != key.find( "]" ))continue;
+               if( std::string::npos != key.find( "\\" ))continue;
+               if( std::string::npos != key.find( "#" ) )continue;
+
+               key     = its->first + "." + key;
+
+               std::string     value = removebrank( its->second.substr( its->second.find( "=" )+1, std::string::npos ) );
+               //Value string validity check
+               if( '"' == value[0] ) {
+                       if( std::string::npos == value.find( "\"", 1 ) )continue;
+                       std::string tmpstr = removebrank( value.substr( value.find( "\"", 1 )+1, value.find( "#", value.find( "\"", 1 )+1  ) ) );
+                       if( !tmpstr.empty() )continue;
+                       tmpstr = removebrank( value.substr( 1, value.find( "\"", 1 )-1 ) );
+                       stringMap.insert( std::pair<std::string, std::string>( key, tmpstr ) );
+                       /*-------- DEBUG LOG for sslproxy --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {
+                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 6,
+                                       "function : bool l7vs::ParameterImpl::rereadFile() : "
+                                       "stringMap.insert("
+                                       "key = %s, "
+                                       "tmpstr = %s)",
+                                       key.c_str(),
+                                       tmpstr.c_str());
+                       }
+                       /*------ DEBUG LOG END for sslproxy ------*/
+               }else{
+                       value = value.substr( 0, value.find_first_of( "#", 0 ) );
+                       if( std::string::npos != value.find( "\\" ))continue;
+                       if( std::string::npos != value.find( "=" ))continue;
+                       if( value.empty() )continue;
+                       if( isNumeric( value ) ){
+                               try{
+                                       intMap.insert( std::pair<std::string, int>( key, boost::lexical_cast<int>( value ) ) );
+                                       /*-------- DEBUG LOG for sslproxy --------*/
+                                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {
+                                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 7,
+                                                       "function : bool l7vs::ParameterImpl::rereadFile() : "
+                                                       "intMap.insert("
+                                                       "key = %s, "
+                                                       "value = %s)",
+                                                       key.c_str(),
+                                                       value.c_str());
+                                       }
+                                       /*------ DEBUG LOG END for sslproxy ------*/
+                               }
+                               catch (boost::bad_lexical_cast& ex) {
+                                       stringMap.insert( std::pair<std::string, std::string>( key, value ) );
+                                       /*-------- DEBUG LOG for sslproxy --------*/
+                                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {
+                                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 8,
+                                                       "function : bool l7vs::ParameterImpl::rereadFile() : "
+                                                       "stringMap.insert("
+                                                       "key = %s, "
+                                                       "value = %s)",
+                                                       key.c_str(),
+                                                       value.c_str());
+                                       }
+                                       /*------ DEBUG LOG END for sslproxy ------*/
+                               }
+                       }else{
+                               stringMap.insert( std::pair<std::string, std::string>( key, value ) );
+                               /*-------- DEBUG LOG for sslproxy --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat)) {
+                                       LOGGER_PUT_LOG_DEBUG(parameter_cat, 9,
+                                               "function : bool l7vs::ParameterImpl::rereadFile() : "
+                                               "stringMap.insert("
+                                               "key = %s, "
+                                               "value = %s)",
+                                               key.c_str(),
+                                               value.c_str());
+                               }
+                               /*------ DEBUG LOG END for sslproxy ------*/
+                       }
+               }
+       }
+       //set parameter
+       std::map<PARAMETER_COMPONENT_TAG, component>::iterator itr = compTable.find( comp );
+       if( itr != compTable.end() ){
+               try{
+                       if( NULL != itr->second.function )itr->second.function();
+               }
+               catch( const std::logic_error& err ){
+                       LOGGER_PUT_LOG_ERROR( parameter_cat,1, "set parameter function failure at category: %s", itr->second.section.c_str() );
+                       retbool = false;
+               }
+       }
+       if( PARAM_COMP_ALL == comp ){
+               for( itr = compTable.begin(); itr != compTable.end(); ++itr ){
+                       try{
+                               if( NULL != itr->second.function )itr->second.function();
+                       }
+                       catch( const std::logic_error& err ){
+                               LOGGER_PUT_LOG_ERROR( parameter_cat,2, "set parameter function failure at category: %s", itr->second.section.c_str() );
+                               retbool = false;
+                       }
+               }
+       }
+
+       return  retbool;
+}
+
+/*!
+ * Existence of a integer parameter is checked
+ * @param[in]  comp    PARAMETER_COMPONENT_TAG
+ * @param[in]  key     key string
+ * @return             exist = true / not exist = false
+ */
+bool   l7vs::ParameterImpl::isIntExist(const PARAMETER_COMPONENT_TAG comp, const std::string& key)
+{
+       bool    retval = false;
+       std::string comp_key = compTable[comp].section + "." + key;
+       if( intMap.end() != intMap.find( comp_key ) ){
+               retval = true;
+       }
+       return  retval;
+}
+
+/*!
+ * Existence of a string parameter is checked
+ * @param[in]  comp    PARAMETER_COMPONENT_TAG
+ * @param[in]  key     key string
+ * @return             exist = true / not exist = false
+ */
+bool   l7vs::ParameterImpl::isStringExist(const PARAMETER_COMPONENT_TAG comp, const std::string& key)
+{
+       bool    retval = false;
+       std::string comp_key = compTable[comp].section + "." + key;
+       if( stringMap.end() != stringMap.find( comp_key ) ){
+               retval = true;
+       }
+       return  retval;
+}
+
+/*!
+ * get a integer parameter
+ * @param[in]  comp    PARAMETER_COMPONENT_TAG
+ * @param[in]  key     key string
+ * @return             integer data
+ */
+int    l7vs::ParameterImpl::getIntValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key)
+{
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+           comp != PARAM_COMP_LOGGER) {
+               LOGGER_PUT_LOG_DEBUG(parameter_cat, 10,
+                       "in_function : int l7vs::ParameterImpl::getIntValue("
+                       "const PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& key) : "
+                       "comp = %s, "
+                       "key = %s",
+                       compTable[comp].section.c_str(),
+                       key.c_str());
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+
+       int retint = 0;
+       std::string comp_key = compTable[comp].section + "." + key;
+       std::multimap<std::string, int>::iterator it = intMap.begin();
+       std::multimap<std::string, int>::iterator ite = intMap.end();
+
+       for( std::multimap<std::string, int>::iterator its = it; its !=ite; its++ ) {
+               /*-------- DEBUG LOG for sslproxy --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+                   comp != PARAM_COMP_LOGGER) {
+                       LOGGER_PUT_LOG_DEBUG(parameter_cat, 11,
+                               "function : int l7vs::ParameterImpl::getIntValue() : "
+                               "Search intMap [%s][%d]",
+                               its->first.c_str(),
+                               its->second);
+               }
+               /*------ DEBUG LOG END for sslproxy ------*/
+               if (its->first == comp_key) {
+                       /*-------- DEBUG LOG for sslproxy --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+                           comp != PARAM_COMP_LOGGER) {
+                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 12,
+                                       "function : int l7vs::ParameterImpl::getIntValue() : "
+                                       "Key matched.");
+                       }
+                       /*------ DEBUG LOG END for sslproxy ------*/
+                       retint = its->second;
+               }
+       }
+
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+           comp != PARAM_COMP_LOGGER) {
+               LOGGER_PUT_LOG_DEBUG(parameter_cat, 13,
+                       "out_function : int l7vs::ParameterImpl::getIntValue("
+                       "const PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& key) : "
+                       "retint = %d",
+                       retint);
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+       return retint;
+}
+
+/*!
+ * get a string parameter
+ * @param[in]  comp    PARAMETER_COMPONENT_TAG
+ * @param[in]  key     key string
+ * @return             string data
+ */
+std::string    l7vs::ParameterImpl::getStringValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key)
+{
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+           comp != PARAM_COMP_LOGGER) {
+               LOGGER_PUT_LOG_DEBUG(parameter_cat, 14,
+                       "in_function : std::string l7vs::ParameterImpl::getStringValue("
+                       "const PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& key) : "
+                       "comp = %s, "
+                       "key = %s",
+                       compTable[comp].section.c_str(),
+                       key.c_str());
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+
+       std::string     retstr = "";
+       std::string     comp_key = compTable[comp].section + "." + key;
+       std::multimap<std::string, std::string>::iterator it = stringMap.begin();
+       std::multimap<std::string, std::string>::iterator ite = stringMap.end();
+
+       for( std::multimap<std::string, std::string>::iterator its = it; its !=ite; its++ ) {
+               /*-------- DEBUG LOG for sslproxy --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+                   comp != PARAM_COMP_LOGGER) {
+                       LOGGER_PUT_LOG_DEBUG(parameter_cat, 15,
+                               "function : std::string l7vs::ParameterImpl::getStringValue() : "
+                               "Search stringMap [%s][%s]",
+                               its->first.c_str(),
+                               its->second.c_str());
+               }
+               /*------ DEBUG LOG END for sslproxy ------*/
+               if (its->first == comp_key) {
+                       /*-------- DEBUG LOG for sslproxy --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+                           comp != PARAM_COMP_LOGGER) {
+                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 16,
+                                       "function : std::string l7vs::ParameterImpl::getStringValue() : "
+                                       "Key matched.");
+                       }
+                       /*------ DEBUG LOG END for sslproxy ------*/
+                       retstr = its->second;
+               }
+       }
+
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+           comp != PARAM_COMP_LOGGER) {
+               LOGGER_PUT_LOG_DEBUG(parameter_cat, 17,
+                       "out_function : std::string l7vs::ParameterImpl::getStringValue("
+                       "const PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& key) : "
+                       "retstr = %s",
+                       retstr.c_str());
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+       return retstr;
+}
+
+/*!
+ * get map parameter
+ * @param[in]  comp    PARAMETER_COMPONENT_TAG
+ * @param[in]  key     key string
+ * @param[out] retMap  map data
+ */
+void   l7vs::ParameterImpl::getStringMapValue(const PARAMETER_COMPONENT_TAG comp, const std::string& key, std::multimap<std::string, std::string>& retMap)
+{
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+           comp != PARAM_COMP_LOGGER) {
+               LOGGER_PUT_LOG_DEBUG(parameter_cat, 18,
+                       "in_function : void l7vs::ParameterImpl::getStringMapValue("
+                       "const PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& key, "
+                       "std::multimap<std::string, std::string>& retMap) : "
+                       "comp = %s, "
+                       "key = %s",
+                       compTable[comp].section.c_str(),
+                       key.c_str());
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+
+       std::string     comp_key = compTable[comp].section + "." + key;
+       std::multimap<std::string, std::string>::iterator it = stringMap.begin();
+       std::multimap<std::string, std::string>::iterator ite = stringMap.end();
+
+       for( std::multimap<std::string, std::string>::iterator its = it; its !=ite; its++ ) {
+               /*-------- DEBUG LOG for sslproxy --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+                   comp != PARAM_COMP_LOGGER) {
+                       LOGGER_PUT_LOG_DEBUG(parameter_cat, 19,
+                               "function : void l7vs::ParameterImpl::getStringMapValue() : "
+                               "Search stringMap [%s][%s]",
+                               its->first.c_str(),
+                               its->second.c_str());
+               }
+               /*------ DEBUG LOG END for sslproxy ------*/
+               if (its->first == comp_key) {
+                       /*-------- DEBUG LOG for sslproxy --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+                           comp != PARAM_COMP_LOGGER) {
+                               LOGGER_PUT_LOG_DEBUG(parameter_cat, 20,
+                                       "function : void l7vs::ParameterImpl::getStringMapValue() : "
+                                       "Key matched. Insert map.");
+                       }
+                       /*------ DEBUG LOG END for sslproxy ------*/
+                       retMap.insert( std::pair<std::string, std::string>( key, its->second ) );
+               }
+       }
+
+       /*-------- DEBUG LOG for sslproxy --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(parameter_cat) &&
+           comp != PARAM_COMP_LOGGER) {
+               LOGGER_PUT_LOG_DEBUG(parameter_cat, 21,
+                       "out_function : void l7vs::ParameterImpl::getStringMapValue("
+                       "const PARAMETER_COMPONENT_TAG comp, "
+                       "const std::string& key, "
+                       "std::multimap<std::string, std::string>& retMap)");
+       }
+       /*------ DEBUG LOG END for sslproxy ------*/
+}
+
+/*!
+ * set-parameter function pointer relates component-tag
+ * @param[in]  comp    section TAG
+ * @param[in]  p_func  function pointer
+ */
+void   l7vs::ParameterImpl::registerFunctionPointer( const PARAMETER_COMPONENT_TAG comp, void (*p_func)() )
+{
+       compTable[comp].function = p_func;
+}
+
index 2662a21..4ee7236 100644 (file)
@@ -1,82 +1,82 @@
-/*\r
- * @file  parameter_impl.h\r
- * @brief parameter module implementation class.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#ifndef __PARAMETER_IMPL_H__\r
-#define __PARAMETER_IMPL_H__\r
-\r
-#include "parameter_enum.h"\r
-#include <iostream>\r
-#include <string>\r
-#include <map>\r
-\r
-\r
-namespace l7vs\r
-{\r
-       struct  component{\r
-               std::string     section;\r
-               void            (*function)();\r
-               component(){ section = ""; function = NULL;}\r
-               component( std::string str, void (*p_func)() ){ section = str; function = p_func;}\r
-               component& operator=(const component& in_comp){\r
-                       section = in_comp.section;\r
-                       function = in_comp.function;\r
-                       return *this;\r
-               }\r
-       };\r
-       class ParameterImpl\r
-       {\r
-       private:\r
-               std::string     removebrank( const std::string& );\r
-               bool    readParameterFile( const std::string& );\r
-               bool    isNumeric( const std::string& );\r
-\r
-               std::multimap<std::string,std::string>  preparse;\r
-\r
-               std::map<PARAMETER_COMPONENT_TAG, component>    compTable;\r
-               std::multimap<std::string, std::string> stringMap;\r
-               std::multimap<std::string, int>         intMap;\r
-\r
-       protected:\r
-               ParameterImpl();\r
-               ParameterImpl( const ParameterImpl& );\r
-               ParameterImpl& operator=( const ParameterImpl& );\r
-\r
-       public:\r
-               static ParameterImpl & getInstance(){\r
-                       static ParameterImpl instance;\r
-                       return instance;\r
-               }\r
-               bool    init();\r
-               bool    rereadFile( const PARAMETER_COMPONENT_TAG, const std::string& );\r
-       \r
-               bool    isIntExist( const PARAMETER_COMPONENT_TAG, const std::string& );\r
-               bool    isStringExist( const PARAMETER_COMPONENT_TAG, const std::string& );\r
-               int     getIntValue( const PARAMETER_COMPONENT_TAG, const std::string& );\r
-               std::string     getStringValue( const PARAMETER_COMPONENT_TAG, const std::string& );\r
-               void    getStringMapValue( const PARAMETER_COMPONENT_TAG, const std::string&, std::multimap<std::string, std::string>&);\r
-\r
-               void    registerFunctionPointer( const PARAMETER_COMPONENT_TAG, void (*)() );\r
-       };\r
-}\r
-#endif //__PARAMETER_IMPL_H__\r
+/*
+ * @file  parameter_impl.h
+ * @brief parameter module implementation class.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 __PARAMETER_IMPL_H__
+#define __PARAMETER_IMPL_H__
+
+#include "parameter_enum.h"
+#include <iostream>
+#include <string>
+#include <map>
+
+
+namespace l7vs
+{
+       struct  component{
+               std::string     section;
+               void            (*function)();
+               component(){ section = ""; function = NULL;}
+               component( std::string str, void (*p_func)() ){ section = str; function = p_func;}
+               component& operator=(const component& in_comp){
+                       section = in_comp.section;
+                       function = in_comp.function;
+                       return *this;
+               }
+       };
+       class ParameterImpl
+       {
+       private:
+               std::string     removebrank( const std::string& );
+               bool    readParameterFile( const std::string& );
+               bool    isNumeric( const std::string& );
+
+               std::multimap<std::string,std::string>  preparse;
+
+               std::map<PARAMETER_COMPONENT_TAG, component>    compTable;
+               std::multimap<std::string, std::string> stringMap;
+               std::multimap<std::string, int>         intMap;
+
+       protected:
+               ParameterImpl();
+               ParameterImpl( const ParameterImpl& );
+               ParameterImpl& operator=( const ParameterImpl& );
+
+       public:
+               static ParameterImpl & getInstance(){
+                       static ParameterImpl instance;
+                       return instance;
+               }
+               bool    init();
+               bool    rereadFile( const PARAMETER_COMPONENT_TAG, const std::string& );
+       
+               bool    isIntExist( const PARAMETER_COMPONENT_TAG, const std::string& );
+               bool    isStringExist( const PARAMETER_COMPONENT_TAG, const std::string& );
+               int     getIntValue( const PARAMETER_COMPONENT_TAG, const std::string& );
+               std::string     getStringValue( const PARAMETER_COMPONENT_TAG, const std::string& );
+               void    getStringMapValue( const PARAMETER_COMPONENT_TAG, const std::string&, std::multimap<std::string, std::string>&);
+
+               void    registerFunctionPointer( const PARAMETER_COMPONENT_TAG, void (*)() );
+       };
+}
+#endif //__PARAMETER_IMPL_H__
index 271c842..35367ea 100644 (file)
-/*\r
- * @file  parameter_wrapper.h\r
- * @brief parameter module c wrapper.\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *      \r
- **********************************************************************/\r
-\r
-#ifndef PARAMETER_WRAPPER\r
-#define PARAMETER_WRAPPER\r
-\r
-#include "parameter.h"\r
-\r
-/*!\r
- * check whether integer data exists.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  *key    key string\r
- * @return     1 = exist setting value / 0 = non exist setting value\r
- */\r
-inline int parameter_is_int_exist(const PARAMETER_COMPONENT_TAG comp, const char* key)\r
-{\r
-       if (l7vs::Parameter::getInstance().isIntExist(comp, key)) {\r
-               return 1;\r
-       }\r
-       return 0;\r
-}\r
-\r
-/*!\r
- * check whether character data exists.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  *key    key string\r
- * @return     1 = exist setting value / 0 = non exist setting value\r
- */\r
-inline int parameter_is_char_exist(const PARAMETER_COMPONENT_TAG comp, const char* key)\r
-{\r
-       if (l7vs::Parameter::getInstance().isStringExist(comp, key)) {\r
-               return 1;\r
-       }\r
-       return 0;\r
-}\r
-\r
-/*!\r
- * get integer data.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  *key    key string\r
- * @return     value\r
- */\r
-inline int parameter_get_int_value(const PARAMETER_COMPONENT_TAG comp, const char* key)\r
-{\r
-       return l7vs::Parameter::getInstance().getIntValue(comp, key);\r
-}\r
-\r
-/*!\r
- * get character data.\r
- * @param[in]  comp    section TAG\r
- * @param[in]  *key    key string\r
- * @return     value\r
- */\r
-inline const char* parameter_get_char_value(const PARAMETER_COMPONENT_TAG comp, const char* key)\r
-{\r
-       return (l7vs::Parameter::getInstance().getStringValue(comp, key)).c_str();\r
-}\r
-\r
-/*!\r
- * reload config file\r
- * @param[in]  comp    section TAG\r
- * @param[in]  filename        config file name\r
- * @return     0 = success read file / -1 = failure read file\r
- */\r
-inline int parameter_reread_file(const PARAMETER_COMPONENT_TAG comp, const std::string& filename)\r
-{\r
-       if (l7vs::Parameter::getInstance().rereadFile(comp, filename)) {\r
-               /*-------- DEBUG LOG for sslproxy --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_PARAMETER)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_PARAMETER, 22,\r
-                               "function : inline int parameter_reread_file("\r
-                               "const PARAMETER_COMPONENT_TAG comp, "\r
-                               "const std::string& filename) : "\r
-                               "Parameter.rereadFile("\r
-                               "comp = %d, "\r
-                               "filename = %s) END.",\r
-                               comp,\r
-                               filename.c_str());\r
-               }\r
-               /*------ DEBUG LOG END for sslproxy ------*/\r
-               return 0;\r
-       }\r
-       return -1;\r
-}\r
-\r
-/*!\r
- * set-parameter function pointer relates component-tag\r
- * @param[in]  comp    section TAG\r
- * @param[in]  p_func  function pointer\r
- */\r
-inline void parameter_register_function_pointer(const PARAMETER_COMPONENT_TAG comp, void(*p_func)())\r
-{\r
-       l7vs::Parameter::getInstance().registerFunctionPointer(comp, p_func);\r
-}\r
-\r
-#endif //PARAMETER_WRAPPER\r
-\r
+/*
+ * @file  parameter_wrapper.h
+ * @brief parameter module c wrapper.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  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 PARAMETER_WRAPPER
+#define PARAMETER_WRAPPER
+
+#include "parameter.h"
+
+/*!
+ * check whether integer data exists.
+ * @param[in]  comp    section TAG
+ * @param[in]  *key    key string
+ * @return     1 = exist setting value / 0 = non exist setting value
+ */
+inline int parameter_is_int_exist(const PARAMETER_COMPONENT_TAG comp, const char* key)
+{
+       if (l7vs::Parameter::getInstance().isIntExist(comp, key)) {
+               return 1;
+       }
+       return 0;
+}
+
+/*!
+ * check whether character data exists.
+ * @param[in]  comp    section TAG
+ * @param[in]  *key    key string
+ * @return     1 = exist setting value / 0 = non exist setting value
+ */
+inline int parameter_is_char_exist(const PARAMETER_COMPONENT_TAG comp, const char* key)
+{
+       if (l7vs::Parameter::getInstance().isStringExist(comp, key)) {
+               return 1;
+       }
+       return 0;
+}
+
+/*!
+ * get integer data.
+ * @param[in]  comp    section TAG
+ * @param[in]  *key    key string
+ * @return     value
+ */
+inline int parameter_get_int_value(const PARAMETER_COMPONENT_TAG comp, const char* key)
+{
+       return l7vs::Parameter::getInstance().getIntValue(comp, key);
+}
+
+/*!
+ * get character data.
+ * @param[in]  comp    section TAG
+ * @param[in]  *key    key string
+ * @return     value
+ */
+inline const char* parameter_get_char_value(const PARAMETER_COMPONENT_TAG comp, const char* key)
+{
+       return (l7vs::Parameter::getInstance().getStringValue(comp, key)).c_str();
+}
+
+/*!
+ * reload config file
+ * @param[in]  comp    section TAG
+ * @param[in]  filename        config file name
+ * @return     0 = success read file / -1 = failure read file
+ */
+inline int parameter_reread_file(const PARAMETER_COMPONENT_TAG comp, const std::string& filename)
+{
+       if (l7vs::Parameter::getInstance().rereadFile(comp, filename)) {
+               /*-------- DEBUG LOG for sslproxy --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_PARAMETER)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_PARAMETER, 22,
+                               "function : inline int parameter_reread_file("
+                               "const PARAMETER_COMPONENT_TAG comp, "
+                               "const std::string& filename) : "
+                               "Parameter.rereadFile("
+                               "comp = %d, "
+                               "filename = %s) END.",
+                               comp,
+                               filename.c_str());
+               }
+               /*------ DEBUG LOG END for sslproxy ------*/
+               return 0;
+       }
+       return -1;
+}
+
+/*!
+ * set-parameter function pointer relates component-tag
+ * @param[in]  comp    section TAG
+ * @param[in]  p_func  function pointer
+ */
+inline void parameter_register_function_pointer(const PARAMETER_COMPONENT_TAG comp, void(*p_func)())
+{
+       l7vs::Parameter::getInstance().registerFunctionPointer(comp, p_func);
+}
+
+#endif //PARAMETER_WRAPPER
+
index 99f8151..c200632 100644 (file)
@@ -13,15 +13,24 @@ sslproxy_SOURCES    =       \
                        $(top_srcdir)/include/sslproxy.h \
                        $(top_srcdir)/include/sslproxyserver.h \
                        $(top_srcdir)/include/sslproxysession.h \
+                       $(top_srcdir)/include/packet_editor.h \
+                       $(top_srcdir)/include/http_message.h \
+                       $(top_srcdir)/include/http_request.h \
+                       $(top_srcdir)/include/http_response.h \
                        sslproxy.cpp \
                        sslproxymain.cpp \
                        sslproxyserver.cpp \
-                       sslproxysession.cpp
+                       sslproxysession.cpp \
+                       packet_editor.cpp \
+                       http_message.cpp \
+                       http_request.cpp \
+                       http_response.cpp
 
 sslproxy_LDADD =       $(top_builddir)/logger/libsslproxy_logger.a \
                        $(top_builddir)/parameter/libsslproxy_parameter.a \
                        -llog4cxx \
                        -lrt \
                        -lssl \
+                       -lboost_regex-gcc41-mt \
                        -lboost_system-gcc41-mt \
                        -lboost_thread-gcc41-mt
diff --git a/src/http_message.cpp b/src/http_message.cpp
new file mode 100644 (file)
index 0000000..bf2ce09
--- /dev/null
@@ -0,0 +1,522 @@
+/*
+ * @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,
+        "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, 2,
+        "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, 3,
+        "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) const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 4,
+        "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<field_map>().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, 5,
+        "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, 6,
+        "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<field_map>().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<field_map>().replace(it, field(name, field_value)) ) {
+                    changed = true;
+                    this->modified = true;
+                }
+            }
+            else {
+                _header.get<field_map>().erase(it);
+                changed = true;
+                this->modified = true;
+            }
+        }
+        if (!changed && field_value != "") {
+            _header.get<field_map>().insert( field(name, field_value) );
+            this->modified = true;
+        }
+    }
+    catch (...) {
+        LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 1,
+        "Exception occured by inserting or replacing boost::multi_index.");
+    }
+
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 7,
+        "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() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 8,
+        "in_function : std::string http_message::body(void)");
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 9,
+        "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, 10,
+        "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, 11,
+        "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, 12,
+        "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, 13,
+        "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, 14,
+        "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<std::string, std::string> field_pair;
+    try {
+        while (ptr != end) {
+            switch(pos) {
+            /*
+             * MESSAGE-HEADER   : field-name ":" [ field-value ]
+             * field-name       : token
+             * field-value      : *( field-content | LWS )
+             * field-content    : <the OCTETs making up the field-value and
+             *                    consisting of either *TEXT or combinations
+             *                    of token, separators, and quoted-string>
+             * TEXT             : <any OCTET except CTLs, but including LWS>
+             * quoted-string    : ( <"> *(qdtext | quoted-pair ) <"> )
+             * qdtext           : <any TEXT except <">>
+             * 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 {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 2,
+                    "Parse error: Invalid header field name.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case MESSAGE_CR:
+                // LF only
+                if (*ptr == '\n') {
+                    pos = MESSAGE_LF;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 3,
+                    "Parse error: No LF.(%c)", *ptr);
+                    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<field_map>().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<field_map>().insert(field_pair);
+                        field_pair.first.clear();
+                    }
+                    pos = MESSAGE_LAST_CR;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 4,
+                    "Parse error: Invalid header field name.(%c)", *ptr);
+                    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 != '%') {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 5,
+                    "Parse error: Invalid header field name.(%c)", *ptr);
+                    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 {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 6,
+                    "Parse error: Invalid header field value.(%c)", *ptr);
+                    throw -1;
+                }
+                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' ) {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 7,
+                    "Parse error: Invalid header field value.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case MESSAGE_LAST_CR:
+                // LF only
+                if (*ptr == '\n') {
+                    pos = MESSAGE_LAST_LF;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 8,
+                    "Parse error: No LF.(%c)", *ptr);
+                    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);
+        }
+    }
+    catch (...) {
+        LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 9,
+        "Exception occured by parsing 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, 15,
+        "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, 16,
+        "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, 17,
+        "out_function : void http_message::rebuild()");
+    }
+    /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Field name convert function.
+ * Convert upper camelcase
+ *     ex. connecTION => Connection
+ *         usEr-aGeNT => User-Agent
+ *         p3p => P3P
+ *
+ * @param[in]   field_name  field name
+ * @return  converted to camel case
+ */
+std::string http_message::convert_upper_camel_case(std::string field_name) const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 18,
+        "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<char> sep("-_0123456789", "-_0123456789", boost::keep_empty_tokens);
+    boost::tokenizer<boost::char_separator<char> > tokens(field_name, sep);
+    boost::tokenizer<boost::char_separator<char> >::iterator tok_it  = tokens.begin();
+    boost::tokenizer<boost::char_separator<char> >::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, 19,
+        "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 (file)
index 0000000..dc769f0
--- /dev/null
@@ -0,0 +1,575 @@
+/*
+ * @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, 20,
+        "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, 21,
+        "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, 22,
+        "in/out_function : Destructor http_request::~http_request(void)");
+    }
+    /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Get method function.
+ *
+ * @return    method
+ */
+std::string http_request::method() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 23,
+        "in_function : std::string http_request::method(void)");
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 24,
+        "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, 25,
+        "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, 26,
+        "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() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 27,
+        "in_function : std::string http_request::request_uri(void)");
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 28,
+        "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, 29,
+        "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, 30,
+        "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() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 31,
+        "in_function : std::string http_request::http_version(void)");
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 32,
+        "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, 33,
+        "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, 34,
+        "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() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 35,
+        "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, 36,
+        "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, 37,
+        "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, 38,
+        "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, 39,
+        "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<std::string, std::string> field_pair;
+    try {
+        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
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 10,
+                    "Parse error: Invalid request method.(%c)", *ptr);
+                    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 {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 11,
+                    "Parse error: Invalid request-uri.(%c)", *ptr);
+                    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 != ';') {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 12,
+                    "Parse error: Invalid request-uri.(%c)", *ptr);
+                    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 {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 13,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case REQUEST_HTTP_VERSION_H:
+                // HTTP-VERSION next
+                if (*ptr == 'T') {
+                    pos = REQUEST_HTTP_VERSION_T1;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 14,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case REQUEST_HTTP_VERSION_T1:
+                // HTTP-VERSION next
+                if (*ptr == 'T') {
+                    pos = REQUEST_HTTP_VERSION_T2;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 15,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case REQUEST_HTTP_VERSION_T2:
+                // HTTP-VERSION next
+                if (*ptr == 'P') {
+                    pos = REQUEST_HTTP_VERSION_P;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 16,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case REQUEST_HTTP_VERSION_P:
+                // HTTP-VERSION next
+                if (*ptr == '/') {
+                    pos = REQUEST_HTTP_VERSION_SLASH;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 17,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case REQUEST_HTTP_VERSION_SLASH:
+                // HTTP-VERSION Mejor number
+                if (isdigit(*ptr)) {
+                    pos = REQUEST_HTTP_VERSION_MAJOR;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 18,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case REQUEST_HTTP_VERSION_MAJOR:
+                // HTTP-VERSION next dot
+                if (*ptr == '.') {
+                    pos = REQUEST_HTTP_VERSION_DOT;
+                } else if (!isdigit(*ptr)) {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 19,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case REQUEST_HTTP_VERSION_DOT:
+                // HTTP-VERSION Minor number
+                if (isdigit(*ptr)) {
+                    pos = REQUEST_HTTP_VERSION_MINOR;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 20,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    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)) {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 21,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case REQUEST_CR:
+                // LF only
+                if (*ptr == '\n') {
+                    pos = REQUEST_LF;
+                    http_message::parse(std::string(ptr + 1, end));
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 22,
+                    "Parse error: No LF.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+            }
+            if (pos == REQUEST_LF)
+                break;
+            ptr++;
+        }
+    }
+    catch (...) {
+        LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 23,
+        "Exception occured by parsing 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, 40,
+        "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, 41,
+        "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, 42,
+        "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 (file)
index 0000000..17b7fe5
--- /dev/null
@@ -0,0 +1,566 @@
+/*
+ * @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, 43,
+        "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, 44,
+        "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, 45,
+        "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() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 46,
+        "in_function : std::string http_response::http_version(void)");
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 47,
+        "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, 48,
+        "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, 49,
+        "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() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 50,
+        "in_function : std::string http_response::status_code(void)");
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 51,
+        "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, 52,
+        "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, 53,
+        "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() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 54,
+        "in_function : std::string http_response::reason_phrase(void)");
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 55,
+        "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, 56,
+        "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, 57,
+        "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() const
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT_HTTP)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT_HTTP, 58,
+        "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, 59,
+        "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, 60,
+        "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, 61,
+        "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, 62,
+        "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<std::string, std::string> field_pair;
+    try {
+        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 {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 24,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_HTTP_VERSION_H:
+                // HTTP-VERSION next
+                if (*ptr == 'T') {
+                    pos = RESPONSE_HTTP_VERSION_T1;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 25,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_HTTP_VERSION_T1:
+                // HTTP-VERSION next
+                if (*ptr == 'T') {
+                    pos = RESPONSE_HTTP_VERSION_T2;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 26,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_HTTP_VERSION_T2:
+                // HTTP-VERSION next
+                if (*ptr == 'P') {
+                    pos = RESPONSE_HTTP_VERSION_P;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 27,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_HTTP_VERSION_P:
+                // HTTP-VERSION next
+                if (*ptr == '/') {
+                    pos = RESPONSE_HTTP_VERSION_SLASH;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 28,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_HTTP_VERSION_SLASH:
+                // HTTP-VERSION Mejor number
+                if (isdigit(*ptr)) {
+                    pos = RESPONSE_HTTP_VERSION_MAJOR;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 29,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_HTTP_VERSION_MAJOR:
+                // HTTP-VERSION next dot
+                if (*ptr == '.') {
+                    pos = RESPONSE_HTTP_VERSION_DOT;
+                } else if (!isdigit(*ptr)) {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 30,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_HTTP_VERSION_DOT:
+                // HTTP-VERSION Minor number
+                if (isdigit(*ptr)) {
+                    pos = RESPONSE_HTTP_VERSION_MINOR;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 31,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    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)) {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 32,
+                    "Parse error: Invalid http-version.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            /*
+             * Status-Code  : 3DIGIT
+             */
+            case RESPONSE_HTTP_VERSION_SP:
+                // STATUS-CODE start
+                if (isdigit(*ptr)) {
+                    pos = RESPONSE_STATUS_CODE1;
+                    start = ptr;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 33,
+                    "Parse error: Invalid status-code.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_STATUS_CODE1:
+                // STATUS-CODE next
+                if (isdigit(*ptr)) {
+                    pos = RESPONSE_STATUS_CODE2;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 34,
+                    "Parse error: Invalid status-code.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_STATUS_CODE2:
+                // STATUS-CODE next
+                if (isdigit(*ptr)) {
+                    pos = RESPONSE_STATUS_CODE3;
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 35,
+                    "Parse error: Invalid status-code.(%c)", *ptr);
+                    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 {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 36,
+                    "Parse error: Invalid status-code.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            /*
+             * Reason-Phrase    : *<TEXT, excluding CR, LF>
+             */
+            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  {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 37,
+                    "Parse error: Invalid reason-phrase.(%c)", *ptr);
+                    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') {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 38,
+                    "Parse error: Invalid reason-phrase.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+    
+            case RESPONSE_CR:
+                // LF only
+                if (*ptr == '\n') {
+                    pos = RESPONSE_LF;
+                    http_message::parse(std::string(ptr + 1, end));
+                } else {
+                    LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 39,
+                    "Parse error: No LF.(%c)", *ptr);
+                    throw -1;
+                }
+                break;
+            }
+            if (pos == RESPONSE_LF)
+                break;
+            ptr++;
+        }
+    }
+    catch (...) {
+        LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT_HTTP, 40,
+        "Exception occured by parsing 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, 63,
+        "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, 64,
+        "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, 65,
+        "out_function : void http_response::rebuild()");
+    }
+    /*------ DEBUG LOG END ------*/
+}
diff --git a/src/packet_editor.cpp b/src/packet_editor.cpp
new file mode 100644 (file)
index 0000000..c233d4f
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+ * @file  packet_editor.cpp
+ * @brief Packet Editor 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
+ *
+ **********************************************************************/
+
+#include <boost/regex.hpp>
+#include "packet_editor.h"
+#include "sslproxy.h"
+#include "sslproxyserver.h"
+#include "sslproxysession.h"
+
+/*!
+ * Packet editor constructor.
+ */
+packet_editor::packet_editor(const sslproxy_session* session)
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 1,
+        "in_function : Constructor packet_editor::packet_editor(const sslproxysession* session)");
+    }
+    /*------ DEBUG LOG END ------*/
+
+    this->session = session;
+
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 2,
+        "out_function : Constructor packet_editor::packet_editor(const sslproxysession* session)");
+    }
+    /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Packet editor destructor.
+ */
+packet_editor::~packet_editor()
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 3,
+        "in/out_function : Destructor packet_editor::~packet_editor(void)");
+    }
+    /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Edit client message function.
+ */
+void packet_editor::edit_client(char* client_msg, size_t& client_length)
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 4,
+        "in_function : void packet_editor::edit_client(char* client_msg, size_t& client_length) : "
+        "client_msg(%s), client_length(%d)", client_msg, client_length);
+    }
+    /*------ DEBUG LOG END ------*/
+
+    // Edit HTTP (request header)
+    std::list<std::pair<std::string, std::string > >::iterator it, end;
+    it  = ::http_request_header.begin();
+    end = ::http_request_header.end();
+    http_request request(std::string(client_msg, client_length));
+    for (;it != end; ++it) {
+        // Set request header field
+        if (it->first == "set") {
+            // "Header-Field-Name":"Set-Value"
+            std::vector<std::string> set_vector = split(it->second, ":", 2);
+            if (set_vector.size() == 2)
+                expand_macro(set_vector.at(1));
+                // Overwrite or insert.
+                request.header(set_vector.at(0), set_vector.at(1));
+        }
+        // Remove request header field
+        else if (it->first == "unset") {
+            // "Header-Field-Name"
+            request.header(it->second, "");
+        }
+        // Add request header field
+        else if (it->first == "add") {
+            // "Header-Field-Name":"Set-Value"
+            std::vector<std::string> add_vector = split(it->second, ":", 2);
+            if (add_vector.size() == 2) {
+                field_range current_range = request.header(add_vector.at(0));
+                expand_macro(add_vector.at(1));
+                // If header field already exists, concatinate values.
+                if (current_range.first != current_range.second) {
+                    std::string new_value = current_range.first->second;
+                    new_value += "," + add_vector.at(1);
+                    request.header(add_vector.at(0), new_value);
+                // otherwise insert new header field.
+                } else {
+                    request.header(add_vector.at(0), add_vector.at(1));
+                }
+            }
+        }
+        // Replace request header field using regular expression
+        else if (it->first == "replace") {
+            // "Header-Field-Name":"From-Value(regex)":"To-Value"
+            std::vector<std::string> replace_vector = split(it->second, ":", 3);
+            if (replace_vector.size() == 3) {
+                field_range current_range = request.header(replace_vector.at(0));
+                expand_macro(replace_vector.at(1));
+                expand_macro(replace_vector.at(2));
+                boost::regex exp(replace_vector.at(1));
+                for (;current_range.first != current_range.second; current_range.first++) {
+                    std::string new_value = current_range.first->second;
+                    // Replace only if exist
+                    if (boost::regex_search(new_value, exp)) {
+                        new_value = boost::regex_replace(new_value, exp, replace_vector.at(2));
+                        request.header(replace_vector.at(0), new_value);
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * Insert other protocol editor.
+     */
+
+    std::string edited = request.as_string();
+    // New client message is too long (over buffer size)
+    if (edited.size() > MAX_BUFFER_SIZE) {
+        LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT, 1, "Edited message is too long. Drop message.");
+    }
+    else {
+        // Set new client message size.
+        client_length = edited.size();
+        // Set new client message.
+        memcpy(client_msg, edited.c_str(), client_length);
+    }
+
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 5,
+        "out_function : void packet_editor::edit_client(char* client_msg, size_t& client_length)");
+    }
+    /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Edit server message function.
+ */
+void packet_editor::edit_server(char* server_msg, size_t& server_length)
+{
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 6,
+        "in_function : void packet_editor::edit_server(char* server_msg, size_t& server_length) : "
+        "server_msg(%s), server_length(%d)", server_msg, server_length);
+    }
+    /*------ DEBUG LOG END ------*/
+
+    // Edit HTTP (response header)
+    std::list<std::pair<std::string, std::string > >::iterator it, end;
+    it  = ::http_response_header.begin();
+    end = ::http_response_header.end();
+    http_response response(std::string(server_msg, server_length));
+    for (;it != end; ++it) {
+        // Set request header field
+        if (it->first == "set") {
+            // "Header-Field-Name":"Set-Value"
+            std::vector<std::string> set_vector = split(it->second, ":", 2);
+            if (set_vector.size() == 2)
+                expand_macro(set_vector.at(1));
+                // Overwrite or insert.
+                response.header(set_vector.at(0), set_vector.at(1));
+        }
+        // Remove request header field
+        else if (it->first == "unset") {
+            // "Header-Field-Name"
+            response.header(it->second, "");
+        }
+        // Add request header field
+        else if (it->first == "add") {
+            // "Header-Field-Name":"Set-Value"
+            std::vector<std::string> add_vector = split(it->second, ":", 2);
+            if (add_vector.size() == 2) {
+                field_range current_range = response.header(add_vector.at(0));
+                expand_macro(add_vector.at(1));
+                // If header field already exists, concatinate values.
+                if (current_range.first != current_range.second) {
+                    std::string new_value = current_range.first->second;
+                    new_value += "," + add_vector.at(1);
+                    response.header(add_vector.at(0), new_value);
+                // otherwise insert new header field.
+                } else {
+                    response.header(add_vector.at(0), add_vector.at(1));
+                }
+            }
+        }
+        // Replace request header field using regular expression
+        else if (it->first == "replace") {
+            // "Header-Field-Name":"From-Value(regex)":"To-Value"
+            std::vector<std::string> replace_vector = split(it->second, ":", 3);
+            if (replace_vector.size() == 3) {
+                field_range current_range = response.header(replace_vector.at(0));
+                expand_macro(replace_vector.at(1));
+                expand_macro(replace_vector.at(2));
+                boost::regex exp(replace_vector.at(1));
+                for (;current_range.first != current_range.second; current_range.first++) {
+                    std::string new_value = current_range.first->second;
+                    // Replace only if exist
+                    if (boost::regex_search(new_value, exp)) {
+                        new_value = boost::regex_replace(new_value, exp, replace_vector.at(2));
+                        response.header(replace_vector.at(0), new_value);
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * Insert other protocol editor.
+     */
+
+    std::string edited = response.as_string();
+    // New server message is too long (over buffer size)
+    if (edited.size() > MAX_BUFFER_SIZE) {
+        LOGGER_PUT_LOG_ERROR(LOG_CAT_PACKET_EDIT, 2, "Edited message is too long. Drop message.");
+    }
+    else {
+        // Set new server message size.
+        server_length = edited.size();
+        // Set new server message.
+        memcpy(server_msg, edited.c_str(), server_length);
+    }
+
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 7,
+        "out_function : void packet_editor::edit_server(char* server_msg, size_t& server_length)");
+    }
+    /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Expand macro function.
+ *
+ * @param[in/out]   source  string
+ */
+void packet_editor::expand_macro(std::string& source) {
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 8,
+        "in_function : void packet_editor::expand_macro(std::string& source) : "
+        "source(%s)", source.c_str());
+    }
+    /*------ DEBUG LOG END ------*/
+    int pos;
+
+    pos = source.find("%{CLIENT_ADDR}");
+    if (pos != std::string::npos) {
+        std::string endpoint = this->session->get_remote_endpoint();
+        if (endpoint.length() > 0) {
+            int addr_end = endpoint.find(':');
+            source.replace(pos, 14, endpoint.substr(0, addr_end));
+        }
+    }
+
+    pos = source.find("%{CLIENT_PORT}");
+    if (pos != std::string::npos) {
+        std::string endpoint = this->session->get_remote_endpoint();
+        if (endpoint.length() > 0) {
+            int port_begin = endpoint.find(':') + 1;
+            source.replace(pos, 14, endpoint.substr(port_begin, endpoint.length() - port_begin));
+        }
+    }
+
+    pos = source.find("%{SERVER_ADDR}");
+    if (pos != std::string::npos) {
+        int addr_end = ::target_endpoint.find(':');
+        source.replace(pos, 14, ::target_endpoint.substr(0, addr_end));
+    }
+
+    pos = source.find("%{SERVER_PORT}");
+    if (pos != std::string::npos) {
+        int port_begin = ::target_endpoint.find(':') + 1;
+        source.replace(pos, 14, ::target_endpoint.substr(port_begin, ::target_endpoint.length() - port_begin));
+    }
+
+    pos = source.find("%{RECV_ADDR}");
+    if (pos != std::string::npos) {
+        int addr_end = ::recv_endpoint.find(':');
+        source.replace(pos, 12, ::recv_endpoint.substr(0, addr_end));
+    }
+
+    pos = source.find("%{RECV_PORT}");
+    if (pos != std::string::npos) {
+        int port_begin = ::recv_endpoint.find(':') + 1;
+        source.replace(pos, 12, ::recv_endpoint.substr(port_begin, ::recv_endpoint.length() - port_begin));
+    }
+
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 9,
+        "out_function : void packet_editor::expand_macro(std::string& source)");
+    }
+    /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Split string function.
+ * Split string by delimiter and return token vector.
+ * If limit is specified and positive, it represents the maximum number of fields
+ * the delimiter will be split into.
+ *
+ * @param[in]   source  string
+ * @param[in]   delimiter   delimiter
+ * @param[in]   limit   max token
+ */
+std::vector<std::string> packet_editor::split(const std::string& source, const std::string& delimiter, int limit = 0) {
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 10,
+        "in_function : std::vector<std::string> packet_editor::split"
+        "(const std::string& source, const std::string& delimiter, int limit) : "
+        "source(%s), delimiter(%s), limit(%d)", source.c_str(), delimiter.c_str(), limit);
+    }
+    /*------ DEBUG LOG END ------*/
+    std::vector<std::string> words;
+    int begin = 0;
+    int end   = source.size();
+    limit--;
+    while (limit != 0) {
+        end = source.find(delimiter, begin);
+        if (end == std::string::npos) {
+            end = source.size();
+            break;
+        }
+        words.push_back(source.substr(begin, end - begin));
+        begin = end + 1;
+        limit--;
+    }
+    words.push_back(source.substr(begin, end - begin));
+    /*-------- DEBUG LOG --------*/
+    if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_PACKET_EDIT)) {
+        LOGGER_PUT_LOG_DEBUG(LOG_CAT_PACKET_EDIT, 11,
+        "out_function : std::vector<std::string> packet_editor::split"
+        "(const std::string& source, const std::string& delimiter, int limit)");
+    }
+    /*------ DEBUG LOG END ------*/
+    return words;
+}
index 74d5f24..e7ce327 100644 (file)
@@ -1,43 +1,43 @@
-/*\r
- * @file  sslproxy.cpp\r
- * @brief the main module of SSLProxy module wrapper\r
- *\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************\r
- *\r
- * Distributed under the Boost Software Licence, Version 1.0\r
- * http://www.boost.org/LICENSE_1_0.txt\r
- *\r
- **********************************************************************/\r
-\r
-#include "logger_wrapper.h"\r
-#include "parameter_wrapper.h"\r
-\r
-extern void sslproxy_main(int, char *[]);\r
-\r
-using namespace l7vs;\r
-\r
-Logger Logger::instance;\r
-Parameter Parameter::instance;\r
-\r
-int\r
-main(int argc, char *argv[])\r
-{\r
-       sslproxy_main(argc, argv);\r
-}\r
+/*
+ * @file  sslproxy.cpp
+ * @brief the main module of SSLProxy module wrapper
+ *
+ * Copyright (C) 2008  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
+ *
+ **********************************************************************
+ *
+ * Distributed under the Boost Software Licence, Version 1.0
+ * http://www.boost.org/LICENSE_1_0.txt
+ *
+ **********************************************************************/
+
+#include "logger_wrapper.h"
+#include "parameter_wrapper.h"
+
+extern void sslproxy_main(int, char *[]);
+
+using namespace l7vs;
+
+Logger Logger::instance;
+Parameter Parameter::instance;
+
+int
+main(int argc, char *argv[])
+{
+       sslproxy_main(argc, argv);
+}
index e561b87..56ad3bd 100644 (file)
@@ -74,6 +74,10 @@ long session_cache_mode;
 long session_cache_size;
 long session_cache_timeout;
 std::string conn_log_flag;
+bool client_packet_edit = DEFAULT_CLIENT_EDIT;
+bool server_packet_edit = DEFAULT_SERVER_EDIT;
+std::list<std::pair<std::string, std::string > > http_request_header;
+std::list<std::pair<std::string, std::string > > http_response_header;
 
 /*!
  * Convert verify option string to intger(#define).
@@ -1190,6 +1194,84 @@ static int getParameters(std::string config_filename)
                                            "Use default value.");
                        conn_log_flag = DEFAULT_CONN_LOG_FLAG;
                }
+
+               // Get parameter "http_request_header".
+               if (Parameter::getInstance().isStringExist(PARAM_COMP_SSLPROXY, "http_request_header")) {
+                       std::multimap<std::string, std::string> request_map;
+                       Parameter::getInstance().getStringMapValue(PARAM_COMP_SSLPROXY, 
+                           "http_request_header", request_map);
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_COMMON)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_COMMON, 101,
+                                   "function : static int getParameters("
+                                   "std::string config_filename) : "
+                                   "get http_request_header OK.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+                       std::multimap<std::string, std::string>::iterator it  = request_map.begin();
+                       std::multimap<std::string, std::string>::iterator end = request_map.end();
+                       while (it != end) {
+                               int delimiter_pos = it->second.find(':');
+                               if (delimiter_pos == std::string::npos) {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_COMMON, 50,
+                                           "Invalid http_request_header parameter value.(no delimiter)");
+                                       throw -1;
+                               }
+                               std::pair<std::string, std::string> header_pair(
+                                   it->second.substr(0, delimiter_pos),
+                                   it->second.substr(delimiter_pos + 1, it->second.size() - delimiter_pos) );
+                               if ( header_pair.first != "set"
+                                 && header_pair.first != "unset"
+                                 && header_pair.first != "add"
+                                 && header_pair.first != "replace" ) {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_COMMON, 51,
+                                           "Invalid http_request_header parameter value.(invalid type)");
+                                       throw -1;
+                               }
+                               ::http_request_header.push_back(header_pair);
+                               ::client_packet_edit = true;
+                               it++;
+                       }
+               }
+
+               // Get parameter "http_response_header".
+               if (Parameter::getInstance().isStringExist(PARAM_COMP_SSLPROXY, "http_response_header")) {
+                       std::multimap<std::string, std::string> response_map;
+                       Parameter::getInstance().getStringMapValue(PARAM_COMP_SSLPROXY, 
+                           "http_response_header", response_map);
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_COMMON)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_COMMON, 102,
+                                   "function : static int getParameters("
+                                   "std::string config_filename) : "
+                                   "get http_response_header OK.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+                       std::multimap<std::string, std::string>::iterator it  = response_map.begin();
+                       std::multimap<std::string, std::string>::iterator end = response_map.end();
+                       while (it != end) {
+                               int delimiter_pos = it->second.find(':');
+                               if (delimiter_pos == std::string::npos) {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_COMMON, 52,
+                                           "Invalid http_response_header parameter value.(no delimiter)");
+                                       throw -1;
+                               }
+                               std::pair<std::string, std::string> header_pair(
+                                   it->second.substr(0, delimiter_pos),
+                                   it->second.substr(delimiter_pos + 1, it->second.size() - delimiter_pos) );
+                               if ( header_pair.first != "set"
+                                 && header_pair.first != "unset"
+                                 && header_pair.first != "add"
+                                 && header_pair.first != "replace" ) {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_COMMON, 53,
+                                           "Invalid http_response_header parameter value.(invalid type)");
+                                       throw -1;
+                               }
+                               ::http_response_header.push_back(header_pair);
+                               ::server_packet_edit = true;
+                               it++;
+                       }
+               }
        } catch (int e) {
                /*-------- DEBUG LOG --------*/
                if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_COMMON)) {
@@ -1504,7 +1586,7 @@ static void usage(void)
        /*------ DEBUG LOG END ------*/
 
        std::cerr << "Usage   : " << "sslproxy <target_id> <config_filename>" << std::endl;
-       std::cerr << "Example : " << "sslproxy target_1 /etc/l7vs/sslproxy/sslproxy.target_1.cf" << std::endl;
+       std::cerr << "Example : " << "sslproxy target_1 /etc/l7vs/sslproxy/sslproxy.target.cf" << std::endl;
 
        /*-------- DEBUG LOG --------*/
        if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_COMMON)) {
index aed1eac..85d354f 100644 (file)
-/*\r
- * @file  sslproxysession.cpp\r
- * @brief module of SSLproxy_session\r
- * @brief SSL handshaking and Connecting.\r
- * @brief Client and Server data read/write.\r
- *\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************\r
- *\r
- * Distributed under the Boost Software Licence, Version 1.0\r
- * http://www.boost.org/LICENSE_1_0.txt\r
- *\r
- **********************************************************************/\r
-\r
-#include <sys/syscall.h>       // for SYS_gettid\r
-#include <boost/lexical_cast.hpp>\r
-\r
-#include "sslproxyserver.h"\r
-#include "sslproxysession.h"\r
-\r
-// sslproxy_session constructor\r
-/*!\r
- * SSLproxy_session constructor.\r
- *\r
- * @param[in]  io_service      IO event dispatcher\r
- * @param[in]  context         SSL context\r
- * @param[in]  itr             endpoint iterator\r
- */\r
-sslproxy_session::sslproxy_session(boost::asio::io_service& ioservice,\r
-                                  boost::asio::ssl::context& context,\r
-                                  boost::asio::ip::tcp::resolver::iterator itr)\r
-                                  :\r
-                                  server_socket(ioservice),\r
-                                  client_socket(ioservice, context),\r
-                                  endpoint_iterator(itr),\r
-                                  timer(ioservice),\r
-                                  cancel_time(timeout_sec),\r
-                                  handshaked(false),\r
-                                  istimeout(false),\r
-                                  c_r_event(false),\r
-                                  c_w_event(false),\r
-                                  s_r_event(false),\r
-                                  s_w_event(false),\r
-                                  finishing(false),\r
-                                  cache_timer(ioservice)\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 1,\r
-                       "in/out_function : Constructor sslproxy_session::sslproxy_session("\r
-                       "boost::asio::io_service& ioservice, "\r
-                       "boost::asio::ssl::context& context, "\r
-                       "boost::asio::ip::tcp::resolver::iterator itr)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-       pthread_mutex_init(&client_socket_mutex, NULL);\r
-}\r
-\r
-/*!\r
- * SSLproxy_session destructor.\r
- */\r
-sslproxy_session::~sslproxy_session()\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 2,\r
-                       "in/out_function : Destructor sslproxy_session::~sslproxy_session("\r
-                       "void)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-}\r
-\r
-/*!\r
- * Low level socket getting function.\r
- *\r
- * @return     password string\r
- * @retval     ssl_socket::lowest_layer_type&\r
- */\r
-ssl_socket::lowest_layer_type& sslproxy_session::low_socket()\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 3,\r
-                       "in_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("\r
-                       "void)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-\r
-       try {\r
-               ssl_socket::lowest_layer_type& sock = client_socket.lowest_layer();\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 4,\r
-                               "function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket() : "\r
-                               "lowest_layer() END.");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       \r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 5,\r
-                               "out_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("\r
-                               "void)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-               return sock;\r
-       } catch (std::exception& e) {\r
-               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 1, \r
-                       "Get low level socket error : %s.", e.what());\r
-               throw -1;\r
-       }\r
-}\r
-\r
-/*!\r
- * Get remote endpoint string.\r
- * get client address:port from SSL socket\r
- *\r
- * @param[in]  socket  client SSL socket\r
- * @return     endpoint string\r
- */\r
-std::string sslproxy_session::get_remote_endpoint(ssl_socket& socket)\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 6,\r
-                       "in_function : std::string sslproxy_session::get_remote_endpoint("\r
-                       "ssl_socket& socket)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-\r
-       std::string endpoint_str = "";\r
-       boost::asio::ip::tcp::endpoint endpoint;\r
-       std::string address;\r
-       std::string port;\r
-\r
-       try {\r
-               try {\r
-                       endpoint = socket.lowest_layer().remote_endpoint();\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 7,\r
-                                       "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                                       "lowest_layer().remote_endpoint() END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               } catch (std::exception& e) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 2, \r
-                               "Get remote endpoint from socket error : %s.", e.what());\r
-                       throw -1;\r
-               }\r
-\r
-               try {\r
-                       address = endpoint.address().to_string();\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 8,\r
-                                       "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                                       "address().to_string() END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               } catch (std::exception& e) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 3, \r
-                               "Get address string error : %s.", e.what());\r
-                       throw -1;\r
-               }\r
-\r
-               try {\r
-                       port = boost::lexical_cast<std::string>(endpoint.port());\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 9,\r
-                                       "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                                       "lexical_cast(port()) END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               } catch (std::exception& e) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 4, \r
-                               "Get port string error : %s.", e.what());\r
-                       throw -1;\r
-               }\r
-\r
-               endpoint_str = address + ":" + port;\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 10,\r
-                               "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                               "Get remote endpoint string END.");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-       } catch (int e) {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 11,\r
-                               "function : std::string sslproxy_session::get_remote_endpoint() : "\r
-                               "get_remote_endpoint() error.");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 12,\r
-                       "out_function : std::string sslproxy_session::get_remote_endpoint("\r
-                       "ssl_socket& socket) : "\r
-                       "return value = %s",\r
-                       endpoint_str.c_str());\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-       return endpoint_str;\r
-}\r
-\r
-/*!\r
- * Session start function.\r
- * Start async handshake and Set handshake timer\r
- */\r
-void sslproxy_session::start()\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 13,\r
-                       "in_function : void sslproxy_session::start(void)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-\r
-       // Output connection log. (info level)\r
-       if (conn_log_flag == "on") {\r
-               LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_CONNECTION, 1, \r
-                       "Connect from [%s] to [%s]. %s", \r
-                       get_remote_endpoint(client_socket).c_str(), \r
-                       target_endpoint.c_str(), target_id.c_str());\r
-       }\r
-\r
-       try {\r
-               if(sessionTable.end() != sessionTable.find((long)this)) {\r
-                       // Start async handshake and Set handshake handler.\r
-                       client_socket.async_handshake(boost::asio::ssl::stream_base::server,\r
-                                                     boost::bind(&sslproxy_session::handle_handshake,\r
-                                                                 this,\r
-                                                                 boost::asio::placeholders::error));\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 14,\r
-                                       "function : void sslproxy_session::start() : "\r
-                                       "async_handshake() registration END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-\r
-                       // Set handshake expire time.\r
-                       try {\r
-                               timer.expires_from_now(boost::posix_time::seconds(cancel_time));\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 15,\r
-                                               "function : void sslproxy_session::start() : "\r
-                                               "expires_from_now() END. "\r
-                                               "cancel_time = %d",\r
-                                               cancel_time);\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } catch (std::exception& e) {\r
-                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 5, \r
-                                       "Set handshake expire time error : %s.", e.what());\r
-                               throw -1;\r
-                       }\r
-\r
-                       // Start timer waiting and Set timer handler.\r
-                       timer.async_wait(boost::bind(&sslproxy_session::cancel,\r
-                                                    this,\r
-                                                    boost::asio::placeholders::error));\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 16,\r
-                                       "function : void sslproxy_session::start() : "\r
-                                       "async_wait() END.");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               }\r
-       } catch (...) {\r
-               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 6, \r
-                       "Exception occured in sslproxy_session::start().");\r
-               destroy_session(this);\r
-       }\r
-\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 17,\r
-                       "outfunction : void sslproxy_session::start(void)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-}\r
-\r
-/*!\r
- * Handshake timeout handler function.\r
- *\r
- * @param[in]  error   error code\r
- */\r
-void sslproxy_session::cancel(const boost::system::error_code& error)\r
-{\r
-       // Check session is not already delete.\r
-       if(sessionTable.end() != sessionTable.find((long)this)) {\r
-               // Check timout and finishing status.\r
-               if (istimeout || finishing) {\r
-                       destroy_session(this);\r
-               } else {\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 18,\r
-                                       "in_function : void sslproxy_session::cancel("\r
-                                       "const boost::system::error_code& error) : "\r
-                                       "error = %d, handshaked = %d",\r
-                                       error.value(), handshaked);\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-\r
-                       if (!error) {\r
-                               // Check session is not already delete.\r
-                               if(sessionTable.end() != sessionTable.find((long)this)) {\r
-                                       // Check handshaked.\r
-                                       if (!handshaked) {\r
-                                               // When handshake not finished then timer is timeout.\r
-                                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 7, \r
-                                                       "Handshake timer wait : %d giveup.", cancel_time);\r
-                                               istimeout = true;\r
-                                               client_socket.lowest_layer().cancel();\r
-                                       } else {\r
-                                               // When handshake finished then timer is diable.\r
-                                               /*-------- DEBUG LOG --------*/\r
-                                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 19,\r
-                                                               "function : void sslproxy_session::cancel() : "\r
-                                                               "Handshake timer is cancel.");\r
-                                               }\r
-                                               /*------ DEBUG LOG END ------*/\r
-                                       }\r
-                               }\r
-                       } else {\r
-                               if (error.value() == ECANCELED) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 1, \r
-                                               "Handshake timer operation cancel. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 8, \r
-                                               "Handshake timer wait NG : %s.",\r
-                                               error.message().c_str());\r
-                               }\r
-                       }\r
-\r
-                       /*-------- DEBUG LOG --------*/\r
-                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 20,\r
-                                       "out_function : void sslproxy_session::cancel("\r
-                                       "const boost::system::error_code& error)");\r
-                       }\r
-                       /*------ DEBUG LOG END ------*/\r
-               }\r
-       }\r
-}\r
-\r
-/*!\r
- * Session cache expire handler function.\r
- *\r
- * @param[in]  error   error code\r
- */\r
-void sslproxy_session::cache_expire(const boost::system::error_code& error)\r
-{\r
-       // Check session is not already delete.\r
-       if(sessionTable.end() != sessionTable.find((long)this)) {\r
-               if (!error) {\r
-                       // Server event remain.\r
-                       server_socket.cancel();\r
-               } else {\r
-                       if (error.value() == ECANCELED) {\r
-                               LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 8, \r
-                                       "Cache expire operation cancel. Normal END : %s.",\r
-                                       error.message().c_str());\r
-                       } else {\r
-                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 22, \r
-                                       "Cache expire wait NG : %s.",\r
-                                       error.message().c_str());\r
-                       }\r
-               }\r
-\r
-       }\r
-}\r
-\r
-/*!\r
- * Destroy session function.\r
- *\r
- * @param[in]  session session object\r
- */\r
-void sslproxy_session::destroy_session(sslproxy_session* session)\r
-{\r
-       /*-------- DEBUG LOG --------*/\r
-       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 21,\r
-                       "in_function : void sslproxy_session::destroy_session("\r
-                       "sslproxy_session* session)");\r
-       }\r
-       /*------ DEBUG LOG END ------*/\r
-\r
-       // Check session is not already delete.\r
-       if(sessionTable.end() != sessionTable.find((long)session)) {\r
-               finishing = true;\r
-               if (!c_r_event && !c_w_event && !s_r_event && !s_w_event) {\r
-                       // All event end.\r
-                       pthread_mutex_lock(&sessionTable_mutex);\r
-                       sessionTable.erase((long)session);\r
-                       pthread_mutex_unlock(&sessionTable_mutex);\r
-                       pthread_mutex_lock(&client_socket_mutex);\r
-                       delete session;\r
-               } else {\r
-                       // Event remain.\r
-                       if (c_r_event || c_w_event) {\r
-                               // Client event remain.\r
-                               if (!istimeout) {\r
-                                       client_socket.lowest_layer().cancel();\r
-                               }\r
-                       } else if (s_r_event || s_w_event) {\r
-                               // Server event remain.\r
-                               // Set expire time for session cache.\r
-                               cache_timer.expires_from_now(boost::posix_time::seconds(session_cache_timeout));\r
-                               cache_timer.async_wait(boost::bind(&sslproxy_session::cache_expire,\r
-                                                            this,\r
-                                                            boost::asio::placeholders::error));\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-/*!\r
- * Hnadshake handling function.\r
- * Check hendshake result and Start async connect.\r
- *\r
- * @param[in]  error   error code\r
- */\r
-void sslproxy_session::handle_handshake(const boost::system::error_code& error)\r
-{\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 22,\r
-                               "in_function : void sslproxy_session::handle_handshake("\r
-                               "const boost::system::error_code& error) : "\r
-                               "error = %d, istimeout = %d",\r
-                               error.value(), istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check handshake result.\r
-                       if (!error) {\r
-                               // Connect to server after handshake\r
-                               boost::asio::ip::tcp::resolver::iterator end;\r
-                               if (endpoint_iterator != end) {\r
-                                       // Start async connect\r
-                                       server_socket.async_connect(*endpoint_iterator++,\r
-                                                                   boost::bind(&sslproxy_session::handle_connect,\r
-                                                                               this,\r
-                                                                               boost::asio::placeholders::error));\r
-                                       /*-------- DEBUG LOG --------*/\r
-                                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 23,\r
-                                                       "function : void sslproxy_session::handle_handshake() : "\r
-                                                       "async_connect() registration END.");\r
-                                       }\r
-                                       /*------ DEBUG LOG END ------*/\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 9, \r
-                                               "Server endpoint is nothing for connect.");\r
-                                       destroy_session(this);\r
-                               }\r
-                       } else {\r
-                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 10, \r
-                                       "Handshaking NG : %s.",\r
-                                       error.message().c_str());\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 11, \r
-                               "Exception occured in sslproxy_session::handle_handshake().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 24,\r
-                               "out_function : void sslproxy_session::handle_handshake("\r
-                               "const boost::system::error_code& error)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Connect handling function.\r
- * Check connect result and Start async read client.\r
- *\r
- * @param[in]  error   error code\r
- */\r
-void sslproxy_session::handle_connect(const boost::system::error_code& error)\r
-{\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 25,\r
-                               "in_function : void sslproxy_session::handle_connect("\r
-                               "const boost::system::error_code& error) : "\r
-                               "error = %d, istimeout = %d",\r
-                               error.value(), istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check connect result.\r
-                       if (!error) {\r
-                               handshaked = true;\r
-                               timer.cancel();\r
-                               // Start async read client.\r
-                               c_r_event = true;\r
-                               pthread_mutex_lock(&client_socket_mutex);\r
-                               client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_BUFFER_SIZE),\r
-                                                             boost::bind(&sslproxy_session::handle_client_read,\r
-                                                                         this,\r
-                                                                         boost::asio::placeholders::error,\r
-                                                                         boost::asio::placeholders::bytes_transferred));\r
-                               pthread_mutex_unlock(&client_socket_mutex);\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 26,\r
-                                               "function : void sslproxy_session::handle_connect() : "\r
-                                               "Client async_read_some() registration END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-\r
-                               // Start async read server.\r
-                               s_r_event = true;\r
-                               server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_BUFFER_SIZE),\r
-                                                             boost::bind(&sslproxy_session::handle_server_read,\r
-                                                                         this,\r
-                                                                         boost::asio::placeholders::error,\r
-                                                                         boost::asio::placeholders::bytes_transferred));\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 27,\r
-                                               "function : void sslproxy_session::handle_connect() : "\r
-                                               "Server async_read_some() registration END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               boost::asio::ip::tcp::resolver::iterator end;\r
-                               if (endpoint_iterator != end) {\r
-                                       // Retry connect to server\r
-                                       LOGGER_PUT_LOG_WARN(LOG_CAT_SSLPROXY_SESSION, 1, \r
-                                               "Connecting NG : %s. Retry connect.",\r
-                                               error.message().c_str());\r
-                                       server_socket.async_connect(*endpoint_iterator++,\r
-                                                                   boost::bind(&sslproxy_session::handle_connect,\r
-                                                                               this,\r
-                                                                               boost::asio::placeholders::error));\r
-                                       /*-------- DEBUG LOG --------*/\r
-                                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 28,\r
-                                                       "function : void sslproxy_session::handle_connect() : "\r
-                                                       "async_connect() retry registration END.");\r
-                                       }\r
-                                       /*------ DEBUG LOG END ------*/\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 12, \r
-                                               "Connecting NG : %s.",\r
-                                               error.message().c_str());\r
-                                       destroy_session(this);\r
-                               }\r
-                       }\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 13, \r
-                               "Exception occured in void sslproxy_session::handle_connect().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 29,\r
-                               "out_function : void sslproxy_session::handle_connect("\r
-                               "const boost::system::error_code& error)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Client read handling function.\r
- * Check client read result and Start async write server.\r
- *\r
- * @param[in]  error                   error code\r
- * @param[in]  bytes_transferred       transferred data size\r
- */\r
-void sslproxy_session::handle_client_read(const boost::system::error_code& error,\r
-                                         size_t bytes_transferred)\r
-{\r
-       c_r_event = false;\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 30,\r
-                               "in_function : void sslproxy_session::handle_client_read("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred) : "\r
-                               "error = %d, bytes_transferred = %d, istimeout = %d",\r
-                               error.value(), (int)bytes_transferred, istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check client read result.\r
-                       if (!error) {\r
-                               // Start async write server.\r
-                               s_w_event = true;\r
-                               boost::asio::async_write(server_socket,\r
-                                                        boost::asio::buffer(client_buffer, bytes_transferred),\r
-                                                        boost::bind(&sslproxy_session::handle_server_write,\r
-                                                                    this,\r
-                                                                    boost::asio::placeholders::error,\r
-                                                                    bytes_transferred));\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 31,\r
-                                               "function : void sslproxy_session::handle_client_read() : "\r
-                                               "Server async_write() registration END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               if (error.value() == boost::asio::error::eof) {\r
-                                       // When End of file. Client data read complete.\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 2, \r
-                                               "Client data read complete. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else if (error.value() == boost::asio::error::shut_down) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 3, \r
-                                               "Client already shutdown. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else if (error.value() == boost::asio::error::operation_aborted) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 4, \r
-                                               "Client read operation canceled. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 14, \r
-                                               "Client read NG : %s.",\r
-                                               error.message().c_str());\r
-                               }\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 15, \r
-                               "Exception occured in void sslproxy_session::handle_client_read().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 32,\r
-                               "out_function : void sslproxy_session::handle_client_read("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Server write handling function.\r
- * Check server write result and Start async read server.\r
- *\r
- * @param[in]  error                   error code\r
- * @param[in]  bytes_transferred       transferred data size\r
- */\r
-void sslproxy_session::handle_server_write(const boost::system::error_code& error,\r
-                                          size_t bytes_transferred)\r
-{\r
-       s_w_event = false;\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 33,\r
-                               "in_function : void sslproxy_session::handle_server_write("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred) : "\r
-                               "error = %d, bytes_transferred = %d, istimeout = %d",\r
-                               error.value(), (int)bytes_transferred, istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check server write result.\r
-                       if (!error) {\r
-                               // Next client data wait, start async read client again.\r
-                               c_r_event = true;\r
-                               pthread_mutex_lock(&client_socket_mutex);\r
-                               client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_BUFFER_SIZE),\r
-                                                             boost::bind(&sslproxy_session::handle_client_read,\r
-                                                                         this,\r
-                                                                         boost::asio::placeholders::error,\r
-                                                                         boost::asio::placeholders::bytes_transferred));\r
-                               pthread_mutex_unlock(&client_socket_mutex);\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 34,\r
-                                               "function : void sslproxy_session::handle_server_write() : "\r
-                                               "Client async_read_some() registration again END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 16, \r
-                                       "Server write NG : %s.",\r
-                                       error.message().c_str());\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 17, \r
-                               "Exception occured in void sslproxy_session::handle_server_write().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 35,\r
-                               "out_function : void sslproxy_session::handle_server_write("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Server read handling function.\r
- * Check server read result and Start async write client.\r
- *\r
- * @param[in]  error                   error code\r
- * @param[in]  bytes_transferred       transferred data size\r
- */\r
-void sslproxy_session::handle_server_read(const boost::system::error_code& error,\r
-                                         size_t bytes_transferred)\r
-{\r
-       s_r_event = false;\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 36,\r
-                               "in_function : void sslproxy_session::handle_server_read("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred) : "\r
-                               "error = %d, bytes_transferred = %d, istimeout = %d",\r
-                               error.value(), (int)bytes_transferred, istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check server read result.\r
-                       if (!error) {\r
-                               // Start async write client.\r
-                               c_w_event = true;\r
-                               pthread_mutex_lock(&client_socket_mutex);\r
-                               boost::asio::async_write(client_socket,\r
-                                                        boost::asio::buffer(server_buffer, bytes_transferred),\r
-                                                        boost::bind(&sslproxy_session::handle_client_write,\r
-                                                                    this,\r
-                                                                    boost::asio::placeholders::error,\r
-                                                                    bytes_transferred));\r
-                               pthread_mutex_unlock(&client_socket_mutex);\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 37,\r
-                                               "function : void sslproxy_session::handle_server_read() : "\r
-                                               "Client async_write() registration END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               if (error.value() == boost::asio::error::eof) {\r
-                                       // When End of file. Server data read complete.\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 5, \r
-                                               "Server data read complete. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 18, \r
-                                               "Server read NG : %s.",\r
-                                               error.message().c_str());\r
-                               }\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 19, \r
-                               "Exception occured in void sslproxy_session::handle_server_read().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 38,\r
-                               "out_function : void sslproxy_session::handle_server_read("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
-\r
-/*!\r
- * Client write handling function.\r
- * Check client write result and Start async read client.\r
- *\r
- * @param[in]  error                   error code\r
- * @param[in]  bytes_transferred       transferred data size\r
- */\r
-void sslproxy_session::handle_client_write(const boost::system::error_code& error,\r
-                                          size_t bytes_transferred)\r
-{\r
-       c_w_event = false;\r
-       // Check timout and finishing status.\r
-       if (istimeout || finishing) {\r
-               destroy_session(this);\r
-       } else {\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 39,\r
-                               "in_function : void sslproxy_session::handle_client_write("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred) : "\r
-                               "error = %d, bytes_transferred = %d, istimeout = %d",\r
-                               error.value(), (int)bytes_transferred, istimeout);\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-\r
-               try {\r
-                       // Check client write result.\r
-                       if (!error) {\r
-                               // Next server data wait, start async read server again.\r
-                               s_r_event = true;\r
-                               server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_BUFFER_SIZE),\r
-                                                             boost::bind(&sslproxy_session::handle_server_read,\r
-                                                                         this,\r
-                                                                         boost::asio::placeholders::error,\r
-                                                                         boost::asio::placeholders::bytes_transferred));\r
-                               /*-------- DEBUG LOG --------*/\r
-                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 40,\r
-                                               "function : void sslproxy_session::handle_client_write() : "\r
-                                               "Server async_read_some() registration again END.");\r
-                               }\r
-                               /*------ DEBUG LOG END ------*/\r
-                       } else {\r
-                               if (error.value() == boost::asio::error::connection_reset) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 6, \r
-                                               "Reset connection. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else if (error.value() == boost::asio::error::broken_pipe) {\r
-                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 7, \r
-                                               "Pipe broken. Normal END : %s.",\r
-                                               error.message().c_str());\r
-                               } else {\r
-                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 20, \r
-                                               "Client write NG : %s.",\r
-                                               error.message().c_str());\r
-                               }\r
-                               destroy_session(this);\r
-                       }\r
-\r
-               } catch (...) {\r
-                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 21, \r
-                               "Exception occured in void sslproxy_session::handle_client_write().");\r
-                       destroy_session(this);\r
-               }\r
-\r
-               /*-------- DEBUG LOG --------*/\r
-               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {\r
-                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 41,\r
-                               "out_function : void sslproxy_session::handle_client_write("\r
-                               "const boost::system::error_code& error, "\r
-                               "size_t bytes_transferred)");\r
-               }\r
-               /*------ DEBUG LOG END ------*/\r
-       }\r
-}\r
+/*
+ * @file  sslproxysession.cpp
+ * @brief module of SSLproxy_session
+ * @brief SSL handshaking and Connecting.
+ * @brief Client and Server data read/write.
+ *
+ * Copyright (C) 2008  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
+ *
+ **********************************************************************
+ *
+ * Distributed under the Boost Software Licence, Version 1.0
+ * http://www.boost.org/LICENSE_1_0.txt
+ *
+ **********************************************************************/
+
+#include <sys/syscall.h>       // for SYS_gettid
+#include <boost/lexical_cast.hpp>
+
+#include "sslproxyserver.h"
+#include "sslproxysession.h"
+#include "packet_editor.h"
+#include "http_message.h"
+#include "http_request.h"
+#include "http_response.h"
+
+// sslproxy_session constructor
+/*!
+ * SSLproxy_session constructor.
+ *
+ * @param[in]  io_service      IO event dispatcher
+ * @param[in]  context         SSL context
+ * @param[in]  itr             endpoint iterator
+ */
+sslproxy_session::sslproxy_session(boost::asio::io_service& ioservice,
+                                  boost::asio::ssl::context& context,
+                                  boost::asio::ip::tcp::resolver::iterator itr)
+                                  :
+                                  server_socket(ioservice),
+                                  client_socket(ioservice, context),
+                                  endpoint_iterator(itr),
+                                  timer(ioservice),
+                                  cancel_time(timeout_sec),
+                                  handshaked(false),
+                                  istimeout(false),
+                                  c_r_event(false),
+                                  c_w_event(false),
+                                  s_r_event(false),
+                                  s_w_event(false),
+                                  finishing(false),
+                                  cache_timer(ioservice)
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 1,
+                       "in/out_function : Constructor sslproxy_session::sslproxy_session("
+                       "boost::asio::io_service& ioservice, "
+                       "boost::asio::ssl::context& context, "
+                       "boost::asio::ip::tcp::resolver::iterator itr)");
+       }
+       /*------ DEBUG LOG END ------*/
+       pthread_mutex_init(&client_socket_mutex, NULL);
+}
+
+/*!
+ * SSLproxy_session destructor.
+ */
+sslproxy_session::~sslproxy_session()
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 2,
+                       "in/out_function : Destructor sslproxy_session::~sslproxy_session("
+                       "void)");
+       }
+       /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Low level socket getting function.
+ *
+ * @return     password string
+ * @retval     ssl_socket::lowest_layer_type&
+ */
+ssl_socket::lowest_layer_type& sslproxy_session::low_socket()
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 3,
+                       "in_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("
+                       "void)");
+       }
+       /*------ DEBUG LOG END ------*/
+
+       try {
+               ssl_socket::lowest_layer_type& sock = client_socket.lowest_layer();
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 4,
+                               "function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket() : "
+                               "lowest_layer() END.");
+               }
+               /*------ DEBUG LOG END ------*/
+       
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 5,
+                               "out_function : ssl_socket::lowest_layer_type& sslproxy_session::low_socket("
+                               "void)");
+               }
+               /*------ DEBUG LOG END ------*/
+               return sock;
+       } catch (std::exception& e) {
+               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 1, 
+                       "Get low level socket error : %s.", e.what());
+               throw -1;
+       }
+}
+
+/*!
+ * Get remote endpoint string.
+ * get client address:port from SSL socket
+ *
+ * @param[in]  socket  client SSL socket
+ * @return     endpoint string
+ */
+std::string sslproxy_session::get_remote_endpoint() const
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 6,
+                       "in_function : std::string sslproxy_session::get_remote_endpoint("
+                       "ssl_socket& socket)");
+       }
+       /*------ DEBUG LOG END ------*/
+
+       std::string endpoint_str = "";
+       boost::asio::ip::tcp::endpoint endpoint;
+       std::string address;
+       std::string port;
+
+       try {
+               try {
+                       endpoint = client_socket.lowest_layer().remote_endpoint();
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 7,
+                                       "function : std::string sslproxy_session::get_remote_endpoint() : "
+                                       "lowest_layer().remote_endpoint() END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               } catch (std::exception& e) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 2, 
+                               "Get remote endpoint from socket error : %s.", e.what());
+                       throw -1;
+               }
+
+               try {
+                       address = endpoint.address().to_string();
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 8,
+                                       "function : std::string sslproxy_session::get_remote_endpoint() : "
+                                       "address().to_string() END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               } catch (std::exception& e) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 3, 
+                               "Get address string error : %s.", e.what());
+                       throw -1;
+               }
+
+               try {
+                       port = boost::lexical_cast<std::string>(endpoint.port());
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 9,
+                                       "function : std::string sslproxy_session::get_remote_endpoint() : "
+                                       "lexical_cast(port()) END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               } catch (std::exception& e) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 4, 
+                               "Get port string error : %s.", e.what());
+                       throw -1;
+               }
+
+               endpoint_str = address + ":" + port;
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 10,
+                               "function : std::string sslproxy_session::get_remote_endpoint() : "
+                               "Get remote endpoint string END.");
+               }
+               /*------ DEBUG LOG END ------*/
+
+       } catch (int e) {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 11,
+                               "function : std::string sslproxy_session::get_remote_endpoint() : "
+                               "get_remote_endpoint() error.");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 12,
+                       "out_function : std::string sslproxy_session::get_remote_endpoint("
+                       "ssl_socket& socket) : "
+                       "return value = %s",
+                       endpoint_str.c_str());
+       }
+       /*------ DEBUG LOG END ------*/
+       return endpoint_str;
+}
+
+/*!
+ * Session start function.
+ * Start async handshake and Set handshake timer
+ */
+void sslproxy_session::start()
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 13,
+                       "in_function : void sslproxy_session::start(void)");
+       }
+       /*------ DEBUG LOG END ------*/
+
+       // Output connection log. (info level)
+       if (conn_log_flag == "on") {
+               LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_CONNECTION, 1, 
+                       "Connect from [%s] to [%s]. %s", 
+                       get_remote_endpoint().c_str(), 
+                       target_endpoint.c_str(), target_id.c_str());
+       }
+
+       try {
+               if(sessionTable.end() != sessionTable.find((long)this)) {
+                       // Start async handshake and Set handshake handler.
+                       client_socket.async_handshake(boost::asio::ssl::stream_base::server,
+                                                     boost::bind(&sslproxy_session::handle_handshake,
+                                                                 this,
+                                                                 boost::asio::placeholders::error));
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 14,
+                                       "function : void sslproxy_session::start() : "
+                                       "async_handshake() registration END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+
+                       // Set handshake expire time.
+                       try {
+                               timer.expires_from_now(boost::posix_time::seconds(cancel_time));
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 15,
+                                               "function : void sslproxy_session::start() : "
+                                               "expires_from_now() END. "
+                                               "cancel_time = %d",
+                                               cancel_time);
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } catch (std::exception& e) {
+                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 5, 
+                                       "Set handshake expire time error : %s.", e.what());
+                               throw -1;
+                       }
+
+                       // Start timer waiting and Set timer handler.
+                       timer.async_wait(boost::bind(&sslproxy_session::cancel,
+                                                    this,
+                                                    boost::asio::placeholders::error));
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 16,
+                                       "function : void sslproxy_session::start() : "
+                                       "async_wait() END.");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               }
+       } catch (...) {
+               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 6, 
+                       "Exception occured in sslproxy_session::start().");
+               destroy_session(this);
+       }
+
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 17,
+                       "outfunction : void sslproxy_session::start(void)");
+       }
+       /*------ DEBUG LOG END ------*/
+}
+
+/*!
+ * Handshake timeout handler function.
+ *
+ * @param[in]  error   error code
+ */
+void sslproxy_session::cancel(const boost::system::error_code& error)
+{
+       // Check session is not already delete.
+       if(sessionTable.end() != sessionTable.find((long)this)) {
+               // Check timout and finishing status.
+               if (istimeout || finishing) {
+                       destroy_session(this);
+               } else {
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 18,
+                                       "in_function : void sslproxy_session::cancel("
+                                       "const boost::system::error_code& error) : "
+                                       "error = %d, handshaked = %d",
+                                       error.value(), handshaked);
+                       }
+                       /*------ DEBUG LOG END ------*/
+
+                       if (!error) {
+                               // Check session is not already delete.
+                               if(sessionTable.end() != sessionTable.find((long)this)) {
+                                       // Check handshaked.
+                                       if (!handshaked) {
+                                               // When handshake not finished then timer is timeout.
+                                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 7, 
+                                                       "Handshake timer wait : %d giveup.", cancel_time);
+                                               istimeout = true;
+                                               client_socket.lowest_layer().cancel();
+                                       } else {
+                                               // When handshake finished then timer is diable.
+                                               /*-------- DEBUG LOG --------*/
+                                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 19,
+                                                               "function : void sslproxy_session::cancel() : "
+                                                               "Handshake timer is cancel.");
+                                               }
+                                               /*------ DEBUG LOG END ------*/
+                                       }
+                               }
+                       } else {
+                               if (error.value() == ECANCELED) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 1, 
+                                               "Handshake timer operation cancel. Normal END : %s.",
+                                               error.message().c_str());
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 8, 
+                                               "Handshake timer wait NG : %s.",
+                                               error.message().c_str());
+                               }
+                       }
+
+                       /*-------- DEBUG LOG --------*/
+                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 20,
+                                       "out_function : void sslproxy_session::cancel("
+                                       "const boost::system::error_code& error)");
+                       }
+                       /*------ DEBUG LOG END ------*/
+               }
+       }
+}
+
+/*!
+ * Session cache expire handler function.
+ *
+ * @param[in]  error   error code
+ */
+void sslproxy_session::cache_expire(const boost::system::error_code& error)
+{
+       // Check session is not already delete.
+       if(sessionTable.end() != sessionTable.find((long)this)) {
+               if (!error) {
+                       // Server event remain.
+                       server_socket.cancel();
+               } else {
+                       if (error.value() == ECANCELED) {
+                               LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 8, 
+                                       "Cache expire operation cancel. Normal END : %s.",
+                                       error.message().c_str());
+                       } else {
+                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 22, 
+                                       "Cache expire wait NG : %s.",
+                                       error.message().c_str());
+                       }
+               }
+
+       }
+}
+
+/*!
+ * Destroy session function.
+ *
+ * @param[in]  session session object
+ */
+void sslproxy_session::destroy_session(sslproxy_session* session)
+{
+       /*-------- DEBUG LOG --------*/
+       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 21,
+                       "in_function : void sslproxy_session::destroy_session("
+                       "sslproxy_session* session)");
+       }
+       /*------ DEBUG LOG END ------*/
+
+       // Check session is not already delete.
+       if(sessionTable.end() != sessionTable.find((long)session)) {
+               finishing = true;
+               if (!c_r_event && !c_w_event && !s_r_event && !s_w_event) {
+                       // All event end.
+                       pthread_mutex_lock(&sessionTable_mutex);
+                       sessionTable.erase((long)session);
+                       pthread_mutex_unlock(&sessionTable_mutex);
+                       pthread_mutex_lock(&client_socket_mutex);
+                       delete session;
+               } else {
+                       // Event remain.
+                       if (c_r_event || c_w_event) {
+                               // Client event remain.
+                               if (!istimeout) {
+                                       client_socket.lowest_layer().cancel();
+                               }
+                       } else if (s_r_event || s_w_event) {
+                               // Server event remain.
+                               // Set expire time for session cache.
+                               cache_timer.expires_from_now(boost::posix_time::seconds(session_cache_timeout));
+                               cache_timer.async_wait(boost::bind(&sslproxy_session::cache_expire,
+                                                            this,
+                                                            boost::asio::placeholders::error));
+                       }
+               }
+       }
+}
+
+/*!
+ * Hnadshake handling function.
+ * Check hendshake result and Start async connect.
+ *
+ * @param[in]  error   error code
+ */
+void sslproxy_session::handle_handshake(const boost::system::error_code& error)
+{
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 22,
+                               "in_function : void sslproxy_session::handle_handshake("
+                               "const boost::system::error_code& error) : "
+                               "error = %d, istimeout = %d",
+                               error.value(), istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check handshake result.
+                       if (!error) {
+                               // Connect to server after handshake
+                               boost::asio::ip::tcp::resolver::iterator end;
+                               if (endpoint_iterator != end) {
+                                       // Start async connect
+                                       server_socket.async_connect(*endpoint_iterator++,
+                                                                   boost::bind(&sslproxy_session::handle_connect,
+                                                                               this,
+                                                                               boost::asio::placeholders::error));
+                                       /*-------- DEBUG LOG --------*/
+                                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 23,
+                                                       "function : void sslproxy_session::handle_handshake() : "
+                                                       "async_connect() registration END.");
+                                       }
+                                       /*------ DEBUG LOG END ------*/
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 9, 
+                                               "Server endpoint is nothing for connect.");
+                                       destroy_session(this);
+                               }
+                       } else {
+                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 10, 
+                                       "Handshaking NG : %s.",
+                                       error.message().c_str());
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 11, 
+                               "Exception occured in sslproxy_session::handle_handshake().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 24,
+                               "out_function : void sslproxy_session::handle_handshake("
+                               "const boost::system::error_code& error)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Connect handling function.
+ * Check connect result and Start async read client.
+ *
+ * @param[in]  error   error code
+ */
+void sslproxy_session::handle_connect(const boost::system::error_code& error)
+{
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 25,
+                               "in_function : void sslproxy_session::handle_connect("
+                               "const boost::system::error_code& error) : "
+                               "error = %d, istimeout = %d",
+                               error.value(), istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check connect result.
+                       if (!error) {
+                               handshaked = true;
+                               timer.cancel();
+                               // Start async read client.
+                               c_r_event = true;
+                               pthread_mutex_lock(&client_socket_mutex);
+                               client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_READ_SIZE),
+                                                             boost::bind(&sslproxy_session::handle_client_read,
+                                                                         this,
+                                                                         boost::asio::placeholders::error,
+                                                                         boost::asio::placeholders::bytes_transferred));
+                               pthread_mutex_unlock(&client_socket_mutex);
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 26,
+                                               "function : void sslproxy_session::handle_connect() : "
+                                               "Client async_read_some() registration END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+
+                               // Start async read server.
+                               s_r_event = true;
+                               server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_READ_SIZE),
+                                                             boost::bind(&sslproxy_session::handle_server_read,
+                                                                         this,
+                                                                         boost::asio::placeholders::error,
+                                                                         boost::asio::placeholders::bytes_transferred));
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 27,
+                                               "function : void sslproxy_session::handle_connect() : "
+                                               "Server async_read_some() registration END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               boost::asio::ip::tcp::resolver::iterator end;
+                               if (endpoint_iterator != end) {
+                                       // Retry connect to server
+                                       LOGGER_PUT_LOG_WARN(LOG_CAT_SSLPROXY_SESSION, 1, 
+                                               "Connecting NG : %s. Retry connect.",
+                                               error.message().c_str());
+                                       server_socket.async_connect(*endpoint_iterator++,
+                                                                   boost::bind(&sslproxy_session::handle_connect,
+                                                                               this,
+                                                                               boost::asio::placeholders::error));
+                                       /*-------- DEBUG LOG --------*/
+                                       if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                               LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 28,
+                                                       "function : void sslproxy_session::handle_connect() : "
+                                                       "async_connect() retry registration END.");
+                                       }
+                                       /*------ DEBUG LOG END ------*/
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 12, 
+                                               "Connecting NG : %s.",
+                                               error.message().c_str());
+                                       destroy_session(this);
+                               }
+                       }
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 13, 
+                               "Exception occured in void sslproxy_session::handle_connect().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 29,
+                               "out_function : void sslproxy_session::handle_connect("
+                               "const boost::system::error_code& error)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Client read handling function.
+ * Check client read result and Start async write server.
+ *
+ * @param[in]  error                   error code
+ * @param[in]  bytes_transferred       transferred data size
+ */
+void sslproxy_session::handle_client_read(const boost::system::error_code& error,
+                                         size_t bytes_transferred)
+{
+       c_r_event = false;
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 30,
+                               "in_function : void sslproxy_session::handle_client_read("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred) : "
+                               "error = %d, bytes_transferred = %d, istimeout = %d",
+                               error.value(), (int)bytes_transferred, istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check client read result.
+                       if (!error) {
+                               // Edit client message if necessary.
+                               if (::client_packet_edit)
+                                       edit_client_message(bytes_transferred);
+                               // Start async write server.
+                               s_w_event = true;
+                               boost::asio::async_write(server_socket,
+                                                        boost::asio::buffer(client_buffer, bytes_transferred),
+                                                        boost::bind(&sslproxy_session::handle_server_write,
+                                                                    this,
+                                                                    boost::asio::placeholders::error,
+                                                                    bytes_transferred));
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 31,
+                                               "function : void sslproxy_session::handle_client_read() : "
+                                               "Server async_write() registration END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               if (error.value() == boost::asio::error::eof) {
+                                       // When End of file. Client data read complete.
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 2, 
+                                               "Client data read complete. Normal END : %s.",
+                                               error.message().c_str());
+                               } else if (error.value() == boost::asio::error::shut_down) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 3, 
+                                               "Client already shutdown. Normal END : %s.",
+                                               error.message().c_str());
+                               } else if (error.value() == boost::asio::error::operation_aborted) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 4, 
+                                               "Client read operation canceled. Normal END : %s.",
+                                               error.message().c_str());
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 14, 
+                                               "Client read NG : %s.",
+                                               error.message().c_str());
+                               }
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 15, 
+                               "Exception occured in void sslproxy_session::handle_client_read().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 32,
+                               "out_function : void sslproxy_session::handle_client_read("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Server write handling function.
+ * Check server write result and Start async read server.
+ *
+ * @param[in]  error                   error code
+ * @param[in]  bytes_transferred       transferred data size
+ */
+void sslproxy_session::handle_server_write(const boost::system::error_code& error,
+                                          size_t bytes_transferred)
+{
+       s_w_event = false;
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 33,
+                               "in_function : void sslproxy_session::handle_server_write("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred) : "
+                               "error = %d, bytes_transferred = %d, istimeout = %d",
+                               error.value(), (int)bytes_transferred, istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check server write result.
+                       if (!error) {
+                               // Next client data wait, start async read client again.
+                               c_r_event = true;
+                               pthread_mutex_lock(&client_socket_mutex);
+                               client_socket.async_read_some(boost::asio::buffer(client_buffer, MAX_READ_SIZE),
+                                                             boost::bind(&sslproxy_session::handle_client_read,
+                                                                         this,
+                                                                         boost::asio::placeholders::error,
+                                                                         boost::asio::placeholders::bytes_transferred));
+                               pthread_mutex_unlock(&client_socket_mutex);
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 34,
+                                               "function : void sslproxy_session::handle_server_write() : "
+                                               "Client async_read_some() registration again END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 16, 
+                                       "Server write NG : %s.",
+                                       error.message().c_str());
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 17, 
+                               "Exception occured in void sslproxy_session::handle_server_write().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 35,
+                               "out_function : void sslproxy_session::handle_server_write("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Server read handling function.
+ * Check server read result and Start async write client.
+ *
+ * @param[in]  error                   error code
+ * @param[in]  bytes_transferred       transferred data size
+ */
+void sslproxy_session::handle_server_read(const boost::system::error_code& error,
+                                         size_t bytes_transferred)
+{
+       s_r_event = false;
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 36,
+                               "in_function : void sslproxy_session::handle_server_read("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred) : "
+                               "error = %d, bytes_transferred = %d, istimeout = %d",
+                               error.value(), (int)bytes_transferred, istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check server read result.
+                       if (!error) {
+                               // Edit client message if necessary.
+                               if (::server_packet_edit)
+                                       edit_server_message(bytes_transferred);
+                               // Start async write client.
+                               c_w_event = true;
+                               pthread_mutex_lock(&client_socket_mutex);
+                               boost::asio::async_write(client_socket,
+                                                        boost::asio::buffer(server_buffer, bytes_transferred),
+                                                        boost::bind(&sslproxy_session::handle_client_write,
+                                                                    this,
+                                                                    boost::asio::placeholders::error,
+                                                                    bytes_transferred));
+                               pthread_mutex_unlock(&client_socket_mutex);
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 37,
+                                               "function : void sslproxy_session::handle_server_read() : "
+                                               "Client async_write() registration END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               if (error.value() == boost::asio::error::eof) {
+                                       // When End of file. Server data read complete.
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 5, 
+                                               "Server data read complete. Normal END : %s.",
+                                               error.message().c_str());
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 18, 
+                                               "Server read NG : %s.",
+                                               error.message().c_str());
+                               }
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 19, 
+                               "Exception occured in void sslproxy_session::handle_server_read().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 38,
+                               "out_function : void sslproxy_session::handle_server_read("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Client write handling function.
+ * Check client write result and Start async read client.
+ *
+ * @param[in]  error                   error code
+ * @param[in]  bytes_transferred       transferred data size
+ */
+void sslproxy_session::handle_client_write(const boost::system::error_code& error,
+                                          size_t bytes_transferred)
+{
+       c_w_event = false;
+       // Check timout and finishing status.
+       if (istimeout || finishing) {
+               destroy_session(this);
+       } else {
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 39,
+                               "in_function : void sslproxy_session::handle_client_write("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred) : "
+                               "error = %d, bytes_transferred = %d, istimeout = %d",
+                               error.value(), (int)bytes_transferred, istimeout);
+               }
+               /*------ DEBUG LOG END ------*/
+
+               try {
+                       // Check client write result.
+                       if (!error) {
+                               // Next server data wait, start async read server again.
+                               s_r_event = true;
+                               server_socket.async_read_some(boost::asio::buffer(server_buffer, MAX_READ_SIZE),
+                                                             boost::bind(&sslproxy_session::handle_server_read,
+                                                                         this,
+                                                                         boost::asio::placeholders::error,
+                                                                         boost::asio::placeholders::bytes_transferred));
+                               /*-------- DEBUG LOG --------*/
+                               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 40,
+                                               "function : void sslproxy_session::handle_client_write() : "
+                                               "Server async_read_some() registration again END.");
+                               }
+                               /*------ DEBUG LOG END ------*/
+                       } else {
+                               if (error.value() == boost::asio::error::connection_reset) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 6, 
+                                               "Reset connection. Normal END : %s.",
+                                               error.message().c_str());
+                               } else if (error.value() == boost::asio::error::broken_pipe) {
+                                       LOGGER_PUT_LOG_INFO(LOG_CAT_SSLPROXY_SESSION, 7, 
+                                               "Pipe broken. Normal END : %s.",
+                                               error.message().c_str());
+                               } else {
+                                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 20, 
+                                               "Client write NG : %s.",
+                                               error.message().c_str());
+                               }
+                               destroy_session(this);
+                       }
+
+               } catch (...) {
+                       LOGGER_PUT_LOG_ERROR(LOG_CAT_SSLPROXY_SESSION, 21, 
+                               "Exception occured in void sslproxy_session::handle_client_write().");
+                       destroy_session(this);
+               }
+
+               /*-------- DEBUG LOG --------*/
+               if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_SSLPROXY_SESSION)) {
+                       LOGGER_PUT_LOG_DEBUG(LOG_CAT_SSLPROXY_SESSION, 41,
+                               "out_function : void sslproxy_session::handle_client_write("
+                               "const boost::system::error_code& error, "
+                               "size_t bytes_transferred)");
+               }
+               /*------ DEBUG LOG END ------*/
+       }
+}
+
+/*!
+ * Edit client message function.
+ * Add, delete or change client message.
+ *
+ * @param[in,out]      bytes_transferred       transferred data size before,after edit
+ */
+void sslproxy_session::edit_client_message(size_t& bytes_transferred)
+{
+    packet_editor editor(this);
+    editor.edit_client(client_buffer, bytes_transferred);
+}
+
+/*!
+ * Edit server message function.
+ * Add, delete or change server message.
+ *
+ * @param[in,out]      bytes_transferred       transferred data size before,after edit
+ */
+void sslproxy_session::edit_server_message(size_t& bytes_transferred)
+{
+    packet_editor editor(this);
+    editor.edit_server(server_buffer, bytes_transferred);
+}