OSDN Git Service

formatted all files with 'astyle -A8 -HUpc -k3 -z2 -r ./*.cpp ./*.c ./*.h'
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / module / protocol / protocol_module_ip.cpp
1 /*
2  * @file  protocol_module_ip.cpp
3  * @brief protocol module of any protocol.
4  * @brief this module never keep session persistence.
5  *
6  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
7  * Copyright (C) 2009  NTT COMWARE Corporation.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  *
24  **********************************************************************/
25
26 #include <vector>
27 #include <list>
28 #include <algorithm>
29 #include <iostream>
30 #include <boost/asio/ip/tcp.hpp>
31 #include <boost/format.hpp>
32 #include <boost/xpressive/xpressive.hpp>
33 #include "protocol_module_ip.h"
34 #include "http_utility.h"
35 #include "utility.h"
36
37 namespace l7vs
38 {
39
40 const std::string protocol_module_ip::MODULE_NAME = "ip";
41 const int protocol_module_ip::THREAD_DIVISION_UP_STREAM = 0;
42 const int protocol_module_ip::THREAD_DIVISION_DOWN_STREAM = 1;
43
44 const int protocol_module_ip::END_FLAG_OFF = 0;
45 const int protocol_module_ip::END_FLAG_ON = 1;
46
47 const int protocol_module_ip::ACCEPT_END_FLAG_OFF = 0;
48 const int protocol_module_ip::ACCEPT_END_FLAG_ON = 1;
49
50 const int protocol_module_ip::SORRY_FLAG_ON = 1;
51 const int protocol_module_ip::SORRY_FLAG_OFF = 0;
52
53 const int protocol_module_ip::SWITCH_FLAG_OFF = 0;
54 const int protocol_module_ip::SWITCH_FLAG_ON = 1;
55
56 const int protocol_module_ip::FORWARDED_FOR_OFF = 0;
57 const int protocol_module_ip::FORWARDED_FOR_ON = 1;
58
59 using namespace boost::xpressive;
60 //! constractor
61 protocol_module_ip::protocol_module_ip() :
62         ip_protocol_module_base(MODULE_NAME), forwarded_for(FORWARDED_FOR_OFF)
63 {
64         sorry_uri.assign('\0');
65         sorry_uri[0] = '/';
66 }
67 //! destractor
68 protocol_module_ip::~protocol_module_ip()
69 {
70 }
71 //! tcp protocol support check
72 //! @return tcp support is true
73 //! @return tcp not-support is false
74 bool protocol_module_ip::is_tcp()
75 {
76         /*-------- DEBUG LOG --------*/
77         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
78                 putLogDebug(600000, "in/out_function : bool protocol_module_ip::is_tcp() : return_value = true.",
79                             __FILE__, __LINE__);
80         }
81         /*------DEBUG LOG END------*/
82         return true;
83 }
84
85 //! udp protocol support check
86 //! @return udp support is true
87 //! @return udp not-support is false
88 bool protocol_module_ip::is_udp()
89 {
90         /*-------- DEBUG LOG --------*/
91         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
92                 putLogDebug(600001, "in/out_function : bool protocol_module_ip::is_udp() : return_value = false.",
93                             __FILE__, __LINE__);
94         }
95         /*------DEBUG LOG END------*/
96         return false;
97 }
98
99 //! replication interval interrrupt
100 //! timer thread call this function. from virtualservice.
101 void protocol_module_ip::replication_interrupt()
102 {
103         /*-------- DEBUG LOG --------*/
104         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
105                 putLogDebug(600002, "in_function : protocol_module_ip::replication_interrupt().", __FILE__, __LINE__);
106         }
107         /*------DEBUG LOG END------*/
108         if (replication_data_processor) {
109                 replication_data_processor->write_replication_area();
110                 /*-------- DEBUG LOG --------*/
111                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
112                         putLogDebug(600003, "function : protocol_module_ip::replication_interrupt() : "
113                                     "write_replication_area() end.", __FILE__, __LINE__);
114                 }
115                 /*------DEBUG LOG END------*/
116         }
117         /*-------- DEBUG LOG --------*/
118         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
119                 putLogDebug(600004, "out_function : void protocol_module_ip::replication_interrupt().", __FILE__, __LINE__);
120         }
121         /*------DEBUG LOG END------*/
122 }
123 //! initialize function. called from module control. module loaded call
124 //! @param[in]    realserver list iterator begin function object type
125 //!    @param[in]    realserver list iterator end function object type
126 //! @param[in]    realserver list iterator next function object type
127 //! @param[in]    realserver list mutex lock function object type.
128 //! @param[in]    realserver list mutex unlock function object type
129 void protocol_module_ip::initialize(rs_list_itr_func_type    inlist_begin,
130                                     rs_list_itr_func_type    inlist_end,
131                                     rs_list_itr_next_func_type    inlist_next,
132                                     boost::function< void(void) >    inlist_lock,
133                                     boost::function< void(void) >    inlist_unlock)
134 {
135         /*-------- DEBUG LOG --------*/
136         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
137                 putLogDebug(600005, "in_function : void protocol_module_ip::initialize("
138                             "rs_list_itr_func_type inlist_begin, rs_list_itr_func_type inlist_end, "
139                             "rs_list_itr_next_func_type inlist_next, boost::function< void(void) > "
140                             "inlist_lock, boost::function< void(void) > inlist_unlock).", __FILE__, __LINE__);
141         }
142         /*------DEBUG LOG END------*/
143
144         //RealServer list begin function
145         rs_list_begin = inlist_begin;
146         //RealServer list end function
147         rs_list_end = inlist_end;
148         //RealServer list next function
149         rs_list_next = inlist_next;
150         //RealServer list lock funtion
151         rs_list_lock = inlist_lock;
152         //RealServer list unlock funtion
153         rs_list_unlock = inlist_unlock;
154
155         /*-------- DEBUG LOG --------*/
156         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
157                 putLogDebug(600006, "out_function : void protocol_module_ip::initialize("
158                             "rs_list_itr_func_type inlist_begin, rs_list_itr_func_type inlist_end, "
159                             "rs_list_itr_next_func_type inlist_next, boost::function< void(void) > "
160                             "inlist_lock, boost::function< void(void) > inlist_unlock).", __FILE__, __LINE__);
161         }
162         /*------DEBUG LOG END------*/
163 }
164
165 //! finalize called from module control. module unloaded call.
166 void protocol_module_ip::finalize()
167 {
168         /*-------- DEBUG LOG --------*/
169         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
170                 putLogDebug(600007, "in_function : void protocol_module_ip::finalize().", __FILE__, __LINE__);
171         }
172         /*------DEBUG LOG END------*/
173
174         //RealServer list functions initializtion
175         //RealServer list begin function
176         rs_list_begin.clear();
177         //RealServer list end function
178         rs_list_end.clear();
179         //RealServer list next function
180         rs_list_next.clear();
181         //RealServer list lock function
182         rs_list_lock.clear();
183         //RealServer list unlock function
184         rs_list_unlock.clear();
185
186         //Replication functions initializtion
187         //component memory allcate function
188         replication_pay_memory.clear();
189         //component memory lock function
190         replication_area_lock.clear();
191         //component memory unlock function
192         replication_area_unlock.clear();
193
194         /*-------- DEBUG LOG --------*/
195         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
196                 putLogDebug(600008, "function : void protocol_module_ip::finalize() : "
197                             "rs_list_begin.clear(), rs_list_end.clear(), rs_list_next.clear(), "
198                             "rs_list_lock.clear(), rs_list_unlock.clear() end.", __FILE__, __LINE__);
199         }
200         /*------DEBUG LOG END------*/
201
202         //ScheduleModule's functions initializtion
203         schedule_tcp.clear();
204
205         /*-------- DEBUG LOG --------*/
206         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
207                 putLogDebug(600009, "function : void protocol_module_ip::finalize() : "
208                             "schedule_tcp.clear() end.", __FILE__, __LINE__);
209         }
210         /*------DEBUG LOG END------*/
211
212         //Module's option initializtion
213         //forwarded_for
214         forwarded_for = FORWARDED_FOR_OFF;
215         //sorry-uri
216         sorry_uri.assign('\0');
217         //time_out
218         timeout = 0;
219         //reschedule flag
220         reschedule = 0;
221
222         // replication initialize
223         if (replication_data_processor) {
224                 /*-------- DEBUG LOG --------*/
225                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
226                         boost::format formatter("delete : address = &(%d).");
227                         formatter % static_cast<void *>(replication_data_processor);
228                         putLogDebug(600010, formatter.str(), __FILE__, __LINE__);
229                 }
230                 /*------DEBUG LOG END------*/
231
232                 delete replication_data_processor;
233                 replication_data_processor = NULL;
234         }
235
236         // session initialize
237         if (ip_data_processor) {
238                 /*-------- DEBUG LOG --------*/
239                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
240                         boost::format formatter("delete : address = &(%d).");
241                         formatter % static_cast<void *>(ip_data_processor);
242                         putLogDebug(600011, formatter.str(), __FILE__, __LINE__);
243                 }
244                 /*------DEBUG LOG END------*/
245
246                 delete ip_data_processor;
247                 ip_data_processor = NULL;
248         }
249
250         /*-------- DEBUG LOG --------*/
251         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
252                 putLogDebug(600012, "out_function : void protocol_module_ip::finalize().", __FILE__, __LINE__);
253         }
254         /*------DEBUG LOG END------*/
255
256         //logger functions initializtion
257         //log level getting function
258         getloglevel.clear();
259         //logger(Fatal)
260         putLogFatal.clear();
261         //logger(Error)
262         putLogError.clear();
263         //logger(Warn)
264         putLogWarn.clear();
265         //logger(Info)
266         putLogInfo.clear();
267         //logger(Debug)
268         putLogDebug.clear();
269 }
270
271 //! sorry support check
272 //! @return true sorry mode is supported.
273 //! @return false sorry mode is unsupported.
274 bool protocol_module_ip::is_use_sorry()
275 {
276         /*-------- DEBUG LOG --------*/
277         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
278                 putLogDebug(600013, "in/out_function : bool protocol_module_ip::is_use_sorry() : return_value = true.",
279                             __FILE__, __LINE__);
280         }
281         /*------DEBUG LOG END------*/
282         return true;
283 }
284
285 //! realserver list update event
286 void protocol_module_ip::handle_rslist_update()
287 {
288         /*-------- DEBUG LOG --------*/
289         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
290                 putLogDebug(600014, "in/out_function : void protocol_module_ip::handle_rslist_update().",
291                             __FILE__, __LINE__);
292         }
293         /*------DEBUG LOG END------*/
294 }
295
296 //! module parameter check.used by l7vsadm
297 //! @param[in]    module paramter string list
298 //! @return    result.flag true is parameter is noproblem.
299 //! @return result.flag false is paramter is problem.
300 protocol_module_base::check_message_result protocol_module_ip::check_parameter(const std::vector <
301                 std::string > & args)
302 {
303         /*-------- DEBUG LOG --------*/
304         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
305                 boost::format formatter("in_function : protocol_module_ip::check_message_result "
306                                         "protocol_module_ip::check_parameter("
307                                         "const std::vector<std::string>& args) : args = %s.");
308                 std::string argsdump;
309                 for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) {
310                         argsdump += *it;
311                 }
312                 formatter % argsdump;
313                 putLogDebug(600015, formatter.str(), __FILE__, __LINE__);
314         }
315         /*------DEBUG LOG END------*/
316
317         //set check result true
318         // set check result flag true
319         check_message_result check_result;
320         check_result.flag = true;
321         bool timeout_flag = false;
322         bool reschedule_flag = false;
323         bool no_reschedule_flag = false;
324         bool forward_checked = false;
325         bool sorryuri_checked = false;
326         sregex    sorry_uri_regex
327         =    +('/' >>
328                *(alpha |
329                  digit |
330                  (set = ';', ':', '@', '&', '=') |
331                  (set = '$', '-', '_', '.', '+') |
332                  (set = '!', '*', '\'', '\(', ')', ',') |
333                  '%' >> repeat<2>(xdigit)));
334
335         typedef std::vector<std::string>::const_iterator vec_str_it;
336
337         try {
338                 vec_str_it it = args.begin();
339                 vec_str_it it_end = args.end();
340                 boost::format formatter;
341
342                 //loop option strings
343                 for (; it != it_end;) {
344                         if (*it == "-T" || *it == "--timeout") {
345                                 // timeout
346                                 if (!timeout_flag) {
347                                         // not set timeout option
348                                         ++it;
349                                         // next parameter exist check
350                                         if (it != it_end) {
351                                                 // next parameter exist
352                                                 if ((*it).substr(0, 1) == "-" || (*it).substr(0, 2) == "--") {
353                                                         continue;
354                                                 }
355
356                                                 try {
357                                                         unsigned long ultimeout = 0;
358                                                         ultimeout = boost::lexical_cast<unsigned long>(*it);
359                                                         // int maxvalue check
360                                                         if (ultimeout > INT_MAX) {
361                                                                 check_result.flag = false;
362                                                                 formatter.parse("'-T/--timeout' option value '%s' is too large.");
363                                                                 formatter % *it;
364                                                                 check_result.message = formatter.str();
365                                                                 putLogError(600000, check_result.message, __FILE__, __LINE__);
366                                                                 break;
367                                                         } else {
368                                                                 timeout_flag = true;
369                                                                 ++it;
370                                                                 continue;
371                                                         }
372                                                 } catch (boost::bad_lexical_cast &e) {
373                                                         // not numeric character
374                                                         check_result.flag = false;
375                                                         formatter.parse("'-T/--timeout' option value '%s' is not numeric character.");
376                                                         formatter % *it;
377                                                         check_result.message = formatter.str();
378                                                         putLogError(600001, check_result.message, __FILE__, __LINE__);
379                                                         break;
380                                                 }
381                                         } else {
382                                                 break;
383                                         }
384                                 } else {
385                                         // already set timeout
386                                         check_result.flag = false;
387                                         check_result.message = "Cannot set multiple option '-T/--timeout'.";
388                                         putLogError(600002, check_result.message, __FILE__, __LINE__);
389                                         break;
390                                 }
391                         } else if (*it == "-R" || *it == "--reschedule") {
392                                 // reschedule
393                                 if (!no_reschedule_flag) {
394                                         // not set no-reschedule flag
395                                         reschedule_flag = true;
396                                 } else {
397                                         // already set no-reschedule flag
398                                         check_result.flag = false;
399                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
400                                         putLogError(600003, check_result.message, __FILE__, __LINE__);
401                                         break;
402                                 }
403                         } else if (*it == "-N" || *it == "--no-reschedule") {
404                                 // no-reschedule
405                                 if (!reschedule_flag) {
406                                         // not set reschedule flag
407                                         no_reschedule_flag = true;
408                                 } else {
409                                         // already set reshcedule flag
410                                         check_result.flag = false;
411                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
412                                         putLogError(600004, check_result.message, __FILE__, __LINE__);
413                                         break;
414                                 }
415                         }
416                         //option string = "-F"
417                         else if (*it == "-F" || *it == "--forwarded-for") {
418                                 //set forward flag  ON
419                                 forward_checked = true;
420                         }
421                         //option string = "-S"
422                         else if (*it == "-S" || *it == "--sorry-uri") {
423                                 //set sorryURI flag OFF
424                                 if (!sorryuri_checked) {
425                                         //next item exist
426                                         if (++it != it_end) {
427                                                 if (!it->empty() && (it->substr(0, 1) == "-" || it->substr(0, 2) == "--")) {
428                                                         //set check result flag false
429                                                         check_result.flag = false;
430                                                         //set check result message
431                                                         check_result.message = "You have to set option value '-S/--sorry-uri'.";
432                                                         putLogError(600005, check_result.message, __FILE__, __LINE__);
433                                                         //loop break;
434                                                         break;
435                                                 }
436                                                 //next option string's length > 127
437                                                 if (it->size() > MAX_OPTION_SIZE - 1) {
438                                                         std::ostringstream ostr;
439                                                         ostr << "'-S/--sorry-uri' option value '" << *it << "' is too long.";
440
441                                                         //set check result flag false
442                                                         check_result.flag = false;
443                                                         //set check result message
444                                                         check_result.message = ostr.str();
445                                                         putLogError(600006, check_result.message, __FILE__, __LINE__);
446                                                         //loop break;
447                                                         break;
448                                                 }
449                                                 //next option string's length <= 127
450                                                 else {
451                                                         //regex check
452                                                         if (regex_match(*it, sorry_uri_regex)) {
453                                                                 //check OK
454                                                                 //set sorryURI flag ON
455                                                                 sorryuri_checked = true;
456                                                         }
457                                                         //check NG
458                                                         else {
459                                                                 std::ostringstream ostr;
460                                                                 ostr << "'-S/--sorry-uri' option value '" << *it << "' is not a valid URI.";
461
462                                                                 //set check result flag false
463                                                                 check_result.flag = false;
464                                                                 //set check result message
465                                                                 check_result.message = ostr.str();
466                                                                 putLogError(600007, check_result.message, __FILE__, __LINE__);
467                                                                 break;
468                                                         }
469                                                 }
470                                         }
471                                         //next item is not exist
472                                         else {
473                                                 //set check flag false
474                                                 check_result.flag = false;
475                                                 //set check result message
476                                                 check_result.message = "You have to set option value '-S/--sorry-uri'.";
477                                                 putLogError(600008, check_result.message, __FILE__,
478                                                             __LINE__);
479                                                 //loop break
480                                                 break;
481                                         }
482                                 }
483                                 //sorryURI flag = ON
484                                 else {
485                                         //set check result flag false
486                                         check_result.flag = false;
487                                         //set check result message
488                                         check_result.message = "Cannot set multiple option '-S/--sorry-uri'.";
489                                         putLogError(600009, check_result.message, __FILE__,
490                                                     __LINE__);
491                                         //loop break
492                                         break;
493                                 }
494                         }
495                         //other option string
496                         else {
497                                 //set check result flag false
498                                 check_result.flag = false;
499                                 //set check result message
500                                 check_result.message = "Option error.";
501                                 putLogError(600010, check_result.message, __FILE__, __LINE__);
502                                 //loop break
503                                 break;
504                         }
505
506                         ++it;
507                 }
508         } catch (const std::exception &ex) {
509                 check_result.flag = false;
510                 std::cerr << "protocol_module_ip::check_parameter() : exception : error = " << ex.what() << "." << std::endl;
511                 boost::format formatter("function : protocol_module_base::check_message_result "
512                                         "protocol_module_ip::check_parameter() exception : "
513                                         "error = %s.");
514                 formatter % ex.what();
515                 putLogError(600011, formatter.str(), __FILE__, __LINE__);
516         } catch (...) {
517                 check_result.flag = false;
518                 std::cerr << "protocol_module_ip::check_parameter() : Unknown exception." << std::endl;
519                 putLogError(600012, "function : protocol_module_base::check_message_result "
520                             "protocol_module_ip::check_parameter() : "
521                             "Unknown exception.", __FILE__, __LINE__);
522         }
523
524         /*-------- DEBUG LOG --------*/
525         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
526                 boost::format formatter("out_function : protocol_module_base::check_message_result "
527                                         "protocol_module_ip::check_parameter("
528                                         "const std::vector<std::string>& args) : return_value = ("
529                                         "check_message_result.flag = %d, check_message_result.message = %s).");
530                 formatter % check_result.flag % check_result.message;
531                 putLogDebug(600016, formatter.str(), __FILE__, __LINE__);
532         }
533         /*------DEBUG LOG END------*/
534
535         return check_result;
536 }
537
538 //! parameter set
539 //! @param[in] module paramter string list
540 //! @return    result.flag true is parameter is noproblem.
541 //! @return result.flag false is paramter is problem.
542 protocol_module_base::check_message_result protocol_module_ip::set_parameter(const std::vector <
543                 std::string > & args)
544 {
545         /*-------- DEBUG LOG --------*/
546         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
547                 boost::format formatter("in_function : protocol_module_base::check_message_result "
548                                         "protocol_module_ip::set_parameter("
549                                         "const std::vector<std::string>& args) : args = %s.");
550                 std::string argsdump;
551                 for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) {
552                         argsdump += *it;
553                         argsdump += " ";
554                 }
555                 formatter % argsdump;
556                 putLogDebug(600017, formatter.str(), __FILE__, __LINE__);
557         }
558         /*------DEBUG LOG END------*/
559
560         //set check result flag true
561         check_message_result check_result;
562         check_result.flag = true;
563         bool timeout_flag = false;
564         bool reschedule_flag = false;
565         bool no_reschedule_flag = false;
566         bool forward_checked = false;
567         bool sorryuri_checked = false;
568         boost::format formatter;
569         sregex    sorry_uri_regex
570         =    +('/' >>
571                *(alpha |
572                  digit |
573                  (set = ';', ':', '@', '&', '=') |
574                  (set = '$', '-', '_', '.', '+') |
575                  (set = '!', '*', '\'', '\(', ')', ',') |
576                  '%' >> repeat<2>(xdigit)));
577
578         typedef std::vector<std::string>::const_iterator vec_str_it;
579
580         //set forwarded flag true
581         forwarded_for = 1;
582
583         try {
584                 vec_str_it it = args.begin();
585                 vec_str_it it_end = args.end();
586
587                 for (; it != it_end;) {
588
589                         if (*it == "-T" || *it == "--timeout") {
590                                 // timeout
591                                 if (!timeout_flag) {
592                                         // not set timeout option
593                                         ++it;
594                                         // next parameter exist check
595                                         if (it != it_end) {
596                                                 // next parameter exist
597                                                 if ((*it).substr(0, 1) == "-" || (*it).substr(0, 2) == "--") {
598                                                         continue;
599                                                 }
600
601                                                 try {
602                                                         unsigned long ultimeout = 0;
603                                                         ultimeout = boost::lexical_cast<unsigned long>(*it);
604                                                         // int maxvalue check
605                                                         if (ultimeout > INT_MAX) {
606                                                                 check_result.flag = false;
607                                                                 formatter.parse("'-T/--timeout' option value '%s' is too large.");
608                                                                 formatter % *it;
609                                                                 check_result.message = formatter.str();
610                                                                 putLogError(600013, check_result.message, __FILE__, __LINE__);
611                                                                 break;
612                                                         } else {
613                                                                 timeout_flag = true;
614                                                                 timeout = ultimeout;
615                                                                 ++it;
616                                                                 continue;
617                                                         }
618                                                 } catch (boost::bad_lexical_cast &e) {
619                                                         // not numeric character
620                                                         check_result.flag = false;
621                                                         formatter.parse("'-T/--timeout' option value '%s' is not numeric character.");
622                                                         formatter % *it;
623                                                         check_result.message = formatter.str();
624                                                         putLogError(600014, check_result.message, __FILE__, __LINE__);
625                                                         break;
626                                                 }
627                                         } else {
628                                                 break;
629                                         }
630                                 } else {
631                                         // already set timeout
632                                         check_result.flag = false;
633                                         check_result.message = "Cannot set multiple option '-T/--timeout'.";
634                                         putLogError(600015, check_result.message, __FILE__, __LINE__);
635                                         break;
636
637                                 }
638                         } else if (*it == "-R" || *it == "--reschedule") {
639                                 // reschedule
640                                 if (!no_reschedule_flag) {
641                                         // not set no-reschedule flag
642                                         reschedule_flag = true;
643                                         reschedule = 1;
644                                 } else {
645                                         // already set no-reschedule flag
646                                         check_result.flag = false;
647                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
648                                         putLogError(600016, check_result.message, __FILE__, __LINE__);
649                                         break;
650                                 }
651                         } else if (*it == "-N" || *it == "--no-reschedule") {
652                                 // no-reschedule
653                                 if (!reschedule_flag) {
654                                         // not set reschedule flag
655                                         no_reschedule_flag = true;
656                                         reschedule = 0;
657
658                                 } else {
659                                         // already set reshcedule flag
660                                         check_result.flag = false;
661                                         check_result.message = "You have to choose either of reschedule or no-reschedule.";
662                                         putLogError(600017, check_result.message, __FILE__, __LINE__);
663                                         break;
664                                 }
665                         }
666                         //option string = "-F"
667                         else if (*it == "-F" || *it == "--forwarded-for") {
668                                 //set forwarded flag ON
669                                 forward_checked = true;
670                                 forwarded_for = FORWARDED_FOR_ON;
671                         }
672                         //option string  = "-S"
673                         else if (*it == "-S" || *it == "--sorry-uri") {
674                                 //sorryURI flag = OFF
675                                 if (!sorryuri_checked) {
676                                         //next item exist
677                                         if (++it != it_end) {
678                                                 if (!it->empty() && (it->substr(0, 1) == "-" || it->substr(0, 2) == "--")) {
679                                                         //set check result flag false
680                                                         check_result.flag = false;
681                                                         //set check result message
682                                                         check_result.message = "You have to set option value '-S/--sorry-uri'.";
683                                                         //loop break
684                                                         break;
685                                                 }
686                                                 //next option string's length > 127
687                                                 if (it->size() > MAX_OPTION_SIZE - 1) {
688                                                         std::ostringstream ostr;
689                                                         ostr << "'-S/--sorry-uri' option value '" << *it << "' is too long.";
690
691                                                         //set check result flag false
692                                                         check_result.flag = false;
693                                                         //set check result message
694                                                         check_result.message = ostr.str();
695                                                         putLogError(600018, check_result.message, __FILE__,
696                                                                     __LINE__);
697                                                         //loop break
698                                                         break;
699                                                 }
700                                                 //next option string's length <= 127
701                                                 else {
702                                                         //regex check
703                                                         //check OK
704                                                         if (regex_match(*it, sorry_uri_regex)) {
705                                                                 sorryuri_checked = true;
706                                                                 memcpy(sorry_uri.data(), it->c_str(), it->size());
707                                                         }
708                                                         //check NG
709                                                         else {
710                                                                 std::ostringstream ostr;
711                                                                 ostr << "'-S/--sorry-uri' option value '" << *it << "' is not a valid URI.";
712
713                                                                 //set check result flag false
714                                                                 check_result.flag = false;
715                                                                 //set check result message
716                                                                 check_result.message = ostr.str();
717                                                                 putLogError(600019, check_result.message, __FILE__,
718                                                                             __LINE__);
719                                                                 break;
720                                                         }
721                                                 }
722                                         }
723                                         //next item not exist
724                                         else {
725                                                 //set check result flag false
726                                                 check_result.flag = false;
727                                                 //set check result message
728                                                 check_result.message = "You have to set option value '-S/--sorry-uri'.";
729                                                 putLogError(600020, check_result.message, __FILE__,
730                                                             __LINE__);
731                                                 break;
732                                         }
733                                 }
734                                 //sorryURI flag = ON
735                                 else {
736                                         //set check result flag false
737                                         check_result.flag = false;
738                                         //set check result message
739                                         check_result.message = "Cannot set multiple option '-S/--sorry-uri'.";
740                                         putLogError(600021, check_result.message, __FILE__,
741                                                     __LINE__);
742                                         break;
743                                 }
744                         }
745                         //others
746                         else {
747                                 //set check result flag false
748                                 check_result.flag = false;
749                                 //set check result message
750                                 check_result.message = "Option error.";
751                                 putLogError(600022, check_result.message, __FILE__, __LINE__);
752
753                                 break;
754                         }
755                         ++it;
756                 }
757
758                 // result check
759                 if (check_result.flag) {
760                         // set timeout's default value
761                         if (!timeout_flag) {
762                                 timeout = 3600;
763                         }
764
765                         // set reschedule's default value
766                         if (!reschedule_flag) {
767                                 reschedule = 0;
768                         }
769                         //forward flag = OFF
770                         if (!forward_checked) {
771                                 forwarded_for = 0;
772                         }
773
774                 }
775                 /*-------- DEBUG LOG --------*/
776                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
777                         boost::format formatter("function : protocol_module_ip::check_message_result "
778                                                 "protocol_module_ip::set_parameter(const std::vector<std::string>& args) : "
779                                                 "timeout = %d, reschedule = %d.");
780                         formatter % timeout  % reschedule;
781                         putLogDebug(600018, formatter.str(), __FILE__, __LINE__);
782                 }
783                 /*------DEBUG LOG END------*/
784
785                 unsigned int data_size = 0;
786                 void *data_addr = NULL;
787                 data_addr = replication_pay_memory(get_name(), &data_size);
788
789                 /*-------- DEBUG LOG --------*/
790                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
791                         putLogDebug(600019, "function : protocol_module_ip::check_message_result protocol_module_ip::"
792                                     "set_parameter() : replication_pay_memory() end.", __FILE__, __LINE__);
793                         boost::format formatter("function : protocol_module_ip::check_message_result protocol_module_ip::"
794                                                 "set_parameter() : data_addr = &(%d), data_size = %d.");
795                         formatter % data_addr % data_size;
796                         putLogDebug(600020, formatter.str(), __FILE__, __LINE__);
797                 }
798
799                 /*------DEBUG LOG END------*/
800                 if (data_addr == NULL || data_size <= 0) {
801                         // replication area is null
802                         putLogInfo(600000, "Replication area is null.", __FILE__, __LINE__);
803
804                         /*-------- DEBUG LOG --------*/
805                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
806                                 putLogDebug(600021, "function : protocol_module_ip::check_message_result "
807                                             "protocol_module_ip::set_parameter() : "
808                                             "Replication area is null.", __FILE__, __LINE__);
809                         }
810                         /*------DEBUG LOG END------*/
811                 }
812
813                 // create ip_replication_data_processor
814                 replication_data_processor = new ip_replication_data_processor(
815                         static_cast<char *>(data_addr),
816                         data_size,
817                         virtual_service_endpoint_tcp,
818                         getloglevel,
819                         putLogFatal,
820                         putLogError,
821                         putLogWarn,
822                         putLogInfo,
823                         putLogDebug);
824
825                 /*-------- DEBUG LOG --------*/
826                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
827                         boost::format formatter("new : address = &(%d), size = %lu.");
828                         formatter % static_cast<void *>(replication_data_processor)
829                         % sizeof(ip_replication_data_processor);
830                         putLogDebug(600022, formatter.str(), __FILE__, __LINE__);
831                 }
832                 /*------DEBUG LOG END------*/
833
834                 replication_data_processor->register_replication_area_lock(replication_area_lock);
835
836                 /*-------- DEBUG LOG --------*/
837                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
838                         putLogDebug(600023, "function : protocol_module_ip::check_message_result protocol_module_ip::"
839                                     "set_parameter() : register_replication_area_lock() end.", __FILE__, __LINE__);
840                 }
841                 /*------DEBUG LOG END------*/
842
843                 replication_data_processor->register_replication_area_unlock(replication_area_unlock);
844
845                 /*-------- DEBUG LOG --------*/
846                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
847                         putLogDebug(600024, "function : protocol_module_ip::check_message_result protocol_module_ip::"
848                                     "set_parameter() : register_replication_area_unlock() end.", __FILE__, __LINE__);
849                 }
850                 /*------DEBUG LOG END------*/
851
852                 // create ip_session_data_processor
853                 ip_data_processor = new ip_session_data_processor(
854                         timeout,
855                         replication_data_processor,
856                         getloglevel,
857                         putLogFatal,
858                         putLogError,
859                         putLogWarn,
860                         putLogInfo,
861                         putLogDebug);
862
863                 /*-------- DEBUG LOG --------*/
864                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
865                         boost::format formatter("new : address = &(%d), size = %lu.");
866                         formatter % static_cast<void *>(ip_data_processor)
867                         % sizeof(ip_session_data_processor);
868                         putLogDebug(600025, formatter.str(), __FILE__, __LINE__);
869                 }
870                 /*------DEBUG LOG END------*/
871
872                 // restore data from replication area
873                 ip_replication_data *redata = replication_data_processor->get_replication_area();
874
875                 /*-------- DEBUG LOG --------*/
876                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
877                         putLogDebug(600026, "function : protocol_module_ip::check_message_result protocol_module_ip::"
878                                     "set_parameter() : get_replication_area() end.", __FILE__, __LINE__);
879                 }
880                 /*------DEBUG LOG END------*/
881
882                 if (data_addr) {
883                         replication_area_lock();
884
885                         /*-------- DEBUG LOG --------*/
886                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
887                                 putLogDebug(600027, "function : protocol_module_ip::check_message_result protocol_module_ip::"
888                                             "set_parameter() : replication_area_lock() end.", __FILE__, __LINE__);
889                         }
890                         /*------DEBUG LOG END------*/
891
892                         ip_data_processor->read_session_data_from_replication_area(redata);
893
894                         /*-------- DEBUG LOG --------*/
895                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
896                                 putLogDebug(600028, "function : protocol_module_ip::check_message_result protocol_module_ip::"
897                                             "set_parameter() : read_session_data_from_replication_area() end.", __FILE__, __LINE__);
898                         }
899                         /*------DEBUG LOG END------*/
900
901                         replication_area_unlock();
902
903                         /*-------- DEBUG LOG --------*/
904                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
905                                 putLogDebug(600029, "function : protocol_module_ip::check_message_result protocol_module_ip::"
906                                             "set_parameter() : replication_area_unlock() end.", __FILE__, __LINE__);
907                         }
908                         /*------DEBUG LOG END------*/
909                 }
910         } catch (const std::bad_alloc &ba) {
911                 if (replication_data_processor) {
912                         delete replication_data_processor;
913                         replication_data_processor = NULL;
914                 }
915
916                 if (ip_data_processor) {
917                         delete ip_data_processor;
918                         ip_data_processor = NULL;
919                 }
920
921                 std::cerr << "protocol_module_ip::set_parameter() : exception : Could not allocate memory." << std::endl;
922                 check_result.flag = false;
923                 check_result.message = "Could not allocate memory.";
924                 putLogError(600023, check_result.message, __FILE__, __LINE__);
925         } catch (const std::exception &ex) {
926                 if (replication_data_processor) {
927                         delete replication_data_processor;
928                         replication_data_processor = NULL;
929                 }
930
931                 if (ip_data_processor) {
932                         delete ip_data_processor;
933                         ip_data_processor = NULL;
934                 }
935
936                 check_result.flag = false;
937                 std::cerr << "protocol_module_ip::set_parameter() : exception : error = " << ex.what() << std::endl;
938                 boost::format formatter("function : protocol_module_ip::check_message_result "
939                                         "protocol_module_ip::set_parameter() : exception : error = %s.");
940                 formatter % ex.what();
941                 putLogError(600024, formatter.str(), __FILE__, __LINE__);
942         } catch (...) {
943                 if (replication_data_processor) {
944                         delete replication_data_processor;
945                         replication_data_processor = NULL;
946                 }
947
948                 if (ip_data_processor) {
949                         delete ip_data_processor;
950                         ip_data_processor = NULL;
951                 }
952
953                 check_result.flag = false;
954                 std::cerr << "protocol_module_ip::set_parameter() : Unknown exception." << std::endl;
955                 putLogError(600025, "function : protocol_module_ip::check_message_result protocol_module_ip::"
956                             "set_parameter() : Unknown exception.", __FILE__, __LINE__);
957         }
958         /*-------- DEBUG LOG --------*/
959         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
960                 boost::format formatter("out_function : protocol_module_ip::check_message_result "
961                                         "protocol_module_ip::set_parameter("
962                                         "const std::vector<std::string>& args) : return_value = ("
963                                         "check_message_result.flag = %d, check_message_result.message = %s).");
964                 formatter % check_result.flag % check_result.message;
965                 putLogDebug(600030, formatter.str(), __FILE__, __LINE__);
966         }
967         /*------DEBUG LOG END------*/
968         return check_result;
969 }
970
971 //! parameter add
972 //! @param[in] module paramter string list
973 //! @return    result.flag true is parameter is noproblem.
974 //! @return result.flag false is paramter is problem.
975 protocol_module_base::check_message_result protocol_module_ip::add_parameter(const std::vector <
976                 std::string > & args)
977 {
978         /*-------- DEBUG LOG --------*/
979         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
980                 boost::format formatter("in_function : protocol_module_ip::check_message_result protocol_module_ip::"
981                                         "add_parameter(const std::vector<std::string>& args) : args = %s.");
982                 std::string argsdump;
983                 for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) {
984                         argsdump += *it;
985                 }
986                 formatter % argsdump;
987                 putLogDebug(600031, formatter.str(), __FILE__, __LINE__);
988         }
989         /*------DEBUG LOG END------*/
990         check_message_result check_result;
991         //set check result flag true
992         check_result.flag = true;
993
994         //param list is not empty
995         if (!args.empty()) {
996                 //set check result flag false
997                 check_result.flag = false;
998                 //set check result message
999                 check_result.message = "Cannot add option.";
1000                 putLogError(600026, check_result.message, __FILE__, __LINE__);
1001         }
1002
1003         /*-------- DEBUG LOG --------*/
1004         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1005                 boost::format formatter("out_function : protocol_module_ip::check_message_result "
1006                                         "protocol_module_ip::add_parameter(const std::vector<std::string>& args) : "
1007                                         "return_value = (check_message_result.flag = %d, check_message_result.message = %s).");
1008                 formatter % check_result.flag % check_result.message;
1009                 putLogDebug(600032, formatter.str(), __FILE__, __LINE__);
1010         }
1011         /*------DEBUG LOG END------*/
1012         return check_result;
1013 }
1014
1015 //! get option info
1016 //! @param[out] module paramter string
1017 void protocol_module_ip::get_option_info(std::string &option)
1018 {
1019         /*-------- DEBUG LOG --------*/
1020         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1021                 putLogDebug(600033, "in_function : void protocol_module_ip::get_option_info("
1022                             "std::string& option).", __FILE__, __LINE__);
1023         }
1024         /*------DEBUG LOG END------*/
1025
1026         boost::format option_formatter("--timeout %d%s %s --sorry-uri '%s'");
1027         option_formatter % timeout % (forwarded_for ? " --forwarded-for" : "") % (reschedule ? "--reschedule" : "--no-reschedule") % sorry_uri.c_array();
1028         option.assign(option_formatter.str());
1029
1030         /*-------- DEBUG LOG --------*/
1031         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1032                 boost::format formatter("out_function : void protocol_module_ip::get_option_info("
1033                                         "std::string& option) : option = %s.");
1034                 formatter % option;
1035                 putLogDebug(600034, formatter.str(), __FILE__, __LINE__);
1036         }
1037         /*------DEBUG LOG END------*/
1038 }
1039
1040 //! TCP/IP scheduled function registation.
1041 //! @param[in] schedule module TCP/IP scheduled function object type
1042 void protocol_module_ip::register_schedule(tcp_schedule_func_type inschedule)
1043 {
1044         /*-------- DEBUG LOG --------*/
1045         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1046                 putLogDebug(600035, "in_function : void protocol_module_ip::register_schedule("
1047                             "tcp_schedule_func_type inschedule).", __FILE__, __LINE__);
1048         }
1049         /*------DEBUG LOG END------*/
1050         schedule_tcp = inschedule;
1051         /*-------- DEBUG LOG --------*/
1052         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1053                 putLogDebug(600036, "out_function : void protocol_module_ip::register_schedule("
1054                             "tcp_schedule_func_type inschedule).", __FILE__, __LINE__);
1055         }
1056         /*------DEBUG LOG END------*/
1057 }
1058
1059 //! UDP scheduled function registation
1060 //! @param[in] schedule module UDP scheduled funtion object type
1061 void protocol_module_ip::register_schedule(udp_schedule_func_type inschedule)
1062 {
1063         /*-------- DEBUG LOG --------*/
1064         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1065                 putLogDebug(600037, "in/out_function : void protocol_module_ip::register_schedule("
1066                             "udp_schedule_func_type inschedule).", __FILE__, __LINE__);
1067         }
1068         /*------DEBUG LOG END------*/
1069 }
1070
1071 //! called from session initialzie use in upstream_thread
1072 //! @param[in]    upstream thread id.
1073 //! @param[in]    downstream thread id
1074 //! @return        session use EVENT mode.
1075 protocol_module_base::EVENT_TAG protocol_module_ip::handle_session_initialize(
1076         const boost::thread::id up_thread_id, const boost::thread::id down_thread_id,
1077         const boost::asio::ip::tcp::endpoint &client_endpoint_tcp,
1078         const boost::asio::ip::udp::endpoint &client_endpoint_udp)
1079 {
1080         /*-------- DEBUG LOG --------*/
1081         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1082                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1083                                         "handle_session_initialize(const boost::thread::id up_thread_id, "
1084                                         "const boost::thread::id down_thread_id, "
1085                                         "const boost::asio::ip::tcp::endpoint& client_endpoint_tcp, "
1086                                         "const boost::asio::ip::udp::endpoint& client_endpoint_udp) : "
1087                                         "up_thread_id = %d, down_thread_id = %d.");
1088                 formatter % up_thread_id % down_thread_id;
1089                 putLogDebug(600038, formatter.str(), __FILE__, __LINE__);
1090         }
1091         /*------DEBUG LOG END------*/
1092
1093         EVENT_TAG status = FINALIZE;
1094         unsigned int ip_hash = 0;
1095
1096         //session thread initialization
1097         try {
1098                 thread_data_ptr p_up(new session_thread_data_ip);
1099                 /*-------- DEBUG LOG --------*/
1100                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1101                         boost::format formatter("new : address = &(%d), size = %lu.");
1102                         formatter % static_cast<void *>(p_up.get()) % sizeof(session_thread_data_ip);
1103                         putLogDebug(600039, formatter.str(), __FILE__, __LINE__);
1104                 }
1105                 /*------DEBUG LOG END------*/
1106
1107                 //calculate ip address's hash
1108                 ip_hash = l7vs_ip_service_calc_hash(client_endpoint_tcp);
1109
1110                 p_up->thread_id                = up_thread_id;
1111                 p_up->thread_division            = THREAD_DIVISION_UP_STREAM;
1112                 p_up->pair_thread_id            = down_thread_id;
1113                 p_up->accept_end_flag            = ACCEPT_END_FLAG_OFF;
1114                 p_up->end_flag                = END_FLAG_OFF;
1115                 p_up->sorry_flag                = SORRY_FLAG_OFF;
1116                 p_up->switch_flag                = SWITCH_FLAG_OFF;
1117                 p_up->last_status                = INITIALIZE;
1118                 p_up->client_endpoint            = client_endpoint_tcp;
1119                 p_up->data_buffer                = new char[MAX_BUFFER_SIZE];
1120                 p_up->data_buffer_size            = MAX_BUFFER_SIZE;
1121                 p_up->data_length                = 0;
1122                 p_up->data_offset                = 0;
1123                 p_up->current_message_rest_size        = 0;
1124                 p_up->data_state                = HTTP_START;
1125                 p_up->ip_hash                = ip_hash;
1126
1127                 /*-------- DEBUG LOG --------*/
1128                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1129                         // data dump
1130                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1131                                                 "handle_session_initialize() : session_thread_data_ip(upthread) : "
1132                                                 "thread_id = %d, thread_division = %d, "
1133                                                 "pair_thread_id = %d, accept_end_flag = %d, end_flag = %d, "
1134                                                 "sorry_flag = %d, switch_flag = %d, last_status = %d, client_endpoint = [%s]:%d, data_buffer = &(%d), "
1135                                                 "data_buffer_size = %d, data_length = %d, data_offset = %d, current_message_rest_size = %d, data_state = %d, "
1136                                                 "ip_hash = %d.");
1137                         formatter % p_up->thread_id
1138                         % p_up->thread_division
1139                         % p_up->pair_thread_id
1140                         % p_up->accept_end_flag
1141                         % p_up->end_flag
1142                         % p_up->sorry_flag
1143                         % p_up->switch_flag
1144                         % p_up->last_status
1145                         % p_up->client_endpoint.address().to_string()
1146                         % p_up->client_endpoint.port()
1147                         % p_up->data_buffer
1148                         % p_up->data_buffer_size
1149                         % p_up->data_length
1150                         % p_up->data_offset
1151                         % p_up->current_message_rest_size
1152                         % p_up->data_state
1153                         % p_up->ip_hash;
1154
1155
1156                         putLogDebug(600040, formatter.str(), __FILE__, __LINE__);
1157                 }
1158                 /*------DEBUG LOG END------*/
1159
1160                 thread_data_ptr p_down(new session_thread_data_ip);
1161
1162                 /*-------- DEBUG LOG --------*/
1163                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1164                         boost::format formatter("new : address = &(%d), size = %lu.");
1165                         formatter % static_cast<void *>(p_down.get()) % sizeof(session_thread_data_ip);
1166                         putLogDebug(600041, formatter.str(), __FILE__, __LINE__);
1167                 }
1168                 /*------DEBUG LOG END------*/
1169
1170                 p_down->thread_id                = down_thread_id;
1171                 p_down->thread_division            = THREAD_DIVISION_DOWN_STREAM;
1172                 p_down->pair_thread_id            = up_thread_id;
1173                 p_down->accept_end_flag            = ACCEPT_END_FLAG_OFF;
1174                 p_down->end_flag                = END_FLAG_OFF;
1175                 p_down->sorry_flag                = SORRY_FLAG_OFF;
1176                 p_down->switch_flag                = SWITCH_FLAG_OFF;
1177                 p_down->last_status                = INITIALIZE;
1178                 p_down->client_endpoint            = client_endpoint_tcp;
1179                 p_down->data_buffer                = new char[MAX_BUFFER_SIZE];
1180                 p_down->data_buffer_size            = MAX_BUFFER_SIZE;
1181                 p_down->data_length                = 0;
1182                 p_down->data_offset                = 0;
1183                 p_down->current_message_rest_size        = 0;
1184                 p_down->data_state                = HTTP_START;
1185                 p_down->ip_hash                = ip_hash;
1186
1187                 /*-------- DEBUG LOG --------*/
1188                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1189                         // data_dump
1190                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1191                                                 "handle_session_initialize() : session_thread_data_ip(downthread) : "
1192                                                 "thread_id = %d, thread_division = %d, "
1193                                                 "pair_thread_id = %d, accept_end_flag = %d, end_flag = %d, "
1194                                                 "sorry_flag = %d, switch_flag = %d, last_status = %d, client_endpoint = [%s]:%d, data_buffer = &(%d), "
1195                                                 "data_buffer_size = %d, data_length = %d, data_offset = %d, current_message_rest_size = %d, data_state = %d, "
1196                                                 "ip_hash = %d.");
1197                         formatter % p_down->thread_id
1198                         % p_down->thread_division
1199                         % p_down->pair_thread_id
1200                         % p_down->accept_end_flag
1201                         % p_down->end_flag
1202                         % p_down->sorry_flag
1203                         % p_down->switch_flag
1204                         % p_down->last_status
1205                         % p_down->client_endpoint.address().to_string()
1206                         % p_down->client_endpoint.port()
1207                         % p_down->data_buffer
1208                         % p_down->data_buffer_size
1209                         % p_down->data_length
1210                         % p_down->data_offset
1211                         % p_down->current_message_rest_size
1212                         % p_down->data_state
1213                         % p_down->ip_hash;
1214                         putLogDebug(600042, formatter.str(), __FILE__, __LINE__);
1215                 }
1216                 /*------DEBUG LOG END------*/
1217
1218
1219                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1220
1221                 session_thread_data_map[up_thread_id] = p_up;
1222                 session_thread_data_map[down_thread_id] = p_down;
1223
1224                 //set return status
1225                 status = ACCEPT;
1226                 //save last status
1227                 session_thread_data_map[up_thread_id]->last_status = status;
1228                 session_thread_data_map[down_thread_id]->last_status = REALSERVER_RECV;
1229         } catch (const std::bad_alloc &) {
1230                 std::cerr << "protocol_module_ip::handle_session_initialize() : exception : Could not allocate memory." << std::endl;
1231                 boost::format formatter("Could not allocate memory. thread id : %d.");
1232                 formatter % boost::this_thread::get_id();
1233                 putLogError(600027, formatter.str(), __FILE__, __LINE__);
1234                 status = FINALIZE;
1235         } catch (const std::exception &ex) {
1236                 std::cerr << "protocol_module_ip::handle_session_initialize() : exception : error = " << ex.what() << "." << std::endl;
1237                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1238                                         "handle_session_initialize() : exception : error = %s. thread id : %d.");
1239                 formatter % ex.what() % boost::this_thread::get_id();
1240                 putLogError(600028, formatter.str(), __FILE__, __LINE__);
1241                 status = FINALIZE;
1242         } catch (...) {
1243                 std::cerr << "protocol_module_ip::handle_session_initialize() : Unknown exception." << std::endl;
1244                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1245                                         "handle_session_initialize() : Unknown exception. thread id : %d.");
1246                 formatter % boost::this_thread::get_id();
1247                 putLogError(600029, formatter.str(), __FILE__, __LINE__);
1248                 status = FINALIZE;
1249         }
1250
1251         /*-------- DEBUG LOG --------*/
1252         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1253                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1254                                         "handle_session_initialize(const boost::thread::id up_thread_id, "
1255                                         "const boost::thread::id down_thread_id, "
1256                                         "const boost::asio::ip::tcp::endpoint& client_endpoint_tcp, "
1257                                         "const boost::asio::ip::udp::endpoint& client_endpoint_udp) : return_value = %d. "
1258                                         "thread id : %d.");
1259                 formatter % status % boost::this_thread::get_id();
1260                 putLogDebug(600043, formatter.str(), __FILE__, __LINE__);
1261         }
1262         /*------DEBUG LOG END------*/
1263
1264         return status;
1265 }
1266 //! called from session finalize use in upstream thread.
1267 //! @param[in]    upstream thread id.
1268 //! @param[in]    downstream thread id
1269 //! @return        session use EVENT mode.
1270 protocol_module_base::EVENT_TAG protocol_module_ip::handle_session_finalize(
1271         const boost::thread::id up_thread_id, const boost::thread::id down_thread_id)
1272 {
1273         /*-------- DEBUG LOG --------*/
1274         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1275                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1276                                         "handle_session_finalize(const boost::thread::id up_thread_id, "
1277                                         "const boost::thread::id down_thread_id) : "
1278                                         "up_thread_id = %d, down_thread_id = %d.");
1279                 formatter % up_thread_id % down_thread_id;
1280                 putLogDebug(600044, formatter.str(), __FILE__, __LINE__);
1281         }
1282         /*------DEBUG LOG END------*/
1283         EVENT_TAG status = STOP;
1284         thread_data_ptr p_up;
1285         thread_data_ptr p_down;
1286         session_thread_data_map_it session_thread_data_it;
1287
1288         //session thread free
1289         try {
1290                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1291
1292                 session_thread_data_it = session_thread_data_map.find(up_thread_id);
1293                 if (session_thread_data_it != session_thread_data_map.end()) {
1294                         p_up = session_thread_data_it->second;
1295                         /*-------- DEBUG LOG --------*/
1296                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1297                                 boost::format formatter("delete : address = &(%d).");
1298                                 formatter % static_cast<void *>(p_up->data_buffer);
1299                                 putLogDebug(600045, formatter.str(), __FILE__, __LINE__);
1300                         }
1301                         /*------DEBUG LOG END------*/
1302
1303                         delete p_up->data_buffer;
1304                         /*-------- DEBUG LOG --------*/
1305                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1306                                 boost::format formatter("delete : address = &(%d).");
1307                                 formatter % static_cast<void *>(p_up.get());
1308                                 putLogDebug(600046, formatter.str(), __FILE__, __LINE__);
1309                         }
1310                         /*------DEBUG LOG END------*/
1311
1312                         session_thread_data_map.erase(up_thread_id);
1313                 }
1314
1315                 session_thread_data_it = session_thread_data_map.find(down_thread_id);
1316                 if (session_thread_data_it != session_thread_data_map.end()) {
1317
1318                         p_down = session_thread_data_it->second;
1319                         /*-------- DEBUG LOG --------*/
1320                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1321                                 boost::format formatter("delete : address = &(%d).");
1322                                 formatter % static_cast<void *>(p_up->data_buffer);
1323                                 putLogDebug(600047, formatter.str(), __FILE__, __LINE__);
1324                         }
1325                         /*------DEBUG LOG END------*/
1326
1327                         delete p_down->data_buffer;
1328                         /*-------- DEBUG LOG --------*/
1329                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1330                                 boost::format formatter("delete : address = &(%d).");
1331                                 formatter % static_cast<void *>(p_down.get());
1332                                 putLogDebug(600048, formatter.str(), __FILE__, __LINE__);
1333                         }
1334                         /*------DEBUG LOG END------*/
1335
1336                         session_thread_data_map.erase(down_thread_id);
1337                 }
1338
1339                 //set return status
1340                 status = STOP;
1341         } catch (const std::exception &ex) {
1342                 std::cerr << "protocol_module_ip::handle_session_finalize() : exception : error = " << ex.what() << "." << std::endl;
1343                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1344                                         "handle_session_finalize() : exception : error = %s. thread id : %d.");
1345                 formatter % ex.what() % boost::this_thread::get_id();
1346                 putLogError(600030, formatter.str(), __FILE__, __LINE__);
1347                 status = STOP;
1348         } catch (...) {
1349                 std::cerr << "protocol_module_ip::handle_session_finalize() : Unknown exception." << std::endl;
1350                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1351                                         "handle_session_finalize() : "
1352                                         "Unknown exception. thread id : %d.");
1353                 formatter % boost::this_thread::get_id();
1354                 putLogError(600031, formatter.str(), __FILE__, __LINE__);
1355                 status = STOP;
1356         }
1357         /*-------- DEBUG LOG --------*/
1358         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1359                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1360                                         "handle_session_finalize(const boost::thread::id up_thread_id, "
1361                                         "const boost::thread::id down_thread_id) : return_value = %d. thread id : %d.");
1362                 formatter % status % boost::this_thread::get_id();
1363                 putLogDebug(600049, formatter.str(), __FILE__, __LINE__);
1364         }
1365         /*------DEBUG LOG END------*/
1366         return status;
1367 }
1368
1369 //! called from after session accept.in client socket use in upstream thread.
1370 //! @param[in]    upstream thread id.
1371 //! @return        session use EVENT mode.
1372 protocol_module_base::EVENT_TAG protocol_module_ip::handle_accept(const boost::thread::id thread_id)
1373 {
1374         /*-------- DEBUG LOG --------*/
1375         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1376                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1377                                         "handle_accept(const boost::thread::id thread_id) : thread_id = %d.");
1378                 formatter % thread_id;
1379                 putLogDebug(600050, formatter.str(), __FILE__, __LINE__);
1380         }
1381         /*------DEBUG LOG END------*/
1382
1383         EVENT_TAG status = FINALIZE;
1384         thread_data_ptr session_data_ptr;
1385         session_thread_data_map_it session_thread_it;
1386
1387         try {
1388                 {
1389                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1390
1391                         session_thread_it = session_thread_data_map.find(thread_id);
1392                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1393                                 boost::format formatter("Invalid thread id. thread id : %d.");
1394                                 formatter % boost::this_thread::get_id();
1395                                 putLogError(600032, formatter.str(), __FILE__, __LINE__);
1396                                 throw - 1;
1397                         }
1398
1399                         session_data_ptr = session_thread_it->second;
1400                 }
1401
1402                 //set accept end flag ON
1403                 session_data_ptr->accept_end_flag = ACCEPT_END_FLAG_ON;
1404
1405                 /*-------- DEBUG LOG --------*/
1406                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1407                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1408                                                 "handle_accept(const boost::thread::id thread_id) : ACCEPT_END_FLAG_ON. thread id : %d.");
1409                         formatter % boost::this_thread::get_id();
1410                         putLogDebug(600051, formatter.str(), __FILE__, __LINE__);
1411                 }
1412                 /*------DEBUG LOG END------*/
1413
1414                 //sorry flag on
1415                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
1416                         //set return status
1417                         status = SORRYSERVER_SELECT;
1418                 }
1419                 //sorry flag off
1420                 else {
1421                         //set return status
1422                         status = REALSERVER_SELECT;
1423                 }
1424
1425                 //set last status
1426                 session_data_ptr->last_status = status;
1427         } catch (int e) {
1428                 /*-------- DEBUG LOG --------*/
1429                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1430                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1431                                                 "handle_accept() : catch exception e = %d. thread id : %d.");
1432                         formatter % e % boost::this_thread::get_id();
1433                         putLogDebug(600052, formatter.str(), __FILE__, __LINE__);
1434                 }
1435                 /*------DEBUG LOG END------*/
1436                 status = FINALIZE;
1437         } catch (const std::exception &ex) {
1438                 std::cerr << "protocol_module_ip::handle_accept() : exception : error = " << ex.what() << "." << std::endl;
1439                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1440                                         "handle_accept() : exception : error = %s. thread id : %d.");
1441                 formatter % ex.what() % boost::this_thread::get_id();
1442                 putLogError(600033, formatter.str(), __FILE__, __LINE__);
1443                 status = FINALIZE;
1444         } catch (...) {
1445                 std::cerr << "protocol_module_ip::handle_accept() : Unknown exception." << std::endl;
1446                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
1447                                         "protocol_module_ip::handle_accept() : "
1448                                         "Unknown exception. thread id : %d.");
1449                 formatter % boost::this_thread::get_id();
1450                 putLogError(600034, formatter.str(), __FILE__, __LINE__);
1451                 status = FINALIZE;
1452         }
1453
1454         /*-------- DEBUG LOG --------*/
1455         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1456                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1457                                         "handle_accept(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
1458                 formatter % status % boost::this_thread::get_id();
1459                 putLogDebug(600053, formatter.str(), __FILE__, __LINE__);
1460         }
1461         /*------DEBUG LOG END------*/
1462
1463         return status;
1464 }
1465
1466 //! called from after session recv in client socket. use in upstream thread.
1467 //! @param[in]    upstream thread id
1468 //! @param[in]    receive buffer refarence.
1469 //! @param[in]    receive length
1470 //! @return        session use EVENT mode.
1471 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_recv(const boost::thread::id thread_id,
1472                 const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen)
1473 {
1474
1475         /*-------- DEBUG LOG --------*/
1476         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1477                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
1478                 std::string buffer;
1479                 dump_memory(recvbuffer.data(), buffer_size, buffer);
1480                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1481                                         "handle_client_recv(const boost::thread::id thread_id, "
1482                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1483                                         "const size_t recvlen) : thread_id = %d, recvbuffer = %s, recvlen = %d.");
1484                 formatter % thread_id % buffer % recvlen;
1485                 putLogDebug(600054, formatter.str(), __FILE__, __LINE__);
1486         }
1487         /*------DEBUG LOG END------*/
1488
1489         EVENT_TAG status                = FINALIZE;
1490         bool find_ret                    = false;
1491         size_t http_header_offset            = 0;
1492         size_t http_header_len                = 0;
1493         size_t http_header_content_length_offset    = 0;
1494         size_t http_header_content_length_len        = 0;
1495         int content_length_value            = 0;
1496         const size_t CR_LF_LEN                = 2; //length of "\r\n"
1497         const size_t CR_LF_CR_LF_LEN            = 4; //length of "\r\n\r\n"
1498         session_thread_data_map_it            session_thread_it;
1499         thread_data_ptr                    session_data_ptr;
1500         http_utility::CHECK_RESULT_TAG             check_ret;
1501
1502         std::string content_length;
1503         cmatch regex_ret;
1504         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
1505
1506         //parameter check
1507         if (unlikely(recvlen > recvbuffer.size())) {
1508                 std::cerr << "protocol_module_ip::handle_client_recv() : Data size bigger than buffer size." << std::endl;
1509                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
1510                 formatter % boost::this_thread::get_id();
1511                 putLogError(600035, formatter.str(), __FILE__, __LINE__);
1512
1513                 /*-------- DEBUG LOG --------*/
1514                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1515                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1516                                                 "handle_client_recv(const boost::thread::id thread_id, "
1517                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1518                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
1519                         formatter % FINALIZE % boost::this_thread::get_id();
1520                         putLogDebug(600055, formatter.str(), __FILE__, __LINE__);
1521                 }
1522                 /*------DEBUG LOG END------*/
1523                 return status;
1524         }
1525
1526         try {
1527                 {
1528                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1529
1530                         session_thread_it = session_thread_data_map.find(thread_id);
1531                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1532
1533                                 boost::format formatter("Invalid thread id. thread id : %d.");
1534                                 formatter % boost::this_thread::get_id();
1535                                 putLogError(600036, formatter.str(), __FILE__, __LINE__);
1536                                 throw - 1;
1537                         }
1538
1539                         session_data_ptr = session_thread_it->second;
1540                 }
1541
1542                 //end flag on
1543                 if (session_data_ptr->end_flag == END_FLAG_ON) {
1544                         //set return status
1545                         status = CLIENT_RECV;
1546                 }
1547                 //end flag off
1548                 else {
1549                         //copy data from recvbuffer
1550                         if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
1551                                 //copy failed
1552                                 std::cerr << "protocol_module_ip::handle_client_recv() : Data size bigger than buffer size." << std::endl;
1553                                 boost::format formatter("Data size bigger than buffer size. thread id : % id.");
1554                                 formatter % boost::this_thread::get_id();
1555                                 putLogError(600037, formatter.str(), __FILE__, __LINE__);
1556                                 status = FINALIZE;
1557                         } else {
1558                                 if (forwarded_for == FORWARDED_FOR_OFF) {
1559                                         session_data_ptr->data_state = UNKNOWN;
1560                                 }
1561                                 //data state is HTTP_START
1562                                 if (session_data_ptr->data_state == HTTP_START) {
1563                                         //search http header
1564                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
1565                                                         session_data_ptr->data_length,
1566                                                         http_header_offset,
1567                                                         http_header_len
1568                                                                                      );
1569
1570                                         /*-------- DEBUG LOG --------*/
1571                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1572                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1573                                                                         "handle_client_recv() : call find_http_header_all : "
1574                                                                         "return_value = %d. thread id : %d.");
1575                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
1576                                                 putLogDebug(600056, formatter.str(), __FILE__, __LINE__);
1577                                         }
1578                                         /*------DEBUG LOG END------*/
1579
1580                                         //search http header result is NG
1581                                         if (!find_ret) {
1582                                                 //data size bigger than max buffer size
1583                                                 if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
1584                                                         //set data state UNKNOWN
1585                                                         session_data_ptr->data_state = UNKNOWN;
1586                                                         //set current message rest size
1587                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1588                                                 }
1589                                         }
1590                                         //search http header result is OK
1591                                         else {
1592                                                 //check http method and version
1593                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer,
1594                                                                 session_data_ptr->data_length);
1595                                                 /*-------- DEBUG LOG --------*/
1596                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1597                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1598                                                                                 "handle_client_recv() : call check_http_method_and_version : "
1599                                                                                 "return_value = %d. thread id : %d.");
1600                                                         formatter % check_ret % boost::this_thread::get_id();
1601                                                         putLogDebug(600057, formatter.str(), __FILE__, __LINE__);
1602                                                 }
1603                                                 /*------DEBUG LOG END------*/
1604
1605                                                 //check http method and version result is NG
1606                                                 if (check_ret == http_utility::CHECK_NG) {
1607                                                         //set data state UNKNOWN
1608                                                         session_data_ptr->data_state = UNKNOWN;
1609                                                         //set current message rest size
1610                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1611                                                 }
1612                                                 //check http method and version result is OK
1613                                                 else {
1614                                                         //search Content_Length header
1615                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
1616                                                                         session_data_ptr->data_length,
1617                                                                         http_header_content_length_offset,
1618                                                                         http_header_content_length_len);
1619                                                         /*-------- DEBUG LOG --------*/
1620                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1621                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1622                                                                                         "handle_client_recv() : call find_http_header_content_length : "
1623                                                                                         "return_value = %d. thread id : %d.");
1624                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
1625                                                                 putLogDebug(600058, formatter.str(), __FILE__, __LINE__);
1626                                                         }
1627                                                         /*------DEBUG LOG END------*/
1628
1629                                                         //search Content_Length result is OK
1630                                                         if (find_ret) {
1631                                                                 //set content length string
1632                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
1633                                                                                       http_header_content_length_len);
1634                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
1635
1636                                                                 //"content-length: ddd\r\n"
1637                                                                 if (find_ret) {
1638                                                                         content_length = content_length.substr(
1639                                                                                                  regex_ret.position(1),
1640                                                                                                  regex_ret.length(1));
1641
1642                                                                         //set content length value
1643                                                                         content_length_value = boost::lexical_cast<int>(content_length);
1644                                                                 }
1645
1646                                                                 //http_header context is "\r\n\r\n" only
1647                                                                 if (http_header_len == 0) {
1648                                                                         //set current message rest size
1649                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
1650                                                                 } else {
1651                                                                         //set current message rest size
1652                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
1653                                                                 }
1654                                                         }
1655                                                         //search Content_Length result is NG
1656                                                         else {
1657                                                                 //http_header context is "\r\n\r\n" only
1658                                                                 if (http_header_len == 0) {
1659                                                                         //set current message rest size
1660                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
1661                                                                 } else {
1662                                                                         //set current message rest size
1663                                                                         session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
1664                                                                 }
1665
1666                                                         }
1667
1668                                                         //set data state HTTP_HEADER
1669                                                         session_data_ptr->data_state = HTTP_HEADER;
1670
1671                                                 }
1672                                         }
1673                                 }
1674                                 //data state is UNKNOWN
1675                                 else if (session_data_ptr->data_state == UNKNOWN) {
1676                                         //set current message rest size
1677                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
1678                                 } else {
1679                                         //none
1680                                 }
1681
1682                                 //data state is HTTP_START
1683                                 if (session_data_ptr->data_state == HTTP_START) {
1684                                         status = CLIENT_RECV;
1685                                 }
1686                                 //data state is not HTTP_START
1687                                 else {
1688                                         //sorry flag is on
1689                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
1690                                                 //set return status
1691                                                 status = SORRYSERVER_CONNECT;
1692                                         }
1693                                         //sorry flag is off
1694                                         else {
1695                                                 //set return status
1696                                                 status = REALSERVER_CONNECT;
1697                                         }
1698                                 }
1699                         }
1700                 }
1701
1702                 //set last status
1703                 session_data_ptr->last_status = status;
1704         } catch (int e) {
1705                 /*-------- DEBUG LOG --------*/
1706                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1707                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1708                                                 "handle_client_recv() : catch exception e = %d. thread id : %d.");
1709                         formatter % e % boost::this_thread::get_id();
1710                         putLogDebug(600059, formatter.str(), __FILE__, __LINE__);
1711                 }
1712                 /*------DEBUG LOG END------*/
1713                 status = FINALIZE;
1714         } catch (const boost::bad_lexical_cast &) {
1715                 std::cerr << "protocol_module_ip::handle_client_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
1716                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_recv() : "
1717                                         "Content_Length field's value is invalid. thread id : %d.");
1718                 formatter % boost::this_thread::get_id();
1719                 putLogError(600038, formatter.str(), __FILE__, __LINE__);
1720                 status = FINALIZE;
1721         } catch (const std::exception &ex) {
1722                 std::cerr << "protocol_module_ip::handle_client_recv() : exception : error = " << ex.what() << "." << std::endl;
1723                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1724                                         "handle_client_recv() : exception : error = %s. thread id : %d.");
1725                 formatter % ex.what() % boost::this_thread::get_id();
1726                 putLogError(600039, formatter.str(), __FILE__, __LINE__);
1727                 status = FINALIZE;
1728         } catch (...) {
1729                 std::cerr << "protocol_module_ip::handle_client_recv() : Unknown exception." << std::endl;
1730                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
1731                                         "protocol_module_ip::handle_client_recv() : "
1732                                         "Unknown exception. thread id : %d.");
1733                 formatter % boost::this_thread::get_id();
1734                 putLogError(600040, formatter.str(), __FILE__, __LINE__);
1735                 status = FINALIZE;
1736         }
1737
1738         /*-------- DEBUG LOG --------*/
1739         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1740                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1741                                         "handle_client_recv(const boost::thread::id thread_id, "
1742                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
1743                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
1744                 formatter % status % boost::this_thread::get_id();
1745                 putLogDebug(600060, formatter.str(), __FILE__, __LINE__);
1746         }
1747         /*------DEBUG LOG END------*/
1748
1749         return status;
1750 }
1751
1752 //! called from after realserver select.use in upstream thread.
1753 //! @param[in]    upstream thread id
1754 //! @param[out]    realserver TCP endpoint
1755 //! @return        session use EVENT mode.
1756 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_select(
1757         const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &rs_endpoint)
1758 {
1759
1760         /*-------- DEBUG LOG --------*/
1761         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1762                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1763                                         "handle_realserver_select(const boost::thread::id thread_id, "
1764                                         "boost::asio::ip::tcp::endpoint& rs_endpoint) : "
1765                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
1766                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
1767                 putLogDebug(600061, formatter.str(), __FILE__, __LINE__);
1768         }
1769         /*------DEBUG LOG END------*/
1770
1771         EVENT_TAG status = FINALIZE;
1772         boost::asio::ip::tcp::endpoint init_endpoint;
1773         thread_data_ptr session_data_ptr;
1774         session_thread_data_map_it session_thread_it;
1775         session_thread_data_map_it session_thread_it_end;
1776         realserverlist_type::iterator    rs_list_itr;
1777
1778         if (unlikely(schedule_tcp.empty())) {
1779                 std::cerr << "protocol_module_ip::handle_realserver_select() : Schedule_tcp function is empty." << std::endl;
1780                 boost::format formatter("Schedule_tcp function is empty. thread id : %d.");
1781                 formatter % boost::this_thread::get_id();
1782                 putLogError(600041, formatter.str(), __FILE__, __LINE__);
1783
1784                 /*-------- DEBUG LOG --------*/
1785                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1786                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1787                                                 "handle_realserver_select(const boost::thread::id thread_id, "
1788                                                 "boost::asio::ip::tcp::endpoint& rs_endpoint)"
1789                                                 " : return_value = %d. thread id : %d.");
1790                         formatter % FINALIZE % boost::this_thread::get_id();
1791                         putLogDebug(600062, formatter.str(), __FILE__, __LINE__);
1792                 }
1793                 /*------DEBUG LOG END------*/
1794                 return FINALIZE;
1795         }
1796
1797
1798         try {
1799                 {
1800                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
1801
1802                         session_thread_it = session_thread_data_map.find(thread_id);
1803                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
1804                                 boost::format formatter("Invalid thread id. thread id : %d.");
1805                                 formatter % boost::this_thread::get_id();
1806                                 putLogError(600042, formatter.str(), __FILE__, __LINE__);
1807                                 throw - 1;
1808                         }
1809
1810                         session_data_ptr = session_thread_it->second;
1811                 }
1812
1813                 //initialize realserver endpoint
1814                 rs_endpoint = init_endpoint;
1815
1816                 boost::mutex::scoped_lock lock(session_data_mutex);
1817
1818                 //get endpoint data from the ip data
1819                 int ret = ip_data_processor->get_endpoint_from_session_data(session_data_ptr->ip_hash,
1820                                 rs_endpoint);
1821
1822                 /*-------- DEBUG LOG --------*/
1823                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1824                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
1825                                                 "protocol_module_ip::handle_realserver_select() : "
1826                                                 "get_endpoint_from_session_data() end. thread id : %d.");
1827                         formatter % boost::this_thread::get_id();
1828                         putLogDebug(600063, formatter.str(), __FILE__, __LINE__);
1829                 }
1830                 /*------DEBUG LOG END------*/
1831
1832                 //endpoint is matched
1833                 if (ret == 0) {
1834                         int is_match = 0;
1835                         //find the rs_endpoint in rs_list
1836                         {
1837                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
1838
1839                                 rs_list_itr = rs_list_begin();
1840
1841                                 while (rs_list_itr != rs_list_end()) {
1842
1843                                         if (rs_list_itr->tcp_endpoint == rs_endpoint) {
1844                                                 is_match = 1;
1845                                                 break;
1846                                         }
1847
1848                                         rs_list_itr = rs_list_next(rs_list_itr);
1849                                 }
1850                         }
1851
1852                         //endpoint is matched in the list
1853                         if (is_match) {
1854                                 //set return status
1855                                 status = REALSERVER_CONNECT;
1856                         }
1857                         //endpoint is not matched in the list
1858                         else {
1859                                 //if reschedule is on then try multi times connect
1860                                 if (reschedule == 1) {
1861                                         // init rs_endpoint
1862                                         rs_endpoint = init_endpoint;
1863                                         {
1864                                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
1865                                                 schedule_tcp(thread_id, rs_list_begin, rs_list_end, rs_list_next, rs_endpoint);
1866                                         }
1867
1868                                         /*-------- DEBUG LOG --------*/
1869                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1870                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1871                                                                         "handle_realserver_select() : call schedule_tcp : "
1872                                                                         "rs_endpoint = [%s]:%d. thread id : %d.");
1873                                                 formatter % rs_endpoint.address().to_string() % rs_endpoint.port() % boost::this_thread::get_id();
1874                                                 putLogDebug(600064, formatter.str(), __FILE__, __LINE__);
1875                                         }
1876                                         /*------DEBUG LOG END------*/
1877
1878                                         //get the endpoint by schedule successfully
1879                                         if (init_endpoint != rs_endpoint) {
1880                                                 time_t init_time = 0;
1881
1882                                                 //write data to session table
1883                                                 ip_data_processor->write_session_data(session_data_ptr->ip_hash, rs_endpoint, init_time);
1884                                                 /*-------- DEBUG LOG --------*/
1885                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1886                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
1887                                                                                 "protocol_module_ip::handle_realserver_select() : "
1888                                                                                 "write_session_data() end. thread id : %d.");
1889                                                         formatter % boost::this_thread::get_id();
1890                                                         putLogDebug(600065, formatter.str(), __FILE__, __LINE__);
1891                                                 }
1892                                                 /*------DEBUG LOG END------*/
1893
1894                                                 //set return status
1895                                                 status = REALSERVER_CONNECT;
1896                                         }
1897                                         //get the endpoint by schedule unsuccessfully
1898                                         else {
1899                                                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
1900                                                 /*-------- DEBUG LOG --------*/
1901                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1902                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1903                                                                                 "handle_realserver_select()"
1904                                                                                 " : SORRY_FLAG_ON. thread id : %d.");
1905                                                         formatter % boost::this_thread::get_id();
1906                                                         putLogDebug(600066, formatter.str(), __FILE__, __LINE__);
1907                                                 }
1908                                                 /*------DEBUG LOG END------*/
1909
1910                                                 //set return status
1911                                                 status = SORRYSERVER_SELECT;
1912                                         }
1913                                 }
1914                                 //reschedule is off
1915                                 else {
1916                                         //set return status
1917                                         status = CLIENT_DISCONNECT;
1918                                 }
1919                         }
1920                 }
1921                 //endpoint is not matched
1922                 else {
1923                         // init rs_endpoint
1924                         rs_endpoint = init_endpoint;
1925
1926                         //call schedule_module's schedule function, get realserver endpoint
1927                         {
1928                                 rs_list_scoped_lock scoped_lock(rs_list_lock, rs_list_unlock);
1929                                 schedule_tcp(thread_id, rs_list_begin, rs_list_end, rs_list_next, rs_endpoint);
1930                         }
1931
1932                         /*-------- DEBUG LOG --------*/
1933                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1934                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1935                                                         "handle_realserver_select() : call schedule_tcp : "
1936                                                         "rs_endpoint = [%s]:%d. thread id : %d.");
1937                                 formatter % rs_endpoint.address().to_string() % rs_endpoint.port() % boost::this_thread::get_id();
1938                                 putLogDebug(600067, formatter.str(), __FILE__, __LINE__);
1939                         }
1940                         /*------DEBUG LOG END------*/
1941
1942                         //get the endpoint by schedule successfully
1943                         if (init_endpoint != rs_endpoint) {
1944                                 time_t init_time = 0;
1945
1946                                 //write data to session table
1947                                 ip_data_processor->write_session_data(session_data_ptr->ip_hash, rs_endpoint, init_time);
1948                                 /*-------- DEBUG LOG --------*/
1949                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1950                                         boost::format formatter("function : protocol_module_base::EVENT_TAG "
1951                                                                 "protocol_module_ip::handle_realserver_select() : "
1952                                                                 "write_session_data() end. thread id : %d.");
1953                                         formatter % boost::this_thread::get_id();
1954                                         putLogDebug(600068, formatter.str(), __FILE__, __LINE__);
1955                                 }
1956                                 /*------DEBUG LOG END------*/
1957
1958                                 //set return status
1959                                 status = REALSERVER_CONNECT;
1960                         }
1961                         //get the endpoint by schedule unsuccessfully
1962                         else {
1963                                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
1964                                 /*-------- DEBUG LOG --------*/
1965                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1966                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1967                                                                 "handle_realserver_select()"
1968                                                                 " : SORRY_FLAG_ON. thread id : %d.");
1969                                         formatter % boost::this_thread::get_id();
1970                                         putLogDebug(600069, formatter.str(), __FILE__, __LINE__);
1971                                 }
1972                                 /*------DEBUG LOG END------*/
1973                                 //set return status
1974                                 status = SORRYSERVER_SELECT;
1975
1976                         }
1977                 }
1978
1979                 //set last status
1980                 session_data_ptr->last_status = status;
1981         } catch (int e) {
1982                 /*-------- DEBUG LOG --------*/
1983                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
1984                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1985                                                 "handle_realserver_select() : catch exception e = %d. thread id : %d.");
1986                         formatter % e % boost::this_thread::get_id();
1987                         putLogDebug(600070, formatter.str(), __FILE__, __LINE__);
1988                 }
1989                 /*------DEBUG LOG END------*/
1990                 status = FINALIZE;
1991         } catch (const std::exception &ex) {
1992                 std::cerr << "protocol_module_ip::handle_realserver_select() : exception : error = " << ex.what() << "." << std::endl;
1993                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
1994                                         "handle_realserver_select() : exception : error = %s. thread id : %d.");
1995                 formatter % ex.what() % boost::this_thread::get_id();
1996                 putLogError(600043, formatter.str(), __FILE__, __LINE__);
1997                 status = FINALIZE;
1998         } catch (...) {
1999                 std::cerr << "protocol_module_ip::handle_realserver_select() : Unknown exception." << std::endl;
2000                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2001                                         "protocol_module_ip::handle_realserver_select() : "
2002                                         "Unknown exception. thread id : %d.");
2003                 formatter % boost::this_thread::get_id();
2004                 putLogError(600044, formatter.str(), __FILE__, __LINE__);
2005                 status = FINALIZE;
2006         }
2007
2008         /*-------- DEBUG LOG --------*/
2009         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2010                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2011                                         "handle_realserver_select(const boost::thread::id thread_id, "
2012                                         "boost::asio::ip::tcp::endpoint& rs_endpoint)"
2013                                         " : return_value = %d. thread id : %d.");
2014                 formatter % status % boost::this_thread::get_id();
2015                 putLogDebug(600071, formatter.str(), __FILE__, __LINE__);
2016         }
2017         /*------DEBUG LOG END------*/
2018         return status;
2019 }
2020
2021 //! called from after realserver select
2022 //! @param[in]    upstream thread id
2023 //! @param[out]    realserver UDP endpoint
2024 //! @param[out]    sendbuffer reference
2025 //! @param[out]    send data length
2026 //! @return        session use EVENT mode.
2027 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_select(
2028         const boost::thread::id thread_id, boost::asio::ip::udp::endpoint &rs_endpoint, boost::array < char,
2029         MAX_BUFFER_SIZE > & sendbuffer, size_t &datalen)
2030 {
2031         /*-------- DEBUG LOG --------*/
2032         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2033                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2034                                         "handle_realserver_select(const boost::thread::id thread_id, "
2035                                         "boost::asio::ip::udp::endpoint& rs_endpoint, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
2036                                         "size_t& datalen) : "
2037                                         "return_value = %d. thread id : %d.");
2038                 formatter % STOP % boost::this_thread::get_id();
2039                 putLogDebug(600072, formatter.str(), __FILE__, __LINE__);
2040         }
2041         /*------DEBUG LOG END------*/
2042         return STOP;
2043 }
2044 //! called from after realserver connect
2045 //! @param[in]    upstream thread id
2046 //! @param[out]    sendbuffer reference
2047 //! @param[out]    send data length
2048 //! @return        session use EVENT mode.
2049 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_connect(
2050         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
2051 {
2052         /*-------- DEBUG LOG --------*/
2053         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2054                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2055                                         "handle_realserver_connect(const boost::thread::id thread_id, "
2056                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
2057                                         "thread_id = %d.");
2058                 formatter % thread_id;
2059                 putLogDebug(600073, formatter.str(), __FILE__, __LINE__);
2060         }
2061         /*------DEBUG LOG END------*/
2062
2063         EVENT_TAG status            = FINALIZE;
2064         size_t send_possible_size        = 0;
2065         size_t x_forwarded_for_insert_pos   = 0;
2066         thread_data_ptr                session_data_ptr;
2067         session_thread_data_map_it        session_thread_it;
2068         std::pair<char *, size_t>        buffer_element;
2069         std::string                x_forwarded_for_context;
2070
2071         try {
2072                 {
2073                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2074
2075                         //thread id check
2076                         session_thread_it = session_thread_data_map.find(thread_id);
2077                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2078                                 boost::format formatter("Invalid thread id. thread id : %d.");
2079                                 formatter % boost::this_thread::get_id();
2080                                 putLogError(600045, formatter.str(), __FILE__, __LINE__);
2081                                 throw - 1;
2082                         }
2083
2084                         session_data_ptr = session_thread_it->second;
2085                 }
2086
2087                 send_possible_size = std::min(session_data_ptr->current_message_rest_size,
2088                                               session_data_ptr->data_length
2089                                              );
2090
2091                 //buffer sequence is empty
2092                 if (session_data_ptr->buffer_sequence.empty()) {
2093                         //data state is HTTP_HEADER
2094                         if (session_data_ptr->data_state == HTTP_HEADER) {
2095                                 //forwarded_for flag is on
2096                                 if (forwarded_for == FORWARDED_FOR_ON) {
2097                                         //search X-Forwarded-For header
2098                                         create_x_forwarded_for(session_data_ptr->client_endpoint.address().to_string(),
2099                                                                session_data_ptr->data_buffer + session_data_ptr->data_offset,
2100                                                                session_data_ptr->data_length,
2101                                                                x_forwarded_for_insert_pos,
2102                                                                x_forwarded_for_context);
2103
2104                                         //put buffer data to buffer_sequence
2105                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2106                                         buffer_element.second = x_forwarded_for_insert_pos;
2107                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2108
2109                                         session_data_ptr->forwarded_for_buffer.assign(0);
2110
2111                                         /*-------- DEBUG LOG --------*/
2112                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2113                                                 std::string datadump;
2114                                                 dump_memory(x_forwarded_for_context.c_str(),
2115                                                             x_forwarded_for_context.size(), datadump);
2116                                                 boost::format formatter(
2117                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2118                                                         "handle_realserver_connect() : before memcpy (data dump) : "
2119                                                         "data begin = 0, data_size = %d, data = %s");
2120                                                 formatter %  x_forwarded_for_context.size() % datadump;
2121                                                 putLogDebug(600074, formatter.str(), __FILE__, __LINE__);
2122                                         }
2123                                         /*------DEBUG LOG END------*/
2124
2125                                         memcpy(session_data_ptr->forwarded_for_buffer.data(),
2126                                                x_forwarded_for_context.c_str(),
2127                                                x_forwarded_for_context.size());
2128
2129                                         /*-------- DEBUG LOG --------*/
2130                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2131                                                 std::string datadump;
2132                                                 dump_memory(x_forwarded_for_context.c_str(),
2133                                                             x_forwarded_for_context.size(), datadump);
2134                                                 boost::format formatter(
2135                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2136                                                         "handle_realserver_connect() : after memcpy (data dump) : "
2137                                                         "data begin = 0, data_size = %d, data = %s");
2138                                                 formatter % x_forwarded_for_context.size() % datadump;
2139                                                 putLogDebug(600075, formatter.str(), __FILE__, __LINE__);
2140                                         }
2141                                         /*------DEBUG LOG END------*/
2142
2143                                         //set buffer's position
2144                                         buffer_element.first = session_data_ptr->forwarded_for_buffer.data();
2145                                         buffer_element.second = x_forwarded_for_context.size();
2146
2147                                         //set data to buffer_sequence
2148                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2149
2150                                         //set buffer's position
2151                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset + x_forwarded_for_insert_pos;
2152                                         buffer_element.second = send_possible_size - x_forwarded_for_insert_pos;
2153
2154                                         //set data to buffer_sequence
2155                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2156                                 }
2157                                 //forwarded_for flag is off
2158                                 else {
2159                                         //set buffer's position
2160                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2161                                         buffer_element.second = send_possible_size;
2162
2163                                         //set data to buffer_sequence
2164                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2165                                 }
2166                                 session_data_ptr->data_state = HTTP_BODY;
2167                         }
2168                         //data state is not HTTP_HEADER
2169                         else {
2170
2171                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2172                                 buffer_element.second = send_possible_size;
2173
2174                                 //set data to buffer_sequence
2175                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2176
2177                         }
2178                 }
2179
2180                 //put buffer_sequence data into sendbuffer
2181                 put_data_into_sendbuffer(session_data_ptr, sendbuffer, datalen);
2182
2183                 //set return status
2184                 status = REALSERVER_SEND;
2185
2186                 //set last status
2187                 session_data_ptr->last_status = status;
2188         } catch (int e) {
2189                 /*-------- DEBUG LOG --------*/
2190                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2191                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2192                                                 "handle_realserver_connect() : catch exception e = %d. thread id : %d.");
2193                         formatter % e % boost::this_thread::get_id();
2194                         putLogDebug(600076, formatter.str(), __FILE__, __LINE__);
2195                 }
2196                 /*------DEBUG LOG END------*/
2197
2198                 //set return status
2199                 status = FINALIZE;
2200         } catch (std::exception &ex) {
2201                 std::cerr << "protocol_module_ip::handle_realserver_connect() : exception : error = " << ex.what() << "." << std::endl;
2202                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2203                                         "handle_realserver_connect() : exception : error = %s. thread id : %d.");
2204                 formatter % ex.what() % boost::this_thread::get_id();
2205                 putLogError(600046, formatter.str(), __FILE__, __LINE__);
2206
2207                 //set return status
2208                 status = FINALIZE;
2209         } catch (...) {
2210                 std::cerr << "protocol_module_ip::handle_realserver_connect() : Unknown exception." << std::endl;
2211                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2212                                         "handle_realserver_connect() : Unknown exception. thread id : %d.");
2213                 formatter % boost::this_thread::get_id();
2214                 putLogError(600047, formatter.str(), __FILE__, __LINE__);
2215
2216                 //set return status
2217                 status = FINALIZE;
2218         }
2219
2220         /*-------- DEBUG LOG --------*/
2221         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2222                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2223                                         "handle_realserver_connect(const boost::thread::id thread_id, "
2224                                         "boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
2225                                         "size_t& datalen) : return_value = %d. thread id : %d.");
2226                 formatter % status % boost::this_thread::get_id();
2227                 putLogDebug(600077, formatter.str(), __FILE__, __LINE__);
2228         }
2229         /*------DEBUG LOG END------*/
2230
2231         return status;
2232 }
2233
2234 //! called from after realserver connection fail
2235 //! @param[in]    upstream thread id
2236 //! @param[in]    fail realserver endpoint reference
2237 //! @return        session use EVENT mode.
2238 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_connection_fail(
2239         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint)
2240 {
2241         /*-------- DEBUG LOG --------*/
2242         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2243                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2244                                         "handle_realserver_connection_fail(const boost::thread::id thread_id, "
2245                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : "
2246                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
2247                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
2248                 putLogDebug(600078, formatter.str(), __FILE__, __LINE__);
2249         }
2250         /*------DEBUG LOG END------*/
2251
2252         EVENT_TAG status = FINALIZE;
2253         thread_data_ptr session_data_ptr;
2254         session_thread_data_map_it session_thread_it;
2255
2256         try {
2257                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2258
2259                 session_thread_it = session_thread_data_map.find(thread_id);
2260                 if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2261                         boost::format formatter("Invalid thread id. thread id : %d.");
2262                         formatter % boost::this_thread::get_id();
2263                         putLogError(600048, formatter.str(), __FILE__, __LINE__);
2264                         throw - 1;
2265                 }
2266
2267                 session_data_ptr = session_thread_it->second;
2268
2269                 //set return status
2270                 status = CLIENT_DISCONNECT;
2271
2272                 //set last status
2273                 session_data_ptr->last_status = status;
2274         } catch (int e) {
2275                 /*-------- DEBUG LOG --------*/
2276                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2277                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2278                                                 "handle_realserver_connection_fail() : catch exception e = %d. thread id : %d.");
2279                         formatter % e % boost::this_thread::get_id();
2280                         putLogDebug(600079, formatter.str(), __FILE__, __LINE__);
2281                 }
2282                 /*------DEBUG LOG END------*/
2283
2284                 //set return status
2285                 status = FINALIZE;
2286         } catch (const std::exception &ex) {
2287                 std::cerr << "protocol_module_ip::handle_realserver_connection_fail() : exception : error = " << ex.what() << "." << std::endl;
2288                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2289                                         "handle_realserver_connection_fail() : exception : error = %s. thread id : %d.");
2290                 formatter % ex.what() % boost::this_thread::get_id();
2291                 putLogError(600049, formatter.str(), __FILE__, __LINE__);
2292
2293                 //set return status
2294                 status = FINALIZE;
2295         } catch (...) {
2296                 std::cerr << "protocol_module_ip::handle_realserver_connection_fail() : Unknown exception." << std::endl;
2297                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2298                                         "protocol_module_ip::handle_realserver_connection_fail() : "
2299                                         "Unknown exception. thread id : %d.");
2300                 formatter % boost::this_thread::get_id();
2301                 putLogError(600050, formatter.str(), __FILE__, __LINE__);
2302
2303                 //set return status
2304                 status = FINALIZE;
2305         }
2306
2307         /*-------- DEBUG LOG --------*/
2308         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2309                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2310                                         "handle_realserver_connection_fail(const boost::thread::id thread_id, "
2311                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : return_value = %d. thread id : %d.");
2312                 formatter % status % boost::this_thread::get_id();
2313                 putLogDebug(600080, formatter.str(), __FILE__, __LINE__);
2314         }
2315         /*------DEBUG LOG END------*/
2316
2317         return status;
2318 }
2319 //! called from after realserver send.
2320 //! @param[in]    upstream thread id
2321 //! @return        session use EVENT mode.
2322 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_send(
2323         const boost::thread::id thread_id)
2324 {
2325         /*-------- DEBUG LOG --------*/
2326         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2327                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2328                                         "handle_realserver_send(const boost::thread::id thread_id) : thread_id = %d.");
2329                 formatter % thread_id;
2330                 putLogDebug(600081, formatter.str(), __FILE__, __LINE__);
2331         }
2332         /*------DEBUG LOG END------*/
2333
2334         EVENT_TAG status                = FINALIZE;
2335         size_t http_header_all_offset            = 0;
2336         size_t http_header_all_len            = 0;
2337         size_t http_header_content_length_offset    = 0;
2338         size_t http_header_content_length_len        = 0;
2339         const size_t CR_LF_LEN                = 2;
2340         const size_t CR_LF_CR_LF_LEN            = 4;
2341         int content_length_value            = 0;
2342
2343         std::string content_length;
2344         cmatch regex_ret;
2345         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
2346
2347
2348         bool find_ret = false;
2349         http_utility::CHECK_RESULT_TAG check_ret;
2350
2351         thread_data_ptr session_data_ptr;
2352         session_thread_data_map_it session_thread_it;
2353
2354         try {
2355                 {
2356                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2357
2358                         //thread id check
2359                         session_thread_it = session_thread_data_map.find(thread_id);
2360                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2361                                 boost::format formatter("Invalid thread id. thread id : %d.");
2362                                 formatter % boost::this_thread::get_id();
2363                                 putLogError(600051, formatter.str(), __FILE__, __LINE__);
2364                                 throw - 1;
2365                         }
2366
2367                         session_data_ptr = session_thread_it->second;
2368                 }
2369
2370                 //current_message_rest_size > 0
2371                 if (session_data_ptr->current_message_rest_size > 0) {
2372                         //data size > 0
2373                         if (session_data_ptr->data_length > 0) {
2374                                 //set return status
2375                                 status = REALSERVER_CONNECT;
2376                         }
2377                         //data size is 0
2378                         else {
2379                                 //data offset is 0
2380                                 session_data_ptr->data_offset = 0;
2381
2382                                 //set return status
2383                                 status = CLIENT_RECV;
2384                         }
2385                 }
2386                 //current_message_rest_size is 0
2387                 else {
2388                         //data size > 0
2389                         if (session_data_ptr->data_length > 0) {
2390                                 //data state is HTTP_BODY
2391                                 if (session_data_ptr->data_state == HTTP_BODY) {
2392                                         //search whole http header, get whole http header's offset and length
2393                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2394                                                         session_data_ptr->data_length,
2395                                                         http_header_all_offset,
2396                                                         http_header_all_len
2397                                                                                      );
2398
2399                                         /*-------- DEBUG LOG --------*/
2400                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2401                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2402                                                                         "handle_realserver_send() : call find_http_header_all : "
2403                                                                         "return_value = %d. thread id : %d.");
2404                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
2405                                                 putLogDebug(600082, formatter.str(), __FILE__, __LINE__);
2406                                         }
2407                                         /*------DEBUG LOG END------*/
2408
2409                                         //search http header result is NG
2410                                         if (!find_ret) {
2411                                                 //set data state HTTP_START
2412                                                 session_data_ptr->data_state = HTTP_START;
2413
2414                                                 //set return status
2415                                                 status = CLIENT_RECV;
2416                                         }
2417                                         //search http header result is OK
2418                                         else {
2419                                                 //check http method and version
2420                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2421                                                                 session_data_ptr->data_length);
2422
2423                                                 /*-------- DEBUG LOG --------*/
2424                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2425                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2426                                                                                 "handle_realserver_send() : call check_http_method_and_version : "
2427                                                                                 "return_value = %d. thread id : %d.");
2428                                                         formatter % check_ret % boost::this_thread::get_id();
2429                                                         putLogDebug(600083, formatter.str(), __FILE__, __LINE__);
2430                                                 }
2431                                                 /*------DEBUG LOG END------*/
2432
2433                                                 //check method and version result is NG
2434                                                 if (check_ret == http_utility::CHECK_NG) {
2435                                                         //set current message rest size
2436                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
2437
2438                                                         //set data state UNKNOWN
2439                                                         session_data_ptr->data_state = UNKNOWN;
2440                                                 }
2441                                                 //check method and version result is OK
2442                                                 else {
2443                                                         //search Content_Length header
2444                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2445                                                                         session_data_ptr->data_length,
2446                                                                         http_header_content_length_offset,
2447                                                                         http_header_content_length_len);
2448
2449                                                         /*-------- DEBUG LOG --------*/
2450                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2451                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2452                                                                                         "handle_realserver_send() : call find_http_header_content_length : "
2453                                                                                         "return_value = %d. thread id : %d.");
2454                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
2455                                                                 putLogDebug(600084, formatter.str(), __FILE__, __LINE__);
2456                                                         }
2457                                                         /*------DEBUG LOG END------*/
2458
2459                                                         //search Content_Length result is OK
2460                                                         if (find_ret) {
2461                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
2462                                                                                       http_header_content_length_len);
2463                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
2464
2465                                                                 //"content-length: ddd\r\n"
2466                                                                 if (find_ret) {
2467                                                                         content_length = content_length.substr(
2468                                                                                                  regex_ret.position(1),
2469                                                                                                  regex_ret.length(1));
2470
2471                                                                         //set content length value
2472                                                                         content_length_value = boost::lexical_cast<int>(content_length);
2473                                                                 }
2474
2475                                                                 //http_header context is "\r\n\r\n" only
2476                                                                 if (http_header_all_len == 0) {
2477                                                                         //set current message rest size
2478                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
2479                                                                 } else {
2480                                                                         //set current message rest size
2481                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
2482                                                                 }
2483                                                         }
2484                                                         //search Content_Length result is OK
2485                                                         else {
2486                                                                 //http_header context is "\r\n\r\n" only
2487                                                                 if (http_header_all_len == 0) {
2488                                                                         //set current message rest size
2489                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
2490                                                                 } else {
2491                                                                         //set current message rest size
2492                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
2493                                                                 }
2494
2495                                                         }
2496
2497                                                         //set data state HTTP_HEADER
2498                                                         session_data_ptr->data_state = HTTP_HEADER;
2499                                                 }
2500
2501                                                 //set return status
2502                                                 status = REALSERVER_CONNECT;
2503                                         }
2504                                 }
2505                                 //data state is UNKNOWN
2506                                 else if (session_data_ptr->data_state == UNKNOWN) {
2507                                         //set return status
2508                                         status = REALSERVER_CONNECT;
2509                                 }
2510
2511                         }
2512                         //data size is 0
2513                         else {
2514                                 //data state is HTTP_BODY
2515                                 if (session_data_ptr->data_state == HTTP_BODY) {
2516                                         //set data state HTTP_START
2517                                         session_data_ptr->data_state = HTTP_START;
2518                                 }
2519
2520                                 //set data offset 0
2521                                 session_data_ptr->data_offset = 0;
2522
2523                                 //set return status
2524                                 status = CLIENT_RECV;
2525                         }
2526                 }
2527                 //set last status
2528                 session_data_ptr->last_status = status;
2529         } catch (int e) {
2530                 /*-------- DEBUG LOG --------*/
2531                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2532                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2533                                                 "handle_realserver_send() : catch exception e = %d. thread id : %d.");
2534                         formatter % e % boost::this_thread::get_id();
2535                         putLogDebug(600085, formatter.str(), __FILE__, __LINE__);
2536                 }
2537                 /*------DEBUG LOG END------*/
2538
2539                 //set return status
2540                 status = FINALIZE;
2541         } catch (const boost::bad_lexical_cast &) {
2542                 std::cerr << "protocol_module_ip::handle_realserver_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
2543                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_send() : "
2544                                         "Content_Length field's value is invalid. thread id : %d.");
2545                 formatter % boost::this_thread::get_id();
2546                 putLogError(600052, formatter.str(), __FILE__, __LINE__);
2547
2548                 //set return status
2549                 status = FINALIZE;
2550         } catch (const std::exception &ex) {
2551                 std::cerr << "protocol_module_ip::handle_realserver_send() : exception : error = " << ex.what() << "." << std::endl;                //set data state HTTP_HEADER
2552                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2553                                         "handle_realserver_send() : exception : error = %s. thread id : %d.");
2554                 formatter % ex.what() % boost::this_thread::get_id();
2555                 putLogError(600053, formatter.str(), __FILE__, __LINE__);
2556
2557                 //set return status
2558                 status = FINALIZE;
2559         } catch (...) {
2560                 std::cerr << "protocol_module_ip::handle_realserver_send() : Unknown exception." << std::endl;
2561                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2562                                         "protocol_module_ip::handle_realserver_send() : "
2563                                         "Unknown exception. thread id : %d.");
2564                 formatter % boost::this_thread::get_id();
2565                 putLogError(600054, formatter.str(), __FILE__, __LINE__);
2566
2567                 //set return status
2568                 status = FINALIZE;
2569         }
2570
2571         /*-------- DEBUG LOG --------*/
2572         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2573                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2574                                         "handle_realserver_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
2575                 formatter % status % boost::this_thread::get_id();
2576                 putLogDebug(600086, formatter.str(), __FILE__, __LINE__);
2577         }
2578         /*------DEBUG LOG END------*/
2579
2580         return status;
2581 }
2582
2583 //! called from after sorryserver select
2584 //! @param[in]    upstream thread id
2585 //! @param[in]    sorryserver endpiont reference
2586 //! @return        session use EVENT mode.
2587 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_select(
2588         const boost::thread::id thread_id, boost::asio::ip::tcp::endpoint &sorry_endpoint)
2589 {
2590         /*-------- DEBUG LOG --------*/
2591         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2592                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2593                                         "handle_sorryserver_select(const boost::thread::id thread_id, "
2594                                         "boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
2595                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
2596                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
2597                 putLogDebug(600087, formatter.str(), __FILE__, __LINE__);
2598         }
2599         /*------DEBUG LOG END------*/
2600
2601         EVENT_TAG status = FINALIZE;
2602         boost::asio::ip::tcp::endpoint tmp_endpoint;
2603         thread_data_ptr session_data_ptr;
2604         session_thread_data_map_it session_thread_it;
2605         session_thread_data_map_it session_thread_it_end;
2606
2607         try {
2608                 {
2609                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2610
2611                         session_thread_it = session_thread_data_map.find(thread_id);
2612                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2613                                 boost::format formatter("Invalid thread id. thread id : %d.");
2614                                 formatter % boost::this_thread::get_id();
2615                                 putLogError(600055, formatter.str(), __FILE__, __LINE__);
2616                                 throw - 1;
2617                         }
2618
2619                         session_data_ptr = session_thread_it->second;
2620                 }
2621
2622                 //data state is HTTP_START
2623                 if (session_data_ptr->data_state == HTTP_START) {
2624                         //set return status
2625                         status = CLIENT_RECV;
2626                 }
2627                 //data state is not HTTP_START
2628                 else {
2629                         //set return status
2630                         status = SORRYSERVER_CONNECT;
2631                 }
2632
2633                 //set last status
2634                 session_data_ptr->last_status = status;
2635         } catch (int e) {
2636                 /*-------- DEBUG LOG --------*/
2637                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2638                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2639                                                 "handle_sorryserver_select() : catch exception e = %d. thread id : %d.");
2640                         formatter % e % boost::this_thread::get_id();
2641                         putLogDebug(600088, formatter.str(), __FILE__, __LINE__);
2642                 }
2643                 /*------DEBUG LOG END------*/
2644
2645                 //set return status
2646                 status = FINALIZE;
2647         } catch (const std::exception &ex) {
2648                 std::cerr << "protocol_module_ip::handle_sorryserver_select() : exception : error = " << ex.what() << "." << std::endl;
2649                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2650                                         "handle_sorryserver_select() : exception : error = %s. thread id : %d.");
2651                 formatter % ex.what() % boost::this_thread::get_id();
2652                 putLogError(600056, formatter.str(), __FILE__, __LINE__);
2653
2654                 //set return status
2655                 status = FINALIZE;
2656         } catch (...) {
2657                 std::cerr << "protocol_module_ip::handle_sorryserver_select() : Unknown exception." << std::endl;
2658                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2659                                         "protocol_module_ip::handle_sorryserver_select() : "
2660                                         "Unknown exception. thread id : %d.");
2661                 formatter % boost::this_thread::get_id();
2662                 putLogError(600057, formatter.str(), __FILE__, __LINE__);
2663
2664                 //set return status
2665                 status = FINALIZE;
2666         }
2667
2668         /*-------- DEBUG LOG --------*/
2669         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2670                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2671                                         "handle_sorryserver_select(const boost::thread::id thread_id, "
2672                                         "boost::asio::ip::tcp::endpoint& sorry_endpoint)"
2673                                         " : return_value = %d. thread id : %d.");
2674                 formatter % status % boost::this_thread::get_id();
2675                 putLogDebug(600089, formatter.str(), __FILE__, __LINE__);
2676         }
2677         /*------DEBUG LOG END------*/
2678
2679         return status;
2680 }
2681
2682 //! called from after sorryserver connect
2683 //!    @param[in]    upstream thread id
2684 //! @param[out]    send buffer reference.
2685 //! @param[out]    send length
2686 //! @return        session use EVENT mode.
2687 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_connect(
2688         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
2689 {
2690         /*-------- DEBUG LOG --------*/
2691         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2692                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2693                                         "handle_sorryserver_connect(const boost::thread::id thread_id, "
2694                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
2695                                         "thread_id = %d.");
2696                 formatter % thread_id;
2697                 putLogDebug(600090, formatter.str(), __FILE__, __LINE__);
2698         }
2699         /*------DEBUG LOG END------*/
2700
2701         EVENT_TAG status            = FINALIZE;
2702         size_t send_possible_size        = 0;
2703         size_t uri_offset            = 0;
2704         size_t uri_len                = 0;
2705         size_t x_forwarded_for_insert_pos   = 0;
2706         thread_data_ptr                session_data_ptr;
2707         session_thread_data_map_it        session_thread_it;
2708         std::pair<char *, size_t>        buffer_element;
2709         std::string                x_forwarded_for_context;
2710
2711         try {
2712                 {
2713                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2714
2715                         //thread id check
2716                         session_thread_it = session_thread_data_map.find(thread_id);
2717                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2718                                 boost::format formatter("Invalid thread id. thread id : %d.");
2719                                 formatter % boost::this_thread::get_id();
2720                                 putLogError(600058, formatter.str(), __FILE__, __LINE__);
2721                                 throw - 1;
2722                         }
2723
2724                         session_data_ptr = session_thread_it->second;
2725                 }
2726                 //set send possible data size
2727                 send_possible_size = std::min(session_data_ptr->current_message_rest_size,
2728                                               session_data_ptr->data_length
2729                                              );
2730
2731                 if (session_data_ptr->buffer_sequence.empty()) {
2732                         //data state is HTTP_HEADER
2733                         if (session_data_ptr->data_state == HTTP_HEADER) {
2734                                 //search uri
2735                                 http_utility::find_uri(session_data_ptr->data_buffer + session_data_ptr->data_offset,
2736                                                        session_data_ptr->data_length, uri_offset, uri_len);
2737
2738                                 //set buffer's position
2739                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2740                                 buffer_element.second = uri_offset;
2741
2742                                 //put buffer data to buffer_sequence
2743                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2744
2745                                 //set buffer's position
2746                                 buffer_element.first = sorry_uri.data();
2747                                 buffer_element.second = strlen(sorry_uri.data());
2748
2749                                 //put buffer data to buffer_sequence
2750                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2751
2752                                 //forwarded_for flag is on
2753                                 if (forwarded_for == FORWARDED_FOR_ON) {
2754                                         create_x_forwarded_for(session_data_ptr->client_endpoint.address().to_string(),
2755                                                                session_data_ptr->data_buffer + session_data_ptr->data_offset,
2756                                                                session_data_ptr->data_length,
2757                                                                x_forwarded_for_insert_pos,
2758                                                                x_forwarded_for_context);
2759
2760                                         //set buffer's position
2761                                         buffer_element.first = session_data_ptr->data_buffer
2762                                                                + session_data_ptr->data_offset
2763                                                                + uri_offset
2764                                                                + uri_len;
2765                                         buffer_element.second = x_forwarded_for_insert_pos - uri_offset - uri_len;
2766
2767                                         //put buffer data to buffer_sequence
2768                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2769
2770                                         session_data_ptr->forwarded_for_buffer.assign(0);
2771
2772                                         /*-------- DEBUG LOG --------*/
2773                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2774                                                 std::string datadump;
2775                                                 dump_memory(x_forwarded_for_context.c_str(),
2776                                                             x_forwarded_for_context.size(), datadump);
2777                                                 boost::format formatter(
2778                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2779                                                         "handle_sorryserver_connect() : before memcpy (data dump) : "
2780                                                         "data begin = 0, data_size = %d, data = %s");
2781                                                 formatter %  x_forwarded_for_context.size() % datadump;
2782                                                 putLogDebug(600091, formatter.str(), __FILE__, __LINE__);
2783                                         }
2784                                         /*------DEBUG LOG END------*/
2785
2786                                         memcpy(session_data_ptr->forwarded_for_buffer.data(),
2787                                                x_forwarded_for_context.c_str(),
2788                                                x_forwarded_for_context.size());
2789
2790                                         /*-------- DEBUG LOG --------*/
2791                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2792                                                 std::string datadump;
2793                                                 dump_memory(x_forwarded_for_context.c_str(),
2794                                                             x_forwarded_for_context.size(), datadump);
2795                                                 boost::format formatter(
2796                                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2797                                                         "handle_sorryserver_connect() : after memcpy (data dump) : "
2798                                                         "data begin = 0, data_size = %d, data = %s");
2799                                                 formatter % x_forwarded_for_context.size() % datadump;
2800                                                 putLogDebug(600092, formatter.str(), __FILE__, __LINE__);
2801                                         }
2802                                         /*------DEBUG LOG END------*/
2803
2804                                         //set buffer's position
2805                                         buffer_element.first = session_data_ptr->forwarded_for_buffer.data();
2806                                         buffer_element.second = x_forwarded_for_context.size();
2807                                         //put buffer data to buffer_sequence
2808                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2809
2810                                         //set buffer's position
2811                                         buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset + x_forwarded_for_insert_pos;
2812                                         buffer_element.second = send_possible_size - x_forwarded_for_insert_pos;
2813                                         //put buffer data to buffer_sequence
2814                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2815                                 }
2816                                 //forwarded_for flag is on
2817                                 else {
2818                                         //set buffer's position
2819                                         buffer_element.first = session_data_ptr->data_buffer
2820                                                                + session_data_ptr->data_offset
2821                                                                + uri_offset
2822                                                                + uri_len;
2823                                         buffer_element.second = send_possible_size - uri_offset - uri_len;
2824                                         //put buffer data to buffer_sequence
2825                                         session_data_ptr->buffer_sequence.push_back(buffer_element);
2826                                 }
2827
2828                                 //set data state HTTP_BODY
2829                                 session_data_ptr->data_state = HTTP_BODY;
2830                         }
2831                         //data state is not HTTP_HEADER
2832                         else {
2833                                 //set buffer's position
2834                                 buffer_element.first = session_data_ptr->data_buffer + session_data_ptr->data_offset;
2835                                 buffer_element.second = send_possible_size;
2836                                 //put buffer data to buffer_sequence
2837                                 session_data_ptr->buffer_sequence.push_back(buffer_element);
2838                         }
2839                 }
2840
2841                 //put buffer_sequence data into sendbuffer
2842                 put_data_into_sendbuffer(session_data_ptr, sendbuffer, datalen);
2843
2844                 //set return status
2845                 status = SORRYSERVER_SEND;
2846
2847                 //set last status
2848                 session_data_ptr->last_status = status;
2849
2850         } catch (int e) {
2851                 /*-------- DEBUG LOG --------*/
2852                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2853                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2854                                                 "handle_sorryserver_connect() : catch exception e = %d. thread id : %d.");
2855                         formatter % e % boost::this_thread::get_id();
2856                         putLogDebug(600093, formatter.str(), __FILE__, __LINE__);
2857                 }
2858                 /*------DEBUG LOG END------*/
2859
2860                 //set return status
2861                 status = FINALIZE;
2862         } catch (const std::exception &ex) {
2863                 std::cerr << "protocol_module_ip::handle_sorryserver_connect() : exception : error = " << ex.what() << "." << std::endl;
2864                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2865                                         "handle_sorryserver_connect() : exception : error = %s. thread id : %d.");
2866                 formatter % ex.what() % boost::this_thread::get_id();
2867                 putLogError(600059, formatter.str(), __FILE__, __LINE__);
2868
2869                 //set return status
2870                 status = FINALIZE;
2871         } catch (...) {
2872                 std::cerr << "protocol_module_ip::handle_sorryserver_connect() : Unknown exception." << std::endl;
2873                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2874                                         "handle_sorryserver_connect() : Unknown exception. thread id : %d.");
2875                 formatter % boost::this_thread::get_id();
2876                 putLogError(600060, formatter.str(), __FILE__, __LINE__);
2877
2878                 //set return status
2879                 status = FINALIZE;
2880         }
2881
2882         /*-------- DEBUG LOG --------*/
2883         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2884                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2885                                         "handle_sorryserver_connect(const boost::thread::id thread_id, "
2886                                         "boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
2887                                         "size_t& datalen) : return_value = %d. thread id : %d.");
2888                 formatter % status % boost::this_thread::get_id();
2889                 putLogDebug(600094, formatter.str(), __FILE__, __LINE__);
2890         }
2891         /*------DEBUG LOG END------*/
2892
2893         return status;
2894 }
2895 //! called from after sorryserver connection fail
2896 //! @param[in]    upstream thread id
2897 //! @param[in]    sorryserver endpoint reference.
2898 //! @return        session use EVENT mode.
2899 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_connection_fail(
2900         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint)
2901 {
2902         /*-------- DEBUG LOG --------*/
2903         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2904                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2905                                         "handle_sorryserver_connection_fail(const boost::thread::id thread_id, "
2906                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
2907                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
2908                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
2909                 putLogDebug(600095, formatter.str(), __FILE__, __LINE__);
2910         }
2911         /*------DEBUG LOG END------*/
2912
2913         EVENT_TAG status = FINALIZE;
2914         thread_data_ptr session_data_ptr;
2915         session_thread_data_map_it session_thread_it;
2916
2917         try {
2918                 boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
2919
2920                 session_thread_it = session_thread_data_map.find(thread_id);
2921                 if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
2922                         boost::format formatter("Invalid thread id. thread id : %d.");
2923                         formatter % boost::this_thread::get_id();
2924                         putLogError(600061, formatter.str(), __FILE__, __LINE__);
2925                         throw - 1;
2926                 }
2927
2928                 session_data_ptr = session_thread_it->second;
2929
2930                 //set return status
2931                 status = CLIENT_DISCONNECT;
2932
2933                 //set last status
2934                 session_data_ptr->last_status = status;
2935         } catch (int e) {
2936                 /*-------- DEBUG LOG --------*/
2937                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2938                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2939                                                 "handle_sorryserver_connection_fail() : catch exception e = %d. thread id : %d.");
2940                         formatter % e % boost::this_thread::get_id();
2941                         putLogDebug(600096, formatter.str(), __FILE__, __LINE__);
2942                 }
2943                 /*------DEBUG LOG END------*/
2944
2945                 //set return status
2946                 status = FINALIZE;
2947         } catch (const std::exception &ex) {
2948                 std::cerr << "protocol_module_ip::handle_sorryserver_connection_fail() : exception : error = " << ex.what() << "." << std::endl;
2949                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2950                                         "handle_sorryserver_connection_fail() : exception : error = %s. thread id : %d.");
2951                 formatter % ex.what() % boost::this_thread::get_id();
2952                 putLogError(600062, formatter.str(), __FILE__, __LINE__);
2953
2954                 //set return status
2955                 status = FINALIZE;
2956         } catch (...) {
2957                 std::cerr << "protocol_module_ip::handle_sorryserver_connection_fail() : Unknown exception." << std::endl;
2958                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
2959                                         "protocol_module_ip::handle_sorryserver_connection_fail() : "
2960                                         "Unknown exception. thread id : %d.");
2961                 formatter % boost::this_thread::get_id();
2962                 putLogError(600063, formatter.str(), __FILE__, __LINE__);
2963
2964                 //set return status
2965                 status = FINALIZE;
2966         }
2967
2968         /*-------- DEBUG LOG --------*/
2969         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2970                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2971                                         "handle_sorryserver_connection_fail(const boost::thread::id thread_id, "
2972                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : return_value = %d. thread id : %d.");
2973                 formatter % status % boost::this_thread::get_id();
2974                 putLogDebug(600097, formatter.str(), __FILE__, __LINE__);
2975         }
2976         /*------DEBUG LOG END------*/
2977
2978         return status;
2979 }
2980
2981 //! called from after sorryserver send
2982 //! @param[in]    upstream thread id
2983 //! @return        session use EVENT mode.
2984 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_send(
2985         const boost::thread::id thread_id)
2986 {
2987         /*-------- DEBUG LOG --------*/
2988         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
2989                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
2990                                         "handle_sorryserver_send(const boost::thread::id thread_id) : thread_id = %d.");
2991                 formatter % thread_id;
2992                 putLogDebug(600098, formatter.str(), __FILE__, __LINE__);
2993         }
2994         /*------DEBUG LOG END------*/
2995
2996         EVENT_TAG status                = FINALIZE;
2997         size_t http_header_all_offset            = 0;
2998         size_t http_header_all_len            = 0;
2999         size_t http_header_content_length_offset    = 0;
3000         size_t http_header_content_length_len        = 0;
3001         const size_t CR_LF_LEN                = 2;
3002         const size_t CR_LF_CR_LF_LEN            = 4;
3003         int content_length_value            = 0;
3004
3005         std::string content_length;
3006         cmatch regex_ret;
3007         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3008
3009
3010         bool find_ret = false;
3011         http_utility::CHECK_RESULT_TAG check_ret;
3012
3013         thread_data_ptr session_data_ptr;
3014         session_thread_data_map_it session_thread_it;
3015
3016         try {
3017                 {
3018                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3019
3020                         //thread id check
3021                         session_thread_it = session_thread_data_map.find(thread_id);
3022                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3023                                 boost::format formatter("Invalid thread id. thread id : %d.");
3024                                 formatter % boost::this_thread::get_id();
3025                                 putLogError(600064, formatter.str(), __FILE__, __LINE__);
3026                                 throw - 1;
3027                         }
3028
3029                         session_data_ptr = session_thread_it->second;
3030                 }
3031
3032                 //current_message_rest_size > 0
3033                 if (session_data_ptr->current_message_rest_size > 0) {
3034                         //data size > 0
3035                         if (session_data_ptr->data_length > 0) {
3036                                 //set return status
3037                                 status = SORRYSERVER_CONNECT;
3038                         }
3039                         //data size is 0
3040                         else {
3041                                 //data offset is 0
3042                                 session_data_ptr->data_offset = 0;
3043
3044                                 //set return status
3045                                 status =  CLIENT_RECV;
3046                         }
3047                 }
3048                 //current_message_rest_size is 0
3049                 else {
3050                         //data size > 0
3051                         if (session_data_ptr->data_length > 0) {
3052                                 //data state is HTTP_BODY
3053                                 if (session_data_ptr->data_state == HTTP_BODY) {
3054                                         //search whole http header, get whole http header's offset and length
3055                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3056                                                         session_data_ptr->data_length,
3057                                                         http_header_all_offset,
3058                                                         http_header_all_len
3059                                                                                      );
3060
3061                                         /*-------- DEBUG LOG --------*/
3062                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3063                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3064                                                                         "handle_sorryserver_send() : call find_http_header_all : "
3065                                                                         "return_value = %d. thread id : %d.");
3066                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3067                                                 putLogDebug(600099, formatter.str(), __FILE__, __LINE__);
3068                                         }
3069                                         /*------DEBUG LOG END------*/
3070
3071                                         //search http header result is NG
3072                                         if (!find_ret) {
3073                                                 //set data state HTTP_START
3074                                                 session_data_ptr->data_state = HTTP_START;
3075
3076                                                 //set return status
3077                                                 status = CLIENT_RECV;
3078                                         }
3079                                         //check method and version result is OK
3080                                         else {
3081                                                 //search Content_Length header
3082                                                 check_ret = http_utility::check_http_method_and_version(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3083                                                                 session_data_ptr->data_length);
3084
3085                                                 /*-------- DEBUG LOG --------*/
3086                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3087                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3088                                                                                 "handle_sorryserver_send() : call check_http_method_and_version : "
3089                                                                                 "return_value = %d. thread id : %d.");
3090                                                         formatter % check_ret % boost::this_thread::get_id();
3091                                                         putLogDebug(600100, formatter.str(), __FILE__, __LINE__);
3092                                                 }
3093                                                 /*------DEBUG LOG END------*/
3094
3095                                                 //check method and version result is NG
3096                                                 if (check_ret == http_utility::CHECK_NG) {
3097                                                         //set current message rest size
3098                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3099
3100                                                         //set data state UNKNOWN
3101                                                         session_data_ptr->data_state = UNKNOWN;
3102                                                 }
3103                                                 //check method and version result is OK
3104                                                 else {
3105                                                         //search Content_Length header
3106                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3107                                                                         session_data_ptr->data_length,
3108                                                                         http_header_content_length_offset,
3109                                                                         http_header_content_length_len);
3110
3111                                                         /*-------- DEBUG LOG --------*/
3112                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3113                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3114                                                                                         "handle_sorryserver_send() : call find_http_header_content_length : "
3115                                                                                         "return_value = %d. thread id : %d.");
3116                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3117                                                                 putLogDebug(600101, formatter.str(), __FILE__, __LINE__);
3118                                                         }
3119                                                         /*------DEBUG LOG END------*/
3120
3121                                                         //search Content_Length result is OK
3122                                                         if (find_ret) {
3123                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3124                                                                                       http_header_content_length_len);
3125                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3126
3127                                                                 //"content-length: ddd\r\n"
3128                                                                 if (find_ret) {
3129                                                                         content_length = content_length.substr(
3130                                                                                                  regex_ret.position(1),
3131                                                                                                  regex_ret.length(1));
3132
3133                                                                         //set content length value
3134                                                                         content_length_value = boost::lexical_cast<int>(content_length);
3135                                                                 }
3136
3137                                                                 //http_header context is "\r\n\r\n" only
3138                                                                 if (http_header_all_len == 0) {
3139                                                                         //set current message rest size
3140                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
3141                                                                 } else {
3142                                                                         //set current message rest size
3143                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
3144                                                                 }
3145                                                         }
3146                                                         //search Content_Length result is OK
3147                                                         else {
3148                                                                 //http_header context is "\r\n\r\n" only
3149                                                                 if (http_header_all_len == 0) {
3150                                                                         //set current message rest size
3151                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
3152                                                                 } else {
3153                                                                         //set current message rest size
3154                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
3155                                                                 }
3156
3157                                                         }
3158
3159                                                         //set data state HTTP_HEADER
3160                                                         session_data_ptr->data_state = HTTP_HEADER;
3161
3162                                                 }
3163                                                 //set return status
3164                                                 status = SORRYSERVER_CONNECT;
3165                                         }
3166                                 }
3167                                 //data state is UNKNOWN
3168                                 else if (session_data_ptr->data_state == UNKNOWN) {
3169                                         //set return status
3170                                         status = SORRYSERVER_CONNECT;
3171                                 }
3172
3173                         }
3174                         //data size is 0
3175                         else {
3176                                 //data state is HTTP_BODY
3177                                 if (session_data_ptr->data_state == HTTP_BODY) {
3178                                         //set data state HTTP_START
3179                                         session_data_ptr->data_state = HTTP_START;
3180                                 }
3181
3182                                 //set data offset 0
3183                                 session_data_ptr->data_offset = 0;
3184
3185                                 //set return status
3186                                 status = CLIENT_RECV;
3187                         }
3188                 }
3189
3190                 //set last status
3191                 session_data_ptr->last_status = status;
3192         } catch (int e) {
3193                 /*-------- DEBUG LOG --------*/
3194                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3195                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3196                                                 "handle_sorryserver_send() : catch exception e = %d. thread id : %d.");
3197                         formatter % e % boost::this_thread::get_id();
3198                         putLogDebug(600102, formatter.str(), __FILE__, __LINE__);
3199                 }
3200                 /*------DEBUG LOG END------*/
3201
3202                 //set return status
3203                 status = FINALIZE;
3204         } catch (const boost::bad_lexical_cast &) {
3205                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
3206                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_send() : "
3207                                         "Content_Length field's value is invalid. thread id : %d.");
3208                 formatter % boost::this_thread::get_id();
3209                 putLogError(600065, formatter.str(), __FILE__, __LINE__);
3210
3211                 //set return status
3212                 status = FINALIZE;
3213         } catch (const std::exception &ex) {
3214                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : exception : error = " << ex.what() << "." << std::endl;
3215                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3216                                         "handle_sorryserver_send() : exception : error = %s. thread id : %d.");
3217                 formatter % ex.what() % boost::this_thread::get_id();
3218                 putLogError(600066, formatter.str(), __FILE__, __LINE__);
3219
3220                 //set return status
3221                 status = FINALIZE;
3222         } catch (...) {
3223                 std::cerr << "protocol_module_ip::handle_sorryserver_send() : Unknown exception." << std::endl;
3224                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3225                                         "protocol_module_ip::handle_sorryserver_send() : "
3226                                         "Unknown exception. thread id : %d.");
3227                 formatter % boost::this_thread::get_id();
3228                 putLogError(600067, formatter.str(), __FILE__, __LINE__);
3229
3230                 //set return status
3231                 status = FINALIZE;
3232         }
3233
3234         /*-------- DEBUG LOG --------*/
3235         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3236                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3237                                         "handle_sorryserver_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
3238                 formatter % status % boost::this_thread::get_id();
3239                 putLogDebug(600103, formatter.str(), __FILE__, __LINE__);
3240         }
3241         /*------DEBUG LOG END------*/
3242
3243         return status;
3244 }
3245
3246 //! called from after realserver receive.for UDP
3247 //! @param[in]    downstream thread id
3248 //! @param[in]    realserver UDP endpoint reference
3249 //! @param[in]    receive from realserver buffer reference
3250 //! @param[in]    recv data length
3251 //! @return        session use EVENT mode.
3252 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv(
3253         const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint, const boost::array < char,
3254         MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3255 {
3256         /*-------- DEBUG LOG --------*/
3257         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3258                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3259                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3260                                         "const boost::asio::ip::udp::endpoint& rs_endpoint, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3261                                         "const size_t& recvlen) : "
3262                                         "return_value = %d. thread id : %d.");
3263                 formatter % STOP % boost::this_thread::get_id();
3264                 putLogDebug(600104, formatter.str(), __FILE__, __LINE__);
3265         }
3266         /*------DEBUG LOG END------*/
3267         return STOP;
3268 }
3269
3270 //! called from after realserver recvive for TCP/IP
3271 //! @param[in]    downstream thread id
3272 //! @param[in]    realserver TCP/IP endpoint reference
3273 //! @param[in]    realserver receive buffer reference.
3274 //! @param[in]    recv data length
3275 //! @return        session use EVENT mode.
3276 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv(
3277         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint, const boost::array < char,
3278         MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3279 {
3280         /*-------- DEBUG LOG --------*/
3281         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3282                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
3283                 std::string buffer;
3284                 dump_memory(recvbuffer.data(), buffer_size, buffer);
3285                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3286                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3287                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3288                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3289                                         "const size_t recvlen) : thread_id = %d, rs_endpoint = [%s]:%d, recvbuffer = %s, recvlen = %d.");
3290                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port()
3291                 % buffer % recvlen;
3292                 putLogDebug(600105, formatter.str(), __FILE__, __LINE__);
3293         }
3294         /*------DEBUG LOG END------*/
3295
3296         EVENT_TAG status                = FINALIZE;
3297
3298         bool find_ret                    = false;
3299         size_t http_header_offset            = 0;
3300         size_t http_header_len                = 0;
3301         size_t http_header_content_length_offset    = 0;
3302         size_t http_header_content_length_len        = 0;
3303         int content_length_value            = 0;
3304         const size_t CR_LF_LEN                = 2; //length of "\r\n"
3305         const size_t CR_LF_CR_LF_LEN            = 4; //length of "\r\n\r\n"
3306
3307         session_thread_data_map_it            session_thread_it;
3308         thread_data_ptr                    session_data_ptr;
3309         http_utility::CHECK_RESULT_TAG            check_ret;
3310
3311         std::string                    content_length;
3312         cmatch                        regex_ret;
3313         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3314
3315         if (unlikely(recvlen > recvbuffer.size())) {
3316                 std::cerr << "protocol_module_ip::handle_realserver_recv() : Data size bigger than buffer size." << std::endl;
3317                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
3318                 formatter % boost::this_thread::get_id();
3319                 putLogError(600068, formatter.str(), __FILE__, __LINE__);
3320
3321                 /*-------- DEBUG LOG --------*/
3322                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3323                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3324                                                 "handle_realserver_recv(const boost::thread::id thread_id, "
3325                                                 "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3326                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3327                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
3328                         formatter % FINALIZE % boost::this_thread::get_id();
3329                         putLogDebug(600106, formatter.str(), __FILE__, __LINE__);
3330                 }
3331                 /*------DEBUG LOG END------*/
3332
3333                 return status;
3334         }
3335
3336         try {
3337                 {
3338                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3339
3340                         session_thread_it = session_thread_data_map.find(thread_id);
3341                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3342                                 boost::format formatter("Invalid thread id. thread id : %d.");
3343                                 formatter % boost::this_thread::get_id();
3344                                 putLogError(600069, formatter.str(), __FILE__, __LINE__);
3345                                 throw - 1;
3346                         }
3347
3348                         session_data_ptr = session_thread_it->second;
3349                 }
3350
3351                 //set switch flag off
3352                 session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
3353
3354                 /*-------- DEBUG LOG --------*/
3355                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3356                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3357                                                 "handle_realserver_recv(const boost::thread::id thread_id, "
3358                                                 "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3359                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3360                                                 "const size_t recvlen) : SWITCH_FLAG_OFF. "
3361                                                 "thread_id = %d, rs_endpoint = [%s]:%d.");
3362                         formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
3363                         putLogDebug(600107, formatter.str(), __FILE__, __LINE__);
3364                 }
3365                 /*------DEBUG LOG END------*/
3366
3367                 //copy data from recvbuffer
3368                 if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
3369                         //copy failed
3370                         std::cerr << "protocol_module_ip::handle_realserver_recv() : Data size bigger than buffer size." << std::endl;
3371                         boost::format formatter("Data size bigger than buffer size. thread id : % id.");
3372                         formatter % boost::this_thread::get_id();
3373                         putLogError(600070, formatter.str(), __FILE__, __LINE__);
3374                         status = FINALIZE;
3375                 } else {
3376                         if (forwarded_for == FORWARDED_FOR_OFF) {
3377                                 session_data_ptr->data_state = UNKNOWN;
3378                         }
3379                         //data state is HTTP_START
3380                         if (session_data_ptr->data_state == HTTP_START) {
3381                                 //search http header
3382                                 find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3383                                                 session_data_ptr->data_length,
3384                                                 http_header_offset,
3385                                                 http_header_len
3386                                                                              );
3387
3388                                 /*-------- DEBUG LOG --------*/
3389                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3390                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3391                                                                 "handle_realserver_recv() : call find_http_header_all : "
3392                                                                 "return_value = %d. thread id : %d.");
3393                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3394                                         putLogDebug(600108, formatter.str(), __FILE__, __LINE__);
3395                                 }
3396                                 /*------DEBUG LOG END------*/
3397
3398                                 //search http header result is NG
3399                                 if (!find_ret) {
3400                                         //data size bigger than max buffer size
3401                                         if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
3402                                                 //set data state UNKNOWN
3403                                                 session_data_ptr->data_state = UNKNOWN;
3404                                                 //set current message rest size
3405                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3406                                         }
3407                                 }
3408                                 //search http header result is OK
3409                                 else {
3410                                         //check http version and status code
3411                                         check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer,
3412                                                         session_data_ptr->data_length);
3413
3414                                         /*-------- DEBUG LOG --------*/
3415                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3416                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3417                                                                         "handle_realserver_recv() : call check_http_version_and_status_code : "
3418                                                                         "return_value = %d. thread id : %d.");
3419                                                 formatter % check_ret % boost::this_thread::get_id();
3420                                                 putLogDebug(600109, formatter.str(), __FILE__, __LINE__);
3421                                         }
3422                                         /*------DEBUG LOG END------*/
3423
3424                                         //check http version and status code result is NG
3425                                         if (check_ret == http_utility::CHECK_NG) {
3426                                                 //set data state UNKNOWN
3427                                                 session_data_ptr->data_state = UNKNOWN;
3428                                                 //set current message rest size
3429                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3430                                         }
3431                                         //check http version and status code result is OK
3432                                         else {
3433                                                 //search Content_Length header
3434                                                 find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3435                                                                 session_data_ptr->data_length,
3436                                                                 http_header_content_length_offset,
3437                                                                 http_header_content_length_len);
3438
3439                                                 /*-------- DEBUG LOG --------*/
3440                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3441                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3442                                                                                 "handle_realserver_recv() : call find_http_header_content_length : "
3443                                                                                 "return_value = %d. thread id : %d.");
3444                                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3445                                                         putLogDebug(600110, formatter.str(), __FILE__, __LINE__);
3446                                                 }
3447                                                 /*------DEBUG LOG END------*/
3448
3449                                                 //search Content_Length result is OK
3450                                                 if (find_ret) {
3451                                                         //set content length string
3452                                                         content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3453                                                                               http_header_content_length_len);
3454                                                         find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3455
3456                                                         //"content-length: ddd\r\n"
3457                                                         if (find_ret) {
3458                                                                 content_length = content_length.substr(
3459                                                                                          regex_ret.position(1),
3460                                                                                          regex_ret.length(1));
3461
3462                                                                 //set content length value
3463                                                                 content_length_value = boost::lexical_cast<int>(content_length);
3464                                                         }
3465
3466                                                         //http_header context is "\r\n\r\n" only
3467                                                         if (http_header_len == 0) {
3468                                                                 //set current message rest size
3469                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
3470                                                         } else {
3471                                                                 //set current message rest size
3472                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
3473                                                         }
3474                                                 }
3475                                                 //search Content_Length result is NG
3476                                                 else {
3477                                                         //http_header context is "\r\n\r\n" only
3478                                                         if (http_header_len == 0) {
3479                                                                 //set current message rest size
3480                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
3481                                                         } else {
3482                                                                 //set current message rest size
3483                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
3484                                                         }
3485                                                 }
3486
3487                                                 //set data state HTTP_HEADER
3488                                                 session_data_ptr->data_state = HTTP_HEADER;
3489                                         }
3490                                 }
3491                         }
3492                         //data state is UNKNOWN
3493                         else if (session_data_ptr->data_state == UNKNOWN) {
3494                                 //set current message rest size
3495                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3496                         } else {
3497                                 //none
3498                         }
3499
3500                         //data state is HTTP_START
3501                         if (session_data_ptr->data_state == HTTP_START) {
3502                                 //set return status
3503                                 status = REALSERVER_RECV;
3504                         }
3505                         //data state is not HTTP_START
3506                         else {
3507                                 //set return status
3508                                 status = CLIENT_CONNECTION_CHECK;
3509                         }
3510                 }
3511
3512                 //set last status
3513                 session_data_ptr->last_status = status;
3514         } catch (int e) {
3515                 /*-------- DEBUG LOG --------*/
3516                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3517                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3518                                                 "handle_realserver_recv() : catch exception e = %d. thread id : %d.");
3519                         formatter % e % boost::this_thread::get_id();
3520                         putLogDebug(600111, formatter.str(), __FILE__, __LINE__);
3521                 }
3522                 /*------DEBUG LOG END------*/
3523
3524                 //set return status
3525                 status = FINALIZE;
3526         } catch (const boost::bad_lexical_cast &) {
3527                 std::cerr << "protocol_module_ip::handle_realserver_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
3528                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_recv() : "
3529                                         "Content_Length field's value is invalid. thread id : %d.");
3530                 formatter % boost::this_thread::get_id();
3531                 putLogError(600071, formatter.str(), __FILE__, __LINE__);
3532
3533                 //set return status
3534                 status = FINALIZE;
3535         } catch (const std::exception &ex) {
3536                 std::cerr << "protocol_module_ip::handle_realserver_recv() : exception : error = " << ex.what() << "." << std::endl;
3537                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3538                                         "handle_realserver_recv() : exception : error = %s. thread id : %d.");
3539                 formatter % ex.what() % boost::this_thread::get_id();
3540                 putLogError(600072, formatter.str(), __FILE__, __LINE__);
3541
3542                 //set return status
3543                 status = FINALIZE;
3544         } catch (...) {
3545                 std::cerr << "protocol_module_ip::handle_realserver_recv() : Unknown exception." << std::endl;
3546                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3547                                         "protocol_module_ip::handle_realserver_recv() : "
3548                                         "Unknown exception. thread id : %d.");
3549                 formatter % boost::this_thread::get_id();
3550                 putLogError(600073, formatter.str(), __FILE__, __LINE__);
3551
3552                 //set return status
3553                 status = FINALIZE;
3554         }
3555
3556         /*-------- DEBUG LOG --------*/
3557         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3558                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3559                                         "handle_realserver_recv(const boost::thread::id thread_id, "
3560                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint, "
3561                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3562                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
3563                 formatter % FINALIZE % boost::this_thread::get_id();
3564                 putLogDebug(600112, formatter.str(), __FILE__, __LINE__);
3565         }
3566         /*------DEBUG LOG END------*/
3567
3568         return status;
3569 }
3570
3571
3572
3573 //! called from after sorryserver receive
3574 //! @param[in]    downstream thread id
3575 //! @param[in]    sorryserver endpoint reference
3576 //! @param[in]    receive from realserver buffer reference.
3577 //! @param[in]    recv data length
3578 //! @return     session use EVENT mode
3579 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_recv(
3580         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint, const boost::array <
3581         char, MAX_BUFFER_SIZE > & recvbuffer, const size_t recvlen)
3582 {
3583         /*-------- DEBUG LOG --------*/
3584         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3585                 size_t buffer_size = recvbuffer.size() < recvlen ? recvbuffer.size() : recvlen;
3586                 std::string buffer;
3587                 dump_memory(recvbuffer.data(), buffer_size, buffer);
3588                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3589                                         "handle_sorryserver_recv(const boost::thread::id thread_id, "
3590                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3591                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3592                                         "const size_t recvlen) : thread_id = %d, sorry_endpoint = [%s]:%d, recvbuffer = %s, recvlen = %d.");
3593                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port()
3594                 % buffer % recvlen;
3595                 putLogDebug(600113, formatter.str(), __FILE__, __LINE__);
3596         }
3597         /*------DEBUG LOG END------*/
3598
3599         EVENT_TAG status                = FINALIZE;
3600         bool find_ret                    = false;
3601         size_t http_header_offset            = 0;
3602         size_t http_header_len                = 0;
3603         size_t http_header_content_length_offset    = 0;
3604         size_t http_header_content_length_len        = 0;
3605         int content_length_value            = 0;
3606         const size_t CR_LF_LEN                = 2; //length of "\r\n"
3607         const size_t CR_LF_CR_LF_LEN            = 4; //length of "\r\n\r\n"
3608
3609         session_thread_data_map_it            session_thread_it;
3610         thread_data_ptr                    session_data_ptr;
3611         http_utility::CHECK_RESULT_TAG            check_ret;
3612         std::string                    content_length;
3613         cmatch                        regex_ret;
3614         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
3615
3616         if (unlikely(recvlen > recvbuffer.size())) {
3617                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Data size bigger than buffer size." << std::endl;
3618                 boost::format formatter("Data size bigger than buffer size. thread id : %d.");
3619                 formatter % boost::this_thread::get_id();
3620                 putLogError(600074, formatter.str(), __FILE__, __LINE__);
3621
3622                 /*-------- DEBUG LOG --------*/
3623                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3624                         boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3625                                                 "handle_sorryserver_recv(const boost::thread::id thread_id, "
3626                                                 "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3627                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3628                                                 "const size_t recvlen) : return_value = %d. thread id : %d.");
3629                         formatter % FINALIZE % boost::this_thread::get_id();
3630                         putLogDebug(600114, formatter.str(), __FILE__, __LINE__);
3631                 }
3632                 /*------DEBUG LOG END------*/
3633
3634                 return status;
3635         }
3636
3637         try {
3638                 {
3639                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
3640
3641                         session_thread_it = session_thread_data_map.find(thread_id);
3642                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3643                                 boost::format formatter("Invalid thread id. thread id : %d.");
3644                                 formatter % boost::this_thread::get_id();
3645                                 putLogError(600075, formatter.str(), __FILE__, __LINE__);
3646                                 throw - 1;
3647                         }
3648
3649                         session_data_ptr = session_thread_it->second;
3650                 }
3651
3652                 //set switch flag off
3653                 session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
3654
3655                 /*-------- DEBUG LOG --------*/
3656                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3657                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3658                                                 "handle_sorryserver_recv(const boost::thread::id thread_id, "
3659                                                 "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3660                                                 "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3661                                                 "const size_t recvlen) : SWITCH_FLAG_OFF. "
3662                                                 "thread_id = %d, rs_endpoint = [%s]:%d.");
3663                         formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
3664                         putLogDebug(600115, formatter.str(), __FILE__, __LINE__);
3665                 }
3666                 /*------DEBUG LOG END------*/
3667
3668                 //copy data from recvbuffer
3669                 if (!get_data_from_recvbuffer(session_data_ptr, recvbuffer, recvlen)) {
3670                         //copy failed
3671                         std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Data size bigger than buffer size." << std::endl;
3672                         boost::format formatter("Data size bigger than buffer size. thread id : % id.");
3673                         formatter % boost::this_thread::get_id();
3674                         putLogError(600076, formatter.str(), __FILE__, __LINE__);
3675
3676                         status = FINALIZE;
3677                 } else {
3678                         if (forwarded_for == FORWARDED_FOR_OFF) {
3679                                 session_data_ptr->data_state = UNKNOWN;
3680                         }
3681                         //data state is HTTP_START
3682                         if (session_data_ptr->data_state == HTTP_START) {
3683                                 //search http header
3684                                 find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3685                                                 session_data_ptr->data_length,
3686                                                 http_header_offset,
3687                                                 http_header_len
3688                                                                              );
3689
3690                                 /*-------- DEBUG LOG --------*/
3691                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3692                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3693                                                                 "handle_sorryserver_recv() : call find_http_header_all : "
3694                                                                 "return_value = %d. thread id : %d.");
3695                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3696                                         putLogDebug(600116, formatter.str(), __FILE__, __LINE__);
3697                                 }
3698                                 /*------DEBUG LOG END------*/
3699
3700                                 //search http header result is NG
3701                                 if (!find_ret) {
3702                                         //data size bigger than max buffer size
3703                                         if (session_data_ptr->data_length >= MAX_IP_MODULE_BUFFER_SIZE - recvbuffer.size()) {
3704                                                 //set data state UNKNOWN
3705                                                 session_data_ptr->data_state = UNKNOWN;
3706                                                 //set current message rest size
3707                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3708                                         }
3709                                 }
3710                                 //search http header result is OK
3711                                 else {
3712                                         //check http version and status code
3713                                         check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer,
3714                                                         session_data_ptr->data_length);
3715
3716                                         /*-------- DEBUG LOG --------*/
3717                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3718                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3719                                                                         "handle_sorryserver_recv() : call check_http_version_and_status_code : "
3720                                                                         "return_value = %d. thread id : %d.");
3721                                                 formatter % check_ret % boost::this_thread::get_id();
3722                                                 putLogDebug(600117, formatter.str(), __FILE__, __LINE__);
3723                                         }
3724                                         /*------DEBUG LOG END------*/
3725
3726                                         //check http version and status code result is NG
3727                                         if (check_ret == http_utility::CHECK_NG) {
3728                                                 //set data state UNKNOWN
3729                                                 session_data_ptr->data_state = UNKNOWN;
3730                                                 //set current message rest size
3731                                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3732                                         }
3733                                         //check http version and status code result is OK
3734                                         else {
3735                                                 //search Content_Length header
3736                                                 find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
3737                                                                 session_data_ptr->data_length,
3738                                                                 http_header_content_length_offset,
3739                                                                 http_header_content_length_len);
3740
3741                                                 /*-------- DEBUG LOG --------*/
3742                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3743                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3744                                                                                 "handle_sorryserver_recv() : call find_http_header_content_length : "
3745                                                                                 "return_value = %d. thread id : %d.");
3746                                                         formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
3747                                                         putLogDebug(600118, formatter.str(), __FILE__, __LINE__);
3748                                                 }
3749                                                 /*------DEBUG LOG END------*/
3750
3751                                                 //search Content_Length result is OK
3752                                                 if (find_ret) {
3753                                                         ////set content length string
3754                                                         content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
3755                                                                               http_header_content_length_len);
3756                                                         find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
3757
3758                                                         //"content-length: ddd\r\n"
3759                                                         if (find_ret) {
3760                                                                 content_length = content_length.substr(
3761                                                                                          regex_ret.position(1),
3762                                                                                          regex_ret.length(1));
3763
3764                                                                 //set content length value
3765                                                                 content_length_value = boost::lexical_cast<int>(content_length);
3766                                                         }
3767
3768                                                         //http_header context is "\r\n\r\n" only
3769                                                         if (http_header_len == 0) {
3770                                                                 //set current message rest size
3771                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_LEN;
3772                                                         } else {
3773                                                                 //set current message rest size
3774                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + content_length_value + CR_LF_CR_LF_LEN;
3775                                                         }
3776                                                 }
3777                                                 //search Content_Length result is NG
3778                                                 else {
3779                                                         //http_header context is "\r\n\r\n" only
3780                                                         if (http_header_len == 0) {
3781                                                                 //set current message rest size
3782                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_LEN;
3783                                                         } else {
3784                                                                 //set current message rest size
3785                                                                 session_data_ptr->current_message_rest_size = http_header_offset + http_header_len + CR_LF_CR_LF_LEN;
3786                                                         }
3787
3788                                                 }
3789
3790                                                 //set data state HTTP_HEADER
3791                                                 session_data_ptr->data_state = HTTP_HEADER;
3792
3793                                         }
3794                                 }
3795                         }
3796                         //data state is UNKNOWN
3797                         else if (session_data_ptr->data_state == UNKNOWN) {
3798                                 //set current message rest size
3799                                 session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
3800                         } else {
3801                                 //none
3802                         }
3803
3804                         //data state is HTTP_START
3805                         if (session_data_ptr->data_state == HTTP_START) {
3806                                 //set return status
3807                                 status = SORRYSERVER_RECV;
3808                         }
3809                         //data state is not HTTP_START
3810                         else {
3811                                 //set return status
3812                                 status = CLIENT_CONNECTION_CHECK;
3813                         }
3814                 }
3815
3816                 //set last status
3817                 session_data_ptr->last_status = status;
3818         } catch (int e) {
3819                 /*-------- DEBUG LOG --------*/
3820                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3821                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3822                                                 "handle_sorryserver_recv() : catch exception e = %d. thread id : %d.");
3823                         formatter % e % boost::this_thread::get_id();
3824                         putLogDebug(600119, formatter.str(), __FILE__, __LINE__);
3825                 }
3826                 /*------DEBUG LOG END------*/
3827
3828                 //set return status
3829                 status = FINALIZE;
3830         } catch (const boost::bad_lexical_cast &) {
3831                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
3832                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_recv() : "
3833                                         "Content_Length field's value is invalid. thread id : %d.");
3834                 formatter % boost::this_thread::get_id();
3835                 putLogError(600077, formatter.str(), __FILE__, __LINE__);
3836
3837                 //set return status
3838                 status = FINALIZE;
3839         } catch (const std::exception &ex) {
3840                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : exception : error = " << ex.what() << "." << std::endl;
3841                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3842                                         "handle_sorryserver_recv() : exception : error = %s. thread id : %d.");
3843                 formatter % ex.what() % boost::this_thread::get_id();
3844                 putLogError(600078, formatter.str(), __FILE__, __LINE__);
3845
3846                 //set return status
3847                 status = FINALIZE;
3848         } catch (...) {
3849                 std::cerr << "protocol_module_ip::handle_sorryserver_recv() : Unknown exception." << std::endl;
3850                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
3851                                         "protocol_module_ip::handle_sorryserver_recv() : "
3852                                         "Unknown exception. thread id : %d.");
3853                 formatter % boost::this_thread::get_id();
3854                 putLogError(600079, formatter.str(), __FILE__, __LINE__);
3855
3856                 //set return status
3857                 status = FINALIZE;
3858         }
3859
3860         /*-------- DEBUG LOG --------*/
3861         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3862                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3863                                         "handle_sorryserver_recv(const boost::thread::id thread_id, "
3864                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint, "
3865                                         "const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
3866                                         "const size_t recvlen) : return_value = %d. thread id : %d.");
3867                 formatter % FINALIZE % boost::this_thread::get_id();
3868                 putLogDebug(600120, formatter.str(), __FILE__, __LINE__);
3869         }
3870         /*------DEBUG LOG END------*/
3871
3872         return status;
3873
3874 }
3875
3876 //! called from UPSTEEARM thread. make module original message.
3877 //! @param[in]    downstream thread id.
3878 //! @return     session use EVENT mode
3879 protocol_module_base::EVENT_TAG protocol_module_ip::handle_response_send_inform(
3880         const boost::thread::id thread_id)
3881 {
3882         /*-------- DEBUG LOG --------*/
3883         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3884                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3885                                         "handle_response_send_inform(const boost::thread::id thread_id) : "
3886                                         "return_value = %d. thread id : %d.");
3887                 formatter % STOP % boost::this_thread::get_id();
3888                 putLogDebug(600121, formatter.str(), __FILE__, __LINE__);
3889         }
3890         /*------DEBUG LOG END------*/
3891
3892         return STOP;
3893 }
3894
3895 //! called from after client connection check. use TCP/IP only. create client send message.
3896 //! @param[in]    downstream thread id
3897 //! @param[out]    send budffer reference
3898 //! @param[out]    send data length
3899 //! @return     session use EVENT mode
3900 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_connection_check(
3901         const boost::thread::id thread_id, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
3902 {
3903         /*-------- DEBUG LOG --------*/
3904         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3905                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3906                                         "handle_client_connection_check(const boost::thread::id thread_id, "
3907                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : "
3908                                         "thread_id = %d.");
3909                 formatter % thread_id;
3910                 putLogDebug(600122, formatter.str(), __FILE__, __LINE__);
3911         }
3912         /*------DEBUG LOG END------*/
3913
3914         EVENT_TAG status = FINALIZE;
3915         thread_data_ptr session_data_ptr;
3916         size_t send_possible_size = 0;
3917
3918         try {
3919                 {
3920                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
3921
3922                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
3923                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
3924                                 boost::format formatter("Invalid thread id. thread id : %d.");
3925                                 formatter % boost::this_thread::get_id();
3926                                 putLogError(600080, formatter.str(), __FILE__, __LINE__);
3927                                 throw - 1;
3928                         }
3929
3930                         session_data_ptr = session_thread_it->second;
3931                 }
3932
3933                 //data state is HTTP_HEADER
3934                 if (session_data_ptr->data_state == HTTP_HEADER) {
3935                         //set data HTTP_BODY
3936                         session_data_ptr->data_state = HTTP_BODY;
3937                 }
3938
3939                 //set send possible data size
3940                 send_possible_size = std::min(std::min(sendbuffer.size(), session_data_ptr->current_message_rest_size),
3941                                               session_data_ptr->data_length
3942                                              );
3943                 //set send data size
3944                 datalen = send_possible_size;
3945
3946                 /*-------- DEBUG LOG --------*/
3947                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3948                         std::string datadump;
3949                         dump_memory(session_data_ptr->data_buffer + session_data_ptr->data_offset, send_possible_size, datadump);
3950
3951                         boost::format formatter(
3952                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3953                                 "handle_client_connection_check() : before memcpy (data dump) : "
3954                                 "data begin = %d, data_size = %d, data = %s");
3955                         formatter % session_data_ptr->data_offset % send_possible_size % datadump;
3956                         putLogDebug(600123, formatter.str(), __FILE__, __LINE__);
3957                 }
3958                 /*------DEBUG LOG END------*/
3959
3960                 //copy send possible data to sendbuffer
3961                 memcpy(sendbuffer.data(), session_data_ptr->data_buffer + session_data_ptr->data_offset,
3962                        send_possible_size);
3963
3964                 /*-------- DEBUG LOG --------*/
3965                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
3966                         std::string datadump;
3967                         dump_memory(sendbuffer.data(), send_possible_size, datadump);
3968
3969                         boost::format formatter(
3970                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
3971                                 "handle_client_connection_check() : after memcpy (data dump) : "
3972                                 "data begin = 0, data_size = %d, data = %s");
3973                         formatter % send_possible_size % datadump;
3974                         putLogDebug(600124, formatter.str(), __FILE__, __LINE__);
3975                 }
3976                 /*------DEBUG LOG END------*/
3977
3978                 //set current message rest size
3979                 session_data_ptr->current_message_rest_size -= send_possible_size;
3980
3981                 //set buffer's position
3982                 session_data_ptr->data_offset += send_possible_size;
3983                 session_data_ptr->data_length -= send_possible_size;
3984
3985                 //current message rest size is 0
3986                 if (session_data_ptr->current_message_rest_size == 0) {
3987                         boost::mutex::scoped_lock lock(session_data_mutex);
3988                         time_t now;
3989                         time(&now);
3990                         boost::asio::ip::tcp::endpoint init_endpoint;
3991
3992                         //write session data to session table
3993                         ip_data_processor->write_session_data(session_data_ptr->ip_hash,
3994                                                               init_endpoint,
3995                                                               now);
3996
3997                 }
3998
3999                 //set return status
4000                 status = CLIENT_SEND;
4001
4002                 //set last status
4003                 session_data_ptr->last_status = status;
4004         } catch (int e) {
4005                 /*-------- DEBUG LOG --------*/
4006                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4007                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4008                                                 "handle_client_connection_check() : catch exception e = %d. thread id : %d.");
4009                         formatter % e % boost::this_thread::get_id();
4010                         putLogDebug(600125, formatter.str(), __FILE__, __LINE__);
4011                 }
4012                 /*------DEBUG LOG END------*/
4013
4014                 //set return status
4015                 status = FINALIZE;
4016         } catch (const std::exception &ex) {
4017                 std::cerr << "protocol_module_ip::handle_client_connection_check() : exception : error = " << ex.what() << "." << std::endl;
4018                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4019                                         "handle_client_connection_check() : exception : error = %s. thread id : %d.");
4020                 formatter % ex.what() % boost::this_thread::get_id();
4021                 putLogError(600081, formatter.str(), __FILE__, __LINE__);
4022
4023                 //set return status
4024                 status = FINALIZE;
4025         } catch (...) {
4026                 std::cerr << "protocol_module_ip::handle_client_connection_check() : Unknown exception." << std::endl;
4027                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4028                                         "handle_client_connection_check() : Unknown exception. thread id : %d.");
4029                 formatter % boost::this_thread::get_id();
4030                 putLogError(600082, formatter.str(), __FILE__, __LINE__);
4031
4032                 //set return status
4033                 status = FINALIZE;
4034         }
4035
4036         /*-------- DEBUG LOG --------*/
4037         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4038                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4039                                         "handle_client_connection_check(const boost::thread::id thread_id, "
4040                                         "boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t& datalen) : return_value = %d. thread id : %d.");
4041                 formatter % status % boost::this_thread::get_id();
4042                 putLogDebug(600126, formatter.str(), __FILE__, __LINE__);
4043         }
4044         /*------DEBUG LOG END------*/
4045
4046         return status;
4047 }
4048
4049 //! called from after client select. use UDP only
4050 //! @param[in]    downstream thread id
4051 //!    @param[in]    client udp endpoint
4052 //! @param[out]    send buffer reference
4053 //! @param[out]    send data length
4054 //! @return     session use EVENT mode
4055 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_select(
4056         const boost::thread::id thread_id, boost::asio::ip::udp::endpoint &cl_endpoint, boost::array < char,
4057         MAX_BUFFER_SIZE > & sendbuffer, size_t &datalen)
4058 {
4059         /*-------- DEBUG LOG --------*/
4060         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4061                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4062                                         "handle_client_select(const boost::thread::id thread_id, "
4063                                         "boost::asio::ip::udp::endpoint& cl_endpoint, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
4064                                         "const size_t& datalen) : "
4065                                         "return_value = %d. thread id : %d.");
4066                 formatter % STOP % boost::this_thread::get_id();
4067                 putLogDebug(600127, formatter.str(), __FILE__, __LINE__);
4068         }
4069         /*------DEBUG LOG END------*/
4070         return STOP;
4071 }
4072
4073 //!    called from after client send
4074 //!    @param[in]    downstream thread id
4075 //! @return     session use EVENT mode
4076 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_send(
4077         const boost::thread::id thread_id)
4078 {
4079         /*-------- DEBUG LOG --------*/
4080         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4081                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4082                                         "handle_client_send(const boost::thread::id thread_id) : thread_id = %d.");
4083                 formatter % thread_id;
4084                 putLogDebug(600128, formatter.str(), __FILE__, __LINE__);
4085         }
4086         /*------DEBUG LOG END------*/
4087
4088         EVENT_TAG status = FINALIZE;
4089         size_t http_header_all_offset        = 0;
4090         size_t http_header_all_len        = 0;
4091         size_t http_header_content_length_offset = 0;
4092         size_t http_header_content_length_len    = 0;
4093         const size_t CR_LF_LEN             = 2;
4094         const size_t CR_LF_CR_LF_LEN        = 4;
4095         int content_length_value        = 0;
4096
4097         std::string content_length;
4098         cmatch regex_ret;
4099         cregex content_length_regex = icase("Content-Length") >> ":" >> *~_d >> (s1 = +_d) >> *~_d;
4100
4101
4102         bool find_ret = false;
4103         http_utility::CHECK_RESULT_TAG check_ret;
4104
4105         thread_data_ptr session_data_ptr;
4106         session_thread_data_map_it session_thread_it;
4107
4108         try {
4109                 {
4110                         boost::mutex::scoped_lock slock(session_thread_data_map_mutex);
4111
4112                         //thread id check
4113                         session_thread_it = session_thread_data_map.find(thread_id);
4114                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4115                                 boost::format formatter("Invalid thread id. thread id : %d.");
4116                                 formatter % boost::this_thread::get_id();
4117                                 putLogError(600083, formatter.str(), __FILE__, __LINE__);
4118                                 throw - 1;
4119                         }
4120
4121                         session_data_ptr = session_thread_it->second;
4122                 }
4123
4124                 //current_message_rest_size > 0
4125                 if (session_data_ptr->current_message_rest_size > 0) {
4126                         //data size > 0
4127                         if (session_data_ptr->data_length > 0) {
4128                                 //set return status
4129                                 status = CLIENT_CONNECTION_CHECK;
4130                         }
4131                         //data size is 0
4132                         else {
4133                                 //data offset is 0
4134                                 session_data_ptr->data_offset = 0;
4135
4136                                 //set return status
4137                                 status = REALSERVER_RECV;
4138                         }
4139                 }
4140                 //current_message_rest_size is 0
4141                 else {
4142                         //data size > 0
4143                         if (session_data_ptr->data_length > 0) {
4144                                 //data state is HTTP_BODY
4145                                 if (session_data_ptr->data_state == HTTP_BODY) {
4146                                         //search whole http header, get whole http header's offset and length
4147                                         find_ret = http_utility::find_http_header_all(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4148                                                         session_data_ptr->data_length,
4149                                                         http_header_all_offset,
4150                                                         http_header_all_len
4151                                                                                      );
4152
4153                                         /*-------- DEBUG LOG --------*/
4154                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4155                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4156                                                                         "handle_client_send() : call find_http_header_all : "
4157                                                                         "return_value = %d. thread id : %d.");
4158                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
4159                                                 putLogDebug(600129, formatter.str(), __FILE__, __LINE__);
4160                                         }
4161                                         /*------DEBUG LOG END------*/
4162
4163                                         //search http header result is NG
4164                                         if (!find_ret) {
4165                                                 //set data state HTTP_START
4166                                                 session_data_ptr->data_state = HTTP_START;
4167
4168                                                 //set return status
4169                                                 status = REALSERVER_RECV;
4170                                         }
4171                                         //search http header result is OK
4172                                         else {
4173                                                 //check http version and status code
4174                                                 check_ret = http_utility::check_http_version_and_status_code(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4175                                                                 session_data_ptr->data_length);
4176
4177                                                 /*-------- DEBUG LOG --------*/
4178                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4179                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4180                                                                                 "handle_client_send() : call check_http_version_and_status_code : "
4181                                                                                 "return_value = %d. thread id : %d.");
4182                                                         formatter % check_ret % boost::this_thread::get_id();
4183                                                         putLogDebug(600130, formatter.str(), __FILE__, __LINE__);
4184                                                 }
4185                                                 /*------DEBUG LOG END------*/
4186
4187                                                 //check version and status code result is NG
4188                                                 if (check_ret == http_utility::CHECK_NG) {
4189                                                         //set current message rest size
4190                                                         session_data_ptr->current_message_rest_size = session_data_ptr->data_length;
4191
4192                                                         //set data state UNKNOWN
4193                                                         session_data_ptr->data_state = UNKNOWN;
4194                                                 }
4195                                                 //check version and status code result is OK
4196                                                 else {
4197                                                         //search Content_Length header
4198                                                         find_ret = http_utility::find_http_header_content_length(session_data_ptr->data_buffer + session_data_ptr->data_offset,
4199                                                                         session_data_ptr->data_length,
4200                                                                         http_header_content_length_offset,
4201                                                                         http_header_content_length_len);
4202
4203                                                         /*-------- DEBUG LOG --------*/
4204                                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4205                                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4206                                                                                         "handle_client_send() : call find_http_header_content_length : "
4207                                                                                         "return_value = %d. thread id : %d.");
4208                                                                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
4209                                                                 putLogDebug(600131, formatter.str(), __FILE__, __LINE__);
4210                                                         }
4211                                                         /*------DEBUG LOG END------*/
4212
4213                                                         //search Content_Length result is OK
4214                                                         if (find_ret) {
4215                                                                 content_length.assign(session_data_ptr->data_buffer + session_data_ptr->data_offset + http_header_content_length_offset,
4216                                                                                       http_header_content_length_len);
4217                                                                 find_ret = regex_search(content_length.c_str(), regex_ret, content_length_regex);
4218
4219                                                                 //"content-length: ddd\r\n"
4220                                                                 if (find_ret) {
4221                                                                         content_length = content_length.substr(
4222                                                                                                  regex_ret.position(1),
4223                                                                                                  regex_ret.length(1));
4224
4225                                                                         //set content length value
4226                                                                         content_length_value = boost::lexical_cast<int>(content_length);
4227                                                                 }
4228
4229                                                                 //http_header context is "\r\n\r\n" only
4230                                                                 if (http_header_all_len == 0) {
4231                                                                         //set current message rest size
4232                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_LEN;
4233                                                                 } else {
4234                                                                         //set current message rest size
4235                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + content_length_value + CR_LF_CR_LF_LEN;
4236                                                                 }
4237                                                         }
4238                                                         //search Content_Length result is OK
4239                                                         else {
4240                                                                 //http_header context is "\r\n\r\n" only
4241                                                                 if (http_header_all_len == 0) {
4242                                                                         //set current message rest size
4243                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_LEN;
4244                                                                 } else {
4245                                                                         //set current message rest size
4246                                                                         session_data_ptr->current_message_rest_size = http_header_all_offset + http_header_all_len + CR_LF_CR_LF_LEN;
4247                                                                 }
4248
4249                                                         }
4250
4251                                                         //set data state HTTP_HEADER
4252                                                         session_data_ptr->data_state = HTTP_HEADER;
4253                                                 }
4254
4255                                                 //set return status
4256                                                 status = CLIENT_CONNECTION_CHECK;
4257                                         }
4258                                 }
4259                                 //data state is UNKNOWN
4260                                 else if (session_data_ptr->data_state == UNKNOWN) {
4261                                         //set return status
4262                                         status = CLIENT_CONNECTION_CHECK;
4263                                 }
4264                         }
4265                         //data size is 0
4266                         else {
4267                                 //data state is HTTP_BODY
4268                                 if (session_data_ptr->data_state == HTTP_BODY) {
4269                                         //set data state HTTP_START
4270                                         session_data_ptr->data_state = HTTP_START;
4271                                 }
4272
4273                                 //set data offset 0
4274                                 session_data_ptr->data_offset = 0;
4275
4276                                 //set return status
4277                                 status = REALSERVER_RECV;
4278                         }
4279                 }
4280
4281                 //switch flag is on and status is REALSERVER_RECV
4282                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON
4283                     && status == REALSERVER_RECV) {
4284                         //set return status
4285                         status = CLIENT_DISCONNECT;
4286                 }
4287                 //sorry flag is on and and status is REALSERVER_RECV
4288                 else if (session_data_ptr->sorry_flag == SORRY_FLAG_ON
4289                          && status == REALSERVER_RECV) {
4290                         //set return status
4291                         status = SORRYSERVER_RECV;
4292                 } else {
4293                         //none
4294                 }
4295
4296                 //set last status
4297                 session_data_ptr->last_status = status;
4298         } catch (int e) {
4299                 /*-------- DEBUG LOG --------*/
4300                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4301                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4302                                                 "handle_client_send() : catch exception e = %d. thread id : %d.");
4303                         formatter % e % boost::this_thread::get_id();
4304                         putLogDebug(600132, formatter.str(), __FILE__, __LINE__);
4305                 }
4306                 /*------DEBUG LOG END------*/
4307
4308                 //set last status
4309                 status = FINALIZE;
4310         } catch (const boost::bad_lexical_cast &) {
4311                 std::cerr << "protocol_module_ip::handle_client_send() : exception : " <<  "Content_Length field's value is invalid." << std::endl;
4312                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_send() : "
4313                                         "Content_Length field's value is invalid. thread id : %d.");
4314                 formatter % boost::this_thread::get_id();
4315                 putLogError(600084, formatter.str(), __FILE__, __LINE__);
4316
4317                 //set last status
4318                 status = FINALIZE;
4319         } catch (const std::exception &ex) {
4320                 std::cerr << "protocol_module_ip::handle_client_send() : exception : error = " << ex.what() << "." << std::endl;
4321                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4322                                         "handle_client_send() : exception : error = %s. thread id : %d.");
4323                 formatter % ex.what() % boost::this_thread::get_id();
4324                 putLogError(600085, formatter.str(), __FILE__, __LINE__);
4325
4326                 //set last status
4327                 status = FINALIZE;
4328         } catch (...) {
4329                 std::cerr << "protocol_module_ip::handle_client_send() : Unknown exception." << std::endl;
4330                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4331                                         "protocol_module_ip::handle_client_send() : "
4332                                         "Unknown exception. thread id : %d.");
4333                 formatter % boost::this_thread::get_id();
4334                 putLogError(600086, formatter.str(), __FILE__, __LINE__);
4335
4336                 //set last status
4337                 status = FINALIZE;
4338         }
4339
4340         /*-------- DEBUG LOG --------*/
4341         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4342                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4343                                         "handle_client_send(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4344                 formatter % status % boost::this_thread::get_id();
4345                 putLogDebug(600133, formatter.str(), __FILE__, __LINE__);
4346         }
4347         /*------DEBUG LOG END------*/
4348
4349         return status;
4350 }
4351
4352 //! call from client disconnect event. use upstream thread and downstream thread.
4353 //! @param[in]    upstream and downstream thread id( check! one thread one event! )
4354 //! @return     session use EVENT mode
4355 protocol_module_base::EVENT_TAG protocol_module_ip::handle_client_disconnect(
4356         const boost::thread::id thread_id)
4357 {
4358         /*-------- DEBUG LOG --------*/
4359         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4360                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4361                                         "handle_client_disconnect(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4362                 formatter % FINALIZE % boost::this_thread::get_id();
4363                 putLogDebug(600134, formatter.str(), __FILE__, __LINE__);
4364         }
4365         /*------DEBUG LOG END------*/
4366         return FINALIZE;
4367 }
4368
4369 //! call from sorry mode event. use upstream thread and downstream thread
4370 //! @param[in]    upstream and downstream thread id( check! one thread one event and first time call pattern )
4371 //! @return     session use EVENT mode
4372 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorry_enable(
4373         const boost::thread::id thread_id)
4374 {
4375         /*-------- DEBUG LOG --------*/
4376         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4377                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4378                                         "handle_sorry_enable(const boost::thread::id thread_id) : thread_id = %d.");
4379                 formatter % boost::this_thread::get_id();
4380                 putLogDebug(600135, formatter.str(), __FILE__, __LINE__);
4381         }
4382         /*------DEBUG LOG END------*/
4383
4384         EVENT_TAG status = FINALIZE;
4385         thread_data_ptr session_data_ptr;
4386
4387         try {
4388                 {
4389                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4390
4391                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4392                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4393                                 boost::format formatter("Invalid thread id. thread id : %d.");
4394                                 formatter % boost::this_thread::get_id();
4395                                 putLogError(600087, formatter.str(), __FILE__, __LINE__);
4396                                 throw - 1;
4397                         }
4398
4399                         session_data_ptr = session_thread_it->second;
4400                 }
4401
4402
4403                 //up thread
4404                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
4405                         //accept_end_flag is off
4406                         if (session_data_ptr->accept_end_flag == ACCEPT_END_FLAG_OFF) {
4407                                 //set return status
4408                                 status = ACCEPT;
4409                         }
4410                         //accept_end_flag is on
4411                         else {
4412                                 //sorry flag is on
4413                                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4414                                         //data state is HTTP_START or HTTP_HEADER
4415                                         if (session_data_ptr->data_state == HTTP_START
4416                                             || session_data_ptr->data_state == HTTP_HEADER) {
4417                                                 //set switch flag on
4418                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4419
4420                                                 /*-------- DEBUG LOG --------*/
4421                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4422                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4423                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4424                                                         formatter % boost::this_thread::get_id();
4425                                                         putLogDebug(600136, formatter.str(), __FILE__, __LINE__);
4426                                                 }
4427                                                 /*------DEBUG LOG END------*/
4428
4429                                                 //set return status
4430                                                 status = SORRYSERVER_DISCONNECT;
4431                                         }
4432                                         //data state is HTTP_BODY or UNKNOWN
4433                                         else {
4434                                                 //set return status
4435                                                 status = session_data_ptr->last_status;
4436                                         }
4437                                 }
4438                                 //sorry flag is off
4439                                 else {
4440                                         //data state is HTTP_START or HTTP_HEADER
4441                                         if (session_data_ptr->data_state == HTTP_START
4442                                             || session_data_ptr->data_state == HTTP_HEADER) {
4443                                                 //set switch flag on
4444                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4445
4446                                                 /*-------- DEBUG LOG --------*/
4447                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4448                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4449                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4450                                                         formatter % boost::this_thread::get_id();
4451                                                         putLogDebug(600137, formatter.str(), __FILE__, __LINE__);
4452                                                 }
4453                                                 /*------DEBUG LOG END------*/
4454                                         }
4455                                         //data state is HTTP_BODY or UNKNOWN
4456                                         else {
4457                                                 //set ebd flag on
4458                                                 session_data_ptr->end_flag = END_FLAG_ON;
4459
4460                                                 /*-------- DEBUG LOG --------*/
4461                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4462                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4463                                                                                 "handle_sorry_enable(const boost::thread::id thread_id) : END_FLAG_ON. thread id : %d.");
4464                                                         formatter % boost::this_thread::get_id();
4465                                                         putLogDebug(600138, formatter.str(), __FILE__, __LINE__);
4466                                                 }
4467                                                 /*------DEBUG LOG END------*/
4468                                         }
4469
4470                                         //set return status
4471                                         status = REALSERVER_DISCONNECT;
4472                                 }
4473                         }
4474                 }
4475                 //down thread
4476                 else {
4477                         //sorry flag is on
4478                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4479                                 //set return status
4480                                 status = session_data_ptr->last_status;
4481                         }
4482                         //sorry flag is off
4483                         else {
4484                                 //data state is HTTP_START and data size is 0
4485                                 if (session_data_ptr->data_state == HTTP_START
4486                                     && session_data_ptr->data_length == 0) {
4487                                         //set return status
4488                                         status = SORRYSERVER_RECV;
4489                                 }
4490                                 //data state is HTTP_START and data size > 0
4491                                 else if (session_data_ptr->data_state == HTTP_START
4492                                          && session_data_ptr->data_length > 0) {
4493                                         //set return status
4494                                         status = REALSERVER_DISCONNECT;
4495                                 }
4496                                 //data state is HTTP_HEADER or HTTP_BODY
4497                                 else if (session_data_ptr->data_state == HTTP_HEADER
4498                                          || session_data_ptr->data_state == HTTP_BODY) {
4499                                         //set switch flag on
4500                                         session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4501
4502                                         /*-------- DEBUG LOG --------*/
4503                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4504                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4505                                                                         "handle_sorry_enable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4506                                                 formatter % boost::this_thread::get_id();
4507                                                 putLogDebug(600139, formatter.str(), __FILE__, __LINE__);
4508                                         }
4509                                         /*------DEBUG LOG END------*/
4510
4511                                         //set return status
4512                                         status = session_data_ptr->last_status;
4513                                 }
4514                                 //other
4515                                 else {
4516                                         //set return status
4517                                         status = REALSERVER_DISCONNECT;
4518                                 }
4519                         }
4520                 }
4521
4522                 //set sorry flag on
4523                 session_data_ptr->sorry_flag = SORRY_FLAG_ON;
4524
4525                 /*-------- DEBUG LOG --------*/
4526                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4527                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4528                                                 "handle_sorry_enable(const boost::thread::id thread_id) : SORRY_FLAG_ON. thread id : %d.");
4529                         formatter % boost::this_thread::get_id();
4530                         putLogDebug(600140, formatter.str(), __FILE__, __LINE__);
4531                 }
4532                 /*------DEBUG LOG END------*/
4533
4534                 //set last status
4535                 session_data_ptr->last_status = status;
4536
4537         } catch (int e) {
4538                 /*-------- DEBUG LOG --------*/
4539                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4540                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4541                                                 "handle_sorry_enable() : catch exception e = %d. thread id : %d.");
4542                         formatter % e % boost::this_thread::get_id();
4543                         putLogDebug(600141, formatter.str(), __FILE__, __LINE__);
4544                 }
4545                 /*------DEBUG LOG END------*/
4546
4547                 //set return status
4548                 status = FINALIZE;
4549         } catch (std::exception &ex) {
4550                 std::cerr << "protocol_module_ip::handle_sorry_enable() : exception : error = " << ex.what() << "." << std::endl;
4551                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4552                                         "handle_sorry_enable() : exception : error = %s. thread id : %d.");
4553                 formatter % ex.what() % boost::this_thread::get_id();
4554                 putLogError(600088, formatter.str(), __FILE__, __LINE__);
4555
4556                 //set return status
4557                 status = FINALIZE;
4558         } catch (...) {
4559                 std::cerr << "protocol_module_ip::handle_sorry_enable() : Unknown exception." << std::endl;
4560                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4561                                         "protocol_module_ip::handle_sorry_enable() : "
4562                                         "Unknown exception. thread id : %d.");
4563                 formatter % boost::this_thread::get_id();
4564                 putLogError(600089, formatter.str(), __FILE__, __LINE__);
4565
4566                 //set return status
4567                 status = FINALIZE;
4568         }
4569
4570         /*-------- DEBUG LOG --------*/
4571         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4572                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4573                                         "handle_sorry_enable(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4574                 formatter % status % boost::this_thread::get_id();
4575                 putLogDebug(600142, formatter.str(), __FILE__, __LINE__);
4576         }
4577         /*------DEBUG LOG END------*/
4578
4579         return status;
4580 }
4581
4582 //! call from sorry mode disable. use upstream thread and downstream thread.
4583 //! @param[in]    upstream and downstream thread id( check! one thread one event )
4584 //! @return     session use EVENT mode
4585 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorry_disable(
4586         const boost::thread::id thread_id)
4587 {
4588         /*-------- DEBUG LOG --------*/
4589         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4590                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4591                                         "handle_sorry_disable(const boost::thread::id thread_id) : thread_id = %d.");
4592                 formatter % boost::this_thread::get_id();
4593                 putLogDebug(600143, formatter.str(), __FILE__, __LINE__);
4594         }
4595         /*------DEBUG LOG END------*/
4596
4597         EVENT_TAG status = FINALIZE;
4598         thread_data_ptr session_data_ptr;
4599
4600         try {
4601                 {
4602                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4603
4604                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4605                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4606                                 boost::format formatter("Invalid thread id. thread id : %d.");
4607                                 formatter % boost::this_thread::get_id();
4608                                 putLogError(600090, formatter.str(), __FILE__, __LINE__);
4609                                 throw - 1;
4610                         }
4611
4612                         session_data_ptr = session_thread_it->second;
4613                 }
4614
4615                 //up thread
4616                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
4617                         //accept_end_flag is off
4618                         if (session_data_ptr->accept_end_flag == ACCEPT_END_FLAG_OFF) {
4619                                 //set return status
4620                                 status = ACCEPT;
4621                         }
4622                         //accept_end_flag is on
4623                         else {
4624                                 //sorry flag is on
4625                                 if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4626                                         ///data state is HTTP_START or HTTP_HEADER
4627                                         if (session_data_ptr->data_state == HTTP_START
4628                                             || session_data_ptr->data_state == HTTP_HEADER) {
4629                                                 //set switch flag on
4630                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4631
4632                                                 /*-------- DEBUG LOG --------*/
4633                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4634                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4635                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4636                                                         formatter % boost::this_thread::get_id();
4637                                                         putLogDebug(600144, formatter.str(), __FILE__, __LINE__);
4638                                                 }
4639                                                 /*------DEBUG LOG END------*/
4640
4641                                         }
4642                                         //data state is HTTP_BODY or UNKNOWN
4643                                         else {
4644                                                 //set end flag on
4645                                                 session_data_ptr->end_flag = END_FLAG_ON;
4646
4647                                                 /*-------- DEBUG LOG --------*/
4648                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4649                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4650                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : END_FLAG_ON. thread id : %d.");
4651                                                         formatter % boost::this_thread::get_id();
4652                                                         putLogDebug(600145, formatter.str(), __FILE__, __LINE__);
4653                                                 }
4654                                                 /*------DEBUG LOG END------*/
4655                                         }
4656
4657                                         //set return status
4658                                         status = SORRYSERVER_DISCONNECT;
4659
4660                                 }
4661                                 //sorry flag is off
4662                                 else {
4663                                         //data state is HTTP_START or HTTP_HEADER
4664                                         if (session_data_ptr->data_state == HTTP_START
4665                                             || session_data_ptr->data_state == HTTP_HEADER) {
4666                                                 //set switch flag on
4667                                                 session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4668
4669                                                 /*-------- DEBUG LOG --------*/
4670                                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4671                                                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4672                                                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4673                                                         formatter % boost::this_thread::get_id();
4674                                                         putLogDebug(600146, formatter.str(), __FILE__, __LINE__);
4675                                                 }
4676                                                 /*------DEBUG LOG END------*/
4677
4678                                                 //set return status
4679                                                 status = REALSERVER_DISCONNECT;
4680                                         }
4681                                         //data state is HTTP_BODY or UNKNOWN
4682                                         else {
4683                                                 //set return status
4684                                                 status = session_data_ptr->last_status;
4685                                         }
4686                                 }
4687                         }
4688                 }
4689                 //down thread
4690                 else {
4691                         //sorry flag is off
4692                         if (session_data_ptr->sorry_flag == SORRY_FLAG_OFF) {
4693                                 //set return status
4694                                 status = session_data_ptr->last_status;
4695                         }
4696                         //sorry flag is on
4697                         else {
4698                                 //data state is HTTP_START and data size is 0
4699                                 if (session_data_ptr->data_state == HTTP_START
4700                                     && session_data_ptr->data_length == 0) {
4701                                         //set return status
4702                                         status = REALSERVER_RECV;
4703                                 }
4704                                 //data state is HTTP_START and data size > 0
4705                                 else if (session_data_ptr->data_state == HTTP_START
4706                                          && session_data_ptr->data_length > 0) {
4707                                         //set return status
4708                                         status = SORRYSERVER_DISCONNECT;
4709                                 }
4710                                 //data state is HTTP_HEADER or HTTP_BODY
4711                                 else if (session_data_ptr->data_state == HTTP_HEADER
4712                                          || session_data_ptr->data_state == HTTP_BODY) {
4713                                         //set switch flag on
4714                                         session_data_ptr->switch_flag = SWITCH_FLAG_ON;
4715
4716                                         /*-------- DEBUG LOG --------*/
4717                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4718                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4719                                                                         "handle_sorry_disable(const boost::thread::id thread_id) : SWITCH_FLAG_ON. thread id : %d.");
4720                                                 formatter % boost::this_thread::get_id();
4721                                                 putLogDebug(600147, formatter.str(), __FILE__, __LINE__);
4722                                         }
4723                                         /*------DEBUG LOG END------*/
4724
4725                                         //set return status
4726                                         status = session_data_ptr->last_status;
4727                                 }
4728                                 //other
4729                                 else {
4730                                         //set return status
4731                                         status = SORRYSERVER_DISCONNECT;
4732                                 }
4733                         }
4734                 }
4735
4736                 //set sorry flag off
4737                 session_data_ptr->sorry_flag = SORRY_FLAG_OFF;
4738
4739                 /*-------- DEBUG LOG --------*/
4740                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4741                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4742                                                 "handle_sorry_disable(const boost::thread::id thread_id) : SORRY_FLAG_OFF. thread id : %d.");
4743                         formatter % boost::this_thread::get_id();
4744                         putLogDebug(600148, formatter.str(), __FILE__, __LINE__);
4745                 }
4746                 /*------DEBUG LOG END------*/
4747
4748                 //set last status
4749                 session_data_ptr->last_status = status;
4750         } catch (int e) {
4751                 /*-------- DEBUG LOG --------*/
4752                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4753                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4754                                                 "handle_sorry_disable() : catch exception e = %d. thread id : %d.");
4755                         formatter % e % boost::this_thread::get_id();
4756                         putLogDebug(600149, formatter.str(), __FILE__, __LINE__);
4757                 }
4758                 /*------DEBUG LOG END------*/
4759
4760                 //set last status
4761                 status = FINALIZE;
4762         } catch (std::exception &ex) {
4763                 std::cerr << "protocol_module_ip::handle_sorry_disable() : exception : error = " << ex.what() << "." << std::endl;
4764                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4765                                         "handle_sorry_disable() : exception : error = %s. thread id : %d.");
4766                 formatter % ex.what() % boost::this_thread::get_id();
4767                 putLogError(600091, formatter.str(), __FILE__, __LINE__);
4768
4769                 //set last status
4770                 status = FINALIZE;
4771         } catch (...) {
4772                 std::cerr << "protocol_module_ip::handle_sorry_disable() : Unknown exception." << std::endl;
4773                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4774                                         "protocol_module_ip::handle_sorry_disable() : "
4775                                         "Unknown exception. thread id : %d.");
4776                 formatter % boost::this_thread::get_id();
4777                 putLogError(600092, formatter.str(), __FILE__, __LINE__);
4778
4779                 //set last status
4780                 status = FINALIZE;
4781         }
4782
4783         /*-------- DEBUG LOG --------*/
4784         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4785                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4786                                         "handle_sorry_disable(const boost::thread::id thread_id) : return_value = %d. thread id : %d.");
4787                 formatter % status % boost::this_thread::get_id();
4788                 putLogDebug(600150, formatter.str(), __FILE__, __LINE__);
4789         }
4790         /*------DEBUG LOG END------*/
4791
4792         return status;
4793 }
4794
4795 //! call from realserver disconnect. use upstream thread and downstream thread
4796 //! @param[in]    upstream and downstream thread id( check! one thread one event )
4797 //! @param[in]    disconnected realserver endpoint.
4798 //! @return     session use EVENT mode
4799 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_disconnect(
4800         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &rs_endpoint)
4801 {
4802         /*-------- DEBUG LOG --------*/
4803         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4804                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4805                                         "handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& rs_endpoint) : "
4806                                         "thread_id = %d, rs_endpoint = [%s]:%d.");
4807                 formatter % thread_id % rs_endpoint.address().to_string() % rs_endpoint.port();
4808                 putLogDebug(600151, formatter.str(), __FILE__, __LINE__);
4809         }
4810         /*------DEBUG LOG END------*/
4811
4812         EVENT_TAG status = FINALIZE;
4813         thread_data_ptr session_data_ptr;
4814
4815         try {
4816                 {
4817                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4818
4819                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4820                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4821                                 boost::format formatter("Invalid thread id. thread id : %d.");
4822                                 formatter % boost::this_thread::get_id();
4823                                 putLogError(600093, formatter.str(), __FILE__, __LINE__);
4824                                 throw - 1;
4825                         }
4826
4827                         session_data_ptr = session_thread_it->second;
4828                 }
4829
4830
4831                 //up thread
4832                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
4833                         //end flag is on
4834                         if (session_data_ptr->end_flag == END_FLAG_ON) {
4835                                 //set return status
4836                                 status = CLIENT_RECV;
4837                         }
4838                         //end flag is off
4839                         else {
4840                                 //switch flag is on
4841                                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON) {
4842                                         //sorry flag is on
4843                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4844                                                 //set return status
4845                                                 status = SORRYSERVER_SELECT;
4846                                         }
4847                                         //sorry flag is off
4848                                         else {
4849                                                 //set return status
4850                                                 status = REALSERVER_SELECT;
4851                                         }
4852
4853                                         //set switch flag off
4854                                         session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
4855
4856                                         /*-------- DEBUG LOG --------*/
4857                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4858                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4859                                                                         "handle_realserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &"                         "rs_endpoint) : SWITCH_FLAG_OFF. thread id : %d.");
4860                                                 formatter % boost::this_thread::get_id();
4861                                                 putLogDebug(600152, formatter.str(), __FILE__, __LINE__);
4862                                         }
4863                                         /*------DEBUG LOG END------*/
4864                                 }
4865                                 //switch flag is off
4866                                 else {
4867                                         //set return status
4868                                         status = CLIENT_RECV;
4869                                 }
4870                         }
4871                 }
4872                 //down thread
4873                 else {
4874                         //set return status
4875                         status = CLIENT_DISCONNECT;
4876                 }
4877
4878                 //set last status
4879                 session_data_ptr->last_status = status;
4880         } catch (int e) {
4881                 /*-------- DEBUG LOG --------*/
4882                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4883                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4884                                                 "handle_realserver_disconnect() : catch exception e = %d. thread id : %d.");
4885                         formatter % e % boost::this_thread::get_id();
4886                         putLogDebug(600153, formatter.str(), __FILE__, __LINE__);
4887                 }
4888                 /*------DEBUG LOG END------*/
4889
4890                 //set return status
4891                 status = FINALIZE;
4892         } catch (std::exception &ex) {
4893                 std::cerr << "protocol_module_ip::handle_realserver_disconnect() : exception : error = " << ex.what() << "." << std::endl;
4894                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4895                                         "handle_realserver_disconnect() : exception : error = %s. thread id : %d.");
4896                 formatter % ex.what() % boost::this_thread::get_id();
4897                 putLogError(600094, formatter.str(), __FILE__, __LINE__);
4898
4899                 //set return status
4900                 status = FINALIZE;
4901         } catch (...) {
4902                 std::cerr << "protocol_module_ip::handle_realserver_disconnect() : Unknown exception." << std::endl;
4903                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
4904                                         "protocol_module_ip::handle_realserver_disconnect() : "
4905                                         "Unknown exception. thread id : %d.");
4906                 formatter % boost::this_thread::get_id();
4907                 putLogError(600095, formatter.str(), __FILE__, __LINE__);
4908
4909                 //set return status
4910                 status = FINALIZE;
4911         }
4912
4913         /*-------- DEBUG LOG --------*/
4914         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4915                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4916                                         "handle_realserver_disconnect(const boost::thread::id thread_id, "
4917                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : return_value = %d. thread id : %d.");
4918                 formatter % status % boost::this_thread::get_id();
4919                 putLogDebug(600154, formatter.str(), __FILE__, __LINE__);
4920         }
4921         /*------DEBUG LOG END------*/
4922
4923         return status;
4924 }
4925
4926 //! call from sorry server disconnect. use upstraem thread and downstream thread
4927 //! @param[in]    upstream and downstream thread id( check! one thread one event )
4928 //! @param[in]    disconnect sorryserver endpoint
4929 //! @return        session use EVENT mode
4930 //! @return        session use EVENT mode
4931 protocol_module_base::EVENT_TAG protocol_module_ip::handle_sorryserver_disconnect(
4932         const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &sorry_endpoint)
4933 {
4934
4935         /*-------- DEBUG LOG --------*/
4936         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4937                 boost::format formatter("in_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4938                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint& sorry_endpoint) : "
4939                                         "thread_id = %d, sorry_endpoint = [%s]:%d.");
4940                 formatter % thread_id % sorry_endpoint.address().to_string() % sorry_endpoint.port();
4941                 putLogDebug(600155, formatter.str(), __FILE__, __LINE__);
4942         }
4943         /*------DEBUG LOG END------*/
4944
4945         EVENT_TAG status = FINALIZE;
4946         thread_data_ptr session_data_ptr;
4947
4948         try {
4949                 {
4950                         boost::mutex::scoped_lock sclock(session_thread_data_map_mutex);
4951
4952                         session_thread_data_map_it session_thread_it = session_thread_data_map.find(thread_id);
4953                         if (unlikely(session_thread_it == session_thread_data_map.end() || session_thread_it->second == NULL)) {
4954                                 boost::format formatter("Invalid thread id. thread id : %d.");
4955                                 formatter % boost::this_thread::get_id();
4956                                 putLogError(600096, formatter.str(), __FILE__, __LINE__);
4957                                 throw - 1;
4958                         }
4959
4960                         session_data_ptr = session_thread_it->second;
4961                 }
4962
4963                 //up thread
4964                 if (session_data_ptr->thread_division == THREAD_DIVISION_UP_STREAM) {
4965                         //end flag is on
4966                         if (session_data_ptr->end_flag == END_FLAG_ON) {
4967                                 //set return status
4968                                 status = CLIENT_RECV;
4969                         }
4970                         //end flag is off
4971                         else {
4972                                 //switch flag is on
4973                                 if (session_data_ptr->switch_flag == SWITCH_FLAG_ON) {
4974                                         //sorry flag is on
4975                                         if (session_data_ptr->sorry_flag == SORRY_FLAG_ON) {
4976                                                 //set return status
4977                                                 status = SORRYSERVER_SELECT;
4978                                         }
4979                                         //sorry flag is off
4980                                         else {
4981                                                 //set return status
4982                                                 status = REALSERVER_SELECT;
4983                                         }
4984
4985                                         //set switch flag off
4986                                         session_data_ptr->switch_flag = SWITCH_FLAG_OFF;
4987
4988                                         /*-------- DEBUG LOG --------*/
4989                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
4990                                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
4991                                                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, const boost::asio::ip::tcp::endpoint &"                         "sorry_endpoint) : SWITCH_FLAG_OFF. thread id : %d.");
4992                                                 formatter % boost::this_thread::get_id();
4993                                                 putLogDebug(600156, formatter.str(), __FILE__, __LINE__);
4994                                         }
4995                                         /*------DEBUG LOG END------*/
4996
4997                                 }
4998                                 //switch flag is off
4999                                 else {
5000                                         //set return status
5001                                         status = CLIENT_RECV;
5002                                 }
5003                         }
5004                 }
5005                 //down thread
5006                 else {
5007                         //set return status
5008                         status = CLIENT_DISCONNECT;
5009                 }
5010
5011                 //set last status
5012                 session_data_ptr->last_status = status;
5013
5014         } catch (int e) {
5015                 /*-------- DEBUG LOG --------*/
5016                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5017                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5018                                                 "handle_sorryserver_disconnect() : catch exception e = %d. thread id : %d.");
5019                         formatter % e % boost::this_thread::get_id();
5020                         putLogDebug(600157, formatter.str(), __FILE__, __LINE__);
5021                 }
5022                 /*------DEBUG LOG END------*/
5023
5024                 //set return status
5025                 status = FINALIZE;
5026         }
5027
5028         catch (std::exception &ex) {
5029                 std::cerr << "protocol_module_ip::handle_sorryserver_disconnect() : exception : error = " << ex.what() << "." << std::endl;
5030                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5031                                         "handle_sorryserver_disconnect() : exception : error = %s. thread id : %d.");
5032                 formatter % ex.what() % boost::this_thread::get_id();
5033                 putLogError(600097, formatter.str(), __FILE__, __LINE__);
5034
5035                 //set return status
5036                 status = FINALIZE;
5037         } catch (...) {
5038                 std::cerr << "protocol_module_ip::handle_sorryserver_disconnect() : Unknown exception." << std::endl;
5039                 boost::format formatter("function : protocol_module_base::EVENT_TAG "
5040                                         "protocol_module_ip::handle_sorryserver_disconnect() : "
5041                                         "Unknown exception. thread id : %d.");
5042                 formatter % boost::this_thread::get_id();
5043                 putLogError(600098, formatter.str(), __FILE__, __LINE__);
5044
5045                 //set return status
5046                 status = FINALIZE;
5047         }
5048
5049         /*-------- DEBUG LOG --------*/
5050         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5051                 boost::format formatter("out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5052                                         "handle_sorryserver_disconnect(const boost::thread::id thread_id, "
5053                                         "const boost::asio::ip::tcp::endpoint& sorry_endpoint) : return_value = %d. thread id : %d.");
5054                 formatter % status % boost::this_thread::get_id();
5055                 putLogDebug(600158, formatter.str(), __FILE__, __LINE__);
5056         }
5057         /*------DEBUG LOG END------*/
5058
5059         return status;
5060 }
5061
5062 //! call from realserver disconnect. use upstream thread and downstream thread.
5063 //! @param[in]    upstream and downstream thread id( check! one thread one event )
5064 //! @param[in]    disconnect realserver endpoint
5065 //! @return        session use EVENT mode.
5066 protocol_module_base::EVENT_TAG protocol_module_ip::handle_realserver_close(
5067         const boost::thread::id thread_id, const boost::asio::ip::udp::endpoint &rs_endpoint)
5068 {
5069         /*-------- DEBUG LOG --------*/
5070         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5071                 boost::format formatter("in/out_function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5072                                         "handle_realserver_close(const boost::thread::id thread_id, "
5073                                         "boost::asio::ip::udp::endpoint& rs_endpoint) : "
5074                                         "return_value = %d. thread id : %d.");
5075                 formatter % STOP % boost::this_thread::get_id();
5076                 putLogDebug(600159, formatter.str(), __FILE__, __LINE__);
5077         }
5078         /*------DEBUG LOG END------*/
5079
5080         return STOP;
5081 }
5082
5083
5084 bool  protocol_module_ip::get_data_from_recvbuffer(
5085         thread_data_ptr data_ptr, const boost::array<char, MAX_BUFFER_SIZE>& recvbuffer, const size_t recvlen)
5086 {
5087         /*-------- DEBUG LOG --------*/
5088         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5089                 boost::format formatter("in_function : bool protocol_module_ip::get_data_from_recvbuffer("
5090                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5091                                         "const size_t& recvlen) : thread_id = %d.");
5092                 formatter % boost::this_thread::get_id();
5093                 putLogDebug(600160, formatter.str(), __FILE__, __LINE__);
5094         }
5095         /*------DEBUG LOG END------*/
5096
5097         char *tmpbuffer = NULL;
5098
5099         //pointer volidate check
5100         if (unlikely(data_ptr == NULL || data_ptr->data_buffer == NULL)) {
5101                 boost::format formatter("Invalid pointer. thread id : %d.");
5102                 formatter % boost::this_thread::get_id();
5103                 putLogError(600099, formatter.str(), __FILE__, __LINE__);
5104
5105                 /*-------- DEBUG LOG --------*/
5106                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5107                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5108                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5109                                                 "const size_t& recvlen) : return_value = false. thread id : %d.");
5110                         formatter % boost::this_thread::get_id();
5111                         putLogDebug(600161, formatter.str(), __FILE__, __LINE__);
5112                 }
5113                 /*------DEBUG LOG END------*/
5114
5115                 return false;
5116         }
5117
5118
5119         //the new data can append to buffer directly
5120         if (data_ptr->data_buffer_size - data_ptr->data_length - data_ptr->data_offset >= recvlen) {
5121
5122                 /*-------- DEBUG LOG --------*/
5123                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5124                         std::string datadump;
5125                         dump_memory(recvbuffer.data(), recvlen, datadump);
5126                         boost::format formatter(
5127                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5128                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5129                                 "data begin = 0, data_size = %d, data = %s");
5130                         formatter % recvlen % datadump;
5131                         putLogDebug(600162, formatter.str(), __FILE__, __LINE__);
5132                 }
5133                 /*------DEBUG LOG END------*/
5134
5135                 memcpy(data_ptr->data_buffer + data_ptr->data_offset + data_ptr->data_length, recvbuffer.data(), recvlen);
5136
5137                 /*-------- DEBUG LOG --------*/
5138                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5139                         std::string datadump;
5140                         dump_memory(data_ptr->data_buffer + data_ptr->data_offset + data_ptr->data_length, recvlen, datadump);
5141                         boost::format formatter(
5142                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5143                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5144                                 "data begin = 0, data_size = %d, data = %s");
5145                         formatter % recvlen % datadump;
5146                         putLogDebug(600163, formatter.str(), __FILE__, __LINE__);
5147                 }
5148                 /*------DEBUG LOG END------*/
5149
5150                 data_ptr->data_length += recvlen;
5151
5152                 /*-------- DEBUG LOG --------*/
5153                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5154                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5155                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5156                                                 "const size_t& recvlen) : return_value = true. thread id : %d.");
5157                         formatter % boost::this_thread::get_id();
5158                         putLogDebug(600164, formatter.str(), __FILE__, __LINE__);
5159                 }
5160                 /*------DEBUG LOG END------*/
5161                 return true;
5162         } else {
5163                 //the new data can append to buffer through moving orignal data
5164                 if (data_ptr->data_buffer_size - data_ptr->data_length >= recvlen) {
5165                         memmove(data_ptr->data_buffer, data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length);
5166                         /*-------- DEBUG LOG --------*/
5167                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5168                                 std::string datadump;
5169                                 dump_memory(recvbuffer.data(), recvlen, datadump);
5170                                 boost::format formatter(
5171                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5172                                         "get_data_from_recvbuffer() : before memcpy (data dump) : "
5173                                         "data begin = 0, data_size = %d, data = %s");
5174                                 formatter % recvlen % datadump;
5175                                 putLogDebug(600165, formatter.str(), __FILE__, __LINE__);
5176                         }
5177                         /*------DEBUG LOG END------*/
5178
5179                         memcpy(data_ptr->data_buffer + data_ptr->data_length, recvbuffer.data(), recvlen);
5180
5181                         /*-------- DEBUG LOG --------*/
5182                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5183                                 std::string datadump;
5184                                 dump_memory(data_ptr->data_buffer + data_ptr->data_length, recvlen, datadump);
5185                                 boost::format formatter(
5186                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5187                                         "get_data_from_recvbuffer() : after memcpy (data dump) : "
5188                                         "data begin = 0, data_size = %d, data = %s");
5189                                 formatter % recvlen % datadump;
5190                                 putLogDebug(600166, formatter.str(), __FILE__, __LINE__);
5191                         }
5192                         /*------DEBUG LOG END------*/
5193
5194                         data_ptr->data_offset = 0;
5195                         data_ptr->data_length += recvlen;
5196
5197                         /*-------- DEBUG LOG --------*/
5198                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5199                                 boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5200                                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5201                                                         "const size_t& recvlen) : return_value = true. thread id : %d.");
5202                                 formatter % boost::this_thread::get_id();
5203                                 putLogDebug(600167, formatter.str(), __FILE__, __LINE__);
5204                         }
5205                         /*------DEBUG LOG END------*/
5206
5207                         return true;
5208                 } else {
5209                         //not allowed to realloc new buffer who's size is larger than the max size
5210                         if (data_ptr->data_buffer_size >= MAX_IP_MODULE_BUFFER_SIZE
5211                             || data_ptr->data_buffer_size + recvlen >= MAX_IP_MODULE_BUFFER_SIZE) {
5212                                 boost::format formatter("Buffer size is bigger than Max size. thread id : %d.");
5213                                 formatter % boost::this_thread::get_id();
5214                                 putLogError(600100, formatter.str(), __FILE__, __LINE__);
5215
5216                                 /*-------- DEBUG LOG --------*/
5217                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5218                                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5219                                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5220                                                                 "const size_t& recvlen) : return_value = false. thread id : %d.");
5221                                         formatter % boost::this_thread::get_id();
5222                                         putLogDebug(600168, formatter.str(), __FILE__, __LINE__);
5223                                 }
5224                                 /*------DEBUG LOG END------*/
5225
5226                                 return false;
5227                         } else {
5228                                 try {
5229                                         /*-------- DEBUG LOG --------*/
5230                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5231                                                 boost::format formatter("new : address = &(%d), size = %lu.");
5232                                                 formatter % static_cast<void *>(tmpbuffer) % MAX_IP_MODULE_BUFFER_SIZE;
5233                                                 putLogDebug(600169, formatter.str(), __FILE__, __LINE__);
5234                                         }
5235                                         /*------DEBUG LOG END------*/
5236
5237                                         //alloc a new buffer who's size is max
5238                                         tmpbuffer = new char[MAX_IP_MODULE_BUFFER_SIZE];
5239                                 } catch (const std::bad_alloc &) { //memory alloc fail
5240                                         std::cerr << "protocol_module_ip::get_data_from_recvbuffer() : exception : Could not allocate memory." << std::endl;
5241                                         boost::format formatter("Could not allocate memory. thread id : %d.");
5242                                         formatter % boost::this_thread::get_id();
5243                                         putLogError(600101, formatter.str(), __FILE__, __LINE__);
5244
5245                                         /*-------- DEBUG LOG --------*/
5246                                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5247                                                 boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5248                                                                         "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5249                                                                         "const size_t& recvlen) : return_value = false. thread id : %d.");
5250                                                 formatter % boost::this_thread::get_id();
5251                                                 putLogDebug(600170, formatter.str(), __FILE__, __LINE__);
5252                                         }
5253                                         /*------DEBUG LOG END------*/
5254
5255                                         return false;
5256                                 }
5257
5258                                 memset(tmpbuffer, 0, MAX_IP_MODULE_BUFFER_SIZE);
5259
5260                                 /*-------- DEBUG LOG --------*/
5261                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5262                                         std::string datadump;
5263                                         dump_memory(data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length, datadump);
5264                                         boost::format formatter(
5265                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5266                                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5267                                                 "data begin = 0, data_size = %d, data = %s");
5268                                         formatter % data_ptr->data_length % datadump;
5269                                         putLogDebug(600171, formatter.str(), __FILE__, __LINE__);
5270                                 }
5271                                 /*------DEBUG LOG END------*/
5272
5273                                 //copy old data to new buffer
5274                                 memcpy(tmpbuffer, data_ptr->data_buffer + data_ptr->data_offset, data_ptr->data_length);
5275
5276                                 /*-------- DEBUG LOG --------*/
5277                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5278                                         std::string datadump;
5279                                         dump_memory(tmpbuffer, data_ptr->data_length, datadump);
5280                                         boost::format formatter(
5281                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5282                                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5283                                                 "data begin = 0, data_size = %d, data = %s");
5284                                         formatter % data_ptr->data_length % datadump;
5285                                         putLogDebug(600172, formatter.str(), __FILE__, __LINE__);
5286                                 }
5287                                 /*------DEBUG LOG END------*/
5288
5289                                 /*-------- DEBUG LOG --------*/
5290                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5291                                         boost::format formatter("delete : address = &(%d).");
5292                                         formatter % static_cast<void *>(data_ptr->data_buffer);
5293                                         putLogDebug(600173, formatter.str(), __FILE__, __LINE__);
5294                                 }
5295                                 /*------DEBUG LOG END------*/
5296
5297                                 //release old memory
5298                                 delete [] data_ptr->data_buffer;
5299                                 data_ptr->data_buffer = tmpbuffer;
5300                                 data_ptr->data_offset = 0;
5301
5302                                 /*-------- DEBUG LOG --------*/
5303                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5304                                         std::string datadump;
5305                                         dump_memory(recvbuffer.data(), recvlen, datadump);
5306                                         boost::format formatter(
5307                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5308                                                 "get_data_from_recvbuffer() : before memcpy (data dump) : "
5309                                                 "data begin = 0, data_size = %d, data = %s");
5310                                         formatter % recvlen % datadump;
5311                                         putLogDebug(600174, formatter.str(), __FILE__, __LINE__);
5312                                 }
5313                                 /*------DEBUG LOG END------*/
5314
5315                                 //append new data
5316                                 memcpy(data_ptr->data_buffer + data_ptr->data_length, recvbuffer.data(), recvlen);
5317
5318                                 /*-------- DEBUG LOG --------*/
5319                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5320                                         std::string datadump;
5321                                         dump_memory(data_ptr->data_buffer + data_ptr->data_length, recvlen, datadump);
5322                                         boost::format formatter(
5323                                                 "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5324                                                 "get_data_from_recvbuffer() : after memcpy (data dump) : "
5325                                                 "data begin = 0, data_size = %d, data = %s");
5326                                         formatter % recvlen % datadump;
5327                                         putLogDebug(600175, formatter.str(), __FILE__, __LINE__);
5328                                 }
5329                                 /*------DEBUG LOG END------*/
5330
5331                                 data_ptr->data_length += recvlen;
5332                                 data_ptr->data_buffer_size = MAX_IP_MODULE_BUFFER_SIZE ;
5333
5334                                 /*-------- DEBUG LOG --------*/
5335                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5336                                         boost::format formatter("out_function : bool protocol_module_ip::get_data_from_recvbuffer("
5337                                                                 "thread_data_ptr data_ptr, const boost::array<char,MAX_BUFFER_SIZE>& recvbuffer, "
5338                                                                 "const size_t& recvlen) : return_value = true. thread id : %d.");
5339                                         formatter % boost::this_thread::get_id();
5340                                         putLogDebug(600176, formatter.str(), __FILE__, __LINE__);
5341                                 }
5342                                 /*------DEBUG LOG END------*/
5343
5344                                 return true;
5345
5346                         }
5347                 }
5348         }
5349 }
5350
5351 bool protocol_module_ip::put_data_into_sendbuffer(
5352         thread_data_ptr data_ptr, boost::array<char, MAX_BUFFER_SIZE>& sendbuffer, size_t &datalen)
5353 {
5354         /*-------- DEBUG LOG --------*/
5355         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5356                 boost::format formatter("in_function : bool protocol_module_ip::put_data_to_sendbuffer("
5357                                         "thread_data_ptr data_ptr, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
5358                                         "size_t& datalen) : thread_id = %d.");
5359                 formatter % boost::this_thread::get_id();
5360                 putLogDebug(600177, formatter.str(), __FILE__, __LINE__);
5361         }
5362         /*------DEBUG LOG END------*/
5363
5364         size_t sendbuffer_rest_size = 0;
5365         size_t new_offset        = 0;
5366
5367         if (unlikely(data_ptr == NULL || data_ptr->data_buffer == NULL || data_ptr->buffer_sequence.empty())) {
5368                 boost::format formatter("Invalid pointer. thread id : %d.");
5369                 formatter % boost::this_thread::get_id();
5370                 putLogError(600102, formatter.str(), __FILE__, __LINE__);
5371
5372                 /*-------- DEBUG LOG --------*/
5373                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5374                         boost::format formatter("out_function : bool protocol_module_ip::put_data_to_sendbuffer("
5375                                                 "thread_data_ptr data_ptr, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
5376                                                 "size_t& datalen) : return_value = false. thread_id = %d.");
5377                         formatter % boost::this_thread::get_id();
5378                         putLogDebug(600178, formatter.str(), __FILE__, __LINE__);
5379                 }
5380                 /*------DEBUG LOG END------*/
5381
5382                 return false;
5383         }
5384
5385         sendbuffer_rest_size = sendbuffer.size();
5386         datalen = 0;
5387
5388         //buffer_sequence loop
5389         //copy data to send buffer until send buffer is full
5390         while (data_ptr->buffer_sequence.size() > 0) {
5391                 std::pair<char *, size_t> buffer_element = data_ptr->buffer_sequence.front();
5392                 //sendbuffer rest size id bigger than copy possible size
5393                 if (buffer_element.second <= sendbuffer_rest_size) {
5394                         /*-------- DEBUG LOG --------*/
5395                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5396                                 std::string datadump;
5397                                 dump_memory(buffer_element.first, buffer_element.second, datadump);
5398                                 boost::format formatter(
5399                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5400                                         "put_data_to_sendbuffer() : before memcpy (data dump) : "
5401                                         "data begin = 0, data_size = %d, data = %s");
5402                                 formatter % buffer_element.second % datadump;
5403                                 putLogDebug(600179, formatter.str(), __FILE__, __LINE__);
5404                         }
5405                         /*------DEBUG LOG END------*/
5406
5407                         //copy data to send buffer
5408                         memcpy(sendbuffer.c_array() + datalen, buffer_element.first, buffer_element.second);
5409
5410                         /*-------- DEBUG LOG --------*/
5411                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5412                                 std::string datadump;
5413                                 dump_memory(sendbuffer.c_array() + datalen, buffer_element.second, datadump);
5414                                 boost::format formatter(
5415                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5416                                         "put_data_to_sendbuffer() : after memcpy (data dump) : "
5417                                         "data begin = 0, data_size = %d, data = %s");
5418                                 formatter % buffer_element.second % datadump;
5419                                 putLogDebug(600180, formatter.str(), __FILE__, __LINE__);
5420                         }
5421                         /*------DEBUG LOG END------*/
5422
5423                         datalen += buffer_element.second;
5424                         sendbuffer_rest_size -= buffer_element.second;
5425
5426                         //it is the last item of the sequence
5427                         if (data_ptr->buffer_sequence.size() == 1) {
5428                                 //set data position
5429                                 new_offset = buffer_element.first + buffer_element.second - data_ptr->data_buffer;
5430                                 data_ptr->current_message_rest_size -= (new_offset - data_ptr->data_offset);
5431                                 data_ptr->data_length -= (new_offset - data_ptr->data_offset);
5432                                 data_ptr->data_offset = new_offset;
5433                         }
5434
5435
5436                         //delete the item
5437                         data_ptr->buffer_sequence.pop_front();
5438                 }
5439                 //sendbuffer rest size is too small
5440                 else {
5441                         /*-------- DEBUG LOG --------*/
5442                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5443                                 std::string datadump;
5444                                 dump_memory(buffer_element.first, sendbuffer_rest_size, datadump);
5445                                 boost::format formatter(
5446                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5447                                         "put_data_to_sendbuffer() : before memcpy (data dump) : "
5448                                         "data begin = 0, data_size = %d, data = %s");
5449                                 formatter % sendbuffer_rest_size % datadump;
5450                                 putLogDebug(600181, formatter.str(), __FILE__, __LINE__);
5451                         }
5452                         /*------DEBUG LOG END------*/
5453
5454                         //copy data to send buffer
5455                         memcpy(sendbuffer.c_array() + datalen, buffer_element.first, sendbuffer_rest_size);
5456
5457                         /*-------- DEBUG LOG --------*/
5458                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5459                                 std::string datadump;
5460                                 dump_memory(sendbuffer.c_array() + datalen, sendbuffer_rest_size, datadump);
5461                                 boost::format formatter(
5462                                         "function : protocol_module_base::EVENT_TAG protocol_module_ip::"
5463                                         "put_data_to_sendbuffer() : after memcpy (data dump) : "
5464                                         "data begin = 0, data_size = %d, data = %s");
5465                                 formatter % sendbuffer_rest_size % datadump;
5466                                 putLogDebug(600182, formatter.str(), __FILE__, __LINE__);
5467                         }
5468                         /*------DEBUG LOG END------*/
5469
5470                         datalen += sendbuffer_rest_size;
5471
5472                         //set item position
5473                         buffer_element.first += sendbuffer_rest_size;
5474                         buffer_element.second -= sendbuffer_rest_size;
5475                         sendbuffer_rest_size = 0;
5476                         break;
5477                 }
5478         }
5479
5480         /*-------- DEBUG LOG --------*/
5481         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5482                 boost::format formatter("out_function : bool protocol_module_ip::put_data_to_sendbuffer("
5483                                         "thread_data_ptr data_ptr, boost::array<char,MAX_BUFFER_SIZE>& sendbuffer, "
5484                                         "size_t& datalen) : return_value = true. thread_id = %d.");
5485                 formatter % boost::this_thread::get_id();
5486                 putLogDebug(600183, formatter.str(), __FILE__, __LINE__);
5487         }
5488         /*------DEBUG LOG END------*/
5489
5490         return true;
5491 }
5492
5493
5494
5495
5496 //! call from put_data_to_buffer_with_x_forwarded_for(). get x_forwarded_for header's offset and length
5497 //! if the buffer isn't include x_forwarded_for header, create a new one
5498 //! @param[in]    buffer
5499 //! @param[in]    buffer_len
5500 //! @param[out] x_forwarded_for_insert_pos
5501 //! @param[out] x_forwarded_for_context
5502 //! @return  true:create a new x_forwarded_for header
5503 //!         false: edit old one
5504 bool protocol_module_ip::create_x_forwarded_for(const std::string &client_endpoint,
5505                 const char *buffer,
5506                 const size_t buffer_len,
5507                 size_t &x_forwarded_for_insert_pos,
5508                 std::string &x_forwarded_for_context)
5509 {
5510         /*-------- DEBUG LOG --------*/
5511         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5512                 boost::format formatter("in_function : bool protocol_module_ip::create_x_forwarded_for("
5513                                         "const std::string& client_endpoint, const char* buffer, const size_t buffer_len, "
5514                                         "size_t& x_forwarded_for_insert_pos, std::string& x_forwarded_for_context) : thread_id = %d.");
5515                 formatter % boost::this_thread::get_id();
5516                 putLogDebug(600184, formatter.str(), __FILE__, __LINE__);
5517         }
5518         /*------DEBUG LOG END------*/
5519
5520         bool find_ret = false;
5521         size_t x_forwarded_for_offset   = 0;
5522         size_t x_forwarded_for_len    = 0;
5523         size_t http_header_all_offset   = 0;
5524         size_t http_header_all_len    = 0;
5525         const char *X_FORWARDED_FOR    = "X-Forwarded-For";
5526
5527         //search "X-Forwared-For" header
5528         find_ret = http_utility::find_http_header_x_forwarded_for(buffer, buffer_len,
5529                         x_forwarded_for_offset, x_forwarded_for_len);
5530
5531         /*-------- DEBUG LOG --------*/
5532         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5533                 boost::format formatter("function : bool protocol_module_ip::create_x_forwarded_for() : "
5534                                         "call find_http_header_x_forwarded_for : "
5535                                         "return_value = %d. thread id : %d.");
5536                 formatter % static_cast<int>(find_ret) % boost::this_thread::get_id();
5537                 putLogDebug(600185, formatter.str(), __FILE__, __LINE__);
5538         }
5539         /*------DEBUG LOG END------*/
5540
5541         //search "X-Forwared-For" result is OK
5542         if (find_ret) {
5543                 //create "X-Forwared-For" string
5544                 x_forwarded_for_insert_pos = x_forwarded_for_offset + x_forwarded_for_len;
5545                 x_forwarded_for_context = ", ";
5546                 x_forwarded_for_context += client_endpoint;
5547
5548                 /*-------- DEBUG LOG --------*/
5549                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5550                         boost::format formatter("out_function : bool protocol_module_ip::create_x_forwarded_for("
5551                                                 "const std::string& client_endpoint, const char* buffer, const size_t buffer_len, "
5552                                                 "size_t& x_forwarded_for_insert_pos, std::string& x_forwarded_for_context) : return_value = false. thread_id = %d.");
5553                         formatter % boost::this_thread::get_id();
5554                         putLogDebug(600186, formatter.str(), __FILE__, __LINE__);
5555                 }
5556                 /*------DEBUG LOG END------*/
5557
5558                 return false;
5559         }
5560
5561         //create a new one
5562         //because state is HTTP_HEADER, find_http_header_all must be return true
5563         http_utility::find_http_header_all(buffer, buffer_len, http_header_all_offset, http_header_all_len);
5564
5565         /*-------- DEBUG LOG --------*/
5566         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5567                 boost::format formatter("function : bool protocol_module_ip::create_x_forwarded_for() : "
5568                                         "call find_http_header_all : "
5569                                         "return_value = true. thread id : %d.");
5570                 formatter % boost::this_thread::get_id();
5571                 putLogDebug(600187, formatter.str(), __FILE__, __LINE__);
5572         }
5573         /*------DEBUG LOG END------*/
5574
5575         //create "X-Forwared-For" string
5576         x_forwarded_for_insert_pos = http_header_all_offset;
5577         x_forwarded_for_context = X_FORWARDED_FOR;
5578         x_forwarded_for_context += ": ";
5579         x_forwarded_for_context += client_endpoint;
5580         x_forwarded_for_context += "\r\n";
5581
5582         /*-------- DEBUG LOG --------*/
5583         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
5584                 boost::format formatter("out_function : bool protocol_module_ip::create_x_forwarded_for("
5585                                         "const std::string& client_endpoint, const char* buffer, const size_t buffer_len, "
5586                                         "size_t& x_forwarded_for_insert_pos, std::string& x_forwarded_for_context) : return_value = true. thread_id = %d.");
5587                 formatter % boost::this_thread::get_id();
5588                 putLogDebug(600188, formatter.str(), __FILE__, __LINE__);
5589         }
5590         /*------DEBUG LOG END------*/
5591
5592         return true;
5593 }
5594
5595
5596
5597 }//namesapce l7vsd
5598
5599 extern "C" l7vs::protocol_module_base*
5600 create_module()
5601 {
5602         return dynamic_cast<l7vs::protocol_module_base *>(new l7vs::protocol_module_ip());
5603 }
5604
5605 extern "C" void
5606 destroy_module(l7vs::protocol_module_base *in)
5607 {
5608         delete in;
5609 }