HttpMessage* read_http_message_from_socket(int sd) { char buffer[HTTP_REQUEST_MAX_LENGTH]; int bytes_read = 0; std::string header_string; std::string body_string; // Reading HTTP header request from the client do { int bytes_read_this_iteration = recv(sd, buffer + bytes_read, sizeof(buffer), 0); if (bytes_read_this_iteration < 0) { log("Error in recv() while reading data from the client's socket"); return nullptr; } if (bytes_read_this_iteration == 0) break; bytes_read += bytes_read_this_iteration; buffer[bytes_read] = '\0'; // Check if the end of HTTP header was encountered char *headers_end = strstr(buffer, "\r\n\r\n"); if (headers_end != NULL) { // Reached end of headers *headers_end = '\0'; header_string = std::string(buffer); buffer[bytes_read] = '\0'; if ((headers_end + 4 - buffer) < bytes_read) { // We've read a part of message's body - append it to body_string std::string t; t.resize(bytes_read - (headers_end + 4 - buffer)); std::copy(buffer + (headers_end + 4 - buffer), buffer + bytes_read, t.begin()); body_string += t; } break; } } while (true); HttpHeader http_header = make_http_header_from_string(header_string); if (http_header.type == HttpHeader::MALFORMED) return NULL; HttpMessage *result = new HttpMessage(); result->header = http_header; log("END OF HTTP HEADERS"); // If there's Content-Length or Content-Encoding header, read the body if ((http_header.headers.find("Content-Length") != http_header.headers.end()) || (http_header.headers.find("Content-Encoding") != http_header.headers.end()) || (http_header.headers.find("Transfer-Encoding") != http_header.headers.end())) { if ((http_header.headers.find("Content-Length") != http_header.headers.end()) && (http_header.headers.find("Content-Encoding") == http_header.headers.end()) || ((http_header.headers.find("Content-Encoding") != http_header.headers.end()) && (http_header.headers["Content-Encoding"] == "identity"))) { // Case 1: body is not compressed int content_length = atoi(http_header.headers["Content-Length"].c_str()); int bytes_left = content_length - body_string.size(); if (bytes_left > 0) { do { int bytes_read_this_iteration = recv(sd, buffer, bytes_left, 0); if (bytes_read_this_iteration < 0) { log("Error in recv() while reading data from the client's socket"); return nullptr; } bytes_left -= bytes_read_this_iteration; if (bytes_read_this_iteration == 0) { // No more data from the client break; } else { std::string t; t.resize(bytes_read_this_iteration); std::copy(buffer, buffer + bytes_read_this_iteration, t.begin()); body_string += t; } } while (true); } } else { // Case 2: body is compressed - just read body until no more data in the socket do { int bytes_read_this_iteration = recv(sd, buffer, sizeof(buffer), 0); if (bytes_read_this_iteration < 0) { log("Error in recv() while reading data from the client's socket"); return nullptr; } if (bytes_read_this_iteration == 0) { break; } else { std::string t; t.resize(bytes_read_this_iteration); std::copy(buffer, buffer + bytes_read_this_iteration, t.begin()); body_string += t; } } while (true); log("Target server's reply is compressed - starting decompresison"); try { std::string encoding = trim(http_header.headers["Content-Encoding"]); if (encoding == "gzip") { body_string = decompress_gzip(body_string); } else if (encoding == "deflate") { body_string = decompress_deflate(body_string); } result->header.headers["Content-Encoding"] = "identity"; std::stringstream content_length_stream; content_length_stream << body_string.size(); result->header.headers["Content-Length"] = content_length_stream.str(); } catch (std::runtime_error e) { log("Error while uncompressing target server's response: " + std::string(e.what())); return NULL; } } } else { body_string = ""; } if (result->header.headers.find("Referer") != result->header.headers.end()) { std::string referer_string = result->header.headers["Referer"]; std::vector<std::string> referer_string_parts = split_all(referer_string, '/'); if (referer_string_parts.size() > 3) { std::string referer_base = referer_string_parts[3]; if (result->header.path.find("/" + referer_base) != 0) { log("Using Referer to rewrite path string in HTTP response to target server"); if (result->header.path == "/") { result->header.path = "/" + referer_base; } else { result->header.path = "/" + referer_base + "/" + result->header.path; } } } } result->body = body_string; return result; }
int main(int argc, char *argv[]) { //std::string buffer; std::string decoded; #if 1 std::ifstream f1; f1.open("test.gz"); if(!f1) { std::cout <<"open test.gz file failed"<<std::endl; return 0; } char c[80]; char buf[30000]; memset(buf, 0, sizeof(buf)); int len = 0; while(!f1.eof()) { f1.read(c,80); //std::string str(c); //buffer += str; //std::cout<<"len="<<len<<" bufsize="<<buffer.size()<<std::endl; memcpy(buf+len, c, f1.gcount()); len += f1.gcount(); } fprintf(stdout, "len = %d\n", len); f1.close(); std::string buffer(buf); std::cout<<"buffer size="<<buffer.size()<<std::endl; #else FILE *fp = NULL; fp = fopen("test.gz", "r"); if (!fp) { std::cout<<"Open file failed"<<std::endl; return 0; } char *buf = (char *)malloc(30000); char tmp[1025]; //memset(buf, 0, ); memset(tmp, 0, sizeof(tmp)); int rc = 0; while( (rc = fread(tmp,sizeof(unsigned char), 1024,fp)) != 0 ) { memcpy(buf, tmp, 1024); std::cout<<"read once"<<std::endl; memset(tmp, 0, sizeof(tmp)); } #endif //std::string tmp1(buf); //buffer = tmp1; std::cout<<"buffer size="<<buffer.size()<<std::endl; decoded = decompress_gzip(buffer); //UncompressData( const Byte* abSrc, int nLenSrc, Byte* abDst, int nLenDst ) //UncompressData((const Byte*)buf, , , ); std::cout<<decoded; // free(buf); return 0; }