Beispiel #1
0
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;
}