Statistics
| Branch: | Tag: | Revision:

root / docs / object-api-guide.rst @ a7887941

History | View | Annotate | Download (70.6 kB)

1
Pithos API
2
==========
3

    
4
Introduction
5
------------
6

    
7
Pithos is a storage service implemented by GRNET (http://www.grnet.gr). Data is stored as objects, organized in containers, belonging to an account. This hierarchy of storage layers has been inspired by the OpenStack Object Storage (OOS) API and similar CloudFiles API by Rackspace. The Pithos API follows the OOS API as closely as possible. One of the design requirements has been to be able to use Pithos with clients built for the OOS, without changes.
8

    
9
However, to be able to take full advantage of the Pithos infrastructure, client software should be aware of the extensions that differentiate Pithos from OOS. Pithos objects can be updated, or appended to. Pithos will store sharing permissions per object and enforce corresponding authorization policies. Automatic version management, allows taking account and container listings back in time, as well as reading previous instances of objects.
10

    
11
The storage backend of Pithos is block oriented, permitting efficient, deduplicated data placement. The block structure of objects is exposed at the API layer, in order to encourage external software to implement advanced data management operations.
12

    
13
This document's goals are:
14

    
15
* Define the Pithos ReST API that allows the storage and retrieval of data and metadata via HTTP calls
16
* Specify metadata semantics and user interface guidelines for a common experience across client software implementations
17

    
18
The present document is meant to be read alongside the OOS API documentation. Thus, it is suggested that the reader is familiar with associated technologies, the OOS API as well as the first version of the Pithos API. This document refers to the second version of Pithos. Information on the first version of the storage API can be found at http://code.google.com/p/gss.
19

    
20
Whatever marked as to be determined (**TBD**), should not be considered by implementors.
21

    
22
More info about Pithos can be found here: https://code.grnet.gr/projects/pithos
23

    
24
Document Revisions
25
^^^^^^^^^^^^^^^^^^
26

    
27
=========================  ================================
28
Revision                   Description
29
=========================  ================================
30
0.15 (Feb 01, 2014)        Optionally enforce a specific content disposition type.
31
0.14 (Jun 18, 2013)        Forbidden response for public listing by non path owners.
32
0.14 (Apr 23, 2013)        Reply with Merkle hash in the ETag if MD5 is not computed.
33
0.13 (Mar 27, 2013)        Restrict public object listing only to the owner.
34
\                          Do not propagate public URL information in shared objects.
35
0.13 (Jan 21, 2013)        Proxy identity management services
36
\                          UUID to displayname translation
37
0.10 (Jul 18, 2012)        Support for bulk COPY/MOVE/DELETE
38
\                          Optionally include public objects in listings.
39
0.9 (Feb 17, 2012)         Change permissions model.
40
\                          Do not include user-defined metadata in account/container/object listings.
41
0.8 (Jan 24, 2012)         Update allowed versioning values.
42
\                          Change policy/meta formatting in JSON/XML replies.
43
\                          Document that all non-ASCII characters in headers should be URL-encoded.
44
\                          Support metadata-based queries when listing objects at the container level.
45
\                          Note Content-Type issue when using the internal django web server.
46
\                          Add object UUID field.
47
\                          Always reply with the MD5 in the ETag.
48
\                          Note that ``/login`` will only work if an external authentication system is defined.
49
\                          Include option to ignore Content-Type on ``COPY``/``MOVE``.
50
\                          Use format parameter for conflict (409) and uploaded hash list (container level) replies.
51
0.7 (Nov 21, 2011)         Suggest upload/download methods using hashmaps.
52
\                          Propose syncing algorithm.
53
\                          Support cross-account object copy and move.
54
\                          Pass token as a request parameter when using ``POST`` via an HTML form.
55
\                          Optionally use source account to update object from another object.
56
\                          Use container ``POST`` to upload missing blocks of data.
57
\                          Report policy in account headers.
58
\                          Add insufficient quota reply.
59
\                          Use special meta to always report Merkle hash.
60
0.6 (Sept 13, 2011)        Reply with Merkle hash as the ETag when updating objects.
61
\                          Include version id in object replace/change replies.
62
\                          Change conflict (409) replies format to text.
63
\                          Tags should be migrated to a meta value.
64
\                          Container ``PUT`` updates metadata/policy.
65
\                          Report allowed actions in shared object replies.
66
\                          Provide ``https://hostname/login`` for Shibboleth authentication.
67
\                          Use ``hashmap`` parameter in object ``GET``/``PUT`` to use hashmaps.
68
0.5 (July 22, 2011)        Object update from another object's data.
69
\                          Support object truncate.
70
\                          Create object using a standard HTML form.
71
\                          Purge container/object history.
72
\                          List other accounts that share objects with a user.
73
\                          List shared containers/objects.
74
\                          Update implementation guidelines.
75
\                          Check preconditions when creating/updating objects.
76
0.4 (July 01, 2011)        Object permissions and account groups.
77
\                          Control versioning behavior and container quotas with container policy directives.
78
\                          Support updating/deleting individual metadata with ``POST``.
79
\                          Create object using hashmap.
80
0.3 (June 14, 2011)        Large object support with ``X-Object-Manifest``.
81
\                          Allow for publicly available objects via ``https://hostname/public``.
82
\                          Support time-variant account/container listings.
83
\                          Add source version when duplicating with ``PUT``/``COPY``.
84
\                          Request version in object ``HEAD``/``GET`` requests (list versions with ``GET``).
85
0.2 (May 31, 2011)         Add object meta listing and filtering in containers.
86
\                          Include underlying storage characteristics in container meta.
87
\                          Support for partial object updates through ``POST``.
88
\                          Expose object hashmaps through ``GET``.
89
\                          Support for multi-range object ``GET`` requests.
90
0.1 (May 17, 2011)         Initial release. Based on OpenStack Object Storage Developer Guide API v1 (Apr. 15, 2011).
91
=========================  ================================
92

    
93
Pithos Users and Authentication
94
-------------------------------
95

    
96
In Pithos, each user is uniquely identified by a token. All API requests require a token and each token is internally resolved to an account string. The API uses the account string to identify the user's own files, thus whether a request is local or cross-account.
97

    
98
Pithos does not keep a user database. For development and testing purposes, user identifiers and their corresponding tokens can be defined in the settings file. However, Pithos is designed with an external authentication service in mind. This service must handle the details of validating user credentials and communicate with Pithos via a middleware software component that, given a token, fills in the internal request account variable.
99

    
100
Client software using Pithos, if not already knowing a user's identifier and token, should forward to the ``/login`` URI. The Pithos server, depending on its configuration will redirect to the appropriate login page.
101

    
102
The login URI accepts the following parameters:
103

    
104
======================  =========================
105
Request Parameter Name  Value
106
======================  =========================
107
next                    The URI to redirect to when the process is finished
108
renew                   Force token renewal (no value parameter)
109
force                   Force logout current user (no value parameter)
110
======================  =========================
111

    
112
When done with logging in, the service's login URI should redirect to the URI provided with ``next``, adding the ``token`` parameters which contains authentication token.
113

    
114
If ``next`` request parameter is missing the call fails with BadRequest (400) response status.
115

    
116
A user management service that implements a login URI according to these conventions is Astakos (https://code.grnet.gr/projects/astakos), by GRNET.
117

    
118
User feedback
119
-------------
120

    
121
Client software using Pithos, should forward to the ``/feedback`` URI. The Pithos service, depending on its configuration will delegate the request to the appropriate identity management URI.
122

    
123
============================ =========  ==================
124
Uri                          Method     Description
125
============================ =========  ==================
126
``/pithos/astakos/feedback`` POST       Send feedback
127
============================ =========  ==================
128

    
129
|
130

    
131
======================  =========================
132
Request Parameter Name  Value
133
======================  =========================
134
feedback_msg            Feedback message
135
feedback_data           Additional information about service client status
136
======================  =========================
137

    
138
|
139

    
140
====================  ===========================
141
Request Header Name   Value
142
====================  ===========================
143
X-Auth-Token          User authentication token
144
====================  ===========================
145

    
146
|
147

    
148
=========================== =====================
149
Return Code                 Description
150
=========================== =====================
151
200 (OK)                    The request succeeded
152
502 (Bad Gateway)           Send feedback failure
153
400 (Bad Request)           Method not allowed or invalid message data
154
401 (Unauthorized)          Missing or expired user token
155
500 (Internal Server Error) The request cannot be completed because of an internal error
156
=========================== =====================
157

    
158
User translation catalogs
159
-------------------------
160

    
161
Client software using Pithos, should forward to the ``/user_catalogs`` URI to get uuid to displayname translations and vice versa. The Pithos service, depending on its configuration will delegate the request to the appropriate identity management URI.
162

    
163
================================= =========  ==================
164
Uri                               Method     Description
165
================================= =========  ==================
166
``/pithos/astakos/user_catalogs`` POST       Get 2 catalogs containing uuid to displayname mapping and the opposite
167
================================= =========  ==================
168

    
169
|
170

    
171
====================  ===========================
172
Request Header Name   Value
173
====================  ===========================
174
X-Auth-Token          User authentication token
175
====================  ===========================
176

    
177
The request body is a json formatted dictionary containing a list with uuids and another list of displaynames to translate.
178

    
179
Example request content:
180

    
181
::
182

    
183
  {"displaynames": ["user1@example.com", "user2@example.com"],
184
   "uuids":["ff53baa9-c025-4d56-a6e3-963db0438830", "a9dc21d2-bcb2-4104-9a9e-402b7c70d6d8"]}
185

    
186
Example reply:
187

    
188
::
189

    
190
  {"displayname_catalog": {"user1@example.com": "a9dc21d2-bcb2-4104-9a9e-402b7c70d6d8",
191
                        "user2@example.com": "816351c7-7405-4f26-a968-6380cf47ba1f"},
192
  'uuid_catalog': {"a9dc21d2-bcb2-4104-9a9e-402b7c70d6d8": "user1@example.com",
193
                   "ff53baa9-c025-4d56-a6e3-963db0438830": "user2@example.com"}}
194

    
195

    
196
|
197

    
198
=========================== =====================
199
Return Code                 Description
200
=========================== =====================
201
200 (OK)                    The request succeeded
202
400 (Bad Request)           Method not allowed or request body is not json formatted
203
401 (Unauthorized)          Missing or expired or invalid user token
204
500 (Internal Server Error) The request cannot be completed because of an internal error
205
=========================== =====================
206

    
207
The Pithos API
208
--------------
209

    
210
The URI requests supported by the Pithos API follow one of the following forms:
211

    
212
* Top level: ``https://hostname/v1/``
213
* Account level: ``https://hostname/v1/<account>``
214
* Container level: ``https://hostname/v1/<account>/<container>``
215
* Object level: ``https://hostname/v1/<account>/<container>/<object>``
216

    
217
All requests must include an ``X-Auth-Token`` - as a header, or a parameter.
218

    
219
The allowable request operations and respective return codes per level are presented in the remainder of this chapter. Common to all requests are the following return codes.
220

    
221
==============================  ================================
222
Return Code                     Description
223
==============================  ================================
224
400 (Bad Request)               The request is invalid
225
401 (Unauthorized)              Missing or invalid token
226
403 (Forbidden)                 Request not allowed
227
404 (Not Found)                 The requested resource was not found
228
413 (Request Entity Too Large)  Insufficient quota to complete the request
229
503 (Service Unavailable)       The request cannot be completed because of an internal error
230
==============================  ================================
231

    
232
Top Level
233
^^^^^^^^^
234

    
235
List of operations:
236

    
237
=========  ==================
238
Operation  Description
239
=========  ==================
240
GET        Authentication (for compatibility with the OOS API) or list allowed accounts
241
=========  ==================
242

    
243
GET
244
"""
245

    
246
If the ``X-Auth-User`` and ``X-Auth-Key`` headers are given, a dummy ``X-Auth-Token`` and ``X-Storage-Url`` will be replied, which can be used as a guest token/namespace for testing Pithos.
247

    
248
================  =====================
249
Return Code       Description
250
================  =====================
251
204 (No Content)  The request succeeded
252
================  =====================
253

    
254
If an ``X-Auth-Token`` is already present, the operation will be interpreted as a request to list other accounts that share objects to the user.
255

    
256
======================  =========================
257
Request Parameter Name  Value
258
======================  =========================
259
limit                   The amount of results requested (default is 10000)
260
marker                  Return containers with name lexicographically after marker
261
format                  Optional extended reply type (can be ``json`` or ``xml``)
262
======================  =========================
263

    
264
The reply is a list of account names.
265
If a ``format=xml`` or ``format=json`` argument is given, extended information on the accounts will be returned, serialized in the chosen format.
266
For each account, the information will include the following (names will be in lower case and with hyphens replaced with underscores):
267

    
268
===========================  ============================
269
Name                         Description
270
===========================  ============================
271
name                         The name of the account
272
last_modified                The last account modification date (regardless of ``until``)
273
===========================  ============================
274

    
275
Example ``format=json`` reply:
276

    
277
::
278

    
279
  [{"name": "user-uuid", "last_modified": "2011-12-02T08:10:41.565891+00:00"}, ...]
280

    
281
Example ``format=xml`` reply:
282

    
283
::
284

    
285
  <?xml version="1.0" encoding="UTF-8"?>
286
  <accounts>
287
    <account>
288
      <name>user-uuid</name>
289
      <last_modified>2011-12-02T08:10:41.565891+00:00</last_modified>
290
    </account>
291
    <account>...</account>
292
  </accounts>
293

    
294
===========================  =====================
295
Return Code                  Description
296
===========================  =====================
297
200 (OK)                     The request succeeded
298
204 (No Content)             The user has no access to other accounts (only for non-extended replies)
299
===========================  =====================
300

    
301
Will use a ``200`` return code if the reply is of type JSON/XML.
302

    
303
Account Level
304
^^^^^^^^^^^^^
305

    
306
List of operations:
307

    
308
=========  ==================
309
Operation  Description
310
=========  ==================
311
HEAD       Retrieve account metadata
312
GET        List containers
313
POST       Update account metadata
314
=========  ==================
315

    
316
HEAD
317
""""
318

    
319
====================  ===========================
320
Request Header Name   Value
321
====================  ===========================
322
If-Modified-Since     Retrieve if account has changed since provided timestamp
323
If-Unmodified-Since   Retrieve if account has not changed since provided timestamp
324
====================  ===========================
325

    
326
|
327

    
328
======================  ===================================
329
Request Parameter Name  Value
330
======================  ===================================
331
until                   Optional timestamp
332
======================  ===================================
333

    
334
Cross-user requests are not allowed to use ``until`` and only include the account modification date in the reply.
335

    
336
==========================  =====================
337
Reply Header Name           Value
338
==========================  =====================
339
X-Account-Container-Count   The total number of containers
340
X-Account-Bytes-Used        The total number of bytes stored
341
X-Account-Until-Timestamp   The last account modification date until the timestamp provided
342
X-Account-Group-*           Optional user defined groups
343
X-Account-Policy-Quota      Account quota limit
344
X-Account-Meta-*            Optional user defined metadata
345
Last-Modified               The last account modification date (regardless of ``until``)
346
==========================  =====================
347

    
348
|
349

    
350
================  =====================
351
Return Code       Description
352
================  =====================
353
204 (No Content)  The request succeeded
354
================  =====================
355

    
356

    
357
GET
358
"""
359

    
360
====================  ===========================
361
Request Header Name   Value
362
====================  ===========================
363
If-Modified-Since     Retrieve if account has changed since provided timestamp
364
If-Unmodified-Since   Retrieve if account has not changed since provided timestamp
365
====================  ===========================
366

    
367
|
368

    
369
======================  =========================
370
Request Parameter Name  Value
371
======================  =========================
372
limit                   The amount of results requested (default is 10000)
373
marker                  Return containers with name lexicographically after marker
374
format                  Optional extended reply type (can be ``json`` or ``xml``)
375
shared                  Show only shared containers (no value parameter)
376
public                  Show only public containers (no value parameter / avalaible only for owner requests)
377
until                   Optional timestamp
378
======================  =========================
379

    
380
The reply is a list of container names. Account headers (as in a ``HEAD`` request) will also be included.
381
Cross-user requests are not allowed to use ``until`` and only include the account/container modification dates in the reply.
382

    
383
If a ``format=xml`` or ``format=json`` argument is given, extended information on the containers will be returned, serialized in the chosen format.
384
For each container, the information will include all container metadata, except user-defined (names will be in lower case and with hyphens replaced with underscores):
385

    
386
===========================  ============================
387
Name                         Description
388
===========================  ============================
389
name                         The name of the container
390
count                        The number of objects inside the container
391
bytes                        The total size of the objects inside the container
392
last_modified                The last container modification date (regardless of ``until``)
393
x_container_until_timestamp  The last container modification date until the timestamp provided
394
x_container_policy           Container behavior and limits
395
===========================  ============================
396

    
397
Example ``format=json`` reply:
398

    
399
::
400

    
401
  [{"name": "pithos",
402
    "bytes": 62452,
403
    "count": 8374,
404
    "last_modified": "2011-12-02T08:10:41.565891+00:00",
405
    "x_container_policy": {"quota": "53687091200", "versioning": "auto"}}, ...]
406

    
407
Example ``format=xml`` reply:
408

    
409
::
410

    
411
  <?xml version="1.0" encoding="UTF-8"?>
412
  <account name="user-uuid">
413
    <container>
414
      <name>pithos</name>
415
      <bytes>62452</bytes>
416
      <count>8374</count>
417
      <last_modified>2011-12-02T08:10:41.565891+00:00</last_modified>
418
      <x_container_policy>
419
        <key>quota</key><value>53687091200</value>
420
        <key>versioning</key><value>auto</value>
421
      </x_container_policy>
422
    </container>
423
    <container>...</container>
424
  </account>
425

    
426
For more examples of container details returned in JSON/XML formats refer to the OOS API documentation. In addition to the OOS API, Pithos returns policy fields, grouped as key-value pairs.
427

    
428
===========================  =====================
429
Return Code                  Description
430
===========================  =====================
431
200 (OK)                     The request succeeded
432
204 (No Content)             The account has no containers (only for non-extended replies)
433
304 (Not Modified)           The account has not been modified
434
403 (Forbidden)              Public is requested but the request user is not the path owner
435
412 (Precondition Failed)    The condition set can not be satisfied
436
===========================  =====================
437

    
438
Will use a ``200`` return code if the reply is of type JSON/XML.
439

    
440

    
441
POST
442
""""
443

    
444
====================  ===========================
445
Request Header Name   Value
446
====================  ===========================
447
X-Account-Group-*     Optional user defined groups
448
X-Account-Meta-*      Optional user defined metadata
449
====================  ===========================
450

    
451
|
452

    
453
======================  ============================================
454
Request Parameter Name  Value
455
======================  ============================================
456
update                  Do not replace metadata/groups (no value parameter)
457
======================  ============================================
458

    
459
No reply content/headers.
460

    
461
The operation will overwrite all user defined metadata, except if ``update`` is defined.
462
To create a group, include an ``X-Account-Group-*`` header with the name in the key and a comma separated list of user identifiers in the value. If no ``X-Account-Group-*`` header is present, no changes will be applied to groups. The ``update`` parameter also applies to groups. To delete a specific group, use ``update`` and an empty header value.
463

    
464
================  ===============================
465
Return Code       Description
466
================  ===============================
467
202 (Accepted)    The request has been accepted
468
================  ===============================
469

    
470

    
471
Container Level
472
^^^^^^^^^^^^^^^
473

    
474
List of operations:
475

    
476
=========  ============================
477
Operation  Description
478
=========  ============================
479
HEAD       Retrieve container metadata
480
GET        List objects
481
PUT        Create/update container
482
POST       Update container metadata
483
DELETE     Delete container
484
=========  ============================
485

    
486

    
487
HEAD
488
""""
489

    
490
====================  ===========================
491
Request Header Name   Value
492
====================  ===========================
493
If-Modified-Since     Retrieve if container has changed since provided timestamp
494
If-Unmodified-Since   Retrieve if container has not changed since provided timestamp
495
====================  ===========================
496

    
497
|
498

    
499
======================  ===================================
500
Request Parameter Name  Value
501
======================  ===================================
502
until                   Optional timestamp
503
======================  ===================================
504

    
505
Cross-user requests are not allowed to use ``until`` and only include the container modification date in the reply.
506

    
507
===========================  ===============================
508
Reply Header Name            Value
509
===========================  ===============================
510
X-Container-Object-Count     The total number of objects in the container
511
X-Container-Bytes-Used       The total number of bytes of all objects stored
512
X-Container-Block-Size       The block size used by the storage backend
513
X-Container-Block-Hash       The hash algorithm used for block identifiers in object hashmaps
514
X-Container-Until-Timestamp  The last container modification date until the timestamp provided
515
X-Container-Object-Meta      A list with all meta keys used by objects (**TBD**)
516
X-Container-Policy-*         Container behavior and limits
517
X-Container-Meta-*           Optional user defined metadata
518
Last-Modified                The last container modification date (regardless of ``until``)
519
===========================  ===============================
520

    
521
The keys returned in ``X-Container-Object-Meta`` are all the unique strings after the ``X-Object-Meta-`` prefix, formatted as a comma-separated list. See container ``PUT`` for a reference of policy directives. (**TBD**)
522

    
523
================  ===============================
524
Return Code       Description
525
================  ===============================
526
204 (No Content)  The request succeeded
527
================  ===============================
528

    
529

    
530
GET
531
"""
532

    
533
====================  ===========================
534
Request Header Name   Value
535
====================  ===========================
536
If-Modified-Since     Retrieve if container has changed since provided timestamp
537
If-Unmodified-Since   Retrieve if container has not changed since provided timestamp
538
====================  ===========================
539

    
540
|
541

    
542
======================  ===================================
543
Request Parameter Name  Value
544
======================  ===================================
545
limit                   The amount of results requested (default is 10000)
546
marker                  Return containers with name lexicographically after marker
547
prefix                  Return objects starting with prefix
548
delimiter               Return objects up to the delimiter (discussion follows)
549
path                    Assume ``prefix=path`` and ``delimiter=/``
550
format                  Optional extended reply type (can be ``json`` or ``xml``)
551
meta                    Return objects that satisfy the key queries in the specified comma separated list (use ``<key>``, ``!<key>`` for existence queries, ``<key><op><value>`` for value queries, where ``<op>`` can be one of ``=``, ``!=``, ``<=``, ``>=``, ``<``, ``>``)
552
shared                  Show only objects (no value parameter)
553
public                  Show only public objects (no value parameter / avalaible only for owner requests)
554
until                   Optional timestamp
555
======================  ===================================
556

    
557
The ``path`` parameter overrides ``prefix`` and ``delimiter``. When using ``path``, results will include objects ending in ``delimiter``.
558

    
559
The keys given with ``meta`` will be matched with the strings after the ``X-Object-Meta-`` prefix.
560

    
561
The reply is a list of object names. Container headers (as in a ``HEAD`` request) will also be included.
562
Cross-user requests are not allowed to use ``until`` and include the following limited set of headers in the reply:
563

    
564
===========================  ===============================
565
Reply Header Name            Value
566
===========================  ===============================
567
X-Container-Block-Size       The block size used by the storage backend
568
X-Container-Block-Hash       The hash algorithm used for block identifiers in object hashmaps
569
X-Container-Object-Meta      A list with all meta keys used by allowed objects (**TBD**)
570
Last-Modified                The last container modification date
571
===========================  ===============================
572

    
573
If a ``format=xml`` or ``format=json`` argument is given, extended information on the objects will be returned, serialized in the chosen format.
574
For each object, the information will include all object metadata, except user-defined (names will be in lower case and with hyphens replaced with underscores). User-defined metadata includes ``X-Object-Meta-*``, ``X-Object-Manifest``, ``Content-Disposition`` and ``Content-Encoding`` keys. Also, sharing directives will only be included with the actual shared objects (inherited permissions are not calculated):
575

    
576
==========================  ======================================
577
Name                        Description
578
==========================  ======================================
579
name                        The name of the object
580
hash                        The ETag of the object
581
bytes                       The size of the object
582
content_type                The MIME content type of the object
583
last_modified               The last object modification date (regardless of version)
584
x_object_hash               The Merkle hash
585
x_object_uuid               The object's UUID
586
x_object_version            The object's version identifier
587
x_object_version_timestamp  The object's version timestamp
588
x_object_modified_by        The user that committed the object's version
589
x_object_sharing            Object permissions (optional)
590
x_object_allowed_to         Allowed actions on object (optional)
591
x_object_public             Object's publicly accessible URI (optional: present if the object is public and the request user is the object owner)
592
==========================  ======================================
593

    
594
Sharing metadata and last modification timestamp will only be returned if there is no ``until`` parameter defined.
595

    
596
Extended replies may also include virtual directory markers in separate sections of the ``json`` or ``xml`` results.
597
Virtual directory markers are only included when ``delimiter`` is explicitly set. They correspond to the substrings up to and including the first occurrence of the delimiter.
598
In JSON results they appear as dictionaries with only a ``subdir`` key. In XML results they appear interleaved with ``<object>`` tags as ``<subdir name="..." />``.
599
In case there is an object with the same name as a virtual directory marker, the object will be returned.
600

    
601
Example ``format=json`` reply:
602

    
603
::
604

    
605
  [{"name": "object",
606
    "bytes": 0,
607
    "hash": "d41d8cd98f00b204e9800998ecf8427e",
608
    "content_type": "application/octet-stream",
609
    "last_modified": "2011-12-02T08:10:41.565891+00:00",
610
    "x_object_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
611
    "x_object_uuid": "8ed9af1b-c948-4bb6-82b0-48344f5c822c",
612
    "x_object_version": 98,
613
    "x_object_version_timestamp": "1322813441.565891",
614
    "x_object_modified_by": "user-uuid"}, ...]
615

    
616
Example ``format=xml`` reply:
617

    
618
::
619

    
620
  <?xml version="1.0" encoding="UTF-8"?>
621
  <container name="pithos">
622
    <object>
623
      <name>object</name>
624
      <bytes>0</bytes>
625
      <hash>d41d8cd98f00b204e9800998ecf8427e</hash>
626
      <content_type>application/octet-stream</content_type>
627
      <last_modified>2011-12-02T08:10:41.565891+00:00</last_modified>
628
      <x_object_hash>e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</x_object_hash>
629
      <x_object_uuid>8ed9af1b-c948-4bb6-82b0-48344f5c822c</x_object_uuid>
630
      <x_object_version>98</x_object_version>
631
      <x_object_version_timestamp>1322813441.565891</x_object_version_timestamp>
632
      <x_object_modified_by>user-uuid</x_object_modified_by>
633
    </object>
634
    <object>...</object>
635
  </container>
636

    
637
For more examples of container details returned in JSON/XML formats refer to the OOS API documentation. In addition to the OOS API, Pithos returns more fields that should help with synchronization.
638

    
639
===========================  ===============================
640
Return Code                  Description
641
===========================  ===============================
642
200 (OK)                     The request succeeded
643
204 (No Content)             The container has no objects (only for non-extended replies)
644
304 (Not Modified)           The container has not been modified
645
403 (Forbidden)              Public is requested but the request user is not the path owner
646
412 (Precondition Failed)    The condition set can not be satisfied
647
===========================  ===============================
648

    
649
Will use a ``200`` return code if the reply is of type JSON/XML.
650

    
651

    
652
PUT
653
"""
654

    
655
====================  ================================
656
Request Header Name   Value
657
====================  ================================
658
X-Container-Policy-*  Container behavior and limits
659
X-Container-Meta-*    Optional user defined metadata
660
====================  ================================
661
 
662
No reply content/headers.
663

    
664
If no policy is defined, the container will be created with the default values.
665
Available policy directives:
666

    
667
* ``versioning``: Set to ``auto`` or ``none`` (default is ``auto``)
668
* ``quota``: Size limit in KB (default is ``0`` - unlimited)
669

    
670
If the container already exists, the operation is equal to a ``POST`` with ``update`` defined.
671

    
672
================  ===============================
673
Return Code       Description
674
================  ===============================
675
201 (Created)     The container has been created
676
202 (Accepted)    The request has been accepted
677
================  ===============================
678

    
679

    
680
POST
681
""""
682

    
683
====================  ================================
684
Request Header Name   Value
685
====================  ================================
686
Content-Length        The size of the supplied data (optional, to upload)
687
Content-Type          The MIME content type of the supplied data (optional, to upload)
688
Transfer-Encoding     Set to ``chunked`` to specify incremental uploading (if used, ``Content-Length`` is ignored)
689
X-Container-Policy-*  Container behavior and limits
690
X-Container-Meta-*    Optional user defined metadata
691
====================  ================================
692

    
693
|
694

    
695
======================  ============================================
696
Request Parameter Name  Value
697
======================  ============================================
698
format                  Optional hash list reply type (can be ``json`` or ``xml``)
699
update                  Do not replace metadata/policy (no value parameter)
700
======================  ============================================
701

    
702
No reply content/headers, except when uploading data, where the reply consists of a list of hashes for the blocks received (in the format specified).
703

    
704
The operation will overwrite all user defined metadata, except if ``update`` is defined.
705
To change policy, include an ``X-Container-Policy-*`` header with the name in the key. If no ``X-Container-Policy-*`` header is present, no changes will be applied to policy. The ``update`` parameter also applies to policy - deleted values will revert to defaults. To delete/revert a specific policy directive, use ``update`` and an empty header value. See container ``PUT`` for a reference of policy directives.
706

    
707
To upload blocks of data to the container, set ``Content-Type`` to ``application/octet-stream`` and ``Content-Length`` to a valid value (except if using ``chunked`` as the ``Transfer-Encoding``).
708

    
709
================  ===============================
710
Return Code       Description
711
================  ===============================
712
202 (Accepted)    The request has been accepted
713
================  ===============================
714

    
715

    
716
DELETE
717
""""""
718

    
719
======================  ===================================
720
Request Parameter Name  Value
721
======================  ===================================
722
until                   Optional timestamp
723
delimiter               Optional delete objects starting with container name and delimiter
724
======================  ===================================
725

    
726
If ``until`` is defined, the container is "purged" up to that time (the history of all objects up to then is deleted). If also ``delimiter`` is defined, purge is applied only on the container.
727

    
728
No reply content/headers.
729

    
730
================  ===============================
731
Return Code       Description
732
================  ===============================
733
204 (No Content)  The request succeeded
734
409 (Conflict)    The container is not empty
735
================  ===============================
736

    
737

    
738
Object Level
739
^^^^^^^^^^^^
740

    
741
List of operations:
742

    
743
=========  =================================
744
Operation  Description
745
=========  =================================
746
HEAD       Retrieve object metadata
747
GET        Read object data
748
PUT        Write object data or copy/move object
749
COPY       Copy object
750
MOVE       Move object
751
POST       Update object metadata/data
752
DELETE     Delete object
753
=========  =================================
754

    
755

    
756
HEAD
757
""""
758

    
759
====================  ================================
760
Request Header Name   Value
761
====================  ================================
762
If-Match              Retrieve if ETags match
763
If-None-Match         Retrieve if ETags don't match
764
If-Modified-Since     Retrieve if object has changed since provided timestamp
765
If-Unmodified-Since   Retrieve if object has not changed since provided timestamp
766
====================  ================================
767

    
768
|
769

    
770
======================  ===================================
771
Request Parameter Name  Value
772
======================  ===================================
773
version                 Optional version identifier
774
======================  ===================================
775

    
776
|
777

    
778
==========================  ===============================
779
Reply Header Name           Value
780
==========================  ===============================
781
ETag                        The ETag of the object
782
Content-Length              The size of the object
783
Content-Type                The MIME content type of the object
784
Last-Modified               The last object modification date (regardless of version)
785
Content-Encoding            The encoding of the object (optional)
786
Content-Disposition         The presentation style of the object (optional)
787
X-Object-Hash               The Merkle hash
788
X-Object-UUID               The object's UUID
789
X-Object-Version            The object's version identifier
790
X-Object-Version-Timestamp  The object's version timestamp
791
X-Object-Modified-By        The user that comitted the object's version
792
X-Object-Manifest           Object parts prefix in ``<container>/<object>`` form (optional)
793
X-Object-Sharing            Object permissions (optional)
794
X-Object-Shared-By          Object inheriting permissions (optional)
795
X-Object-Allowed-To         Allowed actions on object (optional)
796
X-Object-Public             Object's publicly accessible URI (optional: present if the object is public and the request user is the object owner)
797
X-Object-Meta-*             Optional user defined metadata
798
==========================  ===============================
799

    
800
|
801

    
802
================  ===============================
803
Return Code       Description
804
================  ===============================
805
200 (No Content)  The request succeeded
806
================  ===============================
807

    
808

    
809
GET
810
"""
811

    
812
====================  ================================
813
Request Header Name   Value
814
====================  ================================
815
Range                 Optional range of data to retrieve
816
If-Range              Retrieve the missing part if entity is unchanged; otherwise, retrieve the entire new entity (used together with Range header)
817
If-Match              Retrieve if ETags match
818
If-None-Match         Retrieve if ETags don't match
819
If-Modified-Since     Retrieve if object has changed since provided timestamp
820
If-Unmodified-Since   Retrieve if object has not changed since provided timestamp
821
====================  ================================
822

    
823
|
824

    
825
======================  ===================================
826
Request Parameter Name  Value
827
======================  ===================================
828
format                  Optional extended reply type (can be ``json`` or ``xml``)
829
hashmap                 Optional request for hashmap (no value parameter)
830
version                 Optional version identifier or ``list`` (specify a format if requesting a list)
831
disposition-type        Optional enforcement of the specific content disposition type (can be ``inline`` or ``attachement`` otherwise it is ignored - this will override the object's Content-Disposition)
832
======================  ===================================
833

    
834
The reply is the object's data (or part of it), except if a hashmap is requested with ``hashmap``, or a version list with ``version=list`` (in both cases an extended reply format must be specified). Object headers (as in a ``HEAD`` request) are always included.
835

    
836
Hashmaps expose the underlying storage format of the object. Note that each hash is computed after trimming trailing null bytes of the corresponding block. The ``X-Object-Hash`` header reports the single Merkle hash of the object's hashmap (refer to http://bittorrent.org/beps/bep_0030.html for more information).
837

    
838
Example ``format=json`` reply:
839

    
840
::
841

    
842
  {"block_hash": "sha1", "hashes": ["7295c41da03d7f916440b98e32c4a2a39351546c", ...], "block_size": 131072, "bytes": 242}
843

    
844
Example ``format=xml`` reply:
845

    
846
::
847

    
848
  <?xml version="1.0" encoding="UTF-8"?>
849
  <object name="file" bytes="24223726" block_size="131072" block_hash="sha1">
850
    <hash>7295c41da03d7f916440b98e32c4a2a39351546c</hash>
851
    <hash>...</hash>
852
  </object>
853

    
854
Version lists include the version identifier and timestamp for each available object version. Version identifiers can be arbitrary strings, so use the timestamp to find newer versions.
855

    
856
Example ``format=json`` reply:
857

    
858
::
859

    
860
  {"versions": [[85, "1322734861.248469"], [86, "1322734905.009272"], ...]}
861

    
862
Example ``format=xml`` reply:
863

    
864
::
865

    
866
  <?xml version="1.0" encoding="UTF-8"?>
867
  <object name="file">
868
    <version timestamp="1322734861.248469">85</version>
869
    <version timestamp="1322734905.009272">86</version>
870
    <version timestamp="...">...</version>
871
  </object>
872

    
873
The ``Range`` header may include multiple ranges, as outlined in RFC2616. Then the ``Content-Type`` of the reply will be ``multipart/byteranges`` and each part will include a ``Content-Range`` header.
874

    
875
==========================  ===============================
876
Reply Header Name           Value
877
==========================  ===============================
878
ETag                        The ETag of the object
879
Content-Length              The size of the data returned
880
Content-Type                The MIME content type of the object
881
Content-Range               The range of data included (only on a single range request)
882
Last-Modified               The last object modification date (regardless of version)
883
Content-Encoding            The encoding of the object (optional)
884
Content-Disposition         The presentation style of the object (optional)
885
X-Object-Hash               The Merkle hash
886
X-Object-UUID               The object's UUID
887
X-Object-Version            The object's version identifier
888
X-Object-Version-Timestamp  The object's version timestamp
889
X-Object-Modified-By        The user that comitted the object's version
890
X-Object-Manifest           Object parts prefix in ``<container>/<object>`` form (optional)
891
X-Object-Sharing            Object permissions (optional)
892
X-Object-Shared-By          Object inheriting permissions (optional)
893
X-Object-Allowed-To         Allowed actions on object (optional)
894
X-Object-Public             Object's publicly accessible URI (optional: present if the object is public and the request user is the object owner)
895
X-Object-Meta-*             Optional user defined metadata
896
==========================  ===============================
897

    
898
Sharing headers (``X-Object-Sharing``, ``X-Object-Shared-By`` and ``X-Object-Allowed-To``) are only included if the request is for the object's latest version (no specific ``version`` parameter is set).
899

    
900
===========================  ==============================
901
Return Code                  Description
902
===========================  ==============================
903
200 (OK)                     The request succeeded
904
206 (Partial Content)        The range request succeeded
905
304 (Not Modified)           The object has not been modified
906
412 (Precondition Failed)    The condition set can not be satisfied
907
416 (Range Not Satisfiable)  The requested range is out of limits
908
===========================  ==============================
909

    
910

    
911
PUT
912
"""
913

    
914
====================  ================================
915
Request Header Name   Value
916
====================  ================================
917
If-Match              Put if ETags match with current object
918
If-None-Match         Put if ETags don't match with current object
919
ETag                  The MD5 hash of the object (optional to check written data)
920
Content-Length        The size of the data written
921
Content-Type          The MIME content type of the object
922
Transfer-Encoding     Set to ``chunked`` to specify incremental uploading (if used, ``Content-Length`` is ignored)
923
X-Copy-From           The source path in the form ``/<container>/<object>``
924
X-Move-From           The source path in the form ``/<container>/<object>``
925
X-Source-Account      The source account to copy/move from
926
X-Source-Version      The source version to copy from
927
Content-Encoding      The encoding of the object (optional)
928
Content-Disposition   The presentation style of the object (optional)
929
X-Object-Manifest     Object parts prefix in ``<container>/<object>`` form (optional)
930
X-Object-Sharing      Object permissions (optional)
931
X-Object-Public       Object is publicly accessible (optional)
932
X-Object-Meta-*       Optional user defined metadata
933
====================  ================================
934

    
935
|
936

    
937
======================  ===================================
938
Request Parameter Name  Value
939
======================  ===================================
940
format                  Optional extended request/conflict response type (can be ``json`` or ``xml``)
941
hashmap                 Optional hashmap provided instead of data (no value parameter)
942
delimiter               Optional copy/move objects starting with object's path and delimiter (to be used with X-Copy-From/X-Move-From)
943
======================  ===================================
944

    
945
The request is the object's data (or part of it), except if a hashmap is provided (using ``hashmap`` and ``format`` parameters). If using a hashmap and all different parts are stored in the server, the object is created. Otherwise the server returns Conflict (409) with the list of the missing parts (in simple text format, with one hash per line, or in JSON/XML - depending on the ``format`` parameter).
946

    
947
Hashmaps should be formatted as outlined in ``GET``.
948

    
949
==========================  ===============================
950
Reply Header Name           Value
951
==========================  ===============================
952
ETag                        The MD5 (or the Merkle if MD5 is deactivated) hash of the object
953
X-Object-Version            The object's new version
954
==========================  ===============================
955

    
956
The ``X-Object-Sharing`` header may include either a ``read=...`` comma-separated user/group list, or a ``write=...`` comma-separated user/group list, or both separated by a semicolon (``;``). Groups are specified as ``<account>:<group>``. To publish the object, set ``X-Object-Public`` to ``true``. To unpublish, set to ``false``, or use an empty header value.
957

    
958
==============================  ==============================
959
Return Code                     Description
960
==============================  ==============================
961
201 (Created)                   The object has been created
962
409 (Conflict)                  The object can not be created from the provided hashmap (a list of missing hashes will be included in the reply)
963
411 (Length Required)           Missing ``Content-Length`` or ``Content-Type`` in the request
964
413 (Request Entity Too Large)  Insufficient quota to complete the request
965
422 (Unprocessable Entity)      The MD5 (or the Merkle if MD5 is deactivated) checksum of the data written to the storage system does not match the (optionally) supplied ETag value
966
==============================  ==============================
967

    
968

    
969
COPY
970
""""
971

    
972
====================  ================================
973
Request Header Name   Value
974
====================  ================================
975
If-Match              Proceed if ETags match with object
976
If-None-Match         Proceed if ETags don't match with object
977
Destination           The destination path in the form ``/<container>/<object>``
978
Destination-Account   The destination account to copy to
979
Content-Type          The MIME content type of the object (optional :sup:`*`)
980
Content-Encoding      The encoding of the object (optional)
981
Content-Disposition   The presentation style of the object (optional)
982
X-Source-Version      The source version to copy from
983
X-Object-Manifest     Object parts prefix in ``<container>/<object>`` form (optional)
984
X-Object-Sharing      Object permissions (optional)
985
X-Object-Public       Object is publicly accessible (optional)
986
X-Object-Meta-*       Optional user defined metadata
987
====================  ================================
988

    
989
:sup:`*` *When using django locally with the supplied web server, use the ignore_content_type parameter, or do provide a valid Content-Type, as a type of text/plain is applied by default to all requests. Client software should always state ignore_content_type, except when a Content-Type is explicitly defined by the user.*
990

    
991
======================  ===================================
992
Request Parameter Name  Value
993
======================  ===================================
994
format                  Optional conflict response type (can be ``json`` or ``xml``)
995
ignore_content_type     Ignore the supplied Content-Type
996
delimiter               Optional copy objects starting with object's path and delimiter
997
======================  ===================================
998

    
999
Refer to ``PUT``/``POST`` for a description of request headers. Metadata is also copied, updated with any values defined. Sharing/publishing options are not copied.
1000

    
1001
==========================  ===============================
1002
Reply Header Name           Value
1003
==========================  ===============================
1004
X-Object-Version            The object's new version
1005
==========================  ===============================
1006

    
1007
|
1008

    
1009
==============================  ==============================
1010
Return Code                     Description
1011
==============================  ==============================
1012
201 (Created)                   The object has been created
1013
413 (Request Entity Too Large)  Insufficient quota to complete the request
1014
==============================  ==============================
1015

    
1016

    
1017
MOVE
1018
""""
1019

    
1020
Same as ``COPY``, without the ``X-Source-Version`` request header. The ``MOVE`` operation is always applied on the latest version.
1021

    
1022

    
1023
POST
1024
""""
1025

    
1026
====================  ================================
1027
Request Header Name   Value
1028
====================  ================================
1029
If-Match              Proceed if ETags match with object
1030
If-None-Match         Proceed if ETags don't match with object
1031
Content-Length        The size of the data written (optional, to update)
1032
Content-Type          The MIME content type of the object (optional, to update)
1033
Content-Range         The range of data supplied (optional, to update)
1034
Transfer-Encoding     Set to ``chunked`` to specify incremental uploading (if used, ``Content-Length`` is ignored)
1035
Content-Encoding      The encoding of the object (optional)
1036
Content-Disposition   The presentation style of the object (optional)
1037
X-Source-Object       Update with data from the object at path ``/<container>/<object>`` (optional, to update)
1038
X-Source-Account      The source account to update from
1039
X-Source-Version      The source version to update from (optional, to update)
1040
X-Object-Bytes        The updated object's final size (optional, when updating)
1041
X-Object-Manifest     Object parts prefix in ``<container>/<object>`` form (optional)
1042
X-Object-Sharing      Object permissions (optional)
1043
X-Object-Public       Object is publicly accessible (optional)
1044
X-Object-Meta-*       Optional user defined metadata
1045
====================  ================================
1046

    
1047
|
1048

    
1049
======================  ============================================
1050
Request Parameter Name  Value
1051
======================  ============================================
1052
format                  Optional conflict response type (can be ``json`` or ``xml``)
1053
update                  Do not replace metadata (no value parameter)
1054
======================  ============================================
1055

    
1056
The ``Content-Encoding``, ``Content-Disposition``, ``X-Object-Manifest`` and ``X-Object-Meta-*`` headers are considered to be user defined metadata. An operation without the ``update`` parameter will overwrite all previous values and remove any keys not supplied. When using ``update`` any metadata with an empty value will be deleted.
1057

    
1058
To change permissions, include an ``X-Object-Sharing`` header (as defined in ``PUT``). To publish, include an ``X-Object-Public`` header, with a value of ``true``. If no such headers are defined, no changes will be applied to sharing/public. Use empty values to remove permissions/unpublish (unpublishing also works with ``false`` as a header value). Sharing options are applied to the object - not its versions.
1059

    
1060
To update an object's data:
1061

    
1062
* Either set ``Content-Type`` to ``application/octet-stream``, or provide an object with ``X-Source-Object``. If ``Content-Type`` has some other value, it will be ignored and only the metadata will be updated.
1063
* If the data is supplied in the request (using ``Content-Type`` instead of ``X-Source-Object``), a valid ``Content-Length`` header is required - except if using chunked transfers (set ``Transfer-Encoding`` to ``chunked``).
1064
* Set ``Content-Range`` as specified in RFC2616, with the following differences:
1065

    
1066
  * Client software MAY omit ``last-byte-pos`` of if the length of the range being transferred is unknown or difficult to determine.
1067
  * Client software SHOULD not specify the ``instance-length`` (use a ``*``), unless there is a reason for performing a size check at the server.
1068
* If ``Content-Range`` used has a ``byte-range-resp-spec = *``, data will be appended to the object.
1069

    
1070
Optionally, truncate the updated object to the desired length with the ``X-Object-Bytes`` header.
1071

    
1072
A data update will trigger an ETag change. Updated ETags may happen asynchronously and appear at the server with a delay.
1073

    
1074
No reply content. No reply headers if only metadata is updated.
1075

    
1076
==========================  ===============================
1077
Reply Header Name           Value
1078
==========================  ===============================
1079
ETag                        The new ETag of the object (data updated)
1080
X-Object-Version            The object's new version
1081
==========================  ===============================
1082

    
1083
|
1084

    
1085
==============================  ==============================
1086
Return Code                     Description
1087
==============================  ==============================
1088
202 (Accepted)                  The request has been accepted (not a data update)
1089
204 (No Content)                The request succeeded (data updated)
1090
400 (Bad Request)               Invalid ``X-Object-Sharing`` or ``X-Object-Bytes`` header or missing ``Content-Range`` header or invalid source object or source object length is smaller than range length or ``Content-Length`` does not match range length
1091
411 (Length Required)           Missing ``Content-Length`` in the request
1092
413 (Request Entity Too Large)  Insufficient quota to complete the request
1093
416 (Range Not Satisfiable)     The supplied range is invalid
1094
==============================  ==============================
1095

    
1096
The ``POST`` method can also be used for creating an object via a standard HTML form. If the request ``Content-Type`` is ``multipart/form-data``, none of the above headers will be processed. The form should have an ``X-Object-Data`` field, as in the following example. The token is passed as a request parameter. ::
1097

    
1098
  <form method="post" action="https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/folder/EXAMPLE.txt?X-Auth-Token=0000" enctype="multipart/form-data">
1099
    <input type="file" name="X-Object-Data">
1100
    <input type="submit">
1101
  </form>
1102

    
1103
This will create/override the object with the given name, as if using ``PUT``. The ``Content-Type`` of the object will be set to the value of the corresponding header sent in the part of the request containing the data (usually, automatically handled by the browser). Metadata, sharing and other object attributes can not be set this way. The response will contain the object's ETag.
1104

    
1105
==========================  ===============================
1106
Reply Header Name           Value
1107
==========================  ===============================
1108
ETag                        The MD5 (or the Merkle if MD5 is deactivated) hash of the object
1109
X-Object-Version            The object's new version
1110
==========================  ===============================
1111

    
1112
|
1113

    
1114
==============================  ==============================
1115
Return Code                     Description
1116
==============================  ==============================
1117
201 (Created)                   The object has been created
1118
413 (Request Entity Too Large)  Insufficient quota to complete the request
1119
==============================  ==============================
1120

    
1121

    
1122
DELETE
1123
""""""
1124

    
1125
======================  ===================================
1126
Request Parameter Name  Value
1127
======================  ===================================
1128
until                   Optional timestamp
1129
delimiter               Optional delete also objects starting with object's path and delimiter
1130
======================  ===================================
1131

    
1132
If ``until`` is defined, the object is "purged" up to that time (the history up to then is deleted). If also ``delimiter`` is defined, purge is applied only on the object.
1133

    
1134
No reply content/headers.
1135

    
1136
===========================  ==============================
1137
Return Code                  Description
1138
===========================  ==============================
1139
204 (No Content)             The request succeeded
1140
===========================  ==============================
1141

    
1142
Sharing and Public Objects
1143
^^^^^^^^^^^^^^^^^^^^^^^^^^
1144

    
1145
Read and write control in Pithos is managed by setting appropriate permissions with the ``X-Object-Sharing`` header. The permissions are applied using directory-based inheritance. A directory is an object with the corresponding content type. The default delimiter is ``/``. Thus, each set of authorization directives is applied to all objects in the directory object where the corresponding ``X-Object-Sharing`` header is defined. If there are nested/overlapping permissions, the closest to the object is applied. When retrieving an object, the ``X-Object-Shared-By`` header reports where it gets its permissions from. If not present, the object is the actual source of authorization directives.
1146

    
1147
A user may ``GET`` another account or container. The result will include a limited reply, containing only the allowed containers or objects respectively. A top-level request with an authentication token, will return a list of allowed accounts, so the user can easily find out which other users share objects. The ``X-Object-Allowed-To`` header lists the actions allowed on an object, if it does not belong to the requesting user.
1148

    
1149
Shared objects that are also public do not expose the ``X-Object-Public`` meta information.
1150

    
1151
Objects that are marked as public, via the ``X-Object-Public`` meta, are also available at the corresponding URI returned for ``HEAD`` or ``GET``. Requests for public objects do not need to include an ``X-Auth-Token``. Pithos will accept only the following request parameter: 
1152

    
1153
======================  ===================================
1154
Request Parameter Name  Value
1155
======================  ===================================
1156
disposition-type        Optional enforcement of the specific content disposition type (can be ``inline`` or ``attachement`` otherwise it is ignored - this will override the object's Content-Disposition)
1157
======================  ===================================
1158

    
1159
and only include the following headers in the reply (all ``X-Object-*`` meta is hidden):
1160

    
1161
==========================  ===============================
1162
Reply Header Name           Value
1163
==========================  ===============================
1164
ETag                        The ETag of the object
1165
Content-Length              The size of the data returned
1166
Content-Type                The MIME content type of the object
1167
Content-Range               The range of data included (only on a single range request)
1168
Last-Modified               The last object modification date (regardless of version)
1169
Content-Encoding            The encoding of the object (optional)
1170
Content-Disposition         The presentation style of the object (optional)
1171
==========================  ===============================
1172

    
1173
Public objects are not included and do not influence cross-user listings. They are, however, readable by all users.
1174

    
1175
Summary
1176
^^^^^^^
1177

    
1178
List of differences from the OOS API:
1179

    
1180
* Support for ``X-Account-Meta-*`` style headers at the account level. Use ``POST`` to update.
1181
* Support for ``X-Container-Meta-*`` style headers at the container level. Can be set when creating via ``PUT``. Use ``POST`` to update.
1182
* Header ``X-Container-Object-Meta`` at the container level and parameter ``meta`` in container listings. (**TBD**)
1183
* Account and container policies to manage behavior and limits. Container behavior overrides account settings. Account quota sets the maximum bytes limit, regardless of container values.
1184
* Headers ``X-Container-Block-*`` at the container level, exposing the underlying storage characteristics.
1185
* All metadata replies, at all levels, include latest modification information.
1186
* At all levels, a ``HEAD`` or ``GET`` request may use ``If-Modified-Since`` and ``If-Unmodified-Since`` headers.
1187
* Container/object lists include more fields if the reply is of type JSON/XML. Some names are kept to their OOS API equivalents for compatibility.
1188
* Option to include only shared containers/objects in listings.
1189
* Object metadata allowed, in addition to ``X-Object-Meta-*``: ``Content-Encoding``, ``Content-Disposition``, ``X-Object-Manifest``. These are all replaced with every update operation, except if using the ``update`` parameter (in which case individual keys can also be deleted). Deleting meta by providing empty values also works when copying/moving an object.
1190
* Multi-range object ``GET`` support as outlined in RFC2616.
1191
* Object hashmap retrieval through ``GET`` and the ``format`` parameter.
1192
* Object create via hashmap through ``PUT`` and the ``format`` parameter.
1193
* The object's Merkle hash is always returned in the ``X-Object-Hash`` header.
1194
* The object's UUID is always returned in the ``X-Object-UUID`` header. The UUID remains unchanged, even when the object's data or metadata changes, or the object is moved to another path (is renamed). A new UUID is assigned when creating or copying an object.
1195
* Object create using ``POST`` to support standard HTML forms.
1196
* Partial object updates through ``POST``, using the ``Content-Length``, ``Content-Type``, ``Content-Range`` and ``Transfer-Encoding`` headers. Use another object's data to update with ``X-Source-Object`` and ``X-Source-Version``. Truncate with ``X-Object-Bytes``.
1197
* Include new version identifier in replies for object replace/change requests.
1198
* Object ``MOVE`` support and ``ignore_content_type`` parameter in both ``COPY`` and ``MOVE``.
1199
* Conditional object create/update operations, using ``If-Match`` and ``If-None-Match`` headers.
1200
* Time-variant account/container listings via the ``until`` parameter.
1201
* Object versions - parameter ``version`` in ``HEAD``/``GET`` (list versions with ``GET``), ``X-Object-Version-*`` meta in replies, ``X-Source-Version`` in ``PUT``/``COPY``.
1202
* Sharing/publishing with ``X-Object-Sharing``, ``X-Object-Public`` at the object level. Cross-user operations are allowed - controlled by sharing directives. Available actions in cross-user requests are reported with ``X-Object-Allowed-To``. Permissions may include groups defined with ``X-Account-Group-*`` at the account level. These apply to the object - not its versions.
1203
* Support for directory-based inheritance when enforcing permissions. Parent object carrying the authorization directives is reported in ``X-Object-Shared-By``.
1204
* Copy and move between accounts with ``X-Source-Account`` and ``Destination-Account`` headers.
1205
* Large object support with ``X-Object-Manifest``.
1206
* Trace the user that created/modified an object with ``X-Object-Modified-By``.
1207
* Purge container/object history with the ``until`` parameter in ``DELETE``.
1208
* Bulk COPY/MOVE/DELETE objects starting with prefix
1209

    
1210
Clarifications/suggestions:
1211

    
1212
* All non-ASCII characters in headers should be URL-encoded.
1213
* Authentication is done by another system. The token is used in the same way, but it is obtained differently. The top level ``GET`` request is kept compatible with the OOS API and allows for guest/testing operations.
1214
* Some processing is done in the variable part of all ``X-*-Meta-*`` headers. If it includes underscores, they will be converted to dashes and the first letter of all intra-dash strings will be capitalized.
1215
* A ``GET`` reply for a level will include all headers of the corresponding ``HEAD`` request.
1216
* To avoid conflicts between objects and virtual directory markers in container listings, it is recommended that object names do not end with the delimiter used.
1217
* The ``Accept`` header may be used in requests instead of the ``format`` parameter to specify the desired request/reply format. The parameter overrides the header.
1218
* Container/object lists use a ``200`` return code if the reply is of type JSON/XML. The reply will include an empty JSON/XML.
1219
* In headers, dates are formatted according to RFC 1123. In extended information listings, the ``last_modified`` field is formatted according to ISO 8601 (for OOS API compatibility). All other fields (Pithos extensions) use integer tiemstamps.
1220
* The ``Last-Modified`` header value always reflects the actual latest change timestamp, regardless of time control parameters and version requests. Time precondition checks with ``If-Modified-Since`` and ``If-Unmodified-Since`` headers are applied to this value.
1221
* A copy/move using ``PUT``/``COPY``/``MOVE`` will always update metadata, keeping all old values except the ones redefined in the request headers.
1222
* A ``HEAD`` or ``GET`` for an ``X-Object-Manifest`` object, will include modified ``Content-Length`` and ``ETag`` headers, according to the characteristics of the objects under the specified prefix. The ``Etag`` will be the MD5 hash of the corresponding ETags concatenated. In extended container listings there is no metadata processing.
1223

    
1224
Recommended Practices and Examples
1225
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1226

    
1227
Assuming an authentication token is obtained, the following high-level operations are available - shown with ``curl``:
1228

    
1229
* Get account information ::
1230

    
1231
    curl -X HEAD -D - \
1232
         -H "X-Auth-Token: 0000" \
1233
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid
1234

    
1235
* List available containers ::
1236

    
1237
    curl -X GET -D - \
1238
         -H "X-Auth-Token: 0000" \
1239
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid
1240

    
1241
* Get container information ::
1242

    
1243
    curl -X HEAD -D - \
1244
         -H "X-Auth-Token: 0000" \
1245
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/pithos
1246

    
1247
* Add a new container ::
1248

    
1249
    curl -X PUT -D - \
1250
         -H "X-Auth-Token: 0000" \
1251
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/test
1252

    
1253
* Delete a container ::
1254

    
1255
    curl -X DELETE -D - \
1256
         -H "X-Auth-Token: 0000" \
1257
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/test
1258

    
1259
* List objects in a container ::
1260

    
1261
    curl -X GET -D - \
1262
         -H "X-Auth-Token: 0000" \
1263
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/pithos
1264

    
1265
* List objects in a container (extended reply) ::
1266

    
1267
    curl -X GET -D - \
1268
         -H "X-Auth-Token: 0000" \
1269
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/pithos?format=json
1270

    
1271
  It is recommended that extended replies are cached and subsequent requests utilize the ``If-Modified-Since`` header.
1272

    
1273
* List metadata keys used by objects in a container
1274

    
1275
  Will be in the ``X-Container-Object-Meta`` reply header, included in container information or object list (``HEAD`` or ``GET``). (**TBD**)
1276

    
1277
* List objects in a container having a specific meta defined ::
1278

    
1279
    curl -X GET -D - \
1280
         -H "X-Auth-Token: 0000" \
1281
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/pithos?meta=favorites
1282

    
1283
* Retrieve an object ::
1284

    
1285
    curl -X GET -D - \
1286
         -H "X-Auth-Token: 0000" \
1287
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/pithos/README.txt
1288

    
1289
* Retrieve an object (specific ranges of data) ::
1290

    
1291
    curl -X GET -D - \
1292
         -H "X-Auth-Token: 0000" \
1293
         -H "Range: bytes=0-9" \
1294
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/pithos/README.txt
1295

    
1296
  This will return the first 10 bytes. To get the first 10, bytes 30-39 and the last 100 use ``Range: bytes=0-9,30-39,-100``.
1297

    
1298
* Add a new object (folder type) (**TBD**) ::
1299

    
1300
    curl -X PUT -D - \
1301
         -H "X-Auth-Token: 0000" \
1302
         -H "Content-Type: application/directory" \
1303
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/pithos/folder
1304

    
1305
* Add a new object ::
1306

    
1307
    curl -X PUT -D - \
1308
         -H "X-Auth-Token: 0000" \
1309
         -H "Content-Type: text/plain" \
1310
         -T EXAMPLE.txt
1311
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/pithos/folder/EXAMPLE.txt
1312

    
1313
* Update an object ::
1314

    
1315
    curl -X POST -D - \
1316
         -H "X-Auth-Token: 0000" \
1317
         -H "Content-Length: 10" \
1318
         -H "Content-Type: application/octet-stream" \
1319
         -H "Content-Range: bytes 10-19/*" \
1320
         -d "0123456789" \
1321
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/folder/EXAMPLE.txt
1322

    
1323
  This will update bytes 10-19 with the data specified.
1324

    
1325
* Update an object (append) ::
1326

    
1327
    curl -X POST -D - \
1328
         -H "X-Auth-Token: 0000" \
1329
         -H "Content-Length: 10" \
1330
         -H "Content-Type: application/octet-stream" \
1331
         -H "Content-Range: bytes */*" \
1332
         -d "0123456789" \
1333
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/folder/EXAMPLE.txt
1334

    
1335
* Update an object (truncate) ::
1336

    
1337
    curl -X POST -D - \
1338
         -H "X-Auth-Token: 0000" \
1339
         -H "X-Source-Object: /folder/EXAMPLE.txt" \
1340
         -H "Content-Range: bytes 0-0/*" \
1341
         -H "X-Object-Bytes: 0" \
1342
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/folder/EXAMPLE.txt
1343

    
1344
  This will truncate the object to 0 bytes.
1345

    
1346
* Add object metadata ::
1347

    
1348
    curl -X POST -D - \
1349
         -H "X-Auth-Token: 0000" \
1350
         -H "X-Object-Meta-First: first_meta_value" \
1351
         -H "X-Object-Meta-Second: second_meta_value" \
1352
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/folder/EXAMPLE.txt
1353

    
1354
* Delete object metadata ::
1355

    
1356
    curl -X POST -D - \
1357
         -H "X-Auth-Token: 0000" \
1358
         -H "X-Object-Meta-First: first_meta_value" \
1359
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/folder/EXAMPLE.txt
1360

    
1361
  Metadata can only be "set". To delete ``X-Object-Meta-Second``, reset all metadata.
1362

    
1363
* Delete an object ::
1364

    
1365
    curl -X DELETE -D - \
1366
         -H "X-Auth-Token: 0000" \
1367
         https://storage.example.synnefo.org/pithos/object-store/v1.0/user-uuid/folder/EXAMPLE.txt