在之前的教程中,我们使用 Go 编写了可恢复的 tus 服务器。在本教程中,我们将使用curl 和 dd 命令来测试 tus 服务器。
Testing
我们准备好了可恢复文件上传服务器,但我们还没有测试过。我们需要一个 tus 客户端来测试 tus 服务器。我们将在即将到来的教程中创建 Go 客户端。现在我们将使用 curl 命令来测试 tus 服务器。
我们先运行服务器。在终端中运行以下命令以从 github 获取代码然后运行它。
go get github.com/golangbot/tusserver
go install github.com/golangbot/tusserver
tusserver
运行上述命令后,服务器将启动并运行。
2019/03/30 18:01:41 Connection established successfully
2019/03/30 18:01:41 TUS Server started
2019/03/30 18:01:41 Directory created successfully
2019/03/30 18:01:41 table create successfully
我们需要一个文件来测试tus服务器。 我制作了一张我宠物的拼接视频,可以在https://www.dropbox.com/s/evchz5hsuvtrvuu/mypet.mov?dl=0 上找到。 请随意使用它:)。 我已将视频下载到 ~/Downloads
目录。
让我们发一个帖子请求并创建一个新文件。 我们需要在 post
请求中指定整个文件的Upload-Length
。 这只是文件的大小。 我们可以使用 ls
命令查找文件的大小
ls -al ~/Downloads/mypet.mov
上面的命令返回以下输出。
-rw-rw-r-- 1 naveen naveen 11743398 Mar 31 11:11 /home/naveen/Downloads/mypet.mov
文件的大小是 11743398。现在我们知道了上传长度,让我们通过发送 post 请求来创建文件。
curl --request POST localhost:8080/files --header "Upload-Length: 11743398" -i
上面的命令创建文件。最后的 -i
参数用于显示响应头。上面的命令将返回以下结果。
HTTP/1.1 201 Created
Location: localhost:8080/files/1
Date: Sun, 31 Mar 2019 07:47:33 GMT
Content-Length: 0
文件已经成功创建。
现在是比较棘手的部分。 我们如何通过模拟网络断开来测试 tus 服务器?__ 如果我们使用 curl 向文件 URL 发送 patch 请求,则由于服务器在本地运行,请求将立即完成,我们将无法测试服务器是否能够处理可恢复的上载。
这是 curl 的 --limit-rate
参数帮助我们的地方。 此参数可用于对修补程序文件请求进行速率限制。
curl --request PATCH --data-binary "@/home/naveen/Downloads/mypet.mov"
localhost:8080/files/1 --header "Upload-Offset: 0" --header "Expect:" -i
--limit-rate 200K
在上面的 curl 请求中,我们正在向 localhost:8080/files/1
和 Upload-Offset: 0
位置的文件发送 PATCH 请求,我们将请求速率限制为 200KB/Sec。mypet.mov
的内容被添加到请求正文中。 --header "Expect:"
标题需要防止 curl 发送 Expect: 100-continue
header 头。 请阅读 https://gms.tf/when-curl-sends-100-continue.html 以了解为何需要这样做。
发出上述 patch 请求后,文件将以 200KB/S 的速度传输。 让请求运行几秒钟,比如10 秒。 大约 10 秒钟后,请按 ctrl + c
停止请求。 现在我们已经在中间终止了 patch 请求。 服务器应该存储到目前为止传输的字节。 我们来看看它是否已经完成了。
转到服务器日志,你将能够在日志中看到以下内容,
2019/03/31 13:36:00 Received file partially unexpected EOF
2019/03/31 13:36:00 Size of received file 1589248
2019/03/31 13:36:00 number of bytes written 1589248
接收到的文件大小可能与你的不同。上面是我的输出。
嗯,看起来它保存了到现在为止接收到的字节。但是我们如何验证它。让我们检查一下上传文件的大小。
ls -al ~/fileserver/1
运行上面的命令输出
-rw-r--r-- 1 naveen naveen 1589248 Mar 31 13:36 /home/naveen/fileserver/1
文件大小与服务器输出匹配。 现在我们可以100%确定服务器已经保存了它收到的字节。 如果你现在尝试播放视频,则由于该文件尚未完全上传,因此无法播放。
下一步是从停止的位置继续修补请求。 我们首先需要了解 Upload-Offset,以便我们可以发出下一个 patch 请求。 这是头部请求派上用场的地方。
curl --head localhost:8080/files/1 -i
上面的 curl 命令将返回 Upload-Offset
HTTP/1.1 200 OK
Upload-Offset: 1589248
Date: Sun, 31 Mar 2019 08:17:28 GMT
请注意,偏移量与服务器日志和文件大小相匹配。
现在我们需要发送一个带有上述上传偏移量的 PATCH
请求。 另一个问题是我们需要仅从此偏移量发送文件数据(文件的字节),而不是整个文件。
这是 dd 命令帮助我们的地方。
dd if=/home/naveen/Downloads/mypet.mov skip=1589248 bs=1 | curl --request PATCH
--data-binary @- localhost:8080/files/1 --header "Upload-Offset: 1589248"
--header "Expect:" -i
在上面的命令中,我们使用 if
来指定输入文件,skip
用于跳过 1589248
个字节。 1589248
是我们的 Upload-Offset
。 bs
指定我们一次读取一个字节。 我们将 dd
的输出传递给 curl
命令。 运行上面的命令后,我们将得到输出
HTTP/1.1 204 No Content
Upload-Offset: 11743398
Date: Sun, 31 Mar 2019 08:25:10 GMT
204 No 内容表示 patch 成功。要知道文件上传是否完成,我们可以再次发出 head 请求,上传偏移量应该与文件的上传长度(大小)匹配。
curl --head localhost:8080/files/1 -i
上面的命令将输出
HTTP/1.1 200 OK
Upload-Offset: 11743398
Date: Sun, 31 Mar 2019 08:30:54 GMT
上传偏移量与上传长度匹配,我们确信文件已经完全上传。现在,如果你再次尝试发出patch请求,服务器会报错说上传已经完成。现在让我们再次检查文件大小。
现在让我们再次检查文件大小。
ls -al ~/fileserver/1
运行上面的命令输出
-rw-r--r-- 1 naveen naveen 11743398 Mar 31 13:55 /home/naveen/fileserver/1
输出中的文件大小与上载长度匹配,这将确认文件已完全上载。你可以继续播放视频,它现在就会播放:)
我们可恢复的 tus 服务器已经准备好了:)
增强功能
虽然文件上传器有效,但此代码需要进一步重构。它目前不处理并发。例如,当多个客户端为同一文件发送并发patch请求时,我们可能会遇到竞争条件。
此代码也不能很好地处理数据库事务。创建文件的POST请求可能最终会在DB中创建文件,但不会在文件系统中创建实际文件。例如,当文件系统中没有剩余空间时会发生什么?
所有代码当前都存在于单个文件中的主程序包中,并且此方法不可扩展。代码必须重构为可用的包。 Go 中结构代码的一种方法是使用领域驱动设计。
我们还没有准备好 tus 客户端:)
原文链接
https://golangbot.com/resumable-file-uploader-testing-the-server-using-curl-dd/