如何从POST请求的HTTP正文中提取二进制文件内容?

3

目前,我正在尝试在Windows下使用C++实现一个简单的Web服务器。为了支持文件上传,在我的代码中实现了POST

现在,当一个二进制文件通过IE上传时,文件末尾会添加两个额外的字符0D0A

上传前的文件内容:

enter image description here

上传后的文件内容

enter image description here

这里是一些代码片段

// receive data from http socket
char* orig_buf = buf;
while ( (cnt=recv(m_hSocket, buf, 1, 0)) > 0)
{
    if(*buf++ == '\n')
    {
        *buf = '\0';
        buflen = buf - orig_buf;
        return orig_buf;
    }
}

// save buffer to binary file
std::ofstream ofs(szFilename, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
ofs.write(buf, buflen);

通过 Fiddler,我们发现浏览器添加了 0D 0A

enter image description here

在这个规范中,我们知道应该在Boundary之前添加文件行结束符。然而,第一个问题是:如果文件内容和Boundary之间没有0D 0A怎么办?因为如果二进制文件的内容包含0D 0A,很难区分0D 0A是否属于二进制文件。
根据@CodeCaster的建议,在此处添加帖子消息头。

enter image description here

问题2: 如何从HTTP主体中提取二进制文件内容?
通过Content-Length?还是通过Boundary?并消除0D 0A

0D 0A 是典型的 Windows 格式行尾。您在下载后意外在结尾插入了一个吗? - πάντα ῥεῖ
不,在函数“recv”中调试时,“0D 0A”已经在数据缓冲区中,当从套接字接收数据时。 - zangw
在POST头中是否有“Content-Length”可用?如果是,您应该仅接受标头中指定的字节数。 - Csq
@zangw 看起来更像是服务器端的问题。 - πάντα ῥεῖ
1
content-Length 是 HTTP 主体的长度,包括文件内容、边界、内容分发等。 - zangw
你能展示相关的请求头,比如 Content-type 吗? - CodeCaster
1个回答

0
如果文件内容和边界之间没有0D 0A会怎么样?因为如果二进制文件的内容包含0D 0A,很难区分0D 0A是属于二进制文件还是其他部分。
用户代理必须确保选择一个在有效载荷中不存在的边界。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接