作者:理查德·琼斯
Simple Sword 服务器必须使用:
1/ 它是 python 服务器用于兼容 SWORDv2 的服务器库 2/ 它是一个独立服务器,提供 SWORD 2.0 规范的参考实现
SSS 依赖于 web.py 和 lxml,因此您需要在继续之前轻松安装这两个文件。您需要安装 libxml2 和 libxslt1.1 才能安装 lxml。
SSS 有一个配置对象,可以修改它来改变其行为的某些方面。打开sss.py进行编辑,找到Configuration对象;您可以使用的每个选项都内联记录。
如果您使用下面的快速入门来运行此程序,则可以按原样保留配置,一切都应该可以正常工作。如果您在 Apache 下使用 web.py 部署 SSS,则需要将配置对象从 CherryPyConfiguration 更改为 ApacheConfiguration,这可以在文件末尾完成。
SSS 提供了一个对象模型、两个 Web API 实现(用于 web.py 和 pylon)以及一个用于将 SWORD API 绑定到底层服务器的服务器接口。
服务器端要实现的接口是sss.SwordServer。然后可以在 sss.conf.json 配置文件中进行配置,SSS 使用该文件来加载服务器的实现。
Web.py API 位于 sss.webpy 中,并且只能独立运行。这是SSS的推荐用法,供参考实现(见下文)
Pylons API 位于 sss.pylons_sword_controller 中,可以非常轻松地导入到 Pylons 项目中。您应该在 Pylons 项目中创建一个新控制器,并且该控制器的主体如下:
from sss.pylons_sword_controller import SwordController
__controller__ = "SwordController"
当作为参考实现运行时,SSS 对请求的响应就好像它是一个真正的 SWORD 2.0 服务器一样,尽管在幕后它是一个简单的文件存储,对其所处理的内容进行最少的处理。
注意:开箱即用的 CherryPy 不支持 HTTP 1.1(由于错误),因此您需要使用 HTTP 1.0 发出请求。这是一个麻烦,因此对于使用 CURL 以外的用途,建议在 Apache 后面运行 SSS,如下所述......
要使用 CherryPy 启动 SSS,请将 sss.py 放置在其自己的合适目录中并使用以下命令启动它
python sss.py
这将启动网络服务器
http://localhost:8080/
请注意,SSS 会自动在 sss.py 文件所在的目录中创建数据存储,因此应在合适的目录中完成此操作。要在备用端口(例如 8443)上启动服务器,请使用
python sss.py 8443
为了获得 HTTP 1.1 支持,需要在 Apache 下部署 SSS(由于 bug,CherryPy 目前不支持 HTTP 1.1)
为此,您可以按照以下网址的说明进行操作:
http://webpy.org/cookbook/mod_wsgi-apache
设置 httpd.conf 文件时,要允许文件上传使用 Transfer-Encoding: chunked,并确保转发授权凭据,您需要按如下方式设置配置:
LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so
WSGIScriptAlias /sss /path/to/SSS/sss.py
WSGIPassAuthorization On
Alias /sss/static /path/to/SSS/static/
AddType text/html .py
WSGIChunkedRequest On
Order deny,allow
Allow from all
请注意,这为 wsgi_module 设置了显式位置(Ubuntu、其他平台上的 YMMV 需要),并将 WSGICunkedRequest 添加到正确的上下文中。
本节介绍一系列利用 SWORD Web 服务各个部分的 CURL 请求
请注意,对于 POST 和 PUT 请求,我们使用 HTTP 1.0 来处理curl 请求。这是因为 SSS 本身运行的 CherryPy Web 服务器无法正确响应这些请求(尽管服务器的功能不受影响)。您可能会发现针对 SSS 进行编程将要求您显式使用 HTTP 1.0 - 这不应被视为 SWORD 2.0 的要求。
###验证
要查看各种身份验证结果,请尝试对服务文档执行以下请求。默认情况下,SSS 具有以下用户详细信息:
用户:剑
密码:剑
代表人:奥博
卷曲-i http://sword:sword@localhost:8080/sd-uri
无需代表用户即可成功进行身份验证
curl -i -H "X-On-Behalf-Of: obo" http://sword:sword@localhost:8080/sd-uri
代表用户成功进行身份验证
curl -i http://localhost:8080/sd-uri
未提供基本身份验证凭据,401 未经授权响应
curl -i http://sword:drows@localhost:8080/sd-uri
密码错误,401未经授权的响应
curl -i http://drows:sword@localhost:8080/sd-uri
用户不正确,401未经授权的响应
curl -i -H "X-On-Behalf-Of: bob" http://sword:sword@localhost:8080/sd-uri
用户正确,但代表用户无效,401 未经授权的响应
所有后续请求都可以使用 X-On-Behalf-Of 标头来完成;将不再提供更多示例
###获取服务文档
HTTP:SD-URI 上的 GET
curl -i http://sword:sword@localhost:8080/sd-uri
这将返回服务文档,其中列出了配置的集合数量
###存入一些新内容
HTTP:在 Col-URI 上发布
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
sword:sword@[Col-URI]
这会将 example.zip 文件发布到 Col-URI,文件名为“example.zip”,并指定它是一个 zip 文件。如果没有 X-Packaging 标头,这将被解释为默认的 SWORD 包。 Col-URI 应从服务文档中获取。
这应该返回 HTTP 状态 201 Created 和存款收据
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "X-In-Progress: true"
sword:sword@[Col-URI]
这应该返回 HTTP 状态 202 Accepted 和存款收据
curl -i --http1.0 --data-binary "@multipart.dat"
-H 'Content-Type: multipart/related; boundary="===============0670350989=="'
-H "MIME-Version: 1.0"
sword:sword@[Col-URI]
这将模仿 Atom Multipart 存款,并在容器中创建两个项目:atom.xml 和 example.xml(以当前时间戳为前缀)。这应该返回 HTTP 状态 201 Created 和存款收据。您可以添加
-H "X-In-Progress: true" to get a 202 Accepted back instead, as above.
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "X-Packaging: http://purl.org/net/sword/package/METSDSpaceSIP"
sword:sword@[Col-URI]
这是对 example.zip 使用不同包格式的示例。目前,SSS 中的摄取打包器将简单地保留此包,而不会尝试对其进行解包
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "Content-MD5: 2b25f82ba67284461d4a481d7a06dd28"
sword:sword[Col-URI]
在这个示例中,我们为该项目提供了正确的 MD5 校验和,只是为了证明无论有没有校验和,该方法都有效。请参阅下面有关提供错误校验和的错误的部分。
###列出集合的内容
HTTP:在 Col-URI 上获取
curl -i sword:sword@[Col-URI]
这将返回一个 Atom Feed,其中每个atom:entry 引用指定集合中的一个集合。这只是为了方便而实施,因此不是完整的 Feed;相反,它只包含一个atom:link元素,其中包含该集合的编辑URI的href
###获取容器的表示(媒体资源)
HTTP:在 Cont-URI 或 EM-URI 上获取
curl -i [EM-URI]
从服务器获取默认的分发包。在这种情况下,curl 会用“ / ”为我们填充 Accept 标头。这将返回容器中所有内容的 application/zip 文件。请注意,此请求不需要身份验证,因为 SSS 出于示例目的将其建模为内容的公共面孔。
FIXME:这种内容协商方法正在争论中,尽管 SSS 目前支持它
curl -i -H "Accept: application/zip;swordpackage=http://www.swordapp.org/package/default" [EM-URI]
显式请求标准剑包格式的 zip 文件(顺便说一下,这是一个普通的 zip 文件)
curl -i -H "Accept: application/zip" [EM-URI]
显式请求内容的普通 zip 文件(这恰好与标准剑包没有什么不同)
curl -i -H "Accept: text/html" [EM-URI]
显式请求媒体资源的 HTML 表示形式。这将返回一个 302 Found HTTP 标头,其中包含一个指向 HTML 表示的 Location 标头
curl -i -H "Accept: application/vnd+msword" [EM-URI]
生成 415 不支持的媒体类型错误
###用新媒体资源覆盖现有媒体资源
HTTP:放在 EM-URI 上
curl -i -X PUT --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
sword:sword@[EM-URI]
这将用附加的 example.zip 文件替换用 EM-URI 标识的容器中的所有现有内容。包格式被解释为默认的剑包。它将返回 201 Created 和存款收据
curl -i -X PUT --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "X-In-Progress: true"
sword:sword@[EM-URI]
这将执行与上面相同的操作,但将返回 202 Accepted 指示更新已被服务器接受,但尚未处理(显然,出于示例的目的;它与实际情况没有任何区别)发生在服务器上)。
FIXME:这不是 AtomPub 的工作方式,它相反说应该返回 200 - SWORD 对此还没有定论
curl -i -X PUT --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "X-Suppress-Metadata: true"
sword:sword@[EM-URI]
这将执行与上面相同的操作,但告诉服务器不要根据此存款更新项目的元数据。 SSS 不会对非多部分的默认包实现元数据更新,因此这不会产生任何实际效果,但这是一个有效的请求。
curl -i -X PUT --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "X-Packaging: http://purl.org/net/sword/package/METSDSpaceSIP"
sword:sword@[EM-URI]
与上面相同的示例,但传入了 X-Packaging 标头。
###删除内容但不删除容器
HTTP:在 EM-URI 上删除
curl -i -X DELETE sword:sword@[EM-URI]
这将从商店中删除所有内容,但不会删除容器本身,并返回 200 OK 和存款收据
###获取容器的表示
HTTP:编辑 URI 上的 GET
curl -i sword:sword@[Edit-URI]
这会以其默认格式检索 Edit-URI,该格式是存款收据的副本 - 原子条目文档
curl -i -H "Accept: application/rdf+xml" sword:sword@[Edit-URI]
这为我们提供了来自存储库的纯 RDF/XML 语句
curl -i -H "Accept: application/atom+xml;type=entry" sword:sword@[Edit-URI]
这以原子条目形式显式请求 Edit-URI,这与默认格式相同
###通过向现有内容添加新内容来更新容器
HTTP:在编辑 URI 上发布
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
sword:sword@[Edit-URI]
这会将 example.zip 文件添加到服务器(请注意,Content-Disposition 为其提供了相同的名称 - SSS 将在收到时本地化名称以避免覆盖现有文件),而不删除任何现有内容。这将返回 201 Created(或者如果您添加 X-In-Progress 标头,则返回 202 Accepted)和存款收据。
curl -i --http1.0 --data-binary "@multipart.dat"
-H 'Content-Type: multipart/related; boundary="===============0670350989=="'
-H "MIME-Version: 1.0"
sword:sword@[Edit-URI]
这将模仿 Atom Multipart 存款,并在容器中创建两个项目:atom.xml 和 example.xml(以当前时间戳为前缀)。在这种情况下,atom.xml 将覆盖任何现有的atom.xml 文件,而 example.zip 将仅添加到本地化名称下。这应该返回 HTTP 状态 201 Created 和存款收据。您可以添加 -H "X-In-Progress: true" 以获取 202 Accepted 返回,如上所述。
curl -i --http1.0 --data-binary "@multipart.dat"
-H 'Content-Type: multipart/related; boundary="===============0670350989=="'
-H "MIME-Version: 1.0"
-H "X-Suppress-Metadata: true"
sword:sword@[Edit-URI]
设置了 X-Suppress-Metadata 标头的此版本请求将执行与上面相同的操作,但它不会尝试从atom.xml 文件中提取任何元数据,否则它会执行此操作。
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "X-Packaging: http://purl.org/net/sword/package/METSDSpaceSIP"
sword:sword@[Edit-URI]
###删除容器及其所有内容
HTTP:编辑 URI 上的删除
curl -i -X DELETE sword:sword@[Edit-URI]
这将从容器中删除所有内容,然后删除容器本身。它将返回没有响应正文的 204 No Content 响应。
###生成错误
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "X-Packaging: http://purl.org/net/sword/package/error"
sword:sword[Col-URI]
在存放包裹类型与 X-Packaging 标头不匹配的包裹时生成 ErrorContent 错误响应
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "Content-MD5: 1234567890"
sword:sword[Col-URI]
由于校验和与提供的校验和标头不匹配而生成错误,从而导致 412 Precondition Failed 错误。
curl -i --http1.0 --data-binary "@example.zip"
-H "Content-Disposition: filename=example.zip"
-H "Content-Type: application/zip"
-H "X-In-Progress: whatever"
sword:sword[Col-URI]
通过向 X-In-Progress 传递非法值来生成错误请求错误,从而导致 400 错误请求响应