如何计算HTTP多部分"Content-length"标头值?

Mos*_*bin 15 multipart http-content-length content-length http-headers

我读过对"如何计算多部分HTTP请求内容长度?"这一问题的冲突和有些含糊不清的回复.我特别想知道:

  • 计算"Content-length"标题的精确内容范围是多少?
  • CRLF("\ r \n")八位字节序列是否计为一个或两个八位字节?

有人能提供一个明确的例子来回答这些问题吗?

Mos*_*bin 10

下面的实例应该有希望回答这些问题.

使用Google的OAuth 2.0 Playground执行多部分请求

Google的OAuth 2.0 Playground网页是针对Google云端硬盘云执行多部分HTTP请求的绝佳方式.您无需了解有关Google云端硬盘的任何信息 - 我会为您完成所有工作.我们只对HTTP请求和响应感兴趣.但是,如果需要,使用游乐场将允许您尝试使用多部分并回答其他问题.

创建用于上载的测试文件

我创建了一个名为"test-multipart.txt"的本地文本文件,保存在我的文件系统上.该文件大小为34个字节,如下所示:

We're testing multipart uploading!
Run Code Online (Sandbox Code Playgroud)

打开Goog​​le的OAuth 2.0 Playground

我们首先使用网址https://developers.google.com/oauthplayground/在浏览器中打开Goog​​le的OAuth 2.0 Playground :

Google OAuth 2.0 Playground打开屏幕

填写第1步

选择Drive API v2和" https://www.googleapis.com/auth/drive ",然后按"授权API":

为第1步填写的字段

填写第2步

点击"令牌的Exchange授权码":

为第2步填写的字段

填写第3步

这里我们提供所有相关的多部分请求信息:

  • 将HTTP方法设置为"POST"
  • 没有必要添加任何标题,Google的Playground将添加所需的一切(例如,标题,边界序列,内容长度)
  • 请求URI:" https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart "
  • 输入请求正文:这是Google云端硬盘执行分段上传所需的一些元数据JSON.我使用了以下内容:
{"title": "test-multipart.txt", "parents": [{"id":"0B09i2ZH5SsTHTjNtSS9QYUZqdTA"}], "properties": [{"kind": "drive#property", "key": "cloudwrapper", "value": "true"}]}
  • 在"请求正文"屏幕的底部,选择要上载的test-multipart.txt文件.
  • 按"发送请求"按钮

在此输入图像描述

请求和响应

Google的OAuth 2.0 Playground奇迹般地插入所有必需的标题,计算内容长度,生成边界序列,在需要的地方插入边界字符串,并向我们显示服务器的响应: 在此输入图像描述

分析

多部分HTTP请求以200状态代码成功,因此请求和响应是我们可以依赖的好的.谷歌的Playground插入了执行多部分HTTP上传所需的一切.您可以看到"内容长度"设置为352.让我们看一下标题后面的空行之后的每一行:

--===============0688100289==\r\n
Content-type: application/json\r\n
\r\n
{"title": "test-multipart.txt", "parents": [{"id":"0B09i2ZH5SsTHTjNtSS9QYUZqdTA"}], "properties": [{"kind": "drive#property", "key": "cloudwrapper", "value": "true"}]}\r\n
--===============0688100289==\r\n
Content-type: text/plain\r\n
\r\n
We're testing multipart uploading!\r\n
--===============0688100289==--

有九(9)行,我已经在前八(8)行的每一行的末尾手动添加了"\ r \n"(出于可读性原因).以下是每行中八位字节(字符)的数量:

  1. 29 +'\ r \n'
  2. 30 +'\ r \n'
  3. '\ r\N'
  4. 167 +'\ r \n'
  5. 29 +'\ r \n'
  6. 24 +'\ r \n'
  7. '\ r\N'
  8. 34 +'\ r \n'(虽然'\ r \n'不是文本文件的一部分,Google会插入它)
  9. 31

八位字节的总和是344,并且将每个'\ r \n'视为单个一个八位字节序列给出了令人垂涎的内容长度344 + 8 = 352.

摘要

总结一下这些发现:

  1. 多部分请求的"内容长度"是从标题部分的空行之后的边界序列的第一个字节计算的,并且继续直到并包括最后边界序列的最后一个连字符.
  2. 无论您运行的操作系统如何,'\ r \n'序列都应计为一(1)个八位字节,而不是两个.

  • `考虑每个'\ r \n'作为单个一个八位字节` - 这是完全错误的.`Content-Length`是标题后面的字节数.那个"打开Goog​​le的OAuth 2.0 Playground"显然有一个错误,可能会使用'\n'而不是'\ r \n'来表示新行. (6认同)

Mar*_*ham 8

您的计算Content-Length方式不依赖于有效载荷的状态代码或媒体类型; 它是线上的字节数.因此,编写多部分响应,计算字节数(并CRLF计为两个),并将其用于Content-Length.

请参阅:http://httpwg.org/specs/rfc7230.html#message.body.length