【问题标题】:When making HTTP raw POST request multipart/form-data with cURL PHP, how to properly set the Content-Length header?使用 cURL PHP 发出 HTTP 原始 POST 请求 multipart/form-data 时,如何正确设置 Content-Length 标头?
【发布时间】:2014-12-26 23:22:07
【问题描述】:

我有一个问题,我需要在 PHP 中使用 curl 设置 Content-Length 标头以发出 multipart/form-data POST HTTP 请求。

例如,我有一个 PHP 脚本,它通过 curl POST 将图像上传到服务器,请求的 HTTP 实体正文的内容如下所示:

------Boundary123
Content-Disposition: form-data; name="files[]"; filename="image.png"
Content-Type: image/png

... contents of image.png
------Boundary123--

我会这样做:

 $bodiEntity = "--".$boundary."\r\n".
               'Content-Disposition: form-data; name="files[]"; filename="'.$fileName.'"'."\r\n".
               'Content-Type: img/png'."\r\n\r\n".
                file_get_contents($fileName)."\r\n". // binary contents of file
                "--".$boundary."--\r\n";

但是,我应该为 Content-Length 标头设置哪个值?我知道,它是实体体的字节数,但是我应该如何处理“\r\n”呢? 我的意思是,如果我这样做 strlen("\r\n") 我得到 2 作为返回值,但我想在处理发送 multipart/form-data 时它应该是 1(意思是)一个字节,对吗?

所以我应该只使用strlen() 来处理边界字符串、Content-Disposition、Content-Type 等字符串,并将 "\r\n" 计数为单个字符,并使用filesize() 来获取文件的文件大小字节,然后将所有值相加以获得 Content-Length 标头的最终值?还是我应该像 PHP 一样将 "\r\n" 计为 2 个字符?

感谢关注!

【问题讨论】:

  • cURL 不是自动为你做的吗?
  • 我不知道,是吗?

标签: php curl multipartform-data content-length


【解决方案1】:

将“\r\n”计为两个字节。 CRLF 对是两个字节长。整个身体包括

 - the boundary prefix ("--"), 
 - boundary, 
 - the content bytes, 
 - the interim boundaries and their prefixes, 
 - the final boundary prefix, 
 - boundary and boundary post fix,

所有内容都应计入内容长度。

至于内容长度。从 HTTP 1.1 开始,没有为多部分请求中的每个文件部分定义内容长度。

但是,总的 Content-length 标头应在请求的开头定义。 您不妨阅读RFC 7230 第 3.3.2 节。它由一位主要的 Web 和 HTTP 标准作者 Roy Thomas Fielding 编写。

但是还有许多其他方式可以将文件作为请求发送,它不一定需要在基于边界的多部分请求中进行限制。 POST 方法本身的另一个机制是原始内容类型请求。内容在请求中的标头结束后立即传输,后跟一个空行(读取“\r\n”)。

其他机制包括也可以以类似方式工作的 PUT 请求。从技术上讲,这两者之间存在很大差异,尽管我认为详细介绍该问题与该问题无关,因此我将跳过它。

【讨论】:

    猜你喜欢
    • 2021-04-17
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 2020-12-06
    • 2019-04-27
    • 1970-01-01
    • 2021-08-28
    相关资源
    最近更新 更多