Statistics
| Branch: | Tag: | Revision:

root / docs / source / devguide.rst @ 32a437b1

History | View | Annotate | Download (48.3 kB)

1
Pithos v2 Developer Guide
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
Document Revisions
23
^^^^^^^^^^^^^^^^^^
24

    
25
=========================  ================================
26
Revision                   Description
27
=========================  ================================
28
0.5 (July 12, 2011)        Object update from another object's data.
29
\                          Support object truncate.
30
0.4 (July 01, 2011)        Object permissions and account groups.
31
\                          Control versioning behavior and container quotas with container policy directives.
32
\                          Support updating/deleting individual metadata with ``POST``.
33
\                          Create object using hashmap.
34
0.3 (June 14, 2011)        Large object support with ``X-Object-Manifest``.
35
\                          Allow for publicly available objects via ``https://hostname/public``.
36
\                          Support time-variant account/container listings. 
37
\                          Add source version when duplicating with PUT/COPY.
38
\                          Request version in object HEAD/GET requests (list versions with GET).
39
0.2 (May 31, 2011)         Add object meta listing and filtering in containers.
40
\                          Include underlying storage characteristics in container meta.
41
\                          Support for partial object updates through POST.
42
\                          Expose object hashmaps through GET.
43
\                          Support for multi-range object GET requests.
44
0.1 (May 17, 2011)         Initial release. Based on OpenStack Object Storage Developer Guide API v1 (Apr. 15, 2011).
45
=========================  ================================
46

    
47
The Pithos API
48
--------------
49

    
50
The URI requests supported by the Pithos API follow one of the following forms:
51

    
52
* Top level: ``https://hostname/v1/``
53
* Account level: ``https://hostname/v1/<account>``
54
* Container level: ``https://hostname/v1/<account>/<container>``
55
* Object level: ``https://hostname/v1/<account>/<container>/<object>``
56

    
57
All requests must include an ``X-Auth-Token``. The process of obtaining the token is still to be determined (**TBD**).
58

    
59
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.
60

    
61
=========================  ================================
62
Return Code                Description
63
=========================  ================================
64
400 (Bad Request)          The request is invalid
65
401 (Unauthorized)         Request not allowed
66
404 (Not Found)            The requested resource was not found
67
503 (Service Unavailable)  The request cannot be completed because of an internal error
68
=========================  ================================
69

    
70
Top Level
71
^^^^^^^^^
72

    
73
List of operations:
74

    
75
=========  ==================
76
Operation  Description
77
=========  ==================
78
GET        Authentication. This is kept for compatibility with the OOS API
79
=========  ==================
80

    
81
GET
82
"""
83

    
84
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.
85

    
86
================  =====================
87
Return Code       Description
88
================  =====================
89
204 (No Content)  The request succeeded
90
================  =====================
91

    
92

    
93
Account Level
94
^^^^^^^^^^^^^
95

    
96
List of operations:
97

    
98
=========  ==================
99
Operation  Description
100
=========  ==================
101
HEAD       Retrieve account metadata
102
GET        List containers
103
POST       Update account metadata
104
=========  ==================
105

    
106
HEAD
107
""""
108

    
109
======================  ===================================
110
Request Parameter Name  Value
111
======================  ===================================
112
until                   Optional timestamp
113
======================  ===================================
114

    
115
|
116

    
117
==========================  =====================
118
Reply Header Name           Value
119
==========================  =====================
120
X-Account-Container-Count   The total number of containers
121
X-Account-Object-Count      The total number of objects (**TBD**)
122
X-Account-Bytes-Used        The total number of bytes stored
123
X-Account-Bytes-Remaining   The total number of bytes remaining (**TBD**)
124
X-Account-Last-Login        The last login (**TBD**)
125
X-Account-Until-Timestamp   The last account modification date until the timestamp provided
126
X-Account-Group-*           Optional user defined groups
127
X-Account-Meta-*            Optional user defined metadata
128
Last-Modified               The last account modification date (regardless of ``until``)
129
==========================  =====================
130

    
131
|
132

    
133
================  =====================
134
Return Code       Description
135
================  =====================
136
204 (No Content)  The request succeeded
137
================  =====================
138

    
139

    
140
GET
141
"""
142

    
143
====================  ===========================
144
Request Header Name   Value
145
====================  ===========================
146
If-Modified-Since     Retrieve if account has changed since provided timestamp
147
If-Unmodified-Since   Retrieve if account has not changed since provided timestamp
148
====================  ===========================
149

    
150
|
151

    
152
======================  =========================
153
Request Parameter Name  Value
154
======================  =========================
155
limit                   The amount of results requested (default is 10000)
156
marker                  Return containers with name lexicographically after marker
157
format                  Optional extended reply type (can be ``json`` or ``xml``)
158
until                   Optional timestamp
159
======================  =========================
160

    
161
The reply is a list of container names. Account headers (as in a ``HEAD`` request) will also be included.
162
If a ``format=xml`` or ``format=json`` argument is given, extended information on the containers will be returned, serialized in the chosen format.
163
For each container, the information will include all container metadata (names will be in lower case and with hyphens replaced with underscores):
164

    
165
===========================  ============================
166
Name                         Description
167
===========================  ============================
168
name                         The name of the container
169
count                        The number of objects inside the container
170
bytes                        The total size of the objects inside the container
171
last_modified                The last container modification date (regardless of ``until``)
172
x_container_until_timestamp  The last container modification date until the timestamp provided
173
x_container_policy_*         Container behavior and limits
174
x_container_meta_*           Optional user defined metadata
175
===========================  ============================
176

    
177
For examples of container details returned in JSON/XML formats refer to the OOS API documentation.
178

    
179
===========================  =====================
180
Return Code                  Description
181
===========================  =====================
182
200 (OK)                     The request succeeded
183
204 (No Content)             The account has no containers (only for non-extended replies)
184
304 (Not Modified)           The account has not been modified
185
412 (Precondition Failed)    The condition set can not be satisfied
186
===========================  =====================
187

    
188
Will use a ``200`` return code if the reply is of type json/xml.
189

    
190

    
191
POST
192
""""
193

    
194
======================  ============================================
195
Request Parameter Name  Value
196
======================  ============================================
197
update                  Do not replace metadata/groups (no value parameter)
198
======================  ============================================
199

    
200
|
201

    
202
====================  ===========================
203
Request Header Name   Value
204
====================  ===========================
205
X-Account-Group-*     Optional user defined groups
206
X-Account-Meta-*      Optional user defined metadata
207
====================  ===========================
208

    
209
No reply content/headers.
210

    
211
The operation will overwrite all user defined metadata, except if ``update`` is defined.
212
To create a group, include an ``X-Account-Group-*`` header with the name in the key and a comma separated list of user names 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.
213

    
214
================  ===============================
215
Return Code       Description
216
================  ===============================
217
202 (Accepted)    The request has been accepted
218
================  ===============================
219

    
220

    
221
Container Level
222
^^^^^^^^^^^^^^^
223

    
224
List of operations:
225

    
226
=========  ============================
227
Operation  Description
228
=========  ============================
229
HEAD       Retrieve container metadata
230
GET        List objects
231
PUT        Create/update container
232
POST       Update container metadata
233
DELETE     Delete container
234
=========  ============================
235

    
236

    
237
HEAD
238
""""
239

    
240
======================  ===================================
241
Request Parameter Name  Value
242
======================  ===================================
243
until                   Optional timestamp
244
======================  ===================================
245

    
246
|
247

    
248
===========================  ===============================
249
Reply Header Name            Value
250
===========================  ===============================
251
X-Container-Object-Count     The total number of objects in the container
252
X-Container-Bytes-Used       The total number of bytes of all objects stored
253
X-Container-Block-Size       The block size used by the storage backend
254
X-Container-Block-Hash       The hash algorithm used for block identifiers in object hashmaps
255
X-Container-Until-Timestamp  The last container modification date until the timestamp provided
256
X-Container-Object-Meta      A list with all meta keys used by objects
257
X-Container-Policy-*         Container behavior and limits
258
X-Container-Meta-*           Optional user defined metadata
259
Last-Modified                The last container modification date (regardless of ``until``)
260
===========================  ===============================
261

    
262
The keys returned in ``X-Container-Object-Meta`` are all the unique strings after the ``X-Object-Meta-`` prefix. See container ``PUT`` for a reference of policy directives.
263

    
264
================  ===============================
265
Return Code       Description
266
================  ===============================
267
204 (No Content)  The request succeeded
268
================  ===============================
269

    
270

    
271
GET
272
"""
273

    
274
====================  ===========================
275
Request Header Name   Value
276
====================  ===========================
277
If-Modified-Since     Retrieve if container has changed since provided timestamp
278
If-Unmodified-Since   Retrieve if container has not changed since provided timestamp
279
====================  ===========================
280

    
281
|
282

    
283
======================  ===================================
284
Request Parameter Name  Value
285
======================  ===================================
286
limit                   The amount of results requested (default is 10000)
287
marker                  Return containers with name lexicographically after marker
288
prefix                  Return objects starting with prefix
289
delimiter               Return objects up to the delimiter (discussion follows)
290
path                    Assume ``prefix=path`` and ``delimiter=/``
291
format                  Optional extended reply type (can be ``json`` or ``xml``)
292
meta                    Return objects having the specified meta keys (can be a comma separated list)
293
until                   Optional timestamp
294
======================  ===================================
295

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

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

    
300
The reply is a list of object names. Container headers (as in a ``HEAD`` request) will also be included.
301
If a ``format=xml`` or ``format=json`` argument is given, extended information on the objects will be returned, serialized in the chosen format.
302
For each object, the information will include all object metadata (names will be in lower case and with hyphens replaced with underscores):
303

    
304
==========================  ======================================
305
Name                        Description
306
==========================  ======================================
307
name                        The name of the object
308
hash                        The ETag of the object
309
bytes                       The size of the object
310
content_type                The MIME content type of the object
311
content_encoding            The encoding of the object (optional)
312
content-disposition         The presentation style of the object (optional)
313
last_modified               The last object modification date (regardless of version)
314
x_object_version            The object's version identifier
315
x_object_version_timestamp  The object's version timestamp
316
x_object_modified_by        The user that committed the object's version
317
x_object_manifest           Object parts prefix in ``<container>/<object>`` form (optional)
318
x_object_sharing            Object permissions (optional)
319
x_object_shared_by          Object inheriting permissions (optional)
320
x_object_public             Object's publicly accessible URI (optional)
321
x_object_meta_*             Optional user defined metadata
322
==========================  ======================================
323

    
324
Extended replies may also include virtual directory markers in separate sections of the ``json`` or ``xml`` results.
325
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.
326
In JSON results they appear as dictionaries with only a ``"subdir"`` key. In XML results they appear interleaved with ``<object>`` tags as ``<subdir name="..." />``.
327
In case there is an object with the same name as a virtual directory marker, the object will be returned.
328

    
329
For examples of object details returned in JSON/XML formats refer to the OOS API documentation.
330

    
331
===========================  ===============================
332
Return Code                  Description
333
===========================  ===============================
334
200 (OK)                     The request succeeded
335
204 (No Content)             The account has no containers (only for non-extended replies)
336
304 (Not Modified)           The container has not been modified
337
412 (Precondition Failed)    The condition set can not be satisfied
338
===========================  ===============================
339

    
340
Will use a ``200`` return code if the reply is of type json/xml.
341

    
342

    
343
PUT
344
"""
345

    
346
====================  ================================
347
Request Header Name   Value
348
====================  ================================
349
X-Container-Policy-*  Container behavior and limits
350
X-Container-Meta-*    Optional user defined metadata
351
====================  ================================
352
 
353
No reply content/headers.
354

    
355
If no policy is defined, the container will be created with the default values.
356
Available policy directives:
357

    
358
* ``versioning``: Set to ``auto``, ``manual`` or ``none`` (default is ``manual``)
359
* ``quota``: Size limit in KB (default is ``0`` - unlimited)
360
 
361
================  ===============================
362
Return Code       Description
363
================  ===============================
364
201 (Created)     The container has been created
365
202 (Accepted)    The request has been accepted
366
================  ===============================
367

    
368

    
369
POST
370
""""
371

    
372
======================  ============================================
373
Request Parameter Name  Value
374
======================  ============================================
375
update                  Do not replace metadata/policy (no value parameter)
376
======================  ============================================
377

    
378
|
379

    
380
====================  ================================
381
Request Header Name   Value
382
====================  ================================
383
X-Container-Policy-*  Container behavior and limits
384
X-Container-Meta-*    Optional user defined metadata
385
====================  ================================
386

    
387
No reply content/headers.
388

    
389
The operation will overwrite all user defined metadata, except if ``update`` is defined.
390
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.
391

    
392
================  ===============================
393
Return Code       Description
394
================  ===============================
395
202 (Accepted)    The request has been accepted
396
================  ===============================
397

    
398

    
399
DELETE
400
""""""
401

    
402
No request parameters/headers.
403

    
404
No reply content/headers.
405

    
406
================  ===============================
407
Return Code       Description
408
================  ===============================
409
204 (No Content)  The request succeeded
410
409 (Conflict)    The container is not empty
411
================  ===============================
412

    
413

    
414
Object Level
415
^^^^^^^^^^^^
416

    
417
List of operations:
418

    
419
=========  =================================
420
Operation  Description
421
=========  =================================
422
HEAD       Retrieve object metadata
423
GET        Read object data
424
PUT        Write object data or copy/move object
425
COPY       Copy object
426
MOVE       Move object
427
POST       Update object metadata/data
428
DELETE     Delete object
429
=========  =================================
430

    
431

    
432
HEAD
433
""""
434

    
435
======================  ===================================
436
Request Parameter Name  Value
437
======================  ===================================
438
version                 Optional version identifier
439
======================  ===================================
440

    
441
|
442

    
443
==========================  ===============================
444
Reply Header Name           Value
445
==========================  ===============================
446
ETag                        The ETag of the object
447
Content-Length              The size of the object
448
Content-Type                The MIME content type of the object
449
Last-Modified               The last object modification date (regardless of version)
450
Content-Encoding            The encoding of the object (optional)
451
Content-Disposition         The presentation style of the object (optional)
452
X-Object-Version            The object's version identifier
453
X-Object-Version-Timestamp  The object's version timestamp
454
X-Object-Modified-By        The user that comitted the object's version
455
X-Object-Manifest           Object parts prefix in ``<container>/<object>`` form (optional)
456
X-Object-Sharing            Object permissions (optional)
457
X-Object-Shared-By          Object inheriting permissions (optional)
458
X-Object-Public             Object's publicly accessible URI (optional)
459
X-Object-Meta-*             Optional user defined metadata
460
==========================  ===============================
461

    
462
|
463

    
464
================  ===============================
465
Return Code       Description
466
================  ===============================
467
200 (No Content)  The request succeeded
468
================  ===============================
469

    
470

    
471
GET
472
"""
473

    
474
====================  ================================
475
Request Header Name   Value
476
====================  ================================
477
Range                 Optional range of data to retrieve
478
If-Range              Retrieve the missing part if entity is unchanged; otherwise, retrieve the entire new entity (used together with Range header)
479
If-Match              Retrieve if ETags match
480
If-None-Match         Retrieve if ETags don't match
481
If-Modified-Since     Retrieve if object has changed since provided timestamp
482
If-Unmodified-Since   Retrieve if object has not changed since provided timestamp
483
====================  ================================
484

    
485
|
486

    
487
======================  ===================================
488
Request Parameter Name  Value
489
======================  ===================================
490
format                  Optional extended reply type (can be ``json`` or ``xml``)
491
version                 Optional version identifier or ``list`` (specify a format if requesting a list)
492
======================  ===================================
493

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

    
496
Hashmaps expose the underlying storage format of the object. Note that each hash is computed after trimming trailing null bytes of the corresponding block.
497

    
498
Example ``format=json`` reply:
499

    
500
::
501

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

    
504
Example ``format=xml`` reply:
505

    
506
::
507

    
508
  <?xml version="1.0" encoding="UTF-8"?>
509
  <object name="file" bytes="24223726" block_size="131072" block_hash="sha1">
510
    <hash>7295c41da03d7f916440b98e32c4a2a39351546c</hash>
511
    <hash>...</hash>
512
  </object>
513

    
514
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.
515

    
516
Example ``format=json`` reply:
517

    
518
::
519

    
520
  {"versions": [[23, 1307700892], [28, 1307700898], ...]}
521

    
522
Example ``format=xml`` reply:
523

    
524
::
525

    
526
  <?xml version="1.0" encoding="UTF-8"?>
527
  <object name="file">
528
    <version timestamp="1307700892">23</version>
529
    <version timestamp="1307700898">28</version>
530
    <version timestamp="...">...</version>
531
  </object>
532

    
533
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.
534

    
535
==========================  ===============================
536
Reply Header Name           Value
537
==========================  ===============================
538
ETag                        The ETag of the object
539
Content-Length              The size of the data returned
540
Content-Type                The MIME content type of the object
541
Content-Range               The range of data included (only on a single range request)
542
Last-Modified               The last object modification date (regardless of version)
543
Content-Encoding            The encoding of the object (optional)
544
Content-Disposition         The presentation style of the object (optional)
545
X-Object-Version            The object's version identifier
546
X-Object-Version-Timestamp  The object's version timestamp
547
X-Object-Modified-By        The user that comitted the object's version
548
X-Object-Manifest           Object parts prefix in ``<container>/<object>`` form (optional)
549
X-Object-Sharing            Object permissions (optional)
550
X-Object-Shared-By          Object inheriting permissions (optional)
551
X-Object-Public             Object's publicly accessible URI (optional)
552
X-Object-Meta-*             Optional user defined metadata
553
==========================  ===============================
554

    
555
|
556

    
557
===========================  ==============================
558
Return Code                  Description
559
===========================  ==============================
560
200 (OK)                     The request succeeded
561
206 (Partial Content)        The range request succeeded
562
304 (Not Modified)           The object has not been modified
563
412 (Precondition Failed)    The condition set can not be satisfied
564
416 (Range Not Satisfiable)  The requested range is out of limits
565
===========================  ==============================
566

    
567

    
568
PUT
569
"""
570

    
571
====================  ================================
572
Request Header Name   Value
573
====================  ================================
574
ETag                  The MD5 hash of the object (optional to check written data)
575
Content-Length        The size of the data written
576
Content-Type          The MIME content type of the object
577
Transfer-Encoding     Set to ``chunked`` to specify incremental uploading (if used, ``Content-Length`` is ignored)
578
X-Copy-From           The source path in the form ``/<container>/<object>``
579
X-Move-From           The source path in the form ``/<container>/<object>``
580
X-Source-Version      The source version to copy from
581
Content-Encoding      The encoding of the object (optional)
582
Content-Disposition   The presentation style of the object (optional)
583
X-Object-Manifest     Object parts prefix in ``<container>/<object>`` form (optional)
584
X-Object-Sharing      Object permissions (optional)
585
X-Object-Public       Object is publicly accessible (optional)
586
X-Object-Meta-*       Optional user defined metadata
587
====================  ================================
588

    
589
|
590

    
591
======================  ===================================
592
Request Parameter Name  Value
593
======================  ===================================
594
format                  Optional extended request type (can be ``json``) to create the object by suppling its hashmap instead
595
======================  ===================================
596

    
597
The request is the object's data (or part of it), except if a hashmap is provided with the ``format`` parameter.  If format is used 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. 
598

    
599
Hashmaps expose the underlying storage format of the object.
600

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

    
603
::
604

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

    
607
Example ``format=xml`` request:
608

    
609
::
610

    
611
  <?xml version="1.0" encoding="UTF-8"?>
612
  <object name="file" bytes="24223726" block_size="131072" block_hash="sha1">
613
    <hash>7295c41da03d7f916440b98e32c4a2a39351546c</hash>
614
    <hash>...</hash>
615
  </object>
616

    
617
==========================  ===============================
618
Reply Header Name           Value
619
==========================  ===============================
620
ETag                        The MD5 hash of the object (on create)
621
==========================  ===============================
622

    
623
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 (``;``). To publish the object, set ``X-Object-Public`` to ``true``. To unpublish, set to ``false``, or use an empty header value.
624

    
625
===========================  ==============================
626
Return Code                  Description
627
===========================  ==============================
628
201 (Created)                The object has been created
629
409 (Conflict)               The object can not be created from the provided hashmap, or there are conflicting permissions (a list of missing hashes, or a conflicting sharing path will be included in the reply - in JSON format)
630
411 (Length Required)        Missing ``Content-Length`` or ``Content-Type`` in the request
631
422 (Unprocessable Entity)   The MD5 checksum of the data written to the storage system does not match the (optionally) supplied ETag value
632
===========================  ==============================
633

    
634

    
635
COPY
636
""""
637

    
638
====================  ================================
639
Request Header Name   Value
640
====================  ================================
641
Destination           The destination path in the form ``/<container>/<object>``
642
Content-Type          The MIME content type of the object (optional)
643
Content-Encoding      The encoding of the object (optional)
644
Content-Disposition   The presentation style of the object (optional)
645
X-Source-Version      The source version to copy from
646
X-Object-Manifest     Object parts prefix in ``<container>/<object>`` form (optional)
647
X-Object-Sharing      Object permissions (optional)
648
X-Object-Public       Object is publicly accessible (optional)
649
X-Object-Meta-*       Optional user defined metadata
650
====================  ================================
651

    
652
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.
653

    
654
No reply content/headers.
655

    
656
===========================  ==============================
657
Return Code                  Description
658
===========================  ==============================
659
201 (Created)                The object has been created
660
409 (Conflict)               There are conflicting permissions (a conflicting sharing path will be included in the reply - in JSON format)
661
===========================  ==============================
662

    
663

    
664
MOVE
665
""""
666

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

    
669

    
670
POST
671
""""
672

    
673
======================  ============================================
674
Request Parameter Name  Value
675
======================  ============================================
676
update                  Do not replace metadata (no value parameter)
677
======================  ============================================
678

    
679
|
680

    
681
====================  ================================
682
Request Header Name   Value
683
====================  ================================
684
Content-Length        The size of the data written (optional, to update)
685
Content-Type          The MIME content type of the object (optional, to update)
686
Content-Range         The range of data supplied (optional, to update)
687
Transfer-Encoding     Set to ``chunked`` to specify incremental uploading (if used, ``Content-Length`` is ignored)
688
Content-Encoding      The encoding of the object (optional)
689
Content-Disposition   The presentation style of the object (optional)
690
X-Source-Object       Update with data from the object at path ``/<container>/<object>`` (optional, to update)
691
X-Source-Version      The source version to update from (optional, to update)
692
X-Object-Bytes        The updated object's final size (optional, when updating)
693
X-Object-Manifest     Object parts prefix in ``<container>/<object>`` form (optional)
694
X-Object-Sharing      Object permissions (optional)
695
X-Object-Public       Object is publicly accessible (optional)
696
X-Object-Meta-*       Optional user defined metadata
697
====================  ================================
698

    
699
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.
700

    
701
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.
702

    
703
To update an object's data:
704

    
705
* 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.
706
* 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``).
707
* Set ``Content-Range`` as specified in RFC2616, with the following differences:
708

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

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

    
715
A data update will trigger an ETag change. The new ETag will not correspond to the object's MD5 sum (**TBD**) and will be included in reply headers.
716

    
717
No reply content. No reply headers if only metadata is updated.
718

    
719
==========================  ===============================
720
Reply Header Name           Value
721
==========================  ===============================
722
ETag                        The new ETag of the object (data updated)
723
==========================  ===============================
724

    
725
|
726

    
727
===========================  ==============================
728
Return Code                  Description
729
===========================  ==============================
730
202 (Accepted)               The request has been accepted (not a data update)
731
204 (No Content)             The request succeeded (data updated)
732
409 (Conflict)               There are conflicting permissions (a conflicting sharing path will be included in the reply - in JSON format)
733
411 (Length Required)        Missing ``Content-Length`` in the request
734
416 (Range Not Satisfiable)  The supplied range is invalid
735
===========================  ==============================
736

    
737

    
738
DELETE
739
""""""
740

    
741
No request parameters/headers.
742

    
743
No reply content/headers.
744

    
745
===========================  ==============================
746
Return Code                  Description
747
===========================  ==============================
748
204 (No Content)             The request succeeded
749
===========================  ==============================
750

    
751
Sharing and Public Objects
752
^^^^^^^^^^^^^^^^^^^^^^^^^^
753

    
754
Read and write control in Pithos is managed by setting appropriate permissions with the ``X-Object-Sharing`` header. The permissions are applied using prefix-based inheritance. Thus, each set of authorization directives is applied to all objects sharing the same prefix with the object where the corresponding ``X-Object-Sharing`` header is defined. For simplicity, nested/overlapping permissions are not allowed. Setting ``X-Object-Sharing`` will fail, if the object is already "covered", or another object with a longer common-prefix name already has permissions. 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.
755

    
756
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 ignore request parameters and only include the following headers in the reply (all ``X-Object-*`` meta is hidden).
757

    
758
==========================  ===============================
759
Reply Header Name           Value
760
==========================  ===============================
761
ETag                        The ETag of the object
762
Content-Length              The size of the data returned
763
Content-Type                The MIME content type of the object
764
Content-Range               The range of data included (only on a single range request)
765
Last-Modified               The last object modification date (regardless of version)
766
Content-Encoding            The encoding of the object (optional)
767
Content-Disposition         The presentation style of the object (optional)
768
==========================  ===============================
769

    
770
Summary
771
^^^^^^^
772

    
773
List of differences from the OOS API:
774

    
775
* Support for ``X-Account-Meta-*`` style headers at the account level. Use ``POST`` to update.
776
* Support for ``X-Container-Meta-*`` style headers at the container level. Can be set when creating via ``PUT``. Use ``POST`` to update.
777
* Header ``X-Container-Object-Meta`` at the container level and parameter ``meta`` in container listings.
778
* Container policies to manage behavior and limits.
779
* Headers ``X-Container-Block-*`` at the container level, exposing the underlying storage characteristics.
780
* All metadata replies, at all levels, include latest modification information.
781
* At all levels, a ``GET`` request may use ``If-Modified-Since`` and ``If-Unmodified-Since`` headers.
782
* Container/object lists include all associated metadata if the reply is of type json/xml. Some names are kept to their OOS API equivalents for compatibility. 
783
* 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.
784
* Multi-range object GET support as outlined in RFC2616.
785
* Object hashmap retrieval through GET and the ``format`` parameter.
786
* 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``.
787
* Object ``MOVE`` support.
788
* Time-variant account/container listings via the ``until`` parameter.
789
* Object versions - parameter ``version`` in HEAD/GET (list versions with GET), ``X-Object-Version-*`` meta in replies, ``X-Source-Version`` in PUT/COPY.
790
* Sharing/publishing with ``X-Object-Sharing``, ``X-Object-Public`` at the object level. Permissions may include groups defined with ``X-Account-Group-*`` at the account level. These apply to the object - not its versions.
791
* Support for prefix-based inheritance when enforcing permissions. Parent object carrying the authorization directives is reported in ``X-Object-Shared-By``.
792
* Large object support with ``X-Object-Manifest``.
793
* Trace the user that created/modified an object with ``X-Object-Modified-By``.
794

    
795
Clarifications/suggestions:
796

    
797
* 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.
798
* 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.
799
* A ``GET`` reply for a level will include all headers of the corresponding ``HEAD`` request.
800
* 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.
801
* The ``Accept`` header may be used in requests instead of the ``format`` parameter to specify the desired reply format. The parameter overrides the header.
802
* Container/object lists use a ``200`` return code if the reply is of type json/xml. The reply will include an empty json/xml.
803
* In headers, dates are formatted according to RFC 1123. In extended information listings, dates are formatted according to ISO 8601.
804
* 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.
805
* A copy/move using ``PUT``/``COPY``/``MOVE`` will always update metadata, keeping all old values except the ones redefined in the request headers.
806
* 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.
807

    
808
The Pithos Client
809
-----------------
810

    
811
User Experience
812
^^^^^^^^^^^^^^^
813

    
814
Hopefully this API will allow for a multitude of client implementations, each supporting a different device or operating system. All clients will be able to manipulate containers and objects - even software only designed for OOS API compatibility. But a Pithos interface should not be only about showing containers and folders. There are some extra user interface elements and functionalities that should be common to all implementations.
815

    
816
Upon entrance to the service, a user is presented with the following elements - which can be represented as folders or with other related icons:
817

    
818
* The ``home`` element, which is used as the default entry point to the user's "files". Objects under ``home`` are represented in the usual hierarchical organization of folders and files.
819
* The ``trash`` element, which contains files that have been marked for deletion, but can still be recovered.
820
* The ``shared`` element, which contains all objects shared by the user to other users of the system.
821
* The ``others`` element, which contains all objects that other users share with the user.
822
* The ``tags`` element, which lists the names of tags the user has defined. This can be an entry point to list all files that have been assigned a specific tag or manage tags in general (remove a tag completely, rename a tag etc.).
823
* The ``groups`` element, which contains the names of groups the user has defined. Each group consists of a user list. Group creation, deletion, and manipulation is carried out by actions originating here.
824

    
825
Objects in Pithos can be:
826

    
827
* Assigned custom tags.
828
* Moved to trash and then deleted.
829
* Shared with specific permissions.
830
* Made public (shared with non-Pithos users).
831
* Restored from previous versions.
832

    
833
Some of these functions are performed by the client software and some by the Pithos server. Client-driven functionality is based on specific metadata that should be handled equally across implementations. These metadata names are discussed in the next chapter. 
834

    
835
Conventions and Metadata Specification
836
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
837

    
838
Pithos clients should use the ``pithos`` container for all Pithos objects. Object names use the ``/`` delimiter to impose a hierarchy of folders and files.
839

    
840
At the object level, tags are implemented by managing metadata keys. The client software should allow the user to use any string as a tag and then set the corresponding ``X-Object-Meta-<tag>`` key at the server. The API extensions provided, allow for listing all tags in a container and filtering object listings based on one or more tags. The tag list is sufficient for implementing the ``tags`` element, either as a special, virtual folder (as done in the first version of Pithos), or as an application menu.
841

    
842
The metadata specification is summarized in the following table.
843

    
844
===========================  ==============================
845
Metadata Name                Value
846
===========================  ==============================
847
X-Object-Meta-*              Use for other tags that apply to the object
848
===========================  ==============================
849

    
850
Recommended Practices and Examples
851
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
852

    
853
Assuming an authentication token is obtained (**TBD**), the following high-level operations are available - shown with ``curl``:
854

    
855
* Get account information ::
856

    
857
    curl -X HEAD -D - \
858
         -H "X-Auth-Token: 0000" \
859
         https://pithos.dev.grnet.gr/v1/user
860

    
861
* List available containers ::
862

    
863
    curl -X GET -D - \
864
         -H "X-Auth-Token: 0000" \
865
         https://pithos.dev.grnet.gr/v1/user
866

    
867
* Get container information ::
868

    
869
    curl -X HEAD -D - \
870
         -H "X-Auth-Token: 0000" \
871
         https://pithos.dev.grnet.gr/v1/user/pithos
872

    
873
* Add a new container ::
874

    
875
    curl -X PUT -D - \
876
         -H "X-Auth-Token: 0000" \
877
         https://pithos.dev.grnet.gr/v1/user/test
878

    
879
* Delete a container ::
880

    
881
    curl -X DELETE -D - \
882
         -H "X-Auth-Token: 0000" \
883
         https://pithos.dev.grnet.gr/v1/user/test
884

    
885
* List objects in a container ::
886

    
887
    curl -X GET -D - \
888
         -H "X-Auth-Token: 0000" \
889
         https://pithos.dev.grnet.gr/v1/user/pithos
890

    
891
* List objects in a container (extended reply) ::
892

    
893
    curl -X GET -D - \
894
         -H "X-Auth-Token: 0000" \
895
         https://pithos.dev.grnet.gr/v1/user/pithos?format=json
896

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

    
899
* List metadata keys used by objects in a container
900

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

    
903
* List objects in a container having a specific meta defined ::
904

    
905
    curl -X GET -D - \
906
         -H "X-Auth-Token: 0000" \
907
         https://pithos.dev.grnet.gr/v1/user/pithos?meta=favorites
908

    
909
* Retrieve an object ::
910

    
911
    curl -X GET -D - \
912
         -H "X-Auth-Token: 0000" \
913
         https://pithos.dev.grnet.gr/v1/user/pithos/README.txt
914

    
915
* Retrieve an object (specific ranges of data) ::
916

    
917
    curl -X GET -D - \
918
         -H "X-Auth-Token: 0000" \
919
         -H "Range: bytes=0-9" \
920
         https://pithos.dev.grnet.gr/v1/user/pithos/README.txt
921

    
922
  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``.
923

    
924
* Add a new object (folder type) (**TBD**) ::
925

    
926
    curl -X PUT -D - \
927
         -H "X-Auth-Token: 0000" \
928
         -H "Content-Type: application/folder" \
929
         https://pithos.dev.grnet.gr/v1/user/pithos/folder
930

    
931
* Add a new object ::
932

    
933
    curl -X PUT -D - \
934
         -H "X-Auth-Token: 0000" \
935
         -H "Content-Type: text/plain" \
936
         -T EXAMPLE.txt
937
         https://pithos.dev.grnet.gr/v1/user/pithos/folder/EXAMPLE.txt
938

    
939
* Update an object ::
940

    
941
    curl -X POST -D - \
942
         -H "X-Auth-Token: 0000" \
943
         -H "Content-Length: 10" \
944
         -H "Content-Type: application/octet-stream" \
945
         -H "Content-Range: bytes 10-19/*" \
946
         -d "0123456789" \
947
         https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt
948

    
949
  This will update bytes 10-19 with the data specified.
950

    
951
* Update an object (append) ::
952

    
953
    curl -X POST -D - \
954
         -H "X-Auth-Token: 0000" \
955
         -H "Content-Length: 10" \
956
         -H "Content-Type: application/octet-stream" \
957
         -H "Content-Range: bytes */*" \
958
         -d "0123456789" \
959
         https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt
960

    
961
* Update an object (truncate) ::
962

    
963
    curl -X POST -D - \
964
         -H "X-Auth-Token: 0000" \
965
         -H "X-Source-Object: /folder/EXAMPLE.txt" \
966
         -H "Content-Range: bytes 0-0/*" \
967
         -H "X-Object-Bytes: 0" \
968
         https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt
969

    
970
  This will truncate the object to 0 bytes.
971

    
972
* Add object metadata ::
973

    
974
    curl -X POST -D - \
975
         -H "X-Auth-Token: 0000" \
976
         -H "X-Object-Meta-First: first_meta_value" \
977
         -H "X-Object-Meta-Second: second_meta_value" \
978
         https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt
979

    
980
* Delete object metadata ::
981

    
982
    curl -X POST -D - \
983
         -H "X-Auth-Token: 0000" \
984
         -H "X-Object-Meta-First: first_meta_value" \
985
         https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt
986

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

    
989
* Delete an object ::
990

    
991
    curl -X DELETE -D - \
992
         -H "X-Auth-Token: 0000" \
993
         https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt