有多少次你试图上传一个大文件,却发现它由于网络问题而失败!当再次重新上载文件时,上传将从头开始:( Not cool at all。这就是可恢复文件上传器派上用场的地方。
可恢复的文件上传器允许文件上传从它停止的地方开始,而不是重新上传整个文件。
在本系列教程中,我们将学习如何使用 tus 协议在 Go 中创建可恢复的文件上传服务器和客户机。本教程不是 tus 协议的精确实现,而是一个简化版本。本教程足以使用 Go创建一个可恢复的文件上传器。我们将在接下来的教程中继续改进这个上传器,使它完全兼容 tus。
本教程有以下几节
Tus协议
POST请求创建文件
PATCH请求更新文件
HEAD请求获取当前文件偏移量
Tus协议
tus 协议非常简单,tus 的最佳卖点是它可以在 HTTP 之上运行。 让我们首先了解 tus协议是如何工作的。
Tus 协议需要三种 http 方法,即 POST,PATCH 和 HEAD。 最好使用一个例子来理解tus 协议。
我们以上传大小为 250 字节的文件为例。 接下来的部分将解释使用 tus 协议上传文件所需的 http 调用顺序。
POST 请求创建文件
这是第一步。客户端将具有文件上载长度(大小)的 POST
请求发送到服务器。服务器创建一个新文件并使用文件的位置进行响应。
Request
**
POST /files HTTP/1.1
Host: localhost:8080
Content-Length: 0
Upload-Length: 250
在上面的请求中,我们向URL localhost:8080/files
发送 POST 请求,以创建一个Upload-length
为 250 字节的文件。 Upload-length
表示整个文件的大小。由于请求没有消息体,因此 Content-Length
字段为零。
服务器创建文件并返回以下响应。
Response
**
HTTP/1.1 201 Created
Location: localhost:8080/files/12
Location
头提供了创建文件的位置。在我们的代码中, 它是 localhost:8080/files/12
PATCH 请求更新文件
Patch 请求用于在偏移量处将字节写入文件 Upload-Offset
。 每个 Patch 请求都应包含一个 Upload-Offset
字段,表明正在上传的文件数据的当前偏移量。
在我们的例子中,由于我们刚刚创建了一个新文件并开始将数据上传到文件,因此客户端发送一个上传偏移为 0 的 PATCH 请求。请注意文件偏移量为零。** **文件的第一个字节位于偏移 0 处。
Request
PATCH /files/12 HTTP/1.1
Host: localhost:8080
Content-Length: 250
Upload-Offset: 0
[250 bytes of the file]
在上面的请求中,Content-Length
字段是 250,因为我们正在上传大小为 250 字节的文件。 Upload-Offset
为 0 表示服务器应该在文件的第 1 个字节处写入请求的内容。
服务器将响应 204 No Content
头,指示请求成功。 对 PATCH
请求的响应应该包含Upload-Offset
字段,指示要上传的下一个字节。 在这种情况下,Upload-Offset
字段将为 250
,表示服务器已收到整个文件并且上传已完成。
Response
HTTP/1.1 204 No Content
Upload-Offset: 250
来自服务器的上述响应表明上载已成功完成,因为 Upload-Offset
等于 Upload-Length 250
。
HEAD请求获取当前文件偏移量
上面的patch 请求已成功完成,没有任何网络问题,文件已完全上传。
如果在上传文件时出现网络问题,并且中间上传失败,该怎么办? 客户端不应再次上载整个文件,而应从失败的字节开始上载文件。 这是 HEAD 请求有用的地方。
假设上传 100
个字节后文件上传请求已断开连接。 客户端需要向服务器发送 HEAD
请求以获取文件的当前 Upload-Offset
,以了解已上载了多少字节以及还有多少字节需要上载。
Request
HEAD /files/12 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Upload-Offset: 100
服务器响应上传偏移量 100 ,指示客户端必须从偏移量 100 再次开始上载。注意,对头部请求的响应不包含消息体。 它只包含一个 header 头。
客户端发送上传偏移量的 PATCH 请求,并且请求主体包含剩余的 150 个字节
250(文件大小) - 100(上传偏移)= 150个剩余字节
Request
PATCH /files/12 HTTP/1.1
Host: localhost:8080
Content-Length: 150
Upload-Offset: 100
[Remaining 150 bytes]
Response
HTTP/1.1 204 No Content
Upload-Offset: 250
服务器响应 204
状态和 Upload-Offset: 250
等于 Upload-Length
,表示文件上传已完全上传。
如果请求在上载期间再次在中间失败,则客户端应发送 HEAD
请求,然后发送 PATCH
。
要点是继续调用 **HEAD
以了解当前的 Upload-Offset
,然后是 PATCH
,直到服务器响应 Upload-Offset
等于 Upload-Length
**。