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 try
00068 {
00069 TheBESKeys::TheKeys()->get_value( "BES.ProcessManagerMethod",
00070 _method, found ) ;
00071 }
00072 catch( BESError &e )
00073 {
00074 cerr << "Unable to determine method to handle clients, "
00075 << "single or multiple as defined by BES.ProcessManagerMethod"
00076 << ": " << e.get_message() << endl ;
00077 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00078 }
00079 if( _method != "multiple" && _method != "single" )
00080 {
00081 cerr << "Unable to determine method to handle clients, "
00082 << "single or multiple as defined by BES.ProcessManagerMethod"
00083 << endl ;
00084 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00085 }
00086 }
00087
00088
00089
00090
00091
00092 void
00093 BESServerHandler::handle( Connection *c )
00094 {
00095 if(_method=="single")
00096 {
00097 execute( c ) ;
00098 }
00099 else
00100 {
00101 int main_process = getpid() ;
00102 pid_t pid ;
00103 if( ( pid = fork() ) < 0 )
00104 {
00105 string error( "fork error" ) ;
00106 const char* error_info = strerror( errno ) ;
00107 if( error_info )
00108 error += " " + (string)error_info ;
00109 throw BESInternalError( error, __FILE__, __LINE__ ) ;
00110 }
00111 else if( pid == 0 )
00112 {
00113 pid_t pid1 ;
00114
00115 if( ( pid1 = fork() ) < 0 )
00116 {
00117
00118
00119 kill( main_process, 9 ) ;
00120 perror( "fork error" ) ;
00121 exit( SERVER_EXIT_CHILD_SUBPROCESS_ABNORMAL_TERMINATION ) ;
00122 }
00123 else if( pid1 == 0 )
00124 {
00125 execute( c ) ;
00126 }
00127 sleep( 1 ) ;
00128 c->closeConnection() ;
00129 exit( SERVER_EXIT_CHILD_SUBPROCESS_NORMAL_TERMINATION ) ;
00130 }
00131 if( waitpid( pid, NULL, 0 ) != pid )
00132 {
00133 string error( "waitpid error" ) ;
00134 const char *error_info = strerror( errno ) ;
00135 if( error_info )
00136 error += " " + (string)error_info ;
00137 throw BESInternalError( error, __FILE__, __LINE__ ) ;
00138 }
00139 c->closeConnection() ;
00140 }
00141 }
00142
00143 void
00144 BESServerHandler::execute( Connection *c )
00145 {
00146 ostringstream strm ;
00147 string ip = c->getSocket()->getIp() ;
00148 strm << "ip " << ip << ", port " << c->getSocket()->getPort() ;
00149 string from = strm.str() ;
00150
00151 map<string,string> extensions ;
00152
00153 for(;;)
00154 {
00155 ostringstream ss ;
00156
00157 bool done = false ;
00158 while( !done )
00159 done = c->receive( extensions, &ss ) ;
00160
00161 if( extensions["status"] == c->exit() )
00162 {
00163 c->closeConnection() ;
00164 exit( CHILD_SUBPROCESS_READY ) ;
00165 }
00166
00167
00168
00169
00170
00171
00172 string cmd_str = ss.str() ;
00173 BESDEBUG( "server", "BESServerHandler::execute - command = "
00174 << cmd_str << endl ) ;
00175
00176 BESStopWatch *sw = 0 ;
00177 if( BESISDEBUG( "timing" ) )
00178 {
00179 sw = new BESStopWatch() ;
00180 sw->start() ;
00181 }
00182
00183 int descript = c->getSocket()->getSocketDescriptor() ;
00184
00185 unsigned int bufsize = c->getSendChunkSize() ;
00186 PPTStreamBuf fds( descript, bufsize ) ;
00187 std::streambuf *holder ;
00188 holder = cout.rdbuf() ;
00189 cout.rdbuf( &fds ) ;
00190
00191 BESXMLInterface cmd( cmd_str, &cout ) ;
00192 int status = cmd.execute_request( from ) ;
00193
00194 if( status == 0 )
00195 {
00196 BESDEBUG( "server", "BESServerHandler::execute - "
00197 << "executed successfully" << endl ) ;
00198 fds.finish() ;
00199 cout.rdbuf( holder ) ;
00200
00201 if( BESISDEBUG( "timing" ) )
00202 {
00203 if( sw && sw->stop() )
00204 {
00205 BESDEBUG( "timing",
00206 "BESServerHandler::execute - executed in "
00207 << sw->seconds() << " seconds and "
00208 << sw->microseconds() << " microseconds"
00209 << endl ) ;
00210 }
00211 else
00212 {
00213 BESDEBUG( "timing", "BESServerHandler::execute - "
00214 << "no timing available" << endl ) ;
00215 }
00216 }
00217 }
00218 else
00219 {
00220
00221 BESDEBUG( "server", "BESServerHandler::execute - "
00222 << "error occurred" << endl ) ;
00223
00224
00225 cout << flush ;
00226
00227
00228 map<string,string> extensions ;
00229 extensions["status"] = "error" ;
00230 c->sendExtensions( extensions ) ;
00231
00232
00233
00234 cmd.finish_with_error( status ) ;
00235
00236
00237 fds.finish() ;
00238
00239
00240 cout.rdbuf( holder ) ;
00241
00242 switch (status)
00243 {
00244 case BES_INTERNAL_FATAL_ERROR:
00245 {
00246 cout << "BES server " << getpid()
00247 << ": Status not OK, dispatcher returned value "
00248 << status << endl ;
00249
00250
00251 c->sendExit() ;
00252 c->closeConnection() ;
00253 exit( CHILD_SUBPROCESS_READY ) ;
00254 }
00255 break;
00256 case BES_INTERNAL_ERROR:
00257 case BES_SYNTAX_USER_ERROR:
00258 case BES_FORBIDDEN_ERROR:
00259 case BES_NOT_FOUND_ERROR:
00260 default:
00261 break;
00262 }
00263 }
00264
00265 if( sw ) delete sw;
00266 }
00267 }
00268
00275 void
00276 BESServerHandler::dump( ostream &strm ) const
00277 {
00278 strm << BESIndent::LMarg << "BESServerHandler::dump - ("
00279 << (void *)this << ")" << endl ;
00280 BESIndent::Indent() ;
00281 strm << BESIndent::LMarg << "server method: " << _method << endl ;
00282 BESIndent::UnIndent() ;
00283 }
00284