利用Nginx架设Webdav服务并用Python的requests使用
2019-03-18 22:57:40 +08 字数:1228 标签: Nginx Python DockerWebDAV(Web Distributed Authoring and Versioning)是在RFC 4918中定义的一种HTTP协议的扩展,实现了Web文件的远程管理。 虽然最近一次更新,已经是2009年的事了,但它确实影响深远。 Apache httpd、Nginx等Web服务器,默认提供支持;Git、SVN等版本控制系统,在协议上深受影响。
当然,把这老古董翻出来,还是因为它自有独到之处。 基于HTTP默认的动词GET、PUT、DELETE等,它能简单实现文件的读、写、删除功能。 此外,还有扩展的动词,实现特殊的文件远程操作功能,如复制、移动、加锁等。
- COPY: copy a resource from one URI to another
- LOCK: put a lock on a resource. WebDAV supports both shared and exclusive locks.
- MKCOL: create collections (a.k.a. a directory)
- MOVE: move a resource from one URI to another
- PROPFIND: retrieve properties, stored as XML, from a web resource. It is also overloaded to allow one to retrieve the collection structure (also known as directory hierarchy) of a remote system.
- PROPPATCH: change and delete multiple properties on a resource in a single atomic act
- UNLOCK: remove a lock from a resource
这些功能,可以用简单的HTTP扩展协议,实现一个远程版本控制系统。 即使是一个子集,也可以实现一个简单高效、网络共享的文件存取系统。 这在微服务架构的容器化集群中,可以起到意想不到的简化效果。
Nginx ¶
Nginx自带的ngx_http_dav_module,就实现了WebDAV的基本文件操作功能——PUT、DELETE、MKCOL、COPY和MOVE。 而第三方的arut/nginx-dav-ext-module,则实现了加锁等高级功能——PROPFIND、OPTIONS、LOCK和UNLOCK。
使用用官方的Nginx镜像,则自带ngx_http_dav_module功能。
Nginx容器配置 ¶
version: "3"
services:
nginx:
image: nginx:1.14.2-alpine
ports:
- 8080:80
volumes:
- ./conf.d:/etc/nginx/conf.d:ro
Nginx配置 ¶
在./conf.d/default.conf
写入以下配置:
server {
listen 80;
listen [::]:80;
server_name _;
location / {
root /tmp/;
autoindex on;
autoindex_format json;
dav_methods PUT DELETE MKCOL COPY MOVE;
create_full_put_path on;
client_max_body_size 8M;
allow all;
}
}
启动服务 ¶
配置完成后,用docker-compose up -d
,即可启动一个带WebDAV支持的Nginx。
示例代码 ¶
以下以curl
命令和Python的[requests]为例,展示如何使用[Nginx]的webdav服务。
PUT ¶
import os
from urllib.parse import urljoin
import requests
BASE_URL = 'http://localhost:8080'
def put(name):
url = urljoin(BASE_URL, name)
response = requests.put(url, data=open(name, 'rb'))
response.raise_for_status()
if __name__ == '__main__':
import sys
put(sys.argv[1])
执行检查:
$ ./put.py put.py
$ curl -s localhost:8080 | jq
[
{
"name": "put.py",
"type": "file",
"mtime": "Sat, 02 Mar 2019 14:06:17 GMT",
"size": 347
}
]
可见put.py
文件已成功上传。
./put.py put.py
,相当于:
curl -X PUT -F put.py=@put.py localhost:8080/put.py
GET ¶
def get(name):
url = urljoin(BASE_URL, name)
response = requests.get(url)
response.raise_for_status()
print(response.text)
这个函数可以获取文件内容,并打印。
curl
的形式如下:
curl -X GET localhost:8080/put.py
DELETE ¶
def delete(name):
url = urljoin(BASE_URL, name)
response = requests.delete(url)
response.raise_for_status()
这个函数可以删除指定文件。
curl
删除put.py
的示例如下:
curl -X DELETE localhost:8080/put.py
list files ¶
列出文件,是一个常用的浏览操作。 仍然是用GET来实现,但URL确是指向目录。
>>> import requests
>>> r = requests.get('http://localhost:8080/')
>>> r.json()
[{'mtime': 'Sat, 02 Mar 2019 07:58:12 GMT',
'name': 'a.txt',
'size': 6,
'type': 'file'},
{'mtime': 'Sat, 02 Mar 2019 07:58:20 GMT',
'name': 'b.txt',
'size': 7,
'type': 'file'}]
命令行的形式如下:
$ curl -s localhost:8080 | jq
[
{
"name": "a.txt",
"type": "file",
"mtime": "Sat, 02 Mar 2019 07:58:12 GMT",
"size": 6
},
{
"name": "b.txt",
"type": "file",
"mtime": "Sat, 02 Mar 2019 07:58:20 GMT",
"size": 7
}
]
其它 ¶
此外,还有WebDAV独特的动词,需要使用[requests]的高级功能,自定义HTTP动词。 例如:
>>> r = requests.request('MKCOL', url, data=data)
>>> r.status_code
200 # Assuming your call was correct
这里不再详细介绍。