ผู้เขียน: ริชาร์ด โจนส์
Simple Sword Server ต้องใช้:
1/ เป็นไลบรารีเซิร์ฟเวอร์สำหรับเซิร์ฟเวอร์ python ที่จะใช้เพื่อให้เข้ากันได้กับ SWORDv2 2/ เป็นเซิร์ฟเวอร์แบบสแตนด์อโลนซึ่งมีการใช้งานอ้างอิงของข้อกำหนด SWORD 2.0
SSS ขึ้นอยู่กับ web.py และ lxml ดังนั้นคุณจะต้อง easy_install ทั้งสองสิ่งนี้ก่อนดำเนินการต่อ คุณจะต้องติดตั้ง libxml2 และ libxslt1.1 เพื่อให้ lxml ติดตั้งได้
SSS มีออบเจ็กต์การกำหนดค่าซึ่งสามารถปรับเปลี่ยนเพื่อเปลี่ยนแปลงลักษณะการทำงานบางประการได้ เปิด sss.py เพื่อแก้ไขและค้นหาวัตถุการกำหนดค่า แต่ละตัวเลือกที่คุณสามารถใช้ได้จะมีการบันทึกไว้ในบรรทัด
หากคุณใช้งานสิ่งนี้โดยใช้การเริ่มต้นอย่างรวดเร็วด้านล่าง คุณสามารถปล่อยให้การกำหนดค่าเหมือนเดิมได้ และทุกอย่างจะทำงานได้ หากคุณกำลังปรับใช้ SSS โดยใช้ web.py ภายใต้ Apache คุณจะต้องเปลี่ยนออบเจ็กต์การกำหนดค่าจาก CherryPyConfiguration เป็น ApacheConfiguration ซึ่งสามารถทำได้ที่ส่วนท้ายของไฟล์
SSS จัดเตรียมโมเดลอ็อบเจ็กต์ การใช้งาน Web API สองแบบ (สำหรับ web.py และ pylons) และอินเทอร์เฟซเซิร์ฟเวอร์ที่จะนำไปใช้เพื่อผูก 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 ขอแนะนำให้เรียกใช้ SSS หลัง Apache ดังที่อธิบายเพิ่มเติมด้านล่าง...
หากต้องการเริ่ม SSS โดยใช้ CherryPy ให้วาง sss.py ในไดเร็กทอรีที่เหมาะสมของตัวเองแล้วเริ่มต้นด้วย
python sss.py
นี่จะเริ่มต้นเว็บเซิร์ฟเวอร์ที่
http://localhost:8080/
โปรดทราบว่า SSS จะสร้างที่เก็บข้อมูลโดยอัตโนมัติในไดเร็กทอรีซึ่งมีไฟล์ sss.py อยู่ ดังนั้นจึงควรทำในไดเร็กทอรีที่เหมาะสม หากต้องการเริ่มเซิร์ฟเวอร์บนพอร์ตอื่น (เช่น 8443) ให้เริ่มต้นด้วย
python sss.py 8443
เพื่อให้ได้รับการสนับสนุน HTTP 1.1 จำเป็นต้องปรับใช้ SSS ภายใต้ Apache (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 <Directory /path/to/SSS/> WSGIChunkedRequest On Order deny,allow Allow from all </Directory>
โปรดทราบว่านี่เป็นการตั้งค่าตำแหน่งที่ชัดเจนสำหรับ wsgi_module (จำเป็นสำหรับ Ubuntu, YMMV บนแพลตฟอร์มอื่น) และเพิ่ม WSGIChunkedRequest ให้กับบริบทที่ถูกต้อง
ในส่วนนี้จะอธิบายชุดคำขอ CURL ซึ่งใช้แต่ละส่วนของบริการเว็บ SWORD
โปรดสังเกตว่าสำหรับคำขอ POST และ PUT เราใช้ HTTP 1.0 สำหรับคำขอ curl เนื่องจากเว็บเซิร์ฟเวอร์ CherryPy ซึ่ง SSS ทำงานภายใต้ระบบไม่ตอบสนองต่อคำขอเหล่านั้นอย่างเหมาะสม (แม้ว่าฟังก์ชันการทำงานของเซิร์ฟเวอร์จะไม่ได้รับผลกระทบก็ตาม) คุณอาจพบว่าการเขียนโปรแกรมกับ SSS จะทำให้คุณต้องใช้ HTTP 1.0 อย่างชัดเจน ซึ่งไม่ควรถือเป็นข้อกำหนดสำหรับ SWORD 2.0
###การรับรองความถูกต้อง
หากต้องการดูผลลัพธ์การตรวจสอบสิทธิ์ต่างๆ ให้ลองคำขอต่อไปนี้ในเอกสารบริการ ตามค่าเริ่มต้น SSS จะมีรายละเอียดผู้ใช้ดังต่อไปนี้:
ผู้ใช้: ดาบ
รหัสผ่าน: ดาบ
ในนามของ: obo
curl -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
curl -i http://sword:sword@localhost:8080/sd-uri
ซึ่งจะส่งคืนเอกสารการบริการพร้อมจำนวนคอลเลกชันที่กำหนดค่าไว้ในรายการ
###ฝากเนื้อหาใหม่บางส่วน
HTTP: POST บน 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 สร้างแล้ว และใบเสร็จรับเงินเงินฝาก
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 สร้างแล้วและใบเสร็จรับเงินเงินฝาก คุณสามารถเพิ่ม
-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 โดยที่อะตอมแต่ละรายการ: รายการอ้างถึงคอลเลกชันในคอลเลกชันที่ระบุ การดำเนินการนี้ดำเนินการเพื่อความสะดวกเท่านั้น ดังนั้นจึงไม่ใช่ฟีดแบบเต็ม แต่มันมีเพียงองค์ประกอบ atom:link ที่มี href ไปยัง Edit-URI สำหรับคอลเลกชันนั้น
###รับการแสดงคอนเทนเนอร์ (ทรัพยากรสื่อ)
HTTP: GET บน Cont-URI หรือ EM-URI
curl -i [EM-URI]
รับแพ็คเกจการเผยแพร่เริ่มต้นจากเซิร์ฟเวอร์ ในกรณีนี้ curl จะเติมในส่วนหัว Accept สำหรับเราด้วย " / " นี่จะส่งคืนไฟล์แอปพลิเคชัน/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 พร้อมส่วนหัว Location ซึ่งชี้ไปที่การแสดง HTML
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]
การดำเนินการนี้จะแทนที่เนื้อหาที่มีอยู่ในคอนเทนเนอร์ที่ระบุด้วย EM-URI ด้วยไฟล์ example.zip ที่แนบมา รูปแบบแพ็คเกจถูกตีความว่าเป็นแพ็คเกจดาบเริ่มต้น มันจะส่งคืน 201 สร้างและใบเสร็จรับเงินเงินฝาก
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 ซึ่งระบุว่าการอัปเดตได้รับการยอมรับในเซิร์ฟเวอร์แล้ว แต่ยังไม่ได้รับการประมวลผล (สำหรับวัตถุประสงค์ของตัวอย่างเห็นได้ชัดว่ามันไม่ได้สร้างความแตกต่างใด ๆ กับสิ่งที่จริง เกิดขึ้นบนเซิร์ฟเวอร์)
แก้ไข: นี่ไม่ใช่วิธีการทำงานของ 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: GET บน Edit-URI
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: POST บน Edit-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 สร้าง (หรือถ้าคุณเพิ่มส่วนหัว X-In-Progress เป็น 202 ที่ยอมรับ) และใบเสร็จรับเงินเงินฝาก
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 สร้างแล้วและใบเสร็จรับเงินเงินฝาก คุณสามารถเพิ่ม -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: DELETE บน Edit-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]
สร้างการตอบสนองข้อผิดพลาด ErrorContent ในการฝากแพ็คเกจที่มีประเภทแพ็คเกจไม่ตรงกับส่วนหัว X-Packaging
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 รายการ