OSDN Git Service

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