00001 #include "IoFunctions.h"
00002 #include "Threading.h"
00003 #include "Modules/Encoding_Chunked.h"
00004
00005 HTTPIOMapping HTTPIoMappingData[MAXIMUM_OPENED_HANDLES];
00006 #ifndef __uint64
00007 #define __uint64 unsigned __int64
00008 #endif
00009
00010 CRITICAL_SECTION IoMappingLock;
00011 #ifdef __WIN32__RELEASE__
00012 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
00013 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
00014 #else
00015 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
00016 #endif
00017
00018 struct timezone
00019 {
00020 int tz_minuteswest;
00021 int tz_dsttime;
00022 };
00023
00024 static int gettimeofday(struct timeval *tv, struct timezone *tz)
00025 {
00026 FILETIME ft;
00027 unsigned __int64 tmpres = 0;
00028 static int tzflag;
00029
00030 if (NULL != tv)
00031 {
00032 GetSystemTimeAsFileTime(&ft);
00033
00034 tmpres |= ft.dwHighDateTime;
00035 tmpres <<= 32;
00036 tmpres |= ft.dwLowDateTime;
00037
00038
00039 tmpres /= 10;
00040 tmpres -= DELTA_EPOCH_IN_MICROSECS;
00041 tv->tv_sec = (long)(tmpres / 1000000UL);
00042 tv->tv_usec = (long)(tmpres % 1000000UL);
00043 }
00044
00045 if (NULL != tz)
00046 {
00047 if (!tzflag)
00048 {
00049 _tzset();
00050 tzflag++;
00051 }
00052 tz->tz_minuteswest = _timezone / 60;
00053 tz->tz_dsttime = _daylight;
00054 }
00055
00056 return 0;
00057 }
00058 #endif
00059
00060
00062
00071
00072 static int LimitIOBandwidth(unsigned long ChunkSize, struct timeval LastTime, struct timeval CurrentTime, int MAX_BW_LIMIT)
00073 {
00074
00075 if ( ( LastTime.tv_usec || LastTime.tv_sec ) && MAXIMO_BW_PERMITIDO )
00076 {
00077 __uint64 TotalTime = ((CurrentTime.tv_usec + CurrentTime.tv_sec*1000000) - (LastTime.tv_usec + LastTime.tv_sec*1000000) ) / 1000;
00078 if (TotalTime >= MAX_CHECK_TIME_FOR_BW_UTILIZATION )
00079 {
00080 __uint64 CurrentBW = (ChunkSize *1000 ) / (TotalTime *1024 ) ;
00081
00082 if (CurrentBW > MAX_BW_LIMIT )
00083 {
00084 __uint64 WaitFor = (ChunkSize *1000 ) / (MAX_BW_LIMIT *1024) ;
00085
00086 return((int)WaitFor);
00087 }
00088 } else {
00089 return(-1);
00090 }
00091 }
00092 return(0);
00093 }
00094
00095
00096
00097
00099
00105
00106 int SendHTTPRequestData(STABLISHED_CONNECTION *conexion, PHTTP_DATA request) {
00107
00108 if ((conexion) && (request)) {
00109 if (conexion->NeedSSL) {
00110 #ifdef _OPENSSL_SUPPORT_
00111 int err=SSL_write(conexion->ssl, request->Header, request->HeaderSize);
00112 if (err>0) {
00113 if (request->DataSize)
00114 {
00115 err=SSL_write(conexion->ssl, request->Data, request->DataSize);
00116 }
00117 }
00118 if (err <=0) {
00119 #ifdef _DBG_
00120 printf("SSL_write ERROR1: %s:%i\n",conexion->targetDNS,conexion->port);
00121 #endif
00122 return(0);
00123 }
00124 #else
00125 return (0);
00126 #endif
00127 } else {
00128 int err = send(conexion->datasock, request->Header, request->HeaderSize, 0);
00129 if (err > 0) {
00130 if (request->DataSize) {
00131 err = send(conexion->datasock, request->Data, request->DataSize, 0);
00132 }
00133 }
00134 if (err <= 0) {
00135 #ifdef _DBG_
00136 printf("Send() ERROR1: %s:%i\n",conexion->targetDNS,conexion->port);
00137 #endif
00138 return (0);
00139 }
00140 }
00141 }
00142 return (1);
00143 }
00144
00145
00147
00153
00154 PHTTP_DATA ReadHTTPResponseData(STABLISHED_CONNECTION *conexion, PHTTP_DATA request, void *lock)
00155 {
00156
00157 struct timeval tv;
00158 fd_set fdread, fds, fderr;
00159 char buf[BUFFSIZE+1];
00160 int read_size;
00161 char *lpBuffer = NULL;
00162 unsigned int BufferSize = 0;
00163 char *HeadersEnd = NULL;
00164 int offset = 0;
00165 int BytesToBeReaded = -1;
00166 int i;
00167 int pending = 0;
00168 PHTTP_DATA response = NULL;
00169
00170
00171
00172 unsigned int ChunkEncodeSupported = 0;
00173 unsigned int ConnectionClose = 0;
00174 unsigned int ContentLength = 0;
00175
00176
00177 int BwDelay;
00178 struct timeval LastTime={0,0};
00179 struct timeval CurrentTime;
00180 unsigned int ChunkSize = 0;
00181
00182
00183 int ChunkNumber = 0;
00184 char *encodedData = NULL;
00185 unsigned int encodedlen = 0 ;
00186 char *TmpChunkData = NULL;
00187
00188
00189 PHTTPIOMapping HTTPIOMappingData = NULL;
00190 #ifdef __WIN32__RELEASE__
00191 DWORD lpBufferSize;
00192 #endif
00193
00194
00195 LockMutex(&conexion->lock);
00196 tv.tv_sec = READ_TIMEOUT;
00197 tv.tv_usec = 0;
00198
00199 while (BytesToBeReaded != 0)
00200 {
00201
00202
00203 FD_ZERO(&fds);
00204 FD_SET(conexion->datasock, &fds);
00205 FD_ZERO(&fderr);
00206 FD_SET(conexion->datasock, &fderr);
00207 FD_ZERO(&fdread);
00208 FD_SET(conexion->datasock, &fdread);
00209
00210 if (!pending)
00211 {
00212
00213 i = select((int) conexion->datasock + 1, &fdread, NULL,&fderr, &tv);
00214
00215 #ifdef __WIN32__RELEASE__
00216 GetSystemTimeAsFileTime (&conexion->tlastused);
00217 #else
00218 time(&conexion->tlastused);
00219 #endif
00220
00221 if ((i == 0))
00222 {
00223
00224 if ( (!lpBuffer) && (!HTTPIOMappingData) ) {
00225 UnLockMutex(&conexion->lock);
00226 LockMutex(lock);
00227 #ifdef _DBG_
00228 printf("TIMEOUT LEYENDO...\n");
00229 #endif
00230 FreeConnection(conexion);
00231 UnLockMutex(lock);
00232 if (conexion->ConnectionAgainstProxy) {
00233 return ( NULL) ;
00234 } else {
00235 return (InitHTTPData(NULL,NULL));
00236 }
00237
00238 }
00239 ConnectionClose = 1;
00240 break;
00241 }
00242 read_size = 1;
00243 }
00244
00245
00246 if ((FD_ISSET(conexion->datasock, &fdread)) || pending)
00247 {
00248 if (conexion->NeedSSL) {
00249 #ifdef _OPENSSL_SUPPORT_
00250 read_size=SSL_read(conexion->ssl, buf, BytesToBeReaded> sizeof(buf)-1 ? sizeof(buf)-1 :BytesToBeReaded);
00251
00252 pending= SSL_pending(conexion->ssl);
00253 int ret=SSL_get_error(conexion->ssl,read_size);
00254
00255 #ifdef _DBG_
00256 printf("SSL: read: %i bytes\n",read_size);
00257 #endif
00258 #endif
00259 } else {
00260 read_size = recv(conexion->datasock, buf, BytesToBeReaded > sizeof(buf) - 1 ? sizeof(buf) - 1 : BytesToBeReaded, 0);
00261 }
00262 if (read_size>0) buf[read_size]='\0'; else buf[0]='\0';
00263 #ifdef _DBG_
00264 if (read_size>0)
00265 {
00266 printf("---------- read: \n%s\n-----------\n",buf); fflush(stdout);
00267 }
00268 #endif
00269 }
00270
00271
00272 if ((!pending) && ((FD_ISSET(conexion->datasock, &fderr)) || (read_size <= 0)))
00273 {
00274 if (read_size <= 0)
00275 {
00276 if ( (!lpBuffer) && (HTTPIOMappingData == NULL) )
00277 {
00278
00279 UnLockMutex(&conexion->lock);
00280 if (conexion->NumberOfRequests > 0) {
00281 #ifdef _DBG_
00282 printf("CONECTA::DBG Error recv() en peticion reutilizada\n");
00283 printf("LLAMANDO A StablishConnection desde peticion fallida reutilizada\n");
00284 #endif
00285 LockMutex(lock);
00286 shutdown(conexion->datasock,2);
00287 closesocket(conexion->datasock);
00288 i = StablishConnection(conexion);
00289 if (!i) {
00290 FreeConnection(conexion);
00291 UnLockMutex(lock);
00292 return (NULL);
00293 }
00294 for (i = 0; i <= conexion->PENDING_PIPELINE_REQUESTS - 1; i++) {
00295 SendHTTPRequestData(conexion,conexion->PIPELINE_Request[i]);
00296 }
00297
00298 UnLockMutex(lock);
00299 return ReadHTTPResponseData(conexion, request, lock);
00300 } else {
00301 #ifdef _DBG_
00302 printf("CONECTA::DBG Error recv(). Se han recibido 0 bytes. Purgando conexion..\n");
00303 #endif
00304 LockMutex(lock);
00305
00306 FreeConnection(conexion);
00307 UnLockMutex(lock);
00308 return (InitHTTPData(NULL,NULL));
00309 }
00310 }
00311 }
00312 ConnectionClose = 1;
00313 break;
00314 }
00315
00316
00317
00318
00319
00320 if (HTTPIOMappingData)
00321 {
00322 #ifdef __WIN32__RELEASE__
00323 WriteFile(HTTPIOMappingData->hTmpFilename,buf,read_size,&lpBufferSize,NULL);
00324 BufferSize += read_size;
00325 #else
00326 write(HTTPIOMappingData->hTmpFilename,buf,read_size);
00327 BufferSize += read_size;
00328 #endif
00329
00330 } else {
00331 lpBuffer = (char*) realloc(lpBuffer, BufferSize + read_size + 1);
00332 memcpy(lpBuffer + BufferSize, buf, read_size);
00333 BufferSize += read_size;
00334 lpBuffer[BufferSize] = '\0';
00335 }
00336
00337
00338
00339 if (conexion->BwLimit)
00340 {
00341 ChunkSize +=read_size;
00342 gettimeofday(&CurrentTime,NULL);
00343 BwDelay = LimitIOBandwidth( ChunkSize, LastTime, CurrentTime,conexion->BwLimit);
00344 if (BwDelay >= 0){
00345 Sleep(BwDelay);
00346 gettimeofday(&LastTime,NULL);
00347 ChunkSize=0;
00348 }
00349 }
00350
00351
00352 if (!HeadersEnd)
00353 {
00354 char *p = strstr(lpBuffer, "\r\n\r\n");
00355 if (p) {
00356 offset = 4;
00357 HeadersEnd = p;
00358 }
00359 p = strstr(lpBuffer, "\n\n");
00360 if (p)
00361 if ((!HeadersEnd) || (p < HeadersEnd)) {
00362 offset = 2;
00363 HeadersEnd = p;
00364 }
00365 if (HeadersEnd) {
00366
00367 if (strnicmp(lpBuffer, "HTTP/1.1 100 Continue", 21) == 0) {
00368 free(lpBuffer);
00369 return (ReadHTTPResponseData(conexion, request, lock));
00370 }
00371 response = InitHTTPData(NULL,NULL);
00372 response->HeaderSize = (unsigned int)(HeadersEnd - lpBuffer) + offset;
00373 #ifdef _DBG_
00374 printf("HeaderSize vale %i de %ibytes\n",response->HeaderSize,BufferSize);
00375 #endif
00376 response->Header = (char*) realloc(response->Header, response->HeaderSize + 1);
00377 memcpy(response->Header, lpBuffer, response->HeaderSize);
00378 response->Header[response->HeaderSize] = '\0';
00379 #ifdef _DBG_
00380 printf("Value: %s\n",response->Header);
00381 #endif
00382
00383
00384 if (response->HeaderSize>8){
00385 if (strcmp(response->Header+9,"204")==0){
00386 return(response);
00387 }
00388
00389 if (response->Header[7] =='0') ConnectionClose = 1;
00390
00391 }
00392
00393 p = GetHeaderValue(response->Header, "Connection:", 0);
00394 if (p) {
00395 if (strnicmp(p, "close", 7) == 0) {
00396 ConnectionClose = 1;
00397 } else if (strnicmp(p, "Keep-Alive", 10) == 0) {
00398 ConnectionClose = 0;
00399 }
00400 free(p);
00401 } else {
00402 p = GetHeaderValue(response->Header, "Proxy-Connection:", 0);
00403 if (p)
00404 {
00405 if (strnicmp(p, "close", 7) == 0)
00406 {
00407 ConnectionClose = 1;
00408 } else if (strnicmp(p, "Keep-Alive", 10) == 0) {
00409 ConnectionClose = 0;
00410 }
00411 free(p);
00412 }
00413 }
00414
00415 if ((p = GetHeaderValue(response->Header, "Content-Length:", 0))
00416 != NULL) {
00417 ContentLength = atoi(p);
00418 if (p[0] == '-')
00419 {
00420 ConnectionClose = 1;
00421 free(lpBuffer);
00422 lpBuffer = NULL;
00423 break;
00424
00425
00426
00427
00428 } else {
00429 BytesToBeReaded = ContentLength - BufferSize
00430 + response->HeaderSize;
00431 }
00432 free(p);
00433 }
00434 if (strnicmp(request->Header, "HEAD ", 5) == 0) {
00435 if ((lpBuffer[7] == '1') && (ContentLength)) {
00436 free(lpBuffer);
00437 lpBuffer = NULL;
00438 break;
00439 }
00440 }
00441
00442 p = GetHeaderValue(response->Header, "Transfer-Encoding:", 0);
00443 if (p) {
00444 if (strnicmp(p, "chunked", 7) == 0) {
00445 ChunkEncodeSupported = 1;
00446 #ifdef _DBG_
00447 printf("Leido content chunked\n");
00448 #endif
00449 }
00450 free(p);
00451 }
00452 BufferSize = BufferSize - response->HeaderSize;
00453
00454
00455
00456
00457
00458 HTTPIOMappingData = GetFileMapping(0,NULL);
00459 if (HTTPIOMappingData)
00460 {
00461 #ifdef __WIN32__RELEASE__
00462 WriteFile(HTTPIOMappingData->hTmpFilename,lpBuffer + response->HeaderSize,BufferSize,&lpBufferSize,NULL);
00463 #else
00464
00465 write(HTTPIOMappingData->hTmpFilename,lpBuffer + response->HeaderSize,BufferSize);
00466 #endif
00467
00468 TmpChunkData = (char*)malloc(BufferSize + BUFFSIZE +1);
00469 memcpy(TmpChunkData,lpBuffer + response->HeaderSize,BufferSize);
00470 encodedlen=BufferSize;
00471 TmpChunkData[BufferSize]='\0';
00472 free(lpBuffer);
00473 lpBuffer=NULL;
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483 }
00484
00485 }
00486
00487
00488
00489 if ( (ChunkEncodeSupported) && (read_size>0 ) ){
00490 char chunkcode[MAX_CHUNK_LENGTH+1];
00491 char *p;
00492 unsigned long chunk=1;
00493
00494 encodedData = TmpChunkData;
00495 if (ChunkNumber>0) {
00496
00497 memcpy(TmpChunkData+encodedlen,buf,read_size);
00498 encodedlen+=read_size;
00499 TmpChunkData[encodedlen]='\0';
00500 }
00501 do {
00502 #ifdef _DBG_
00503 printf("\n\n*+++++++++++++++++++++++*\n");
00504 printf("Parseando buffer de %i bytes\n",encodedlen);
00505
00506 #endif
00507
00508 if (BytesToBeReaded <=0)
00509 {
00510 #ifdef _DBG_
00511 printf("%s\n",encodedData);
00512 printf("\n\n*----------------*\n");
00513 #endif
00514 if (encodedlen<=2) break;
00515
00516 if (ChunkNumber !=0)
00517 {
00518 encodedData+=2;
00519 encodedlen-=2;
00520 }
00521
00522 if (encodedlen>=MAX_CHUNK_LENGTH) {
00523
00524 memcpy(chunkcode,encodedData,MAX_CHUNK_LENGTH);
00525 chunkcode[MAX_CHUNK_LENGTH]='\0';
00526 p=strstr(chunkcode,"\r\n");
00527 if (!p){
00528 #ifdef _DBG_
00529
00530 printf("Chunk encoding Error. Data chunk Format error %s\n",chunkcode);
00531 printf("MORE: %s\n",encodedData);
00532
00533 #endif
00534 ChunkEncodeSupported = 0;
00535 ConnectionClose=1;
00536 free(TmpChunkData);
00537 TmpChunkData=NULL;
00538 break;
00539 }
00540 } else {
00541 memcpy(chunkcode,encodedData,encodedlen);
00542 chunkcode[encodedlen]='\0';
00543 p=strstr(chunkcode,"\r\n");
00544 if (!p) {
00545 #ifdef _DBG_
00546 printf("Chunk encoding Error. Not enought data. Waiting for next chunk\n");
00547 #endif
00548 if (ChunkNumber !=0) encodedlen+=2;
00549 break;
00550 }
00551 }
00552 ChunkNumber++;
00553 *p='\0';
00554 chunk=strtol(chunkcode,NULL,16);
00555 #ifdef _DBG_
00556 printf("Leido chunk de valor : %i\n",chunk);
00557 #endif
00558 if (chunk==0) {
00559 BytesToBeReaded=0;
00560 break;
00561 }
00562
00563 if ( (unsigned int) encodedlen >= 2 + strlen(chunkcode)+chunk) {
00564 #ifdef _DBG_
00565 printf("Encodedlen (%i) >= 2 + strlen(chunkcode)+chunk\n",encodedlen);
00566 #endif
00567 encodedlen-=2+chunk+strlen(chunkcode);
00568
00569
00570
00571 BytesToBeReaded = -1;
00572
00573
00574 memcpy(TmpChunkData,encodedData+2+chunk+strlen(chunkcode),encodedlen);
00575
00576 encodedData=TmpChunkData;
00577 TmpChunkData[encodedlen]='\0';
00578
00579 } else {
00580 encodedlen-=2 + (unsigned int)strlen(chunkcode);
00581 BytesToBeReaded = chunk - encodedlen;
00582 if (BytesToBeReaded == 0) BytesToBeReaded = -1;
00583 encodedlen=0;
00584
00585 #ifdef _DBG_
00586 printf("No llegan los datos: BytesToBeReaded asignado a %i\n",BytesToBeReaded);
00587 #endif
00588 }
00589 } else {
00590 #ifdef _DBG_
00591 printf("Tenemos un trozo de %i bytes . necesitamos %i bytes\n",encodedlen,BytesToBeReaded);
00592 #endif
00593 if (encodedlen >= BytesToBeReaded)
00594 {
00595
00596 encodedData+=BytesToBeReaded;
00597 encodedlen-=BytesToBeReaded;
00598 BytesToBeReaded=-1;
00599 memcpy(TmpChunkData,encodedData,encodedlen);
00600 TmpChunkData[encodedlen]='\0';
00601 #ifdef _DBG_
00602 printf("Nos quedan %i bytes para seguir trabajando\n",encodedlen);
00603 #endif
00604 } else {
00605 BytesToBeReaded -=encodedlen;
00606 encodedlen=0;
00607 #ifdef _DBG_
00608 printf("Seguimos necesitando %i bytes\n",BytesToBeReaded);
00609 #endif
00610 }
00611 }
00612 } while (encodedlen);
00613 #ifdef _DBG_
00614 printf("Salimos del bucle\n");
00615 #endif
00616 }
00617
00618 if (ContentLength)
00619 {
00620 BytesToBeReaded = ContentLength - BufferSize;
00621 if (BytesToBeReaded < 0) {
00622 #ifdef _DBG_
00623 printf("***********\nError leyendo..\n************\n");
00624 #endif
00625 ConnectionClose = 1;
00626 }
00627 }
00628 }
00629
00630
00631
00632
00633 if (!response) {
00634
00635 response=InitHTTPData(NULL,NULL);
00636 if (lpBuffer) {
00637 free(response->Data);
00638 response->Data=lpBuffer;
00639 response->DataSize = BufferSize;
00640 }
00641 } else {
00642 if (HTTPIOMappingData)
00643 {
00644 #ifdef __WIN32__RELEASE__
00645 WriteFile(HTTPIOMappingData->hTmpFilename,"\x00",1,&lpBufferSize,NULL);
00646
00647 HTTPIOMappingData->hMapping = CreateFileMapping (HTTPIOMappingData->hTmpFilename, NULL, PAGE_READWRITE, 0, BufferSize,NULL);
00648 if (HTTPIOMappingData->hMapping == 0)
00649 {
00650 printf("error %i con %s %i\n",GetLastError(),HTTPIOMappingData->BufferedFileName,BufferSize);
00651 printf("%s\n",response->Header);
00652 return(NULL);
00653 } else {
00654 free(response->Data);
00655 response->Data =HTTPIOMappingData->BufferedPtr = (char*) MapViewOfFile (HTTPIOMappingData->hMapping , FILE_MAP_ALL_ACCESS, 0,0,0);
00656
00657
00658
00659 }
00660
00661 #else
00662
00663 write(HTTPIOMappingData->hTmpFilename,"\x00",1);
00664 response->Data =HTTPIOMappingData->BufferedPtr = (char*) mmap (0, BufferSize +1, PROT_READ | PROT_WRITE, MAP_SHARED, HTTPIOMappingData->hTmpFilename, 0);
00665 #endif
00666 response->DataSize = BufferSize;
00667
00668 }
00669 }
00670 if (TmpChunkData) free(TmpChunkData);
00671
00672 LockMutex(lock);
00673 if (ConnectionClose) {
00674 FreeConnection(conexion);
00675 } else {
00676 conexion->NumberOfRequests++;
00677 RemovePipeLineRequest(conexion);
00678 conexion->io = 0;
00679 }
00680 UnLockMutex(lock);
00681
00682 UnLockMutex(&conexion->lock);
00683
00684
00685
00686
00687
00688 return (response);
00689
00690 }
00691
00692
00693
00694
00695
00696
00698
00702
00703 int StablishConnection(STABLISHED_CONNECTION *connection) {
00704 fd_set fds, fderr;
00705 struct timeval tv;
00706
00707 connection->datasock = (int) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00708
00709 connection->webserver.sin_family = AF_INET;
00710 connection->webserver.sin_addr.s_addr = connection->target;
00711 connection->webserver.sin_port = htons(connection->port);
00712 #ifdef __WIN32__RELEASE__
00713 u_long tmp=1;
00714 ioctlsocket( connection->datasock, FIONBIO, &tmp);
00715 #else
00716 int tmp = 1;
00717 ioctl(connection->datasock, FIONBIO, (char *) &tmp);
00718 #endif
00719
00720 connection->NumberOfRequests = 0;
00721 connect(connection->datasock, (struct sockaddr *) &connection->webserver, sizeof(connection->webserver));
00722 tv.tv_sec = CONN_TIMEOUT;
00723 tv.tv_usec = 0;
00724 FD_ZERO(&fds);
00725 FD_ZERO(&fderr);
00726 FD_SET(connection->datasock, &fds);
00727 FD_SET(connection->datasock, &fderr);
00728 if (select((int) connection->datasock + 1, NULL,&fds, NULL,&tv) <= 0) {
00729
00730 #ifdef _DBG_
00731 printf("StablishConnection::Unable to connect Conexion %i to (%s):%i\n",connection->id,inet_ntoa(connection->webserver.sin_addr),connection->port);
00732 #endif
00733 closesocket(connection->datasock);
00734 return (0);
00735 }
00736
00737 #ifdef _DBG_
00738 printf("StablishConnection: Socket CONNECTED Conexion %i (%s:%i)\n",connection->id,inet_ntoa(connection->webserver.sin_addr),connection->port);
00739
00740 #endif
00741 if (connection->NeedSSL) {
00742 #ifdef _OPENSSL_SUPPORT_
00743 int err=0;
00744 tmp=0;
00745
00746 #ifdef __WIN32__RELEASE__
00747 ioctlsocket( connection->datasock, FIONBIO, &tmp);
00748 #else
00749 ioctl(connection->datasock, FIONBIO, (char *)&tmp);
00750 #endif
00751
00752
00753 connection->ctx = SSL_CTX_new(TLSv1_client_method());
00754 if (!connection->ctx)
00755 {
00756 #ifdef _DBG_
00757 printf("SSL_CTX_new failed\n");
00758 #endif
00759 closesocket(connection->datasock);
00760 return 0;
00761 }
00762 connection->ssl=SSL_new(connection->ctx);
00763 SSL_set_fd(connection->ssl, connection->datasock);
00764 if ((err = SSL_connect(connection->ssl)) != 1)
00765 {
00766 #ifdef _DBG_
00767 int newerr;
00768 newerr= SSL_get_error(connection->ssl,err);
00769 printf("SSL_connect failed: %s", strerror(errno));
00770 printf("SSLError: %i %i\n",newerr,err);
00771 #endif
00772 SSL_shutdown(connection->ssl);
00773 SSL_free(connection->ssl);
00774 SSL_CTX_free(connection->ctx);
00775 closesocket(connection->datasock);
00776 return(0);
00777 }
00778 tmp=0;
00779 #ifdef __WIN32__RELEASE__
00780 ioctlsocket( connection->datasock, FIONBIO, &tmp);
00781 #else
00782 ioctl(connection->datasock, FIONBIO, (char *)&tmp);
00783 #endif
00784
00785 #endif
00786 }
00787 return (1);
00788
00789 }
00790
00791
00792
00793
00794
00795
00796
00797 int InitFileMapping(void)
00798 {
00799 InitMutex(&IoMappingLock);
00800 for (int i = 0; i< MAXIMUM_OPENED_HANDLES; i++) memset(&HTTPIoMappingData[i],0,sizeof ( HTTPIOMapping) );
00801 return(1);
00802 }
00803
00804 int EndFileMapping(void)
00805 {
00806 LockMutex(&IoMappingLock);
00807 for (int i = 0; i< MAXIMUM_OPENED_HANDLES; i++) {
00808 if (HTTPIoMappingData[i].assigned){
00809 #ifdef __WIN32__RELEASE__
00810 CloseHandle(HTTPIoMappingData[i].hMapping);
00811 CloseHandle(HTTPIoMappingData[i].hTmpFilename);
00812 #else
00813 close(HTTPIoMappingData[i].hTmpFilename);
00814 #endif
00815 HTTPIoMappingData[i].assigned=0;
00816 }
00817 }
00818 UnLockMutex(&IoMappingLock);
00819 DeleteMutex(&IoMappingLock);
00820 return(1);
00821
00822 }
00823
00824 char *DeleteFileMapping(void* ptr)
00825 {
00826 LockMutex(&IoMappingLock);
00827 for(int i=0;i<MAXIMUM_OPENED_HANDLES;i++)
00828 {
00829 if (HTTPIoMappingData[i].assigned)
00830 {
00831
00832 if (HTTPIoMappingData[i].BufferedPtr == ptr )
00833 {
00834 int ret;
00835 HTTPIoMappingData[i].assigned=0;
00836
00837
00838 #ifdef __WIN32__RELEASE__
00839 ret = UnmapViewOfFile(HTTPIoMappingData[i].BufferedPtr);
00840 if (!ret) printf("UnmapViewOfFile Error: %i\n",GetLastError());
00841 ret = CloseHandle(HTTPIoMappingData[i].hMapping);
00842 if (ret==0) printf("CloseHandle1 Error: %i\n",GetLastError());
00843
00844 ret= CloseHandle(HTTPIoMappingData[i].hTmpFilename);
00845 if (ret==0) printf("CloseHandle2 Error: %i (file %s)\n",GetLastError(),HTTPIoMappingData[i].BufferedFileName);
00846
00847 ret = DeleteFile(HTTPIoMappingData[i].BufferedFileName);
00848 if (!ret) printf("DeleteFile Error: %i\n",GetLastError());
00849 #else
00850 ret=munmap(HTTPIoMappingData[i].BufferedPtr,HTTPIoMappingData[i].MemoryLenght+1);
00851 if (ret==-1) printf("ERROR REMOVING MAPPING DATA\n");
00852 close(HTTPIoMappingData[i].hTmpFilename);
00853 remove(HTTPIoMappingData[i].BufferedFileName);
00854
00855
00856 #endif
00857 HTTPIoMappingData[i].MemoryLenght=0;
00858 UnLockMutex(&IoMappingLock);
00859 return (NULL);;
00860 }
00861 }
00862 }
00863 UnLockMutex(&IoMappingLock);
00864 return((char*)ptr);
00865 }
00866
00867
00868
00869 PHTTPIOMapping GetFileMapping(unsigned int DataSize, char *lpData )
00870 {
00871 LockMutex(&IoMappingLock);
00872
00873 for(int i=0;i<MAXIMUM_OPENED_HANDLES;i++)
00874 {
00875 if (!HTTPIoMappingData[i].assigned)
00876 {
00877 char szTmpFile[256];
00878 HTTPIoMappingData[i].assigned=1;
00879 HTTPIoMappingData[i].BufferedPtr = NULL;
00880 UnLockMutex(&IoMappingLock);
00881
00882 #ifdef __WIN32__RELEASE__
00883 GetTempPath (256, szTmpFile);
00884 GetTempFileNameA (szTmpFile, "FHScan",0,HTTPIoMappingData[i].BufferedFileName);
00885
00886
00887 HTTPIoMappingData[i].hTmpFilename = CreateFile ( HTTPIoMappingData[i].BufferedFileName,
00888 GENERIC_WRITE | GENERIC_READ,
00889 FILE_SHARE_WRITE,
00890 NULL,
00891 CREATE_ALWAYS,
00892 FILE_ATTRIBUTE_TEMPORARY,
00893 NULL);
00894 if ( HTTPIoMappingData[i].hTmpFilename == INVALID_HANDLE_VALUE) {
00895 #ifdef _DBG_
00896 printf("GetFileMapping Error: Unable to create temporary filename\n");
00897 #endif
00898 HTTPIoMappingData[i].assigned= 0;
00899 return(NULL);
00900 }
00901
00902 #else
00903 strcpy(HTTPIoMappingData[i].BufferedFileName,tempnam(NULL,"FHScan") );
00904
00905 HTTPIoMappingData[i].hTmpFilename = open(HTTPIoMappingData[i].BufferedFileName,O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
00906 #endif
00907
00908
00909 if (DataSize){
00910 #ifdef __WIN32__RELEASE__
00911 HTTPIoMappingData[i].hMapping = CreateFileMapping (HTTPIoMappingData[i].hTmpFilename,
00912 NULL,
00913 PAGE_READWRITE,
00914 0,
00915 DataSize,
00916 NULL);
00917 if (!HTTPIoMappingData[i].hMapping) {
00918 #ifdef _DBG_
00919 printf("GetFileMapping Error: Unable to create file mapping\n");
00920 return(NULL);
00921 #endif
00922
00923 }
00924 #endif
00925 if (lpData)
00926 {
00927 #ifdef __WIN32__RELEASE__
00928 DWORD lpBufferSize;
00929 WriteFile(HTTPIoMappingData[i].hTmpFilename,lpData,DataSize,&lpBufferSize,NULL);
00930 #else
00931 write(HTTPIoMappingData[i].hTmpFilename,lpData,DataSize);
00932
00933
00934 #endif
00935 }
00936 }
00937 return ( &HTTPIoMappingData[i] );
00938 }
00939 }
00940 UnLockMutex(&IoMappingLock);
00941 printf(" ** CRITICAL ERROR** NOT ENOUGHT FREE FILEHANDLES. Maybe you forget to call FreeRequest() up to %i times\n",MAXIMUM_OPENED_HANDLES);
00942 return ( (PHTTPIOMapping) NULL);
00943 }
00944
00945
00946
00947
00948