00001
00006 #include "Encoding_Chunked.h"
00007 #include "../IoFunctions.h"
00008 #include "../CallBack.h"
00009 #include "../Build.h"
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013
00014
00015 #ifndef _CRT_SECURE_NO_DEPRECATE
00016 #define _CRT_SECURE_NO_DEPRECATE
00017 #endif
00018
00019
00021
00028
00029 static char *DecodeChunk(char *lpBuffer, unsigned int encodedlen, unsigned int *decodedlen)
00030 {
00031
00032
00033 char *encoded=lpBuffer;
00034
00035 char chunkcode[MAX_CHUNK_LENGTH+1];
00036 char *p;
00037 unsigned long chunk=1;
00038
00039 unsigned long lpBufferSize;
00040 PHTTPIOMapping HTTPIoMapping = NULL;
00041
00042 *decodedlen=0;
00043 do {
00044 if (lpBuffer!=encoded){
00045 if (encodedlen<=2) {
00046 break;
00047 }
00048 encoded+=2;
00049 encodedlen-=2;
00050 }
00051 if (encodedlen>=MAX_CHUNK_LENGTH) {
00052 memcpy(chunkcode,encoded,MAX_CHUNK_LENGTH);
00053 chunkcode[MAX_CHUNK_LENGTH]='\0';
00054 } else {
00055
00056 memcpy(chunkcode,encoded,encodedlen);
00057 chunkcode[encodedlen]='\0';
00058 }
00059 p=strstr(chunkcode,"\r\n");
00060 if (!p)
00061 {
00062
00063 if (HTTPIoMapping)
00064 {
00065 #ifdef __WIN32__RELEASE__
00066 CloseHandle(HTTPIoMapping->hTmpFilename);
00067 DeleteFile(HTTPIoMapping->BufferedFileName);
00068 #else
00069 close(HTTPIoMapping->hTmpFilename);
00070 rmdir(HTTPIoMapping->BufferedFileName);
00071 #endif
00072 HTTPIoMapping->assigned=0;
00073 }
00074 #ifdef _DBG_
00075 printf("DecodeChunk::error...\n");
00076 #endif
00077 return(NULL);
00078 }
00079 *p='\0';
00080 chunk=strtol(chunkcode,NULL,16);
00081 if ( (unsigned int) encodedlen > strlen(chunkcode)+ 2 + chunk) {
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 if (!HTTPIoMapping){
00092 HTTPIoMapping = GetFileMapping(0,NULL);
00093 if (!HTTPIoMapping) return(NULL);
00094 }
00095 if (HTTPIoMapping) {
00096 #ifdef __WIN32__RELEASE__
00097 WriteFile(HTTPIoMapping->hTmpFilename,encoded+2+strlen(chunkcode),chunk,&lpBufferSize,NULL);
00098 #else
00099
00100 write(HTTPIoMapping->hTmpFilename,encoded+2+strlen(chunkcode),chunk);
00101 #endif
00102 HTTPIoMapping->MemoryLenght+=chunk;
00103 }
00104 *decodedlen+=chunk;
00105 encodedlen-=2+chunk+strlen(chunkcode);
00106 encoded+=2+chunk+strlen(chunkcode);
00107 } else {
00108 if (!HTTPIoMapping){
00109 HTTPIoMapping = GetFileMapping(0,NULL);
00110 if (!HTTPIoMapping) return(NULL);
00111 }
00112 if (HTTPIoMapping) {
00113 #ifdef __WIN32__RELEASE__
00114 WriteFile(HTTPIoMapping->hTmpFilename,encoded+2+strlen(chunkcode),encodedlen-strlen(chunkcode)-2,&lpBufferSize,NULL);
00115 #else
00116
00117 write(HTTPIoMapping->hTmpFilename,encoded+2+strlen(chunkcode),encodedlen-strlen(chunkcode)-2);
00118 #endif
00119 HTTPIoMapping->MemoryLenght+=encodedlen-strlen(chunkcode)-2;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 *decodedlen+=encodedlen-strlen(chunkcode)-2;
00131 encodedlen=0;
00132 }
00133
00134 } while ( (encodedlen>0) && (chunk>0) );
00135
00136 if (!HTTPIoMapping) return (NULL);
00137 #ifdef __WIN32__RELEASE__
00138 WriteFile(HTTPIoMapping->hTmpFilename,"\x00",1,&lpBufferSize,NULL);
00139 HTTPIoMapping->hMapping = CreateFileMapping (HTTPIoMapping->hTmpFilename,
00140 NULL,
00141 PAGE_READWRITE,
00142 0,
00143 HTTPIoMapping->MemoryLenght+1,
00144 NULL);
00145 HTTPIoMapping->BufferedPtr = (char*) MapViewOfFile (HTTPIoMapping->hMapping , FILE_MAP_ALL_ACCESS, 0,0,0);
00146 #else
00147 write(HTTPIoMapping->hTmpFilename,"\x00",1);
00148 HTTPIoMapping->BufferedPtr = (char*) mmap (0, *decodedlen +1, PROT_READ | PROT_WRITE, MAP_SHARED, HTTPIoMapping->hTmpFilename, 0);
00149 #endif
00150
00151
00152 return(HTTPIoMapping->BufferedPtr);
00153
00154 }
00155
00157
00165
00166 int CBDecodeChunk(int cbType,HTTPHANDLE HTTPHandle,PHTTP_DATA *prequest,PHTTP_DATA *presponse)
00167 {
00168
00169 PHTTP_DATA response = *presponse;
00170 if ((cbType == CBTYPE_CLIENT_RESPONSE) || (cbType == CBTYPE_PROXY_RESPONSE) )
00171 {
00172 if (response) {
00173 char *p=GetHeaderValue(response->Header,"Transfer-Encoding:",0);
00174 if (p)
00175 {
00176 if (strnicmp(p,"chunked",7)==0) {
00177 unsigned int decodedlen;
00178 char *decoded= DecodeChunk(response->Data,response->DataSize,&decodedlen);
00179 if (decoded)
00180 {
00181 char tmp[256];
00182 response->Data = DeleteFileMapping(response->Data);
00183 if (response->Data)
00184 {
00185
00186 free(response->Data);
00187 }
00188 response->Data=decoded;
00189 response->DataSize=decodedlen;
00190 RemoveHeader(response,"Transfer-Encoding: ");
00191 sprintf(tmp,"Content-Length: %i\r\n",decodedlen);
00192 AddHeader(response, tmp);
00193 }
00194 }
00195 free(p);
00196 }
00197 }
00198 }
00199
00200 return(CBRET_STATUS_NEXT_CB_CONTINUE);
00201
00202 }
00203 #if 0
00204
00206
00213
00214 int ParseDataChunks(char *lpBuffer, unsigned int encodedlen)
00215 {
00216
00217
00218
00219
00220
00221 char *encoded=lpBuffer;
00222 char chunkcode[MAX_CHUNK_LENGTH+1];
00223 char *p;
00224 unsigned long chunk=1;
00225
00226
00227 do {
00228 if (lpBuffer!=encoded)
00229 {
00230 encoded+=2;
00231 encodedlen-=2;
00232 }
00233 if (encodedlen>=MAX_CHUNK_LENGTH) {
00234 memcpy(chunkcode,encoded,MAX_CHUNK_LENGTH);
00235 chunkcode[MAX_CHUNK_LENGTH]='\0';
00236 p=strstr(chunkcode,"\r\n");
00237 if (!p) {
00238 return(0); }
00239 *p='\0';
00240 } else {
00241 if (encodedlen<=0) {
00242 break;
00243 }
00244 memcpy(chunkcode,encoded,encodedlen);
00245 chunkcode[encodedlen]='\0';
00246 p=strstr(chunkcode,"\r\n");
00247 if (p==NULL) break;
00248 *p='\0';
00249 }
00250 chunk=strtol(chunkcode,NULL,16);
00251 if (chunk==0) return (0);
00252 if ( (unsigned int) encodedlen > 2 + strlen(chunkcode)+chunk) {
00253 encodedlen-=2+chunk+strlen(chunkcode);
00254 encoded+=2+chunk+strlen(chunkcode);
00255 } else break;
00256 } while (1);
00257 return (ERROR_MORE_DATA_NEEDED);
00258
00259 }
00260
00261
00262 #endif