问题 HTTP部分上传,恢复上传的标准方法


我正在开发http客户端/服务器框架,并寻找处理部分上传的正确方法(与使用带有Range标头的GET方法的下载相同)。

但是,HTTP PUT不打算恢复。 我知道,PATCH方法不接受Range标头。

有没有办法通过HTTP标准处理这个(不使用扩展标题或其他)?

提前致谢。


1212
2018-01-07 10:32


起源

请参阅@ btimby的回答 内容范围和范围标题之间的区别?。 - CodeCaster
谢谢你的评论。我看到了关于差异和答案的问题。但是,部分PUT并不清楚,因为有些rfcs说带有PUT的Content-range标头是不可接受的。关于PATCH方法,我没有看到任何关于使用Content-Range的信息。 - Андрей Москвичёв
该规范并未禁止它,但您必须查阅服务器的手册,了解它是否实现它。您可能必须编写自定义代码或配置,具体取决于您的服务器软件和版本。 - CodeCaster
我正在从头开始编写http客户端和服务器。当然,我可以使用一些非标准扩展,但如果有一种标准方式,使用它总是更好。 - Андрей Москвичёв
然后解释你想要做什么。如果您希望您的客户支持它,您必须这样做 知道 不知何故,服务器实现它。是你的实际问题吗? “如何检测HTTP服务器支持部分上传使用 Content-Range 头”?如果您希望服务器支持它,请执行它。 - CodeCaster


答案:


我认为部分上传没有标准:

  • 未明确禁止内容范围内的请求 RFC2616 (http),但是措辞也将其称为响应头,其响应于范围请求而被使用
  • 虽然您可以使用PATCH方法来更新现有资源(例如,添加更多字节),但它与部分上载不同,因为所有不完整资源都可用

如果你看看Dropbox,谷歌驱动器等的协议,他们都会推出自己的协议,以便在多个块中传输单个文件。恢复上传所需的是

  • 解决不完整上传的方法。普通URL可以处理完整的资源,而不是部分资源,我知道部分资源没有标准。
  • 一种查找上传当前状态的方法,也可能是该部分的校验和,以确保本地文件没有改变。这可以通过WebDAV PROPFIND方法提供(一旦你能够解决不完整的资源:)
  • 一种上传块的方法。这里可以使用PATCH和内容范围标题。 mod_dav似乎允许PUT使用内容范围标题(参见 http://www.gossamer-threads.com/lists/apache/users/432346
  • 一旦资源完成就发布资源的方法,或者预先定义完整资源的方法(例如资源大小,校验和......)

9
2018-01-07 17:40



HTTP规范现在不幸地禁止为PUT请求明确使用Contant-Range标头,这本来是最简单和最干净的解决方案。 - Piranna
有 tus.io “基于HTTP的可恢复上传的新开放协议” - jrc


使用Range xxxx-yyyy标头或带有PUT的Range xxxx-标头来更新文件的一部分。它受Apache支持。

不要被RFC 7231中的语句混淆,即不能使用Content-Range。这是为了防止客户端从服务器接收标头并使用PUT将它们发送回服务器。该警告通知与部分PUT问题无关。


1
2018-04-03 09:44



你有没有提到备份关于该声明的声明 意向 RFC 7231中的声明? - Ajoy Bhatia
不,这只是我对RFC的解释,因为我正在研究使其发挥作用。实际上在那之后我遇到了让Apache正确执行的问题,抱歉。 - Bruce


正如一些评论中所指出的,HTTP规范的较新版本在某种程度上澄清了这一点。每 RFC 7231的4.3.4节

允许PUT在给定目标资源上的原始服务器必须发送   对包含a的PUT请求的400(错误请求)响应   内容范围标题字段([RFC7233]的第4.2节),因为有效载荷   可能是部分内容被错误地作为一个完整的PUT   表示。通过定位a,可以进行部分内容更新   单独识别的资源与状态重叠的部分   更大的资源,或者使用具体的不同方法   为部分更新定义(例如,在中定义的PATCH方法)    [RFC5789])。

不幸的是,讨论范围标题出现在 RFC 7233 或多或少完全关注GET请求,RFC 5789几乎没有定义任何关于PATCH的内容,除了特别不需要传输整个内容(但允许),也不要求它是幂等的(但允许) 。

好的一面是,因为PATCH的定义非常松散,所以它确实适应了相关问题答案中给出的方法(https://stackoverflow.com/a/6711496/7467189):只需将“PUT”更改为“PATCH”。虽然不要求服务器以这种方式解释具有Content-Range头的PATCH请求,但它肯定是一种有效的解释,而不是任何可以依赖于任意服务器或客户端的解释。但在诸如原始问题的情况下,两端的控制都是可用的,这至少是一种明显的方法,并且不违反现行标准。

另外一个考虑因素是Content-Type应该表达正在传输的内容,而不是整个实体的内容类型(RFC在这方面提供了一些示例)。对于以任意块“修补”的内容,这将意味着应用程序/八位字节流,尽管有些情况下客户端和服务器可能更具内容感知并且选择将补丁作为具有更具体定义的实体发送(例如,单页的多页图像格式)。


0
2018-02-02 03:59