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 "BESCmdInterface.h"
00055 #include "TheBESKeys.h"
00056 #include "BESInternalError.h"
00057 #include "ServerExitConditions.h"
00058 #include "BESUtil.h"
00059 #include "PPTStreamBuf.h"
00060 #include "BESDebug.h"
00061
00062 BESServerHandler::BESServerHandler()
00063 {
00064 bool found = false ;
00065 _method = TheBESKeys::TheKeys()->get_key( "BES.ProcessManagerMethod", found ) ;
00066 if( _method != "multiple" && _method != "single" )
00067 {
00068 cerr << "Unable to determine method to handle clients, "
00069 << "single or multiple as defined by BES.ProcessManagerMethod"
00070 << endl ;
00071 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00072 }
00073 }
00074
00075
00076
00077
00078
00079 void
00080 BESServerHandler::handle( Connection *c )
00081 {
00082 if(_method=="single")
00083 {
00084 execute( c ) ;
00085 }
00086 else
00087 {
00088 int main_process = getpid() ;
00089 pid_t pid ;
00090 if( ( pid = fork() ) < 0 )
00091 {
00092 string error( "fork error" ) ;
00093 const char* error_info = strerror( errno ) ;
00094 if( error_info )
00095 error += " " + (string)error_info ;
00096 throw BESInternalError( error, __FILE__, __LINE__ ) ;
00097 }
00098 else if( pid == 0 )
00099 {
00100 pid_t pid1 ;
00101
00102 if( ( pid1 = fork() ) < 0 )
00103 {
00104
00105
00106 kill( main_process, 9 ) ;
00107 perror( "fork error" ) ;
00108 exit( SERVER_EXIT_CHILD_SUBPROCESS_ABNORMAL_TERMINATION ) ;
00109 }
00110 else if( pid1 == 0 )
00111 {
00112 execute( c ) ;
00113 }
00114 sleep( 1 ) ;
00115 c->closeConnection() ;
00116 exit( SERVER_EXIT_CHILD_SUBPROCESS_NORMAL_TERMINATION ) ;
00117 }
00118 if( waitpid( pid, NULL, 0 ) != pid )
00119 {
00120 string error( "waitpid error" ) ;
00121 const char *error_info = strerror( errno ) ;
00122 if( error_info )
00123 error += " " + (string)error_info ;
00124 throw BESInternalError( error, __FILE__, __LINE__ ) ;
00125 }
00126 c->closeConnection() ;
00127 }
00128 }
00129
00130 void
00131 BESServerHandler::execute( Connection *c )
00132 {
00133 ostringstream strm ;
00134 strm << "ip " << c->getSocket()->getIp() << ", port " << c->getSocket()->getPort() ;
00135 string from = strm.str() ;
00136
00137 map<string,string> extensions ;
00138
00139 for(;;)
00140 {
00141 ostringstream ss ;
00142
00143 bool done = false ;
00144 while( !done )
00145 done = c->receive( extensions, &ss ) ;
00146
00147 if( extensions["status"] == c->exit() )
00148 {
00149 c->closeConnection() ;
00150 exit( CHILD_SUBPROCESS_READY ) ;
00151 }
00152
00153 string cmd_str = BESUtil::www2id( ss.str(), "%", "%20" ) ;
00154 BESDEBUG( "server", "BESServerHandler::execute - command = " << cmd_str << endl )
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 PPTStreamBuf fds( c->getSocket()->getSocketDescriptor(), 4000 ) ;
00166 std::streambuf *holder ;
00167 holder = cout.rdbuf() ;
00168 cout.rdbuf( &fds ) ;
00169
00170 BESCmdInterface cmd( cmd_str, &cout ) ;
00171 int status = cmd.execute_request( from ) ;
00172
00173 if( status == 0 )
00174 {
00175 BESDEBUG( "server", "BESServerHandler::execute - executed successfully" << endl )
00176 fds.finish() ;
00177 cout.rdbuf( holder ) ;
00178 }
00179 else
00180 {
00181
00182 BESDEBUG( "server", "BESServerHandler::execute - error occurred" << endl )
00183
00184
00185 cout << flush ;
00186
00187
00188 map<string,string> extensions ;
00189 extensions["status"] = "error" ;
00190 c->sendExtensions( extensions ) ;
00191
00192
00193
00194 cmd.finish_with_error( status ) ;
00195
00196
00197 fds.finish() ;
00198
00199
00200 cout.rdbuf( holder ) ;
00201
00202 switch (status)
00203 {
00204 case BES_INTERNAL_FATAL_ERROR:
00205 {
00206 cout << "BES server " << getpid()
00207 << ": Status not OK, dispatcher returned value "
00208 << status << endl ;
00209
00210
00211 c->sendExit() ;
00212 c->closeConnection() ;
00213 exit( CHILD_SUBPROCESS_READY ) ;
00214 }
00215 break;
00216 case BES_INTERNAL_ERROR:
00217 case BES_SYNTAX_USER_ERROR:
00218 case BES_FORBIDDEN_ERROR:
00219 case BES_NOT_FOUND_ERROR:
00220 default:
00221 break;
00222 }
00223 }
00224 }
00225 }
00226
00233 void
00234 BESServerHandler::dump( ostream &strm ) const
00235 {
00236 strm << BESIndent::LMarg << "BESServerHandler::dump - ("
00237 << (void *)this << ")" << endl ;
00238 BESIndent::Indent() ;
00239 strm << BESIndent::LMarg << "server method: " << _method << endl ;
00240 BESIndent::UnIndent() ;
00241 }
00242