00001
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 #ifdef _MSC_VER
00032 #pragma warning(disable:4786)
00033 #endif
00034 #include "Ajp13Socket.h"
00035 #include "ajp13.h"
00036 #include "HttpRequest.h"
00037 #include "HttpResponse.h"
00038 #include "IFile.h"
00039 #include "Utility.h"
00040
00041 #ifdef SOCKETS_NAMESPACE
00042 namespace SOCKETS_NAMESPACE {
00043 #endif
00044
00045 #ifdef _DEBUG
00046 #define DEB(x) x
00047 #else
00048 #define DEB(x)
00049 #endif
00050
00051
00052
00053 Ajp13Socket::Ajp13Socket(ISocketHandler& h) : AjpBaseSocket(h)
00054 , m_body_size_left(0)
00055 {
00056 }
00057
00058
00059
00060 void Ajp13Socket::OnHeader( short id, short len )
00061 {
00062 if (id != 0x1234)
00063 {
00064 fprintf(stderr, "ABORT: bad packet id: %x\n", id);
00065 SetCloseAndDelete();
00066 }
00067 else
00068 {
00069 DEB(fprintf(stderr, "Packet size: %d bytes\n", len);)
00070 }
00071 }
00072
00073
00074
00075 void Ajp13Socket::ReceiveBody(const char *buf, size_t sz)
00076 {
00077 if (sz - 2 > m_body_size_left)
00078 {
00079 fprintf(stderr, "More body data received than expected\n");
00080 SetCloseAndDelete();
00081 return;
00082 }
00083
00084 m_req.Write( buf + 2, sz - 2 );
00085 m_body_size_left -= sz - 2;
00086
00087
00088 if (m_body_size_left)
00089 {
00090 int ptr = 4;
00091 char msg[100];
00092 msg[0] = 'A';
00093 msg[1] = 'B';
00094
00095
00096
00097
00098
00099
00100
00101
00102 put_byte(msg, ptr, 0x06);
00103 put_integer(msg, ptr, 1000);
00104
00105 short len = htons( ptr - 4 );
00106 memcpy( msg + 2, &len, 2 );
00107
00108 SendBuf( msg, ptr );
00109 return;
00110 }
00111
00112
00113 m_req.CloseBody();
00114
00115
00116 Execute();
00117
00118 }
00119
00120
00121
00122 void Ajp13Socket::ReceiveForwardRequest( const char *buf, size_t sz )
00123 {
00124
00125 int ptr = 0;
00126
00127 get_byte(buf, ptr);
00128 unsigned char method = get_byte(buf, ptr);
00129 std::string protocol = get_string(buf, ptr);
00130 std::string req_uri = get_string(buf, ptr);
00131 std::string remote_addr = get_string(buf, ptr);
00132 std::string remote_host = get_string(buf, ptr);
00133 std::string server_name = get_string(buf, ptr);
00134 short server_port = get_integer(buf, ptr);
00135 bool is_ssl = get_boolean(buf, ptr);
00136
00137 std::string method_str = Utility::l2string( method );
00138 std::map<int, std::string>::const_iterator it = Init.Method.find( method );
00139 if (it != Init.Method.end())
00140 {
00141 method_str = it -> second;
00142 }
00143 m_req.SetHttpMethod( method_str );
00144 m_req.SetHttpVersion( protocol );
00145 m_req.SetUri( req_uri );
00146 m_req.SetRemoteAddr( remote_addr );
00147 m_req.SetRemoteHost( remote_host );
00148 m_req.SetServerName( server_name );
00149 m_req.SetServerPort( server_port );
00150 m_req.SetIsSsl( is_ssl );
00151
00152
00153 short num_headers = get_integer(buf, ptr);
00154 for (int i = 0; i < num_headers; i++)
00155 {
00156 std::string key;
00157 switch ( (unsigned char)buf[ptr])
00158 {
00159 case 0xa0:
00160 {
00161 unsigned short x = (unsigned short)get_integer(buf, ptr);
00162 std::map<int, std::string>::const_iterator it;
00163 if ( (it = Init.Header.find(x)) != Init.Header.end())
00164 {
00165 key = it -> second;
00166 }
00167 else
00168 {
00169 fprintf(stderr, "Unknown header key value: %x\n", x);
00170 SetCloseAndDelete();
00171 }
00172 }
00173 break;
00174
00175 default:
00176 key = get_string(buf, ptr);
00177 }
00178 if (Utility::ToLower(key) == "cookie" || Utility::ToLower(key) == "cookie2")
00179 m_req.AddCookie(get_string(buf, ptr));
00180 else
00181 m_req.SetHeader(key, get_string(buf, ptr));
00182 }
00183
00184
00185 m_body_size_left = m_req.ContentLength();
00186
00187
00188 while ( (unsigned char)buf[ptr] != 0xff)
00189 {
00190 std::string key;
00191 unsigned char code = buf[ptr++];
00192 switch ( code)
00193 {
00194 case 10:
00195 key = get_string(buf, ptr);
00196 break;
00197 default:
00198 {
00199 std::map<int, std::string>::const_iterator it = Init.Attribute.find( code );
00200 if (it != Init.Attribute.end())
00201 {
00202 key = it -> second;
00203 }
00204 else
00205 {
00206 fprintf(stderr, "Unknown attribute key: 0x%02x\n", buf[ptr]);
00207 SetCloseAndDelete();
00208 }
00209 }
00210 }
00211 m_req.SetAttribute(key, get_string(buf, ptr));
00212 }
00213
00214
00215 if (!m_body_size_left)
00216 {
00217 Execute();
00218 }
00219 else
00220 {
00221
00222 m_req.InitBody( m_body_size_left );
00223 }
00224 }
00225
00226
00227
00228 void Ajp13Socket::ReceiveShutdown( const char *buf, size_t sz )
00229 {
00230 }
00231
00232
00233
00234 void Ajp13Socket::ReceivePing( const char *buf, size_t sz )
00235 {
00236 }
00237
00238
00239
00240 void Ajp13Socket::ReceiveCPing( const char *buf, size_t sz )
00241 {
00242 }
00243
00244
00245
00246 void Ajp13Socket::Execute()
00247 {
00248
00249 m_req.ParseBody();
00250
00251
00252 OnExec( m_req );
00253
00254 }
00255
00256
00257
00258 void Ajp13Socket::Respond(const HttpResponse& res)
00259 {
00260 char msg[8192];
00261 msg[0] = 'A';
00262 msg[1] = 'B';
00263
00264 m_res = res;
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 if (!m_res.ContentLength() && m_res.GetFile().size())
00275 {
00276
00277 }
00278
00279
00280 {
00281 int ptr = 4;
00282 put_byte(msg, ptr, 0x04);
00283 put_integer(msg, ptr, m_res.HttpStatusCode() );
00284 put_string(msg, ptr, m_res.HttpStatusMsg() );
00285 put_integer(msg, ptr, (short)m_res.Headers().size() );
00286 for (Utility::ncmap<std::string>::const_iterator it = m_res.Headers().begin(); it != m_res.Headers().end(); ++it)
00287 {
00288 Utility::ncmap<int>::const_iterator it2 = Init.ResponseHeader.find( it -> first );
00289 if (it2 != Init.ResponseHeader.end())
00290 {
00291 put_integer(msg, ptr, it2 -> second);
00292 }
00293 else
00294 {
00295 put_string(msg, ptr, it -> first);
00296 }
00297 put_string(msg, ptr, it -> second);
00298 }
00299 std::list<std::string> vec = m_res.CookieNames();
00300 {
00301 for (std::list<std::string>::iterator it = vec.begin(); it != vec.end(); it++)
00302 {
00303 Utility::ncmap<int>::const_iterator it2 = Init.ResponseHeader.find( "set-cookie" );
00304 if (it2 != Init.ResponseHeader.end())
00305 {
00306 put_integer(msg, ptr, it2 -> second);
00307 }
00308 else
00309 {
00310 put_string(msg, ptr, "set-cookie");
00311 }
00312 put_string(msg, ptr, m_res.Cookie(*it) );
00313 }
00314 }
00315
00316 short len = htons( ptr - 4 );
00317 memcpy( msg + 2, &len, 2 );
00318
00319 SendBuf( msg, ptr );
00320 }
00321
00322 OnTransferLimit();
00323 }
00324
00325
00326
00327 void Ajp13Socket::OnTransferLimit()
00328 {
00329 char msg[8192];
00330 msg[0] = 'A';
00331 msg[1] = 'B';
00332
00333
00334 size_t n = m_res.GetFile().fread(msg + 7, 1, 8100);
00335 while (n > 0)
00336 {
00337 int ptr = 4;
00338 put_byte(msg, ptr, 0x03);
00339 put_integer(msg, ptr, (short)n);
00340 ptr += (int)n;
00341
00342 short len = htons( ptr - 4 );
00343 memcpy( msg + 2, &len, 2 );
00344
00345 SendBuf( msg, ptr );
00346 if (GetOutputLength() > 1)
00347 {
00348 SetTransferLimit( 1 );
00349 break;
00350 }
00351
00352
00353 n = m_res.GetFile().fread(msg + 7, 1, 8100);
00354 }
00355 if (!GetOutputLength())
00356 {
00357
00358 int ptr = 4;
00359 put_byte(msg, ptr, 0x05);
00360 put_boolean(msg, ptr, false);
00361
00362
00363
00364
00365
00366
00367 short len = htons( ptr - 4 );
00368 memcpy( msg + 2, &len, 2 );
00369
00370 SendBuf( msg, ptr );
00371
00372 m_res.GetFile().fclose();
00373 OnResponseComplete();
00374 }
00375 }
00376
00377
00378
00379 void Ajp13Socket::OnPacket( const char *buf, size_t sz )
00380 {
00381 DEB(fprintf(stderr, "OnPacket: %d bytes, code 0x%02x %02x %02x %02x\n", sz, *buf, buf[1], buf[2], buf[3]);)
00382
00383
00384 if (m_body_size_left)
00385 {
00386 ReceiveBody(buf, sz);
00387 return;
00388 }
00389 switch (*buf)
00390 {
00391 case 0x2:
00392 ReceiveForwardRequest(buf, sz);
00393 break;
00394 case 0x7:
00395 ReceiveShutdown(buf, sz);
00396 break;
00397 case 0x8:
00398 ReceivePing(buf, sz);
00399 break;
00400 case 0xa:
00401 ReceiveCPing(buf, sz);
00402 break;
00403 default:
00404 fprintf(stderr, "Unknown packet type: 0x%02x\n", *buf);
00405 SetCloseAndDelete();
00406 }
00407
00408 }
00409
00410
00411 #ifdef SOCKETS_NAMESPACE
00412 }
00413 #endif
00414
00415