欢迎来到我们的 "简历文件上传器 "系列教程之四。我们的可恢复文件上传器系列中的第4篇。
在之前的教程中,我们用Go编码了我们的可恢复的tus服务器。在本教程中,我们将使用curl和dd命令来测试tus服务器。
测试
我们已经准备好了可恢复文件上传的tus服务器,但我们还没有测试它。我们需要一个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服务器。我做了一个关于我的宠物的拼贴视频,它可以在www.dropbox.com/s/evchz5hsu…请自由使用它:)。我已经把视频下载到我的~/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是文件的大小。现在我们知道了Upload-Length,让我们通过发送一个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发送一个补丁请求,由于服务器在本地运行,请求将立即完成,我们将无法测试服务器是否能够处理可恢复的上传。
这就是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 的文件发送一个补丁请求,并且我们将请求的速率限制在200KB/秒。mypet.mov 的内容被添加到请求正文中。--header "Expect:" 头是需要的,以防止curl发送Expect: 100-continue 头。请阅读gms.tf/when-curl-s…以了解为什么需要这样做。
发出上述补丁请求后,文件将以200KB/S的速度被传输。让请求运行几秒钟,比如10秒钟。大约10秒后,请按ctrl + c ,停止请求。现在我们已经在中间终止了补丁请求。服务器应该已经存储了到现在为止所传输的字节。让我们检查一下它是否已经做到了。
移动到服务器日志,你将能够在日志中看到以下内容。
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,以便我们能够发出下一个补丁请求。这就是head request的用武之地。
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 请求。还有一个问题是,我们需要只从这个偏移量发送文件数据(文件的字节数),而不是整个文件。
这就是<a href="man7.org/linux/man-p…" target="_blank"">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 Content表明补丁是成功的。要知道文件上传是否完成,我们可以再次发出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 上传偏移量与上传长度相匹配,我们确信文件已经被完全上传。现在,如果你试图再次发出一个补丁请求,服务器将抱怨说上传已经完成。
现在让我们再次检查文件大小。
ls -al ~/fileserver/1 运行上述命令输出
-rw-r-r-- 1 naveen naveen 11743398 Mar 31 13:55 /home/naveen/fileserver/1 输出中的文件大小与上传长度一致,这证实了文件已经被完全上传。你可以继续播放视频,现在就可以播放了:)
我们的可恢复tus服务器已经准备好了:)
Enhancements
虽然文件上传器可以工作,但这段代码需要进一步重构。它目前没有处理并发性。例如,当多个客户端在相同的偏移量上为同一文件发送并发的补丁请求时,我们可能会遇到一个竞赛条件。
这段代码也不能很好地处理 DB 事务。创建文件的 POST 请求有可能最终在 DB 中创建文件,但却没有在文件系统中创建实际文件。例如,当文件系统中没有剩余空间时会发生什么。
目前所有的代码都存在于主包中的一个文件中,这种方法是不可扩展的。代码必须被重构为可用的包。在 Go 中结构化代码的一种方法是使用领域驱动设计。
我们也还没有准备好一个 tus 客户端 :)。
所有这些都将在接下来的教程中解决。我希望你喜欢阅读。请留下您的评论。祝您愉快。
喜欢我的教程吗?请通过捐赠来表示您的支持。您的捐款将帮助我创造更多令人敬畏的教程。