gue*_*tli 4 hash webdav put rfc deduplication
HTTP/WebDav规范是否允许此客户端 - 服务器对话框?
注意:此PUT是初始上传.这不是更新.
如果可以,则可以实现更快的文件同步.
使用案例:WebDAV服务器为每个用户托管一个目录.最喜欢的视频foo.mkv由多个用户上传.在此示例中,收藏的视频已存储在此位置:/user2/myfoo.mkv.第二次和以后的上传不需要发送任何数据,因为服务器已经知道内容.这会减少很多网络负载.
前提条件:
在自定义客户端和服务器中实现它非常容易.但这不是我想要的.
我的问题:是否有允许这样的对话的RFC或其他标准?
如果还没有标准,那么如何实现这个梦想呢?
安全考虑
通过上面的对话框,它将能够访问已知哈希的内容.恶意客户端的示例知道存在哈希值为的文件1234567....他可以执行上述两个步骤,之后客户端可以使用GET下载数据.
解决此问题的方法是扩展对话框:
abcde...怎么做到这一点?
由于似乎还没有规范,问题的这一部分仍然存在:
如何实现梦想成真?
根据你的描述,似乎应该使用ETag.
它专门用于将标记(通常是MD5哈希,但可以是任何内容)与资源的内容(和/或位置)相关联,以便稍后可以判断资源是否已更改.
ETag支持PUT请求,并且通常与If-Match标头一起使用以进行乐观并发控制.
然而,你的使用情况稍有不同,你正试图防止一个PUT到具有相同内容的资源,而If-Match头被用来将只允许PUT到资源与相同的内容.
在您的情况下,您可以改为使用If-None-Match标题:
"If-None-Match:*"的含义是,如果由原始服务器(或通过缓存,可能使用Vary机制,参见第14.44节)选择的表示存在,则不得执行该方法,并且应该执行如果表示不存在.此功能旨在用于防止PUT操作之间的比赛.
WebDAV也支持Etags,但它的使用方式可能取决于实现:
请注意,PUT响应中ETag的含义在本文档或RFC 2616中没有明确定义(即,ETag是否意味着资源是八位字节,相当于PUT请求的主体,或者是否服务器可能在存储时对文档的格式或内容进行了微小的更改.这是一个HTTP问题,不仅仅是WebDAV问题.
如果您正在实现自己的客户端,我会做这样的事情:
ETagIf-None-Matches标头的PUT请求从您更新的问题,现在看来很清楚,当收到PUT请求时,您希望在接受请求之前检查服务器上的所有资源是否缺少相同的内容.这意味着还要检查位于与PUT请求的目标指定位置不同的位置的资源.
AFAIK,没有专门处理此案例的现有规范.但是,ETag机制(和HTTP协议)被设计为通用且足够灵活,可以处理许多情况,这就是其中之一.
当然,这只是意味着您无法利用标准的HTTP服务器逻辑 - 您需要自定义客户端和服务器端的代码.
在进入可能的实现之前,需要做一些假设.
如果简单的情况对您不起作用,这些已经从最简单到复杂的顺序排序.
这假设您的服务器实现允许您在收到整个请求之前读取请求标头并进行响应.
If-None-Match包含ETag 的标头向服务器发送PUT请求(位置无关紧要)并继续正常发送正文.这稍微复杂一点,但更好地遵守HTTP规范.此外,如果您的服务器体系结构不允许您在收到整个请求之前读取标头,那么这可能会起作用.
If-None-Match包含ETag和Expect: 100-continue标头的标头向服务器发送PUT请求(位置无关紧要).此时尚未发送请求正文.此实现可能需要最多的工作,但应与所有主要库/架构广泛兼容.但是,另一个客户端在两个请求之间上传具有相同内容的文件的风险很小.
/check-etag/<etag>,其中<etag>是的ETag.这将检查ETag是否已存在于服务器上./check-etag/*检查服务器代码以查看具有该ETag的资源是否已存在.虽然实施取决于您,但有以下几点需要考虑:
如果源服务器收到的请求不包含具有"100-continue"期望的Expect请求标头字段,则该请求包括请求主体,并且服务器在从读取整个请求主体之前使用最终状态代码进行响应.传输连接,然后服务器不应关闭传输连接,直到它已读取整个请求,或直到客户端关闭连接.否则,客户端可能无法可靠地接收响应消息.
此外,请勿在不发送任何状态代码的情况下关闭服务器端的连接,因为客户端很可能会重试该请求:
如果HTTP/1.1客户端发送包含请求主体的请求,但不包含具有"100-continue"期望的Expect请求标头字段,并且客户端未直接连接到HTTP/1.1源服务器,如果客户端在从服务器接收任何状态之前看到连接关闭,则客户端应该重试该请求.