为啥http post响应在响应末尾添加随机字符

Posted

技术标签:

【中文标题】为啥http post响应在响应末尾添加随机字符【英文标题】:why does an http post response add random characters at the end of response为什么http post响应在响应末尾添加随机字符 【发布时间】:2021-12-27 02:01:57 【问题描述】:

我正在使用此 Web 服务器,但遇到了一个小问题。当客户端向我的 C web 服务器发送一个 post 请求时,最后总是有随机字符。末尾的随机字符数量各不相同,但末尾总是有字符。我尝试使用 content-length 标头来确保我只读取了一定数量的字节,但这仍然不能解决它。这是我得到的响应示例:

sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
Origin: http://localhost
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

rad1=on&rad2=on&rad3=on&rad4=on7

(我知道这不是完整的请求,但出于字符串操作的原因我切断了一些请求)

这是我用于读取客户端回复的代码:

readSock = read(acceptSock, recvLine, sizeof(recvLine)-1);
strcat(fullResp, recvLine);

if (readSock < 0) 
    printf("readSock error\n");

    memset(fileDir, 0, 255);
    memset(recvLineGET1, 0, 70);
    memset(httpResponseReport, 0, 1000);
    memset(recvLineGET, 0, 60);
    memset(fileLine, 0, 1);
    memset(httpResponse, 0, 1000);

    close(acceptSock);
    return NULL;



if ((endOfPost = strstr(fullResp, "\r\n\r\n")) != NULL) 

    postContentLength = strstr(fullResp, "Content-Length:");
    if (postContentLength != NULL) 
        strcpy(tempPost, postContentLength);

        finalPostLength = strchr(tempPost, ' ');

        contentLen = atoi(finalPostLength);
        printf("contentLength: %d\n", contentLen);


        char tempFull[contentLen];
        readSock = read(acceptSock, tempFull, sizeof(tempFull));
        strcat(fullResp, tempFull);
        printf("final: %s\n", fullResp);
    
    if (strlen(endOfPost) > 4) 
        convertToDB(endOfPost);
    
        

    printf("newline detected\n");
    break;

编辑:我对程序进行了更多调试,发现 tempFull 仅包含部分发布数据。这是我得到的:

d3=on&rad4=onP*?

编辑 2:我还发现 fullResp 包含响应的第一部分,这可能是我得到奇怪字符的原因。也许是我从套接字中读取的内容过多

【问题讨论】:

我们需要一个完整的minimal reproducible example 才能完整回答,但很可能您使用的是未正确 NUL 终止的字符串。例如,readSock = read(acceptSock, tempFull, sizeof(tempFull)); 不会在 tempFull 中生成有效的 NUL 终止字符串。它是 ascii 数据,但不是 C 字符串。您需要自己 NUL 终止缓冲区。 @kaylum,我如何 null 终止字符串? tempFull[readSock] = '\0'; @Barmar,但不会 read() 只是覆盖空字符吗?另外,我无法初始化具有预设大小的变量。 您在 read() 之后执行此操作,然后再调用 strcat() 【参考方案1】:

我找到了解决方案。我基本上只是将所有内容复制到 fullResp 变量,然后使用 strstr() 在 fullResp 中找到 \r\n\r\n,之后我仅将 contentLen 指定的数量加上 4 复制到最终的 post body 变量中(加上 4 来读取 \r\n\r\n并阅读全文)。

这是我添加的更新部分:

char tempFull[contentLen];
readSock = read(acceptSock, tempFull, sizeof(tempFull)-1);
strcat(fullResp, tempFull);
refindBody = strstr(fullResp, "\r\n\r\n");
strncpy(finalBody, refindBody, contentLen+4);

printf("finalBody: %s\n", finalBody);

【讨论】:

以上是关于为啥http post响应在响应末尾添加随机字符的主要内容,如果未能解决你的问题,请参考以下文章

如果请求和响应的 uri 相同,为啥 Microsoft Edge 在调用 POST/REDIRECT/GET 方法时发送空的 http-referer?

为啥在 Internet Explorer 中未收到 POST 响应数据?

xml 响应 http post - 将 request.inputstream 转换为字符串 - asp.net

为啥 Fetch API 调用不返回响应标头?

当我通过 POST 发送大于 20MB 的视频文件时,为啥 json 响应为 NULL?

Fiddler script 获取http响应和post的请求body数据