static int get_resp_body(http_resp_t *resp, char *body_start, size_t len) { assert(resp && body_start); bool is_chunked = false; char *val = http_hdr_list_get_value(resp->headers, "Transfer-Encoding"); if (val && strcasestr(val, "chunked")) { is_chunked = true; } int content_len; if (is_chunked) { content_len = merge_chunk(body_start); } else { val = http_hdr_list_get_value(resp->headers, "Content-length"); if (val) { content_len = atoi(val); if (content_len > len) { content_len = len; } } else { content_len = len; // use the data length } } /*the buffer end with '\0'*/ val = http_hdr_list_get_value(resp->headers, "Content-Encoding"); bool is_compressed = false; if (val && strcasestr(val, "gzip")) { is_compressed = true; } if (is_compressed) { resp->body = Malloc(content_len * 6); Byte *data = (Byte *)(resp->body); uLong ndata = content_len * 6; if (httpgzdecompress((Byte *)body_start, content_len, data, &ndata) < 0) { log_error("gzip decompress error"); return -1; } resp->content_len = ndata; } else { /*content_len+1 is a safer size than content_len*/ resp->body = Malloc(content_len + 1); memcpy(resp->body, body_start, content_len); resp->content_len = content_len; } return 0; }
uint32 get_content(HTTP_RESPONSE* response, void** content, uint32* content_len) { uint32 ret = SUCCEEDED; uint32 length = 0; char* content_encoding = 0; if (response == NULL || content == NULL || content_len == NULL) return ARGUMENT_ERR; if (response->content_len == 0 || response->content == 0 || response->current_len == 0) { *content = NULL; *content_len = 0; return SUCCEEDED; } ret = get_http_response_value_for_key(response->header.header, "Content-Encoding", &content_encoding); if (ret == SUCCEEDED) { if(0 == strcmp(content_encoding, "gzip") || 0 == strcmp(content_encoding, "deflate")) { free(content_encoding); content_encoding = NULL; length = response->current_len * 10; *content = (char*)malloc(length); if (*content == 0) return OUTOFMEM; ret = httpgzdecompress(response->content, response->current_len, *content, &length); if (ret != 0) { free(*content); *content = NULL; return FAILED; } (*(char**)content)[length] = '\0'; *content_len = length; return SUCCEEDED; } } if ((ret == SUCCEEDED && 0 == strcmp(content_encoding, "default")) || ret != SUCCEEDED) { if (content_encoding) { free(content_encoding); content_encoding = NULL; } length = response->current_len + 1; *content = (char*)malloc(length); if (*content == 0) return OUTOFMEM; memcpy(*content, response->content, response->current_len); (*(char**)content)[length] = '\0'; *content_len = length; return SUCCEEDED; } if (content_encoding){ free(content_encoding); content_encoding = NULL; } return SUCCEEDED; }
int MelodyProxy::Response(char* header, char* content, int count, MelodyProxy* pProxy, ProxyParam* pPar){ char* bufferAll=new char[MAXBUFFERSIZE*50]; int retval=0; //如果是gzip,先解码 char *p=strstr(header,"Content-Encoding: gzip"); uLong contentLength=count; if(p){ contentLength=MAXBUFFERSIZE*50; Byte* data=new Byte[MAXBUFFERSIZE*50]; httpgzdecompress((Byte*)content, count, data, &contentLength); char buf[100],buf1[100]; sprintf(buf,"%s%ld","Content-Length: ",contentLength); sprintf(buf1,"%s%d","Content-Length: ",count); char header3[MAXBUFFERSIZE]={0},header4[MAXBUFFERSIZE]={0}; replace(header,buf1,buf, header3, MAXBUFFERSIZE); replace(header3,"Content-Encoding: gzip\r\n","",header4,MAXBUFFERSIZE); header=header4; memcpy(content,data,contentLength); content[contentLength]=0; delete data; } strcat(bufferAll,header); memcpy(bufferAll+strlen(header),content,contentLength); MelodyProxy *proxy=(MelodyProxy *)pPar->pProxy; pProxy->winHandler->agentResponse(pPar->Request,header,content,pPar); if(pProxy->replaceResponse){ ::WaitForSingleObject(pPar->ReplaceResponseOK,INFINITE); if(pPar->CancelReplaceResponse){ retval = send(pPar->pPair->ProxyToUserSocket,bufferAll,strlen(header)+contentLength,0); } else{ retval = send(pPar->pPair->ProxyToUserSocket,pPar->Response,strlen(pPar->Response),0); } } else{ retval = send(pPar->pPair->ProxyToUserSocket,bufferAll,strlen(header)+contentLength,0); } if (retval == SOCKET_ERROR) { fprintf(stderr,"send() failed: error %d\n",WSAGetLastError()); closesocket(pPar->pPair->ProxyToUserSocket); pPar->pPair->ProxyToUserSocket=TRUE; } delete []bufferAll; return retval; }
string Http_handler::dezip(){ string &s=body_buffer; char *rawdata;int nrawdata=-1; printf("dezipping(content_encoding is %s)...",response_header_dict["content-encoding"].c_str()); const char *data=s.c_str(); string content_encoding=response_header_dict["content-encoding"]; if(content_encoding.substr(0,4)=="gzip"){ nrawdata = body_len * 16 + Z_HEADER_SIZE; rawdata=new char[nrawdata]; if((httpgzdecompress((Bytef *)data, body_len, (Bytef *)rawdata, (uLong *)&nrawdata)) == 0){ } }else if(content_encoding.substr(0,7)=="deflate"){ nrawdata = body_len * 16 + Z_HEADER_SIZE; rawdata=new char[nrawdata]; if((zdecompress((Bytef *)data, body_len, (Bytef *)rawdata, (uLong *)&nrawdata)) == 0){ } }else if(content_encoding==""){ rawdata=new char[body_len]; memcpy(rawdata,data,body_len); nrawdata=body_len; } cout<<"done!nrawdata "<<nrawdata<<endl; return string(rawdata,nrawdata); }