文件断点续传的协议-Tus 协议

核心协议

核心协议描述了如何恢复中断的上传。假定您已经有一个上载URL,通常是通过 Creation扩展创建的

所有的客户端和服务器必须实现核心协议。

该规范未描述URL的结构,因为这留给特定的实现方式来决定。本文档中显示的所有URL仅用于示例目的。

另外,身份验证和授权的实现留给服务器决定。

HEAD请求用于确定在上载应持续的偏移量。

下面的示例显示了100字节上传的继续,该上传在传输70字节后中断。

请求:

HEAD /files/24e533e02ec3bc40c387f1a0e460e216 HTTP/1.1
Host: tus.example.org
Tus-Resumable: 1.0.0

响应:

HTTP/1.1 200 OK
Upload-Offset: 70
Tus-Resumable: 1.0.0

给定偏移量后,客户端将使用该PATCH方法恢复上传:

请求:

PATCH /files/24e533e02ec3bc40c387f1a0e460e216 HTTP/1.1
Host: tus.example.org
Content-Type: application/offset+octet-stream
Content-Length: 30
Upload-Offset: 70
Tus-Resumable: 1.0.0

[remaining 30 bytes]

响应:

HTTP/1.1 204 No Content
Tus-Resumable: 1.0.0
Upload-Offset: 100

header信息

上传偏移

Upload-Offset请求和响应首部指示一个字节的资源内的偏移。该值必须是非负整数。

上传长度

Upload-Length请求和响应首部以字节指示整个上载的大小。该值必须是非负整数。

Tus版本

Tus-Version响应报头必须是逗号分隔的由服务器支持的协议版本的列表。该列表必须按服务器的首选项进行排序,其中第一个是首选列表。

Tus可恢复

Tus-Resumable报头必须被包含在每个请求中和除了响应OPTIONS请求。该值必须是客户端或服务器使用的协议版本。

如果服务器不支持客户端指定的版本,则它必须以412 Precondition Failed状态进行响应,并且必须Tus-Version在响应中包含 标头。另外,服务器不得处理该请求。

Tus扩展

Tus-Extension响应报头必须是逗号分隔的由所述服务器所支持的扩展名列表。如果不支持扩展,则Tus-Extension 必须省略头。

Tus最大限制

Tus-Max-Size响应报头必须是一个非负整数,其表示以字节为单位的整个上载所允许的最大尺寸。如果存在已知的硬限制,则服务器应设置此标头。

X-HTTP-方法重写

如果X-HTTP-Method-Override请求头出现,则请求头必须为字符串,服务器必须将其解释为请求的方法。请求的实际方法必须被忽略。如果客户端的环境不支持PATCH或DELETE方法,则应该使用该头。

要求

HEAD

服务器必须始终Upload-OffsetHEAD请求的响应中包含标头 ,即使偏移量为0,或者上传已被视为已完成。如果知道上传的大小,则服务器必须Upload-Length在响应中包含 标头。如果未找到资源,服务器将返回要么404 Not Found410 Gone403 Forbidden状态没有Upload-Offset头。

服务器必须通过将Cache-Control: no-store标头添加到响应中来防止客户端和/或代理缓存响应。

PATCH

服务器应该接受PATCH针对任何上传URL的请求,并以Upload-Offset报头指定的给定偏移量应用消息中包含的字节 。所有PATCH请求都必须使用 Content-Type: application/offset+octet-stream,否则服务器应该返回一个415 Unsupported Media Type状态。

Upload-Offset头的值必须等于当前资源的偏移。为了实现并行上传, 可以使用Concatenation扩展。如果偏移量不匹配,则服务器必须在409 Conflict不修改上传资源的情况下以状态响应。

客户端应在单个PATCH 请求中发送上载的所有剩余字节,但在需要时,也可以连续使用多个小请求。这些情况的一个示例 是使用Checksum扩展名。

服务器必须PATCH204 No Content状态确认成功的请求 。它必须包括Upload-Offset包含新偏移量的头。新的偏移量必须是PATCH 请求之前的偏移量与当前PATCH请求期间接收和处理或存储的字节数之和。

如果服务器收到PATCH针对不存在资源的请求,则应返回404 Not Found状态。

客户端和服务器均应尝试可预测地检测和处理网络错误。他们可以通过检查读/写套接字错误以及设置读/写超时来做到这一点。超时应该通过关闭基础连接来处理。

服务器应始终尝试存储尽可能多的接收数据。

OPTIONS

一个OPTIONS请求可以用来收集有关服务器当前配置的信息。由204 No Content200 OK状态指示的成功响应必须包含Tus-Version标题。它可以包含Tus-ExtensionTus-Max-Size标头。

客户端不应该Tus-Resumable在请求中包含头,服务器必须忽略头。

本示例阐明了OPTIONS请求的响应。响应中使用的版本是1.0.0Server还可以处理0.2.2和的版本0.2.1。允许上传的文件总大小最大为1GB,并且启用了创建过期扩展名。

请求:

OPTIONS /files HTTP/1.1
Host: tus.example.org

响应:

HTTP/1.1 204 No Content
Tus-Resumable: 1.0.0
Tus-Version: 1.0.0,0.2.2,0.2.1
Tus-Max-Size: 1073741824
Tus-Extension: creation,expiration

协议扩展

鼓励客户端和服务器实施尽可能多的扩展。功能检测应该通过客户端发送 OPTIONS请求和服务器响应Tus-Extension头来实现。

创建

客户端和服务器应该实现上传创建扩展。如果服务器支持此扩展名,则必须添加creationTus-Extension 标题中。

POST请求用于创建新的上传资源。的 Upload-Length报头指示以字节为单位的整个上载的大小。

请求:

POST /files HTTP/1.1
Host: tus.example.org
Content-Length: 0
Upload-Length: 100
Tus-Resumable: 1.0.0
Upload-Metadata: filename d29ybGRfZG9taW5hdGlvbl9wbGFuLnBkZg==,is_confidential

响应:

HTTP/1.1 201 Created
Location: https://tus.example.org/files/24e533e02ec3bc40c387f1a0e460e216
Tus-Resumable: 1.0.0

新资源具有隐式偏移量,0该偏移量允许客户端使用核心协议执行实际的上载。

header

上传延迟时间

Upload-Defer-Length请求和响应标头指示上载的大小不是目前已知的,并且将在稍后传送。其值必须为1。如果上传的长度没有延迟,则必须省略此标头。

上传元数据

Upload-Metadata请求和响应首部必须由一个或多个以逗号分隔的键-值对。键和值必须用空格分隔。键不得包含空格和逗号,且不得为空。密钥应该是ASCII编码的,值必须是Base64编码的。所有密钥必须唯一。该值可以为空。在这些情况下,通常会把键和值分开的空格可能会被忽略。

由于元数据可以包含任意二进制值,因此服务器在将它们用作头值之前应仔细验证元数据值或清理它们,以避免头走私。

要求

POST

客户端必须POST针对已知的上传创建URL发送请求,以请求新的上传资源。该请求必须包含以下标头之一:

a)Upload-Length以字节为单位指示整个上传的大小。

b)Upload-Defer-Length: 1如果当时未知上传大小。一旦知道了,客户端必须Upload-Length在下一个PATCH请求中设置头。设置后,长度不得更改。只要上传的长度未知,服务器必须Upload-Defer-Length: 1在对HEAD请求的所有响应中 设置。如果Upload-Defer-Length标头包含任何其他值,1则服务器应返回一个400 Bad Request状态。

如果服务器支持延迟长度,则必须添加creation-defer-lengthTus-Extension报头中。

客户端可以提供Upload-Metadata标题,以将其他元数据添加到上传创建请求中。服务器可以决定忽略或使用该信息来进一步处理该请求或拒绝它。如果上载包含其他元数据,则对HEAD请求的响应必须包括Upload-Metadata标头及其在客户端在创建过程中指定的值。

如果上传的长度超过最大长度(可以使用Tus-Max-Size标题指定),则服务器务必以413 Request Entity Too Large状态响应 。

服务器必须以201 Created 状态确认成功的上传创建。服务器必须将Location头设置为创建资源的URL。该URL可以是绝对的或相对的。

客户端必须使用核心协议执行实际的上传。

上传创建

客户端可以使用带有上载的创建扩展,在初始创建请求中包括上载的一部分。

如果服务器支持此扩展,则它必须通过creation-with-uploadTus-Extension标头中包括来进行宣传 。此外,此扩展直接取决于Creation扩展。因此,如果服务器不提供创建扩展名,则它也绝不能提供创建上载扩展名。

客户端可以在POST请求的主体中包含全部或部分上传数据。在这种情况下,适用与PATCH请求和响应相似的规则。客户端必须包括 Content-Type: application/offset+octet-stream标题。服务器应该接受尽可能多的字节,并且必须Upload-Offset在响应中包含头,并且必须在应用接受的字节后将其值设置为上载的偏移量。

如果客户端要使用此扩展名,则客户端应在发送POST请求之前验证服务器是否支持该扩展名。另外,客户端应Expect: 100-continue在请求中包含标头,以便在尝试传输第一个块之前,先从服务器接收有关服务器是否接受创建请求的早期反馈。

非空POST请求用于创建新的上传资源。Upload-Offset响应中的 标头指示已接受多少数据。

请求:

POST /files HTTP/1.1
Host: tus.example.org
Content-Length: 5
Upload-Length: 100
Tus-Resumable: 1.0.0
Content-Type: application/offset+octet-stream

hello

响应:

HTTP/1.1 201 Created
Location: https://tus.example.org/files/24e533e02ec3bc40c387f1a0e460e216
Tus-Resumable: 1.0.0
Upload-Offset: 5

过期

一旦过期,服务器可以删除未完成的上传。为了向客户端指示此行为,服务器必须添加expirationTus-Extension报头。

未完成的上载直到中指定的时间才可用Upload-Expires。在此日期之后,无法恢复上传。

请求:

PATCH /files/24e533e02ec3bc40c387f1a0e460e216 HTTP/1.1
Host: tus.example.org
Content-Type: application/offset+octet-stream
Content-Length: 30
Upload-Offset: 70
Tus-Resumable: 1.0.0

[remaining 30 bytes]

响应:

HTTP/1.1 204 No Content
Upload-Expires: Wed, 25 Jun 2014 16:00:00 GMT
Tus-Resumable: 1.0.0
Upload-Offset: 100

header

上传到期

Upload-Expires响应报头指示之后将未完成上传期满的时刻。服务器可能希望在给定的时间段后删除不完整的上载,以防止废弃的上载占用额外的存储空间。客户端应使用此标头来确定上传是否仍然有效,然后再尝试继续上传。

PATCH如果上传即将过期,则此标头必须包含在每个响应中。如果在创建时已知道到期时间,则Upload-Expires 必须在对初始POST请求的响应中包含头。它的值可能会随时间变化。

如果客户端确实尝试恢复已被服务器删除的上载,则服务器应以404 Not Found410 Gone状态响应。如果服务器跟踪过期的上传,则应使用后一种。在这两种情况下,客户端都应开始新的上传。

Upload-Expires标头的值必须为 RFC 7231日期时间格式。

校验

客户端和服务器可以实现并使用这个扩展来验证每个PATCH请求的数据完整性。如果支持,则服务器必须添加checksumTus-Extension标题中。

客户可以Upload-ChecksumPATCH请求中包含头。一旦收到整个请求,服务器必须使用指定的算法根据提供的校验和来验证上传的块。根据结果,服务器可以使用以下状态代码之一进行响应:1)400 Bad Request如果服务器不支持校验和算法,2)460 Checksum Mismatch如果校验和不匹配,或者3)204 No Content如果校验和匹配并且数据处理成功。在前两种情况下,必须丢弃上传的块,并且不得更新上传及其偏移量。

服务器必须至少支持由标识的SHA1校验和算法sha1。校验和算法的名称必须仅由ASCII字符组成,但修改为不包括大写字符。

Tus-Checksum-Algorithm报头必须被包含在响应于一个 OPTIONS请求。

如果不能在上传开始时计算出哈希值,则可以将其作为预告片包含在内。如果服务器可以处理预告片,则必须通过将其添加checksum-trailerTus-Extension标头中来宣布此行为。尾部,也称为尾部标头,是在请求主体已经被发送之后发送的标头。遵循 RFC 7230,必须使用Trailer标头宣布它们,并且仅允许在分块传输中使用。

header

Tus-Checksum-算法

Tus-Checksum-Algorithm响应报头必须是一个逗号分隔的由服务器支持的校验和算法列表。

上传校验

Upload-Checksum请求报头包含关于当前体有效载荷的校验和信息。头必须由所用校验和算法的名称和以空格分隔的Base64编码校验和组成。

要求

OPTIONS /files HTTP/1.1
Host: tus.example.org

回应

HTTP/1.1 204 No Content
Tus-Resumable: 1.0.0
Tus-Version: 1.0.0
Tus-Extension: checksum
Tus-Checksum-Algorithm: md5,sha1,crc32

要求

PATCH /files/17f44dbe1c4bace0e18ab850cf2b3a83 HTTP/1.1
Content-Length: 11
Upload-Offset: 0
Tus-Resumable: 1.0.0
Upload-Checksum: sha1 Kq5sNclPz7QV2+lfQIuc6R7oRu0=

hello world

回应

HTTP/1.1 204 No Content
Tus-Resumable: 1.0.0
Upload-Offset: 11

客户端终止

该扩展定义了客户端终止已完成和未完成的上传的方式,从而允许服务器释放已使用的资源。

如果服务器支持此扩展,则必须通过添加terminationTus-Extension标头中来宣布 。

要求

DELETE

当服务器收到一个DELETE现有的上传请求时,应该释放相关资源,并且必须以204 No Content确认上传已终止的状态进行响应。对于以后对该URL的所有请求,服务器应以404 Not Found410 Gone状态响应。

请求:

DELETE /files/24e533e02ec3bc40c387f1a0e460e216 HTTP/1.1
Host: tus.example.org
Content-Length: 0
Tus-Resumable: 1.0.0

响应:

HTTP/1.1 204 No Content
Tus-Resumable: 1.0.0

续传

此扩展名可用于将多个上传连接为一个上传,从而使客户端可以执行并行上载和上载不连续的块。如果服务器支持此扩展名,则必须添加concatenationTus-Extension标题中。

部分上传代表文件的一部分。它是通过在Upload-Concat: partial使用“创建”扩展名创建新上传文件时包含标头来 构造的 。多个部分上载按指定顺序串联为最终上载。服务器不应处理这些部分上载,直到它们串联起来形成最终上载。最终上传的长度必须是所有部分上传的长度的总和。

为了创建新的最终上传,客户端务必将Upload-Concat标头添加到上传创建请求中。值后必须final紧跟一个分号和需要连接的部分上传URL的空格分隔列表。部分上传内容必须按照列表中指定的顺序进行串联。所有所有相应的部分上载完成后,都应发生此串联请求。客户端不得Upload-Length在最终的上载创建中包含标头。

当部分上传仍在进行时,客户端可以发送连接请求。服务器必须通过添加concatenation-unfinishedTus-Extension标头中明确宣布此功能 。

创建新的最终上传文件时,部分上传文件的元数据不得转移到新的最终上传文件中。所有的元数据都应使用Upload-Metadata标头包含在连接请求中。

连接后,服务器可以删除部分上传。但是,它们可以多次使用以形成最终资源。

服务器必须以最终上传URL的403 Forbidden状态响应PATCH请求,并且绝不能修改最终或部分上传。

Upload-Offset 除非连接成功完成,对HEAD的最终上传请求的响应不应包含标头。成功连接后,将Upload-OffsetUpload-Length必须设置和它们的值必须相等。Upload-Offset没有为最终上传定义串联之前的标头值。

对HEAD要求部分上传的响应必须包含Upload-Offset标头。

Upload-Length必须被包含标头如果最终资源的长度可以在该请求的时间来计算。HEAD针对部分上传或最终上传的请求的响应必须包括Upload-Concat标头及其在上传创建请求中收到的值。

header

上传Concat

Upload-Concat请求和响应首部必须在两个部分和最终的上载创建请求来设置。它指示上传是部分上传还是最终上传。如果上传是部分上传,则标头值务必为partial。在最终上传的情况下,其值必须final后跟一个分号和要连接的部分上传URL的空格分隔列表。部分上传URL可以是绝对URL或相对URL,并且不得包含RFC 3986中定义的空格。

在以下示例中,为便于阅读,省略了HostTus-Resumable标头,尽管规范要求它们。在开始时,创建了两个部分上传:

POST /files HTTP/1.1
Upload-Concat: partial
Upload-Length: 5

HTTP/1.1 201 Created
Location: https://tus.example.org/files/a
POST /files HTTP/1.1
Upload-Concat: partial
Upload-Length: 6

HTTP/1.1 201 Created
Location: https://tus.example.org/files/b

现在,您可以使用PATCH 请求将数据上传到两个部分资源:

PATCH /files/a HTTP/1.1
Upload-Offset: 0
Content-Length: 5

hello

HTTP/1.1 204 No Content
PATCH /files/b HTTP/1.1
Upload-Offset: 0
Content-Length: 6

 world

HTTP/1.1 204 No Content

在第一个请求中,该字符串hello已上传,而第二个文件现在包含带有前导空格的“ world”。

下一步是创建由两个较早生成的部分上传组成的最终上传。在以下请求中,未Upload-Length显示任何标头。

POST /files HTTP/1.1
Upload-Concat: final;/files/a /files/b

HTTP/1.1 201 Created
Location: https://tus.example.org/files/ab

现在,最终资源的长度为11个字节,由字符串组成 hello world

HEAD /files/ab HTTP/1.1

HTTP/1.1 200 OK
Upload-Length: 11
Upload-Concat: final;/files/a /files/b

常问问题

常见问题解答可从https://tus.io/faq.html在线获得。

实现:

golang: https://github.com/tus/tusd

php: https://github.com/ankitpokhrel/tus-php

原文: https://tus.io/protocols/resumable-upload.html

本文基于谷歌翻译

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268