简体   繁体   English

在C中使用OpenSSL接收http响应消息

[英]Receive http response messages using OpenSSL in C

I have some problems when trying to receive http response message of a website. 尝试接收网站的http响应消息时遇到一些问题。
This is my function: 这是我的功能:

void Reveive_response(char *resp, SSL *ssl) {

    const int BUFFER_SIZE = 1024;
    char response[1048576];
    char *buffer = NULL;            // to read from ssl
    char *check = (char *) malloc(BUFFER_SIZE*sizeof(char));
    int bytes;                      // number of bytes actually read
    int received = 0;               // number of bytes received

    buffer = (char *) malloc(BUFFER_SIZE*sizeof(char));     // malloc
    memset(response, '\0', sizeof(response));               // response
    assign = '\0'
    do{
        memset(buffer, '\0', BUFFER_SIZE);          // empty buffer
        bytes = SSL_read(ssl, buffer, BUFFER_SIZE);
        if (bytes < 0) {
            printf("Error: Receive response\n");
            exit(0);
        }
        if (bytes == 0) break;
        received += bytes;
        printf("Received...%d bytes\n", received);
        strncat(response, buffer, bytes);   // concat buffer to response
    } while (SSL_pending(ssl));             // while pending
    response[received] = '\0';
    printf("Receive DONE\n");
    printf("Response: \n%s\n", response);
    free(buffer);
    strcpy(resp, response);                 // return via resp

}

When I call the function, it seems like the response message is not complete. 当我调用该函数时,响应消息似乎未完成。 Like this: 像这样:

Received...1014 bytes
Received...1071 bytes
Receive DONE
Response: 
HTTP/1.1 200 OK
<... something else....>
Vary: Accept-Encoding
Content-Type: text/html
Conne

Then if i call the function again, it returns: 然后,如果我再次调用该函数,它将返回:

Received...39 bytes
Receive DONE
Response:
ction: keep-alive
Content-Length: 0

The field Connection was split. 连接字段已拆分。 Why my function didn't receive all the response message? 为什么我的函数没有收到所有响应消息? I used do while loop inside. 我曾经在里面做过while循环。 Please tell me where did i go wrong? 请告诉我我哪里出问题了? Thank you. 谢谢。

There is nothing wrong. 没有任何错误。 This is simply how TCP works. 这就是TCP的工作原理。 It is a streaming transport, it has no concept of message boundaries. 它是一种流传输,没有消息边界的概念。 There is no 1-to-1 relationship between the number of bytes sent and the number of bytes read. 发送的字节数和读取的字节数之间没有一对一的关系。 Your reading receives arbitrary bytes, which you are then responsible for processing as needed. 您的读数将接收到任意字节,然后由您负责根据需要进行处理。 Keep reading, buffering and parsing the HTTP data as you go, until you discover the end of the response (see RFC 2616 Section 4.4 Message Length for details). 继续读取,缓冲和解析HTTP数据,直到发现响应结束为止(有关详细信息,请参阅RFC 2616第4.4节“消息长度 ”)。 Looping on SSL_pending() is not sufficient (or correct). SSL_pending()上循环是不够的(或正确的)。

In this case, you have to read CRLF-delimited lines one at a time until you reach a CRLF/CRLF pair indicating the end of the response headers, then you need to analyze the headers you have received to know whether a response body is present and how to read it, as it may be in one of several different encoded formats. 在这种情况下,您必须一次读取一个以CRLF分隔的行,直到到达指示响应头结尾的CRLF / CRLF对,然后需要分析收到的头以了解是否存在响应主体以及如何读取,因为它可能是几种不同的编码格式之一。 If present, you can then read the body (decoding it as you go along) until you reach the end of the body as specified by the headers. 如果存在,则可以读取正文(继续进行解码),直到到达标题指定的正文末尾为止。

See the pseudo-code I posted in my answer to the following question: 请参阅我在以下问题的答案中发布的伪代码:

Receiving Chunked HTTP Data With Winsock 使用Winsock接收块状HTTP数据

That said, you really should not be implementing HTTP (let alone HTTPS) manually to begin with. 就是说,您确实不应该一开始就手动实现HTTP(更不用说HTTPS)了。 HTTP is not trivial to implement from scratch, and neither is SSL/TLS for that matter. HTTP是平凡从头开始实施,也不是SSL / TLS对这一问题。 You have dived head-first into a deep well without understand some important basics of network programming and OpenSSL programming. 您已经不了解网络编程和OpenSSL编程的一些重要基础而直接进入了深井。 You should use an existing HTTP/S library instead, such as libcurl , and let it handle the details for you so you can focus on your code's business logic and not its communications logic. 您应该改用现有的HTTP / S库,例如libcurl ,并让它为您处理详细信息,以便您可以专注于代码的业务逻辑而不是其通信逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM