BESServerHandler.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <unistd.h>
00034 #include <sys/types.h>
00035 #include <sys/socket.h>
00036 #include <signal.h>
00037 #include <sys/wait.h>
00038
00039 #include <cstring>
00040 #include <cstdlib>
00041 #include <cerrno>
00042 #include <sstream>
00043 #include <iostream>
00044
00045 using std::ostringstream ;
00046 using std::cout ;
00047 using std::endl ;
00048 using std::cerr ;
00049 using std::flush ;
00050
00051 #include "BESServerHandler.h"
00052 #include "Connection.h"
00053 #include "Socket.h"
00054 #include "BESXMLInterface.h"
00055 #include "TheBESKeys.h"
00056 #include "BESInternalError.h"
00057 #include "ServerExitConditions.h"
00058 #include "BESUtil.h"
00059 #include "PPTStreamBuf.h"
00060 #include "PPTProtocol.h"
00061 #include "BESDebug.h"
00062 #include "BESStopWatch.h"
00063
00064 BESServerHandler::BESServerHandler()
00065 {
00066 bool found = false ;
00067 _method = TheBESKeys::TheKeys()->get_key( "BES.ProcessManagerMethod", found ) ;
00068 if( _method != "multiple" && _method != "single" )
00069 {
00070 cerr << "Unable to determine method to handle clients, "
00071 << "single or multiple as defined by BES.ProcessManagerMethod"
00072 << endl ;
00073 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00074 }
00075 }
00076
00077
00078
00079
00080
00081 void
00082 BESServerHandler::handle( Connection *c )
00083 {
00084 if(_method=="single")
00085 {
00086 execute( c ) ;
00087 }
00088 else
00089 {
00090 int main_process = getpid() ;
00091 pid_t pid ;
00092 if( ( pid = fork() ) < 0 )
00093 {
00094 string error( "fork error" ) ;
00095 const char* error_info = strerror( errno ) ;
00096 if( error_info )
00097 error += " " + (string)error_info ;
00098 throw BESInternalError( error, __FILE__, __LINE__ ) ;
00099 }
00100 else if( pid == 0 )
00101 {
00102 pid_t pid1 ;
00103
00104 if( ( pid1 = fork() ) < 0 )
00105 {
00106
00107
00108 kill( main_process, 9 ) ;
00109 perror( "fork error" ) ;
00110 exit( SERVER_EXIT_CHILD_SUBPROCESS_ABNORMAL_TERMINATION ) ;
00111 }
00112 else if( pid1 == 0 )
00113 {
00114 execute( c ) ;
00115 }
00116 sleep( 1 ) ;
00117 c->closeConnection() ;
00118 exit( SERVER_EXIT_CHILD_SUBPROCESS_NORMAL_TERMINATION ) ;
00119 }
00120 if( waitpid( pid, NULL, 0 ) != pid )
00121 {
00122 string error( "waitpid error" ) ;
00123 const char *error_info = strerror( errno ) ;
00124 if( error_info )
00125 error += " " + (string)error_info ;
00126 throw BESInternalError( error, __FILE__, __LINE__ ) ;
00127 }
00128 c->closeConnection() ;
00129 }
00130 }
00131
00132 void
00133 BESServerHandler::execute( Connection *c )
00134 {
00135 ostringstream strm ;
00136 string ip = c->getSocket()->getIp() ;
00137 strm << "ip " << ip << ", port " << c->getSocket()->getPort() ;
00138 string from = strm.str() ;
00139
00140 map<string,string> extensions ;
00141
00142 for(;;)
00143 {
00144 ostringstream ss ;
00145
00146 bool done = false ;
00147 while( !done )
00148 done = c->receive( extensions, &ss ) ;
00149
00150 if( extensions["status"] == c->exit() )
00151 {
00152 c->closeConnection() ;
00153 exit( CHILD_SUBPROCESS_READY ) ;
00154 }
00155
00156
00157
00158
00159
00160
00161 string cmd_str = ss.str() ;
00162 BESDEBUG( "server", "BESServerHandler::execute - command = " << cmd_str << endl )
00163
00164 BESStopWatch *sw = 0 ;
00165 if( BESISDEBUG( "timing" ) )
00166 {
00167 sw = new BESStopWatch() ;
00168 sw->start() ;
00169 }
00170
00171 int descript = c->getSocket()->getSocketDescriptor() ;
00172
00173 unsigned int bufsize = c->getSendChunkSize() ;
00174 PPTStreamBuf fds( descript, bufsize ) ;
00175 std::streambuf *holder ;
00176 holder = cout.rdbuf() ;
00177 cout.rdbuf( &fds ) ;
00178
00179 BESXMLInterface cmd( cmd_str, &cout ) ;
00180 int status = cmd.execute_request( from ) ;
00181
00182 if( status == 0 )
00183 {
00184 BESDEBUG( "server", "BESServerHandler::execute - executed successfully" << endl )
00185 fds.finish() ;
00186 cout.rdbuf( holder ) ;
00187
00188 if( BESISDEBUG( "timing" ) )
00189 {
00190 if( sw && sw->stop() )
00191 {
00192 BESDEBUG( "timing",
00193 "BESServerHandler::execute - executed in "
00194 << sw->seconds() << " seconds and "
00195 << sw->microseconds() << " microseconds"
00196 << endl )
00197 }
00198 else
00199 {
00200 BESDEBUG( "timing", \
00201 "BESServerHandler::execute - no timing available" )
00202 }
00203 }
00204 }
00205 else
00206 {
00207
00208 BESDEBUG( "server", "BESServerHandler::execute - error occurred" << endl )
00209
00210
00211 cout << flush ;
00212
00213
00214 map<string,string> extensions ;
00215 extensions["status"] = "error" ;
00216 c->sendExtensions( extensions ) ;
00217
00218
00219
00220 cmd.finish_with_error( status ) ;
00221
00222
00223 fds.finish() ;
00224
00225
00226 cout.rdbuf( holder ) ;
00227
00228 switch (status)
00229 {
00230 case BES_INTERNAL_FATAL_ERROR:
00231 {
00232 cout << "BES server " << getpid()
00233 << ": Status not OK, dispatcher returned value "
00234 << status << endl ;
00235
00236
00237 c->sendExit() ;
00238 c->closeConnection() ;
00239 exit( CHILD_SUBPROCESS_READY ) ;
00240 }
00241 break;
00242 case BES_INTERNAL_ERROR:
00243 case BES_SYNTAX_USER_ERROR:
00244 case BES_FORBIDDEN_ERROR:
00245 case BES_NOT_FOUND_ERROR:
00246 default:
00247 break;
00248 }
00249 }
00250
00251 delete sw;
00252 }
00253 }
00254
00261 void
00262 BESServerHandler::dump( ostream &strm ) const
00263 {
00264 strm << BESIndent::LMarg << "BESServerHandler::dump - ("
00265 << (void *)this << ")" << endl ;
00266 BESIndent::Indent() ;
00267 strm << BESIndent::LMarg << "server method: " << _method << endl ;
00268 BESIndent::UnIndent() ;
00269 }
00270