0

我的想法是LOCK在 apache/WebDAV 服务器上创建一个文件,在服务器PUT上更新它的版本,然后在UNLOCK它之后。

我刚刚用尸体尝试了以下操作:

  1. 创建一个A.txt包含内容的文件a file
  2. GETA.txt产生的文件a file
  3. 编辑A.txtupdated file保存(在尸体中)
  4. GET产生的文件A.txt仍然产生a file
  5. 尸体中的关闭编辑(VIM)
  6. GETA.txt产生的文件updated file

我猜在内部 cadaver LOCKs 文件,GETs 它并在本地更改它。然后它PUT就是UNLOCK它。

问题:我怎样才能用 curl 做到这一点?

问题:当连接速度很慢并且我PUT为一个尚未完全上传的文件做一个时,我只得到尚未上传的部分。我想买旧的,只要新的不完整。

尝试:我尝试了以下手动锁定文件(即使用 cURL):

curl -v -X LOCK --user "user:password" http://myServer/newFile

我得到的是:

* About to connect() to myServer port 80 (#0)
*   Trying xx.xx.xxx.xxx... connected
* Connected to myServer (xx.xx.xxx.xxx) port 80 (#0)
* Server auth using Basic with user 'user'
> LOCK /newFile HTTP/1.1
> Authorization: Basic xxxxxxxxxxxxxxxxx
> User-Agent: curl/7.21.6 (x86_64-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3
> Host: myServer
> Accept: */*
> 
< HTTP/1.1 400 Bad Request
< Date: Wed, 02 May 2012 15:20:55 GMT
< Server: Apache/2.2.3 (CentOS)
< Content-Length: 226
< Connection: close
< Content-Type: text/html; charset=iso-8859-1
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>
* Closing connection #0

查看 apache 日志文件,我发现:

[Wed May 02 15:20:55 2012] [error] [client xx.xx.xxx.xxx] The lock refresh for /newFile failed because no lock tokens were specified in an "If:" header.  [400, #0]
[Wed May 02 15:20:55 2012] [error] [client xx.xx.xxx.xxx] (20)Not a directory: No locktokens were specified in the "If:" header, so the refresh could not be performed.  [400, #103]

感谢您的任何提示!

更新:我添加了我的问题描述..干杯!

4

1 回答 1

3

LOCK方法需要一个正文,其中包含您要取出的锁的 XML 描述。您的 cURL 测试不包括此正文,因此 400 错误响应。

但是,如果我正确理解您的问题,您希望:

  1. 开锁

如果那是真的,你为什么还要为 LOCK 和 UNLOCK 烦恼呢?只需执行 PUT!仅当您想在持有锁时执行多个操作并避免让另一个客户端看到处于部分修改状态的对象或(可能更糟)与您同时修改对象时,锁才会有用。

锁定有用的典型情况是读-修改-写循环:您想要获取对象,在本地对其进行修改,然后将其放回,但不允许另一个客户端在您获取对象和时间你把它。然而,为了处理这种特殊情况,HTTP 提供了一种不同的解决问题的方法,而不使用锁(这不适合 HTTP 等无状态协议):

  1. 获取对象
  2. 本地修改
  3. 使用包含在步骤 1 中返回的原始 ETag的If-Match标头将对象放回原处
  4. 如果 PUT 导致 412 错误,请返回步骤 1。否则,您已完成。

更新:根据您更新的问题,如果您同时执行 GET 与 PUT,我看到您会看到新文件的部分截断或半上传版本。这是不幸的。服务器应将 PUT 视为相对于其他请求的原子。其他客户端应该看到旧版本或新版本,而不是介于两者之间的状态。您不需要从客户端做任何事情来实现这一点。它应该在服务器中修复。

于 2012-05-02T15:59:45.743 回答