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
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 #ifndef __NO_SOCKETS__
00205
00206 #include <stdio.h>
00207 #include <string.h>
00208 #ifdef WIN32
00209 #include <winsock2.h>
00210 #include <winbase.h>
00211 #define SLEEPER 1000
00212 #else
00213 #include <sys/time.h>
00214 #include <sys/types.h>
00215 #include <sys/socket.h>
00216 #include <netinet/in.h>
00217 #include <netdb.h>
00218 #include <unistd.h>
00219 #include <signal.h>
00220 #include <sys/wait.h>
00221 #define Sleep sleep
00222 #define SLEEPER 1
00223 #endif
00224
00225 #include "thread.h"
00226 #include "filesys.h"
00227 #include "httpd.h"
00228 #include "getopt.h"
00229
00230 #define MAXBINDTRIAL 1200
00231 #define BINDSLEEP 1
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 #ifdef WIN32
00325
00326 void InitSignalHandlers(){}
00327 #else
00328 void SEGV_handle(int i) {
00329 char fname[2000];
00330 int pid;
00331 pid=getpid();
00332 fclose(fopen(fname,"w+"));
00333 sleep(1000000);
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 void InitSignalHandlers(
00348 ){
00349
00350
00351 signal(SIGPIPE,SIG_IGN);
00352 signal(SIGSEGV,SEGV_handle);
00353
00354 }
00355
00356 #endif
00357
00358 static struct _StateCode {
00359 int Code;
00360 char *StateMessage;
00361 }StateMessages[]={
00362 200, "OK",
00363 201, "CREATED",
00364 202, "Accepted",
00365 203, "Partial Information",
00366 204, "No Response",
00367 301, "Found, but moved",
00368 302, "Found, but data resides under different URL (add a /)",
00369 303, "Method",
00370 304, "Not Modified",
00371 400, "Bad request",
00372 401, "Unauthorized",
00373 402, "PaymentRequired",
00374 403, "Forbidden",
00375 404, "Not found",
00376 500, "Internal Error",
00377 501, "Not implemented",
00378 502, "Service temporarily overloaded",
00379 503, "Gateway timeout ",
00380 600, "Bad request",
00381 601, "Not implemented",
00382 602, "Connection failed",
00383 603, "Timed out",
00384 000, NULL
00385 };
00386
00387 static int unhex(int t){
00388 if( t >= 'A' && t <= 'F' )return t-'A'+10;
00389 if( t >= 'a' && t <= 'f' )return t-'a'+10;
00390 return t-'0';
00391 }
00392
00393 static int strIcmp(char *a, char *b){
00394 int ca,cb;
00395
00396 while( (ca=*a) && (cb=*b) ){
00397 if( isupper(ca) )ca = tolower(ca);
00398 if( isupper(cb) )cb = tolower(cb);
00399 if( ca != cb )return ca-cb;
00400 a++,b++;
00401 }
00402 return 0;
00403 }
00404
00405 static char *_GetServerVariable(pThreadData ThisThread,
00406 char *VariableName){
00407 int i;
00408
00409 for( i = 0 ; i < ThisThread->iHeaderLines ; i++ ){
00410 if( ! strIcmp(ThisThread->HeaderKey[i],VariableName) )return ThisThread->HeaderString[i];
00411 }
00412 return NULL;
00413 }
00414
00415 static void _CloseClient(pThreadData ThisThread){
00416 if( ThisThread->SocketOpened ){
00417 closesocket(ThisThread->msgsock);
00418 ThisThread->SocketOpened = 0;
00419 }
00420 }
00421
00422 static int _WriteClient(pThreadData ThisThread,
00423 char *pszBuffer,
00424 int cbBuffer){
00425 int i;
00426 fd_set writefds;
00427 struct timeval timeout;
00428
00429 FD_ZERO(&writefds);
00430 FD_SET(ThisThread->msgsock,&writefds);
00431 timeout.tv_sec=60;
00432 timeout.tv_usec=0;
00433 i = select(FD_SETSIZE,NULL,&writefds,NULL,&timeout);
00434 if( i == 0 )return 1;
00435 return cbBuffer != send(ThisThread->msgsock,pszBuffer,cbBuffer,0);
00436 }
00437
00438 static int _WriteClientText(pThreadData ThisThread,
00439 char *pszBuffer){
00440 int i;
00441 fd_set writefds;
00442 struct timeval timeout;
00443
00444 FD_ZERO(&writefds);
00445 FD_SET(ThisThread->msgsock,&writefds);
00446 timeout.tv_sec=60;
00447 timeout.tv_usec=0;
00448 i = select(FD_SETSIZE,NULL,&writefds,NULL,&timeout);
00449 if( i == 0 )return 1;
00450
00451 if( pszBuffer == NULL )
00452 return 4 != send(ThisThread->msgsock,"null",4,0);
00453
00454 i = strlen(pszBuffer);
00455 return i != send(ThisThread->msgsock,pszBuffer,i,0);
00456 }
00457
00458 static int _State(pThreadData ThisThread,
00459 int StateCode){
00460 int i;
00461 char buffer[80];
00462
00463 for( i = 0 ; StateMessages[i].StateMessage &&
00464 StateMessages[i].Code <= StateCode ; i++ ){
00465 if( StateMessages[i].Code == StateCode ){
00466 sprintf(buffer,"HTTP/1.0 %d %s\n",StateCode,StateMessages[i].StateMessage);
00467 return _WriteClientText(ThisThread,buffer);
00468 }
00469 }
00470 sprintf(buffer,"HTTP/1.0 %d\n",StateCode);
00471 return _WriteClientText(ThisThread,buffer);
00472 }
00473
00474 static int _ContentType(pThreadData ThisThread,
00475 char *pszContentType){
00476 _WriteClient(ThisThread,"Content-Type: ",14);
00477 _WriteClientText(ThisThread,pszContentType);
00478 return _WriteClient(ThisThread,"\n",1);
00479 }
00480
00481 static int _Header(pThreadData ThisThread,
00482 char *pszHeaderKey,
00483 char *pszHeaderValue){
00484 _WriteClientText(ThisThread,pszHeaderKey);
00485 _WriteClient(ThisThread,": ",2);
00486 _WriteClientText(ThisThread,pszHeaderValue);
00487 return _WriteClient(ThisThread,"\n",1);
00488 }
00489
00490 static int _StartBody(pThreadData ThisThread){
00491 return _WriteClient(ThisThread,"\n",1);
00492 }
00493
00494 static int _ReadClient(pThreadData ThisThread,
00495 char *pszBuffer,
00496 int cbBuffer){
00497 int i;
00498 fd_set readfds;
00499 struct timeval timeout;
00500
00501 FD_ZERO(&readfds);
00502 FD_SET(ThisThread->msgsock,&readfds);
00503 timeout.tv_sec=60;
00504 timeout.tv_usec=0;
00505 i = select(FD_SETSIZE,&readfds,NULL,NULL,&timeout);
00506 if( i == 0 )return 0;
00507
00508 return recv(ThisThread->msgsock,pszBuffer,cbBuffer,0);
00509 }
00510
00511 static char *_ScriptName(pThreadData ThisThread){
00512 int i,j;
00513
00514 if( ! ThisThread->script[0] ){
00515 for( i = 0 ; ThisThread->pszQueryString[i] ; i++ )
00516 if( ThisThread->pszQueryString[i] == '?' )break;
00517 while( i && ThisThread->pszQueryString[i] != '/' )i--;
00518 if( ThisThread->pszQueryString[i] == '/' )i++;
00519 for( j = 0 ; ThisThread->pszQueryString[i] &&
00520 ThisThread->pszQueryString[i] != '?' ; i++, j++ ){
00521 ThisThread->script[j] = ThisThread->pszQueryString[i];
00522 if( j >= MAX_QUERY_LENGTH ){
00523 ThisThread->script[0] = (char)0;
00524 return NULL;
00525 }
00526 }
00527 ThisThread->script[j] = (char)0;
00528 }
00529 return ThisThread->script;
00530 }
00531
00532 static char *_GetParam(pThreadData ThisThread,
00533 char *key){
00534 char *s;
00535 int i,j;
00536
00537 if( ! ThisThread->getparams[0] ){
00538
00539 s = ThisThread->pszQueryString;
00540 while( *s && *s != '?' )s++;
00541 if( ! *s )return NULL;
00542 s++;
00543
00544 ThisThread->getparlen = strlen(s);
00545 if( ThisThread->getparlen >= MAX_QUERY_LENGTH )return NULL;
00546 strcpy(ThisThread->getparams,s);
00547 s = ThisThread->getparams;
00548 for( i=j=0 ; ; i++ ){
00549 s[i] = s[j];
00550 if( ! s[j] )break;
00551 if( s[j] == '%' && s[j+1] && s[j+2] ){
00552 s[i] = unhex(s[j+1])*16+unhex(s[j+2]);
00553 j += 3;
00554 }else j++;
00555 }
00556 ThisThread->getparlen = i;
00557 s = ThisThread->getparams;
00558 while( *s ){
00559 if( *s == '&' )*s = (char)0;
00560 s++;
00561 }
00562 }
00563
00564 s = ThisThread->getparams;
00565 for( i = 0 ; i < ThisThread->getparlen ; i++ ){
00566 for( j = 0 ; key[j] && s[i] && s[i] != '=' ; j++, i++ ){
00567 if( s[i] != key[j] ){
00568 while( s[i] )i++;
00569 break;
00570 }
00571 }
00572 if( s[i] )return s+i+1;
00573 }
00574 return NULL;
00575 }
00576
00577 static char *_PostParam(pThreadData ThisThread,
00578 char *key){
00579 return NULL;
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 int httpd(int argc,
00599 char *argv[],
00600 int (*AppInit)(int argc,char *argv[],pHttpdThread pHT,void **AppData),
00601 int (*AppStart)(void **AppData),
00602 void (*HttpProc)(pHttpdThread pHT,pThreadData ThisThread),
00603 int (*FtpProc)(pHttpdThread pHT,pThreadData ThisThread, char *pszCommand)
00604 ){
00605
00606
00607 int addr_size;
00608 int i,j,so;
00609 int length;
00610 struct _fun Functions;
00611 struct sockaddr_in server;
00612 pThreadData ThisThread;
00613 HttpdThread HT;
00614 int iState;
00615 int cThread;
00616 unsigned long iL;
00617 #ifdef WIN32
00618 WORD wVersionRequested;
00619 WSADATA wsaData;
00620 int err;
00621 #else
00622 int cpid;
00623 #endif
00624 char *optarg,opt;
00625 int OptionIndex;
00626 fd_set acceptfds;
00627 struct timeval timeout;
00628
00629
00630 #ifdef WIN32
00631 wVersionRequested = MAKEWORD( 2, 2 );
00632 err = WSAStartup( wVersionRequested, &wsaData );
00633 if( err != 0 ){
00634 fprintf(stderr,"Error initializing the Windows Socket subsystem\n");
00635 exit(1);
00636 }
00637 #endif
00638 HT.server[0].port = HTTPD_PORT;
00639 HT.server[0].ip = HTTPD_IP;
00640 HT.c_servers = 1;
00641 HT.threadmax = CONCURRENT_HITS;
00642 HT.listenmax = LISTEN_BACKLOG;
00643 HT.server[0].cAllowed = 0;
00644 HT.server[0].cDenied = 0;
00645
00646
00647 InitSignalHandlers();
00648
00649
00650 HT.AppData = NULL;
00651
00652 if( i=AppInit(argc,argv,&HT,&(HT.AppData)) ){
00653 fprintf(stderr,"AppInit returned %d\n",i);
00654 exit(i);
00655 }
00656
00657 OptionIndex = 0;
00658 while( (opt = getoptt(argc, argv, "p:h:",&optarg,&OptionIndex)) != ':'){
00659 switch( opt ){
00660 case 'p' :
00661
00662 HT.server[0].port = atoi(optarg);
00663 HT.c_servers = 1;
00664 break;
00665 case 'h' :
00666
00667 HT.server[0].ip = inet_addr(optarg);
00668 HT.c_servers = 1;
00669 break;
00670 }
00671 }
00672
00673 for( i=0 ; i < HT.c_servers ; i++ ){
00674 HT.server[i].sock = socket(AF_INET, SOCK_STREAM, 0);
00675 so=1;
00676 setsockopt(HT.server[i].sock, SOL_SOCKET, SO_REUSEADDR, (char *)(&so),sizeof(i));
00677 if( HT.server[i].sock < 0 ){
00678 fprintf(stderr, "Error at socket");
00679 exit(1);
00680 }
00681 server.sin_family = AF_INET;
00682 server.sin_addr.s_addr = HT.server[i].ip;
00683 server.sin_port = htons(HT.server[i].port);
00684
00685 for( j=0 ; j<MAXBINDTRIAL ; j++ ){
00686 if( ! bind(HT.server[i].sock, (struct sockaddr *)&server, sizeof(server)) )break;
00687 if( j == MAXBINDTRIAL-1 ){
00688 fprintf(stderr, "\nError at bind.");
00689 exit(1);
00690 }
00691 if( j== 0 )fprintf(stderr,"Bind failed on %s:%d, retrying at most %d times\n.",
00692 inet_ntoa(server.sin_addr), ntohs(server.sin_port),MAXBINDTRIAL);
00693 else fprintf(stderr,".");
00694 if( j%40 == 39 )fprintf(stderr,"\n");
00695 Sleep(BINDSLEEP);
00696 }
00697 if( j )fprintf(stderr,"\nBind finally successful after %d trials\n",j);
00698
00699 length = sizeof(server);
00700 if( getsockname(HT.server[i].sock, (struct sockaddr *)&server, &length) ){
00701 fprintf(stderr, "Error at getsockname.");
00702 exit(1);
00703 }
00704
00705 listen(HT.server[i].sock, HT.listenmax);
00706 }
00707 HT.iState = STATE_NORMAL;
00708
00709 if( j=AppStart(&(HT.AppData)) ){
00710 fprintf(stderr,"Appstart returned %d\n",j);
00711 exit(j);
00712 }
00713
00714 HT.threads = (pThreadData)malloc(HT.threadmax*sizeof(ThreadData));
00715 if( HT.threads == NULL ){
00716 fprintf(stderr,"Not enough memory\n");
00717 exit(1);
00718 }
00719
00720
00721
00722 for( i=0 ; i < HT.threadmax ; i++ ){
00723 HT.threads[i].ThreadIndex = i;
00724 HT.threads[i].pFunctions = &Functions;
00725 HT.threads[i].NextFree = i+1;
00726 HT.threads[i].pHT = &HT;
00727 }
00728 HT.cThread = 0;
00729
00730 HT.threads[HT.threadmax-1].NextFree = -1;
00731 HT.FirstFreeThread = 0;
00732 thread_InitMutex(&(HT.mxFirstFreeThread));
00733 Functions.pGetServerVariable = _GetServerVariable;
00734 Functions.pWriteClient = _WriteClient;
00735 Functions.pWriteClientText = _WriteClientText;
00736 Functions.pReadClient = _ReadClient;
00737 Functions.pState = _State;
00738 Functions.pContentType = _ContentType;
00739 Functions.pHeader = _Header;
00740 Functions.pStartBody = _StartBody;
00741 Functions.pGetParam = _GetParam;
00742 Functions.pPostParam = _PostParam;
00743 Functions.pCloseClient = _CloseClient;
00744 Functions.pScriptName = _ScriptName;
00745 Functions.HttpProc = HttpProc;
00746 Functions.FtpProc = FtpProc;
00747 while(1){
00748 ThisThread = GetFreeThread(&HT);
00749
00750 FD_ZERO(&acceptfds);
00751 for( i=0 ; i < HT.c_servers ; i++ )
00752 FD_SET(HT.server[i].sock,&acceptfds);
00753 timeout.tv_sec=60;
00754 timeout.tv_usec=0;
00755 i = select(FD_SETSIZE,&acceptfds,NULL,NULL,&timeout);
00756 for( i=0 ; i < HT.c_servers ; i++ ){
00757 if( FD_ISSET(HT.server[i].sock,&acceptfds) ){
00758 do{
00759 addr_size=sizeof(struct sockaddr);
00760 ThisThread->msgsock = accept(HT.server[i].sock,
00761 (struct sockaddr *)&(ThisThread->addr),
00762 &addr_size);
00763 }while(
00764 #ifdef WIN32
00765 ThisThread->msgsock == INVALID_SOCKET
00766 #else
00767 ThisThread->msgsock <= 0
00768 #endif
00769 );
00770 thread_LockMutex(&(HT.mxState));
00771 iState = HT.iState;
00772 thread_UnlockMutex(&(HT.mxState));
00773 if( iState == STATE_SHUT ){
00774
00775 for( iL = 0 ; iL < HT.lWaitCount ; iL++ ){
00776 thread_LockMutex(&(HT.mxFirstFreeThread));
00777 cThread = HT.cThread;
00778 thread_UnlockMutex(&(HT.mxFirstFreeThread));
00779 if( cThread == 1 )break;
00780 Sleep(HT.lWaitSec*SLEEPER);
00781 }
00782 return 0;
00783 }
00784 ThisThread->SocketOpened = 1;
00785 ThisThread->server_index = i;
00786 thread_CreateThread(&(ThisThread->T),HitHandler,ThisThread);
00787 }
00788 }
00789 }
00790
00791 return 0;
00792 }
00793
00794
00795 pThreadData GetFreeThread(pHttpdThread pHT
00796 ){
00797 pThreadData t;
00798
00799 thread_LockMutex(&(pHT->mxFirstFreeThread));
00800
00801 while( pHT->FirstFreeThread == -1 ){
00802 thread_UnlockMutex(&(pHT->mxFirstFreeThread));
00803 Sleep(1*SLEEPER);
00804 thread_LockMutex(&(pHT->mxFirstFreeThread));
00805 }
00806 t = pHT->threads+pHT->FirstFreeThread;
00807 pHT->FirstFreeThread = pHT->threads[pHT->FirstFreeThread].NextFree;
00808 pHT->cThread++;
00809 thread_UnlockMutex(&(pHT->mxFirstFreeThread));
00810
00811 return t;
00812 }
00813
00814
00815 void ReleaseThreadData(pHttpdThread pHT,
00816 int index
00817 ){
00818 thread_LockMutex(&(pHT->mxFirstFreeThread));
00819 pHT->threads[index].NextFree = pHT->FirstFreeThread;
00820 pHT->FirstFreeThread = index;
00821 pHT->cThread--;
00822 thread_UnlockMutex(&(pHT->mxFirstFreeThread));
00823 }
00824
00825 #define MSPACE(x) while( *x && isspace(*x)) x++
00826 #define SSPACE(x) if( *x && isspace(*x)) x++
00827
00828
00829 int CheckAllowDeny(pThreadData ThisThread
00830 ){
00831 int fAllowed;
00832 pHttpdThread pHT;
00833 unsigned long h;
00834 unsigned long lClientIP;
00835 pServerData ThisServer;
00836
00837 pHT = ThisThread->pHT;
00838
00839
00840
00841 fAllowed = 1;
00842
00843
00844 ThisServer = pHT->server + ThisThread->server_index;
00845
00846 if( ThisServer->cAllowed || ThisServer->cDenied ){
00847
00848 lClientIP = ThisThread->ClientIP[3] + 256*(
00849 ThisThread->ClientIP[2] + 256*(
00850 ThisThread->ClientIP[1] + 256*(
00851 ThisThread->ClientIP[0] )));
00852 if( ThisServer->cAllowed ){
00853 fAllowed = 0;
00854 for( h=0 ; h < ThisServer->cAllowed ; h++ ){
00855 if( (lClientIP&ThisServer->plAllowedMask[h]) ==
00856 (ThisServer->plAllowedIP[h]&ThisServer->plAllowedMask[h]) ){
00857 fAllowed = 1;
00858 break;
00859 }
00860 }
00861 }
00862 if( fAllowed && ThisServer->cDenied ){
00863 for( h=0 ; h < ThisServer->cDenied ; h++ ){
00864 if( (lClientIP&ThisServer->plDeniedMask[h]) ==
00865 (ThisServer->plDeniedIP[h]&ThisServer->plDeniedMask[h]) ){
00866 fAllowed = 0;
00867 break;
00868 }
00869 }
00870 }
00871 }
00872 return fAllowed;
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886 void FinishConnection(pThreadData ThisThread
00887 ){
00888
00889
00890 if( ThisThread->SocketOpened ){
00891 closesocket(ThisThread->msgsock);
00892 ThisThread->SocketOpened = 0;
00893 }
00894 ReleaseThreadData(ThisThread->pHT,ThisThread->ThreadIndex);
00895 thread_ExitThread();
00896 }
00897
00898
00899
00900 void HitHandler(void *t
00901 ){
00902 pThreadData ThisThread;
00903 pServerData ThisServer;
00904 pHttpdThread pHT;
00905
00906 ThisThread = (pThreadData)t;
00907 pHT = ThisThread->pHT;
00908
00909 ThisThread->AppThreadData = NULL;
00910
00911 #ifdef WIN32
00912 ThisThread->ClientIP[0] = ThisThread->addr.sin_addr.S_un.S_un_b.s_b1;
00913 ThisThread->ClientIP[1] = ThisThread->addr.sin_addr.S_un.S_un_b.s_b2;
00914 ThisThread->ClientIP[2] = ThisThread->addr.sin_addr.S_un.S_un_b.s_b3;
00915 ThisThread->ClientIP[3] = ThisThread->addr.sin_addr.S_un.S_un_b.s_b4;
00916 #else
00917 memcpy(ThisThread->ClientIP,&(ThisThread->addr.sin_addr.s_addr),4);
00918 #endif
00919
00920 if( ! CheckAllowDeny(ThisThread) )FinishConnection(ThisThread);
00921
00922
00923 ThisServer = pHT->server + ThisThread->server_index;
00924 switch( ThisServer->type ){
00925 case SERVER_HTTP:
00926 HandleHttpHit(ThisThread);
00927 case SERVER_FTP:
00928 HandleFtpHit(ThisThread);
00929 }
00930 FinishConnection(ThisThread);
00931 }
00932
00933
00934 void HandleFtpHit(pThreadData ThisThread
00935 ){
00936 pServerData ThisServer;
00937 fd_set readfds;
00938 struct timeval timeout;
00939 pHttpdThread pHT;
00940 char *Buffer;
00941 int cbBuffer,cbCharsRead,i;
00942
00943 Buffer = ThisThread->buffer;
00944 cbBuffer = HIT_MAX_SIZE;
00945
00946
00947 pHT = ThisThread->pHT;
00948 ThisServer = pHT->server + ThisThread->server_index;
00949
00950 send(ThisThread->msgsock,ThisServer->salute,strlen(ThisServer->salute),0);
00951 send(ThisThread->msgsock,"\r\n",2,0);
00952
00953 while(1){
00954 FD_ZERO(&readfds);
00955 FD_SET(ThisThread->msgsock,&readfds);
00956 timeout.tv_sec=60;
00957 timeout.tv_usec=0;
00958 i = select(FD_SETSIZE,&readfds,NULL,NULL,&timeout);
00959 if( i == 0 )FinishConnection(ThisThread);
00960 cbCharsRead = recv(ThisThread->msgsock,Buffer,cbBuffer,0);
00961
00962 if( cbCharsRead == 0 )FinishConnection(ThisThread);
00963 if( cbCharsRead < 0 )FinishConnection(ThisThread);
00964 Buffer[cbCharsRead] = (char)0;
00965
00966
00967 if( ThisThread->pFunctions->FtpProc(ThisThread->pHT,ThisThread,Buffer) )FinishConnection(ThisThread);
00968 }
00969 }
00970
00971
00972 void HandleHttpHit(pThreadData ThisThread
00973 ){
00974 pServerData ThisServer;
00975 int j,i,cbBuffer,cbCharsRead,cbCharsReadTotal;
00976 char *Buffer;
00977 char *s;
00978 void MyHttpExtensionProc(pThreadData);
00979 fd_set readfds;
00980 struct timeval timeout;
00981 pHttpdThread pHT;
00982
00983 Buffer = ThisThread->buffer;
00984 cbBuffer = HIT_MAX_SIZE;
00985
00986
00987 pHT = ThisThread->pHT;
00988 ThisServer = pHT->server + ThisThread->server_index;
00989
00990 cbCharsReadTotal = 0;
00991 while(1){
00992 FD_ZERO(&readfds);
00993 FD_SET(ThisThread->msgsock,&readfds);
00994 timeout.tv_sec=60;
00995 timeout.tv_usec=0;
00996 i = select(FD_SETSIZE,&readfds,NULL,NULL,&timeout);
00997 if( i == 0 )FinishConnection(ThisThread);
00998 cbCharsRead = recv(ThisThread->msgsock,Buffer,cbBuffer,0);
00999
01000 if( cbCharsRead == 0 )FinishConnection(ThisThread);
01001 if( cbCharsRead < 0 )FinishConnection(ThisThread);
01002
01003
01004
01005
01006 if( cbCharsReadTotal < 3 )j = 4 - cbCharsReadTotal; else j = 1;
01007
01008 cbCharsReadTotal += cbCharsRead;
01009
01010
01011 for( ; j <= cbCharsRead ; j++ ){
01012 if( Buffer[j-1] == '\n' && Buffer[j-2] == '\r' &&
01013 Buffer[j-3] == '\n' && Buffer[j-4] == '\r' ){
01014 Buffer[j-4] = (char)0;
01015 ThisThread->pszData = Buffer+j;
01016 ThisThread->cbAvailable = cbCharsRead - j;
01017 goto HEADER_IS_READ;
01018 }
01019 }
01020 cbBuffer -= i;
01021 Buffer += i;
01022 if( cbBuffer <= 0 )FinishConnection(ThisThread);
01023 }
01024 HEADER_IS_READ:;
01025
01026
01027 s = ThisThread->pszMethod = ThisThread->buffer;
01028 while( *s && ! isspace(*s) )s++;
01029 if( *s )
01030 *s++ = (char)0;
01031 else FinishConnection(ThisThread);
01032
01033 ThisThread->pszQueryString = s;
01034 while( *s && ! isspace(*s) )s++;
01035 if( *s )
01036 *s++ = (char)0;
01037 else FinishConnection(ThisThread);
01038
01039
01040 while( *s && *s != '\n' )s++;
01041
01042 while( *s == '\n' || *s == '\r' )s++;
01043
01044 ThisThread->iHeaderLines = 0;
01045
01046 while( *s ){
01047
01048 ThisThread->HeaderKey[ThisThread->iHeaderLines] = s;
01049 while( *s && ! isspace(*s) && *s != ':' )s++;
01050 if( *s )*s++ = (char)0;
01051 while( isspace(*s) )s++;
01052 if( *s ){
01053 ThisThread->HeaderString[ThisThread->iHeaderLines] = s;
01054 while( *s && *s != '\n' && *s != '\r' )s++;
01055 if( *s )*s++ = (char)0;
01056 while( *s == '\n' || *s == '\r' )s++;
01057 ThisThread->iHeaderLines++;
01058 }
01059 }
01060
01061 ThisThread->getparams[0] = (char)0;
01062 ThisThread->script[0] = (char)0;
01063 ThisThread->pThreadLocalData = NULL;
01064
01065 ThisThread->pFunctions->HttpProc(ThisThread->pHT,ThisThread);
01066
01067 FinishConnection(ThisThread);
01068 }
01069 #endif