OSDN Git Service

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