C/C++socket construction HTTPS gzip request, response message 'inflate ERROR: ZDATA_RROR' during decompression process
why The message returned by the server is abnormal, and some websites request to add "Accept-Encoding: gzip" to the message, but the returned result cannot be correctly decompressed. Could you please help me take a look, experts
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <zlib.h>#include <arpa/inet.h>#include <unistd.h>#include <zlib.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/fcntl.h>#include <netdb.h>#include <openssl/ssl.h>#include <openssl/err.h>#include <netinet/in.h>#define BUFFER 500000int decompress_string(const char* input, uLong input_length, char* output, uLong *output_length) { printf("input_length=%d\n",input_length); z_stream stream={0}; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; if (inflateInit2(&stream,15 + 32) != Z_OK) { fprintf(stderr, "ERROR: inflateInit call error\n"); return -1; } stream.next_in = (Bytef*)input; stream.avail_in = input_length; stream.next_out = (Bytef*)output; stream.avail_out = *output_length; int ret = Z_OK; while (stream.avail_in != 0 && ret == Z_OK) { ret = inflate(&stream, Z_SYNC_FLUSH); if (ret == Z_STREAM_END) { break; } else if (ret != Z_OK) { if (ret == Z_DATA_ERROR) { fprintf(stderr, "Z_DATA_ERROR while decompressing data\n"); } else if (ret == Z_MEM_ERROR) { fprintf(stderr, "Z_MEM_ERROR while decompressing data\n"); } if (inflateEnd(&stream) != Z_OK) { fprintf(stderr, "ERROR: inflateEnd call error\n"); return -1; } } if (stream.avail_out == 0) { printf("stream.avail_out\n"); stream.next_out = (Bytef*)(output + stream.total_out); stream.avail_out = *output_length - strlen(output); } } *output_length = strlen(output); if (inflateEnd(&stream) != Z_OK) { fprintf(stderr, "ERROR: inflateEnd call error\n"); return -1; } return 0;}int main() { int sock; struct hostent *host; struct sockaddr_in server; char *message, buffer[BUFFER]; SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { ERR_print_errors_fp(stderr); exit(1); } const char *hostname = "www.baidu.com"; if ((host = gethostbyname(hostname)) == NULL) { fprintf(stderr, "No such host\n"); return 0; } sock = socket(AF_INET, SOCK_STREAM, 0); server.sin_addr = *((struct in_addr *)host->h_addr_list[0]); server.sin_family = AF_INET; server.sin_port = htons(443); if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) { fprintf(stderr, "Connection Failed\n"); return 0; } SSL *ssl = SSL_new(ctx); if (ssl == NULL) { ERR_print_errors_fp(stderr); exit(1); } SSL_set_fd (ssl, sock); long ssl_certificate_verify = SSL_get_verify_result(ssl); if (ssl_certificate_verify == X509_V_OK) { fprintf(stdout,"ssl_certificate_verify success\n"); } else { fprintf(stderr,"Could not connect to server\n"); return 0; } if (SSL_connect(ssl) != 1) { ERR_print_errors_fp(stderr); exit(1); } char *request = "GET / HTTP/1.1\r\n""Host: www.baidu.com\r\n""Accept-Encoding: gzip\r\n" // "accept-language:en-US,en;q=0.9\r\n" // "cache-control:max-age=0\r\n" // "connection:keep-alive\r\n" // "if-modified-since:Thu, 17 Oct 2019 07:18:26 GMT\r\n" // "if-none-match:'3147526947'\r\n" // "upgrade-insecure-requests:1\r\n""User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36\r\n""Connection: close\r\n\r\n"; SSL_write(ssl, request, strlen(request)); int bytes; int response_len=0; char response_data[500000]={0}; while ((bytes = SSL_read(ssl, buffer, sizeof(buffer))) > 0) { memcpy(response_data+response_len,buffer,bytes); response_len += bytes; } size_t index; for(int i=3;i<response_len;i++){ if(response_data[i-3] == '\r'&& response_data[i-2] == '\n'&& response_data[i-1] == '\r'&& response_data[i] == '\n'){ index=i; break; } } char response_head[2000]={0}; memcpy(response_head,response_data,index); for(int i=0;i<index;i++){ printf("%c" ,response_head[i]); } printf("\n"); uLong output_length_compress =response_len-index; char *output_compress=(char*)malloc(output_length_compress); memset(output_compress,0,output_length_compress); memcpy(output_compress,response_data+index+1,output_length_compress-1); for(int i=0;i<output_length_compress-1;i++){ printf("%c" ,output_compress[i]); } printf("\n"); uLong *input_length_decompress = (uLong*)malloc(sizeof(uLong)); *input_length_decompress = output_length_compress*10; char* output_decompress = (char*)malloc(output_length_compress*10); if (decompress_string(output_compress,output_length_compress-1,output_decompress,input_length_decompress) == 0){ printf("Compressed string: %s\n", output_decompress); } SSL_free(ssl); SSL_CTX_free(ctx); close(sock); return 0;}
The result of not configuring 'Accept Encoding: gzip' is normal