Statistics
| Branch: | Tag: | Revision:

root / docs / source / devguide.rst @ e9285524

History | View | Annotate | Download (29.5 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. They can also be versioned, meaning that the server will track changes, assign version numbers and allow reading previous instances.
10

    
11
The storage backend of Pithos is block oriented, which allows for 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.2 (May 29, 2011)         Add object meta listing and filtering in containers.
29
\                          Support for partial object updates through POST.
30
\                          Expose object hashmaps through GET.
31
\                          Support for multi-range object GET requests.
32
0.1 (May 17, 2011)         Initial release. Based on OpenStack Object Storage Developer Guide API v1 (Apr. 15, 2011).
33
=========================  ================================
34

    
35
The Pithos API
36
--------------
37

    
38
The URI requests supported by Pithos follow one of the following forms:
39

    
40
* Top level: ``https://hostname/v1/``
41
* Account level: ``https://hostname/v1/<account>``
42
* Container level: ``https://hostname/v1/<account>/<container>``
43
* Object level: ``https://hostname/v1/<account>/<container>/<object>``
44

    
45
All requests must include an ``X-Auth-Token``, except from those that refer to publicly available files (**TBD**). The process of obtaining the token is still to be determined (**TBD**).
46

    
47
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.
48

    
49
=========================  ================================
50
Return Code                Description
51
=========================  ================================
52
400 (Bad Request)          The request is invalid
53
401 (Unauthorized)         Request not allowed
54
404 (Not Found)            The requested resource was not found
55
503 (Service Unavailable)  The request cannot be completed because of an internal error
56
=========================  ================================
57

    
58
Top Level
59
^^^^^^^^^
60

    
61
List of operations:
62

    
63
=========  ==================
64
Operation  Description
65
=========  ==================
66
GET        Authentication. This is kept for compatibility with the OOS API
67
=========  ==================
68

    
69
GET
70
"""
71

    
72
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.
73

    
74
================  =====================
75
Return Code       Description
76
================  =====================
77
204 (No Content)  The request succeeded
78
================  =====================
79

    
80

    
81
Account Level
82
^^^^^^^^^^^^^
83

    
84
List of operations:
85

    
86
=========  ==================
87
Operation  Description
88
=========  ==================
89
HEAD       Retrieve account metadata
90
GET        List containers
91
POST       Update account metadata
92
=========  ==================
93

    
94
HEAD
95
""""
96

    
97
No request parameters/headers.
98

    
99
==========================  =====================
100
Reply Header Name           Value
101
==========================  =====================
102
X-Account-Container-Count   The total number of containers
103
X-Account-Object-Count      The total number of objects (**TBD**)
104
X-Account-Bytes-Used        The total number of bytes stored
105
X-Account-Bytes-Remaining   The total number of bytes remaining (**TBD**)
106
X-Account-Last-Login        The last login (**TBD**)
107
X-Account-Meta-*            Optional user defined metadata
108
Last-Modified               The last object modification date
109
==========================  =====================
110

    
111
|
112

    
113
================  =====================
114
Return Code       Description
115
================  =====================
116
204 (No Content)  The request succeeded
117
================  =====================
118

    
119

    
120
GET
121
"""
122

    
123
====================  ===========================
124
Request Header Name   Value
125
====================  ===========================
126
If-Modified-Since     Retrieve if account has changed since provided timestamp
127
If-Unmodified-Since   Retrieve if account has not changed since provided timestamp
128
====================  ===========================
129

    
130
|
131

    
132
======================  =========================
133
Request Parameter Name  Value
134
======================  =========================
135
limit                   The amount of results requested (default is 10000)
136
marker                  Return containers with name lexicographically after marker
137
format                  Optional extended reply type (can be ``json`` or ``xml``)
138
======================  =========================
139

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

    
144
===================  ============================
145
Name                 Description
146
===================  ============================
147
name                 The name of the container
148
count                The number of objects inside the container
149
bytes                The total size of the objects inside the container
150
last_modified        The last object modification date
151
x_container_meta_*   Optional user defined metadata
152
===================  ============================
153

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

    
156
================  =====================
157
Return Code       Description
158
================  =====================
159
200 (OK)          The request succeeded
160
204 (No Content)  The account has no containers (only for non-extended replies)
161
================  =====================
162

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

    
165

    
166
POST
167
""""
168

    
169
====================  ===========================
170
Request Header Name   Value
171
====================  ===========================
172
X-Account-Meta-*      Optional user defined metadata
173
====================  ===========================
174

    
175
No reply content/headers.
176

    
177
The update operation will overwrite all user defined metadata.
178

    
179
================  ===============================
180
Return Code       Description
181
================  ===============================
182
202 (Accepted)    The request has been accepted
183
================  ===============================
184

    
185

    
186
Container Level
187
^^^^^^^^^^^^^^^
188

    
189
List of operations:
190

    
191
=========  ============================
192
Operation  Description
193
=========  ============================
194
HEAD       Retrieve container metadata
195
GET        List objects
196
PUT        Create/update container
197
POST       Update container metadata
198
DELETE     Delete container
199
=========  ============================
200

    
201

    
202
HEAD
203
""""
204

    
205
No request parameters/headers.
206

    
207
==========================  ===============================
208
Reply Header Name           Value
209
==========================  ===============================
210
X-Container-Object-Count    The total number of objects in the container
211
X-Container-Bytes-Used      The total number of bytes of all objects stored
212
X-Container-Meta-*          Optional user defined metadata
213
X-Container-Object-Meta     A list with all meta keys used by objects
214
Last-Modified               The last object modification date
215
==========================  ===============================
216

    
217
The keys returned in ``X-Container-Object-Meta`` are all the unique strings after the ``X-Object-Meta-`` prefix.
218

    
219
================  ===============================
220
Return Code       Description
221
================  ===============================
222
204 (No Content)  The request succeeded
223
================  ===============================
224

    
225

    
226
GET
227
"""
228

    
229
====================  ===========================
230
Request Header Name   Value
231
====================  ===========================
232
If-Modified-Since     Retrieve if container has changed since provided timestamp
233
If-Unmodified-Since   Retrieve if container has not changed since provided timestamp
234
====================  ===========================
235

    
236
|
237

    
238
======================  ===================================
239
Request Parameter Name  Value
240
======================  ===================================
241
limit                   The amount of results requested (default is 10000)
242
marker                  Return containers with name lexicographically after marker
243
prefix                  Return objects starting with prefix
244
delimiter               Return objects up to the delimiter (discussion follows)
245
path                    Assume ``prefix=path`` and ``delimiter=/``
246
format                  Optional extended reply type (can be ``json`` or ``xml``)
247
meta                    Return objects having the specified meta keys (can be a comma separated list)
248
======================  ===================================
249

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

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

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

    
258
===================  ======================================
259
Name                 Description
260
===================  ======================================
261
name                 The name of the object
262
hash                 The ETag of the object
263
bytes                The size of the object
264
content_type         The MIME content type of the object
265
content_encoding     The encoding of the object (optional)
266
last_modified        The last object modification date
267
x_object_manifest    Large object support
268
x_object_meta_*      Optional user defined metadata
269
===================  ======================================
270

    
271
Extended replies may also include virtual directory markers in separate sections of the ``json`` or ``xml`` results.
272
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.
273
In JSON results they appear as dictionaries with only a ``"subdir"`` key. In XML results they appear interleaved with ``<object>`` tags as ``<subdir name="..." />``.
274
In case there is an object with the same name as a virtual directory marker, the object will be returned.
275
 
276
For examples of object details returned in JSON/XML formats refer to the OOS API documentation.
277

    
278
================  ===============================
279
Return Code       Description
280
================  ===============================
281
200 (OK)          The request succeeded
282
204 (No Content)  The account has no containers (only for non-extended replies)
283
================  ===============================
284

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

    
287

    
288
PUT
289
"""
290

    
291
====================  ================================
292
Request Header Name   Value
293
====================  ================================
294
X-Container-Meta-*    Optional user defined metadata
295
====================  ================================
296
 
297
No reply content/headers.
298
 
299
================  ===============================
300
Return Code       Description
301
================  ===============================
302
201 (Created)     The container has been created
303
202 (Accepted)    The request has been accepted
304
================  ===============================
305

    
306

    
307
POST
308
""""
309

    
310
====================  ================================
311
Request Header Name   Value
312
====================  ================================
313
X-Container-Meta-*    Optional user defined metadata
314
====================  ================================
315

    
316
No reply content/headers.
317

    
318
The update operation will overwrite all user defined metadata.
319

    
320
================  ===============================
321
Return Code       Description
322
================  ===============================
323
202 (Accepted)    The request has been accepted
324
================  ===============================
325

    
326

    
327
DELETE
328
""""""
329

    
330
No request parameters/headers.
331

    
332
No reply content/headers.
333

    
334
================  ===============================
335
Return Code       Description
336
================  ===============================
337
204 (No Content)  The request succeeded
338
409 (Conflict)    The container is not empty
339
================  ===============================
340

    
341

    
342
Object Level
343
^^^^^^^^^^^^
344

    
345
List of operations:
346

    
347
=========  =================================
348
Operation  Description
349
=========  =================================
350
HEAD       Retrieve object metadata
351
GET        Read object data
352
PUT        Write object data or copy/move object
353
COPY       Copy object
354
MOVE       Move object
355
POST       Update object metadata
356
DELETE     Delete object
357
=========  =================================
358

    
359

    
360
HEAD
361
""""
362

    
363
No request parameters/headers.
364

    
365
==========================  ===============================
366
Reply Header Name           Value
367
==========================  ===============================
368
ETag                        The ETag of the object
369
Content-Length              The size of the object
370
Content-Type                The MIME content type of the object
371
Last-Modified               The last object modification date
372
Content-Encoding            The encoding of the object (optional)
373
Content-Disposition         The presentation style of the object (optional)
374
X-Object-Manifest           Large object support (optional)
375
X-Object-Meta-*             Optional user defined metadata
376
==========================  ===============================
377

    
378
|
379

    
380
================  ===============================
381
Return Code       Description
382
================  ===============================
383
204 (No Content)  The request succeeded
384
================  ===============================
385

    
386

    
387
GET
388
"""
389

    
390
====================  ================================
391
Request Header Name   Value
392
====================  ================================
393
Range                 Optional range of data to retrieve
394
If-Match              Retrieve if ETags match
395
If-None-Match         Retrieve if ETags don't match
396
If-Modified-Since     Retrieve if object has changed since provided timestamp
397
If-Unmodified-Since   Retrieve if object has not changed since provided timestamp
398
====================  ================================
399

    
400
|
401

    
402
======================  ===================================
403
Request Parameter Name  Value
404
======================  ===================================
405
format                  Optional extended reply type (can be ``json`` or ``xml``)
406
======================  ===================================
407

    
408
The reply is the object's data (or part of it), except if a hashmap is requested with the ``format`` parameter. Object headers (as in a ``HEAD`` request) are always included.
409

    
410
Hashmaps expose the underlying storage format of the object:
411

    
412
* Blocksize of 4MB.
413
* Blocks stored indexed by SHA256 hash.
414
* Hash is computed after trimming trailing null bytes.
415

    
416
Example ``format=json`` reply:
417

    
418
::
419

    
420
  {"hashes": ["7295c41da03d7f916440b98e32c4a2a39351546c", ...], "bytes": 24223726}
421

    
422
Example ``format=xml`` reply:
423

    
424
::
425

    
426
  <?xml version="1.0" encoding="UTF-8"?>
427
  <object name="file" bytes="24223726">
428
    <hash>7295c41da03d7f916440b98e32c4a2a39351546c</hash>
429
    <hash>...</hash>
430
  </object>
431

    
432
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.
433

    
434
==========================  ===============================
435
Reply Header Name           Value
436
==========================  ===============================
437
ETag                        The ETag of the object
438
Content-Length              The size of the data returned
439
Content-Type                The MIME content type of the object
440
Content-Range               The range of data included (only on a single range request)
441
Last-Modified               The last object modification date
442
Content-Encoding            The encoding of the object (optional)
443
Content-Disposition         The presentation style of the object (optional)
444
X-Object-Manifest           Large object support (optional)
445
X-Object-Meta-*             Optional user defined metadata
446
==========================  ===============================
447

    
448
|
449

    
450
===========================  ==============================
451
Return Code                  Description
452
===========================  ==============================
453
200 (OK)                     The request succeeded
454
206 (Partial Content)        The range request succeeded
455
304 (Not Modified)           The object has not been modified
456
412 (Precondition Failed)    The condition set can not be satisfied
457
416 (Range Not Satisfiable)  The requested range is out of limits
458
===========================  ==============================
459

    
460

    
461
PUT
462
"""
463

    
464
====================  ================================
465
Request Header Name   Value
466
====================  ================================
467
ETag                  The MD5 hash of the object (optional to check written data)
468
Content-Length        The size of the data written
469
Content-Type          The MIME content type of the object
470
Transfer-Encoding     Set to ``chunked`` to specify incremental uploading (if used, ``Content-Length`` is ignored)
471
X-Copy-From           The source path in the form ``/<container>/<object>``
472
X-Move-From           The source path in the form ``/<container>/<object>``
473
Content-Encoding      The encoding of the object (optional)
474
Content-Disposition   The presentation style of the object (optional)
475
X-Object-Manifest     Large object support (optional)
476
X-Object-Meta-*       Optional user defined metadata
477
====================  ================================
478

    
479
|
480

    
481
==========================  ===============================
482
Reply Header Name           Value
483
==========================  ===============================
484
ETag                        The MD5 hash of the object (on create)
485
==========================  ===============================
486

    
487
|
488

    
489
===========================  ==============================
490
Return Code                  Description
491
===========================  ==============================
492
201 (Created)                The object has been created
493
411 (Length Required)        Missing ``Content-Length`` or ``Content-Type`` in the request
494
422 (Unprocessable Entity)   The MD5 checksum of the data written to the storage system does not match the (optionally) supplied ETag value
495
===========================  ==============================
496

    
497

    
498
COPY
499
""""
500

    
501
====================  ================================
502
Request Header Name   Value
503
====================  ================================
504
Destination           The destination path in the form ``/<container>/<object>``
505
Content-Type          The MIME content type of the object (optional)
506
Content-Encoding      The encoding of the object (optional)
507
Content-Disposition   The presentation style of the object (optional)
508
X-Object-Manifest     Large object support (optional)
509
X-Object-Meta-*       Optional user defined metadata
510
====================  ================================
511

    
512
No reply content/headers.
513

    
514
===========================  ==============================
515
Return Code                  Description
516
===========================  ==============================
517
201 (Created)                The object has been created
518
===========================  ==============================
519

    
520

    
521
MOVE
522
""""
523

    
524
Same as ``COPY``.
525

    
526

    
527
POST
528
""""
529

    
530
====================  ================================
531
Request Header Name   Value
532
====================  ================================
533
Content-Length        The size of the data written (optional, to update)
534
Content-Type          The MIME content type of the object (optional, to update)
535
Content-Range         The range of data supplied (optional, to update)
536
Transfer-Encoding     Set to ``chunked`` to specify incremental uploading (if used, ``Content-Length`` is ignored)
537
Content-Encoding      The encoding of the object (optional)
538
Content-Disposition   The presentation style of the object (optional)
539
X-Object-Manifest     Large object support (optional)
540
X-Object-Meta-*       Optional user defined metadata
541
====================  ================================
542

    
543
The ``Content-Encoding``, ``Content-Disposition``, ``X-Object-Manifest`` and ``X-Object-Meta-*`` headers are considered to be user defined metadata. The update operation will overwrite all previous values and remove any keys not supplied.
544

    
545
To update an object:
546

    
547
* Supply ``Content-Length`` (except if using chunked transfers), ``Content-Type`` and ``Content-Range`` headers.
548
* Set ``Content-Type`` to ``application/octet-stream``.
549
* Set ``Content-Range`` as specified in RFC2616, with the following differences:
550

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

    
555
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.
556

    
557
No reply content. No reply headers if only metadata is updated.
558

    
559
==========================  ===============================
560
Reply Header Name           Value
561
==========================  ===============================
562
ETag                        The new ETag of the object (data updated)
563
==========================  ===============================
564

    
565
|
566

    
567
===========================  ==============================
568
Return Code                  Description
569
===========================  ==============================
570
202 (Accepted)               The request has been accepted (not a data update)
571
204 (No Content)             The request succeeded (data updated)
572
416 (Range Not Satisfiable)  The supplied range is out of limits or invalid size
573
===========================  ==============================
574

    
575

    
576
DELETE
577
""""""
578

    
579
No request parameters/headers.
580

    
581
No reply content/headers.
582

    
583
===========================  ==============================
584
Return Code                  Description
585
===========================  ==============================
586
204 (No Content)             The request succeeded
587
===========================  ==============================
588

    
589

    
590
Summary
591
^^^^^^^
592

    
593
List of differences from the OOS API:
594

    
595
* Support for ``X-Account-Meta-*`` style headers at the account level. Use ``POST`` to update.
596
* Support for ``X-Container-Meta-*`` style headers at the account level. Can be set when creating via ``PUT``. Use ``POST`` to update.
597
* Header ``X-Container-Object-Meta`` at the container level and parameter ``meta`` in container listings.
598
* All metadata replies, at all levels, include latest modification information.
599
* At all levels, a ``GET`` request may use ``If-Modified-Since`` and ``If-Unmodified-Since`` headers.
600
* 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. 
601
* Object metadata allowed, in addition to ``X-Object-Meta-*``: ``Content-Encoding``, ``Content-Disposition``, ``X-Object-Manifest``. These are all replaced with every update operation.
602
* Multi-range object GET support as outlined in RFC2616.
603
* Object hashmap retrieval through GET and the ``format`` parameter.
604
* Partial object updates through POST, using the ``Content-Length``, ``Content-Type``, ``Content-Range`` and ``Transfer-Encoding`` headers.
605
* Object ``MOVE`` support.
606

    
607
Clarifications/suggestions:
608

    
609
* 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.
610
* 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.
611
* A ``GET`` reply for a level will include all headers of the corresponding ``HEAD`` request.
612
* 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.
613
* The ``Accept`` header may be used in requests instead of the ``format`` parameter to specify the desired reply format. The parameter overrides the header.
614
* Container/object lists use a ``200`` return code if the reply is of type json/xml. The reply will include an empty json/xml.
615
* In headers, dates are formatted according to RFC 1123. In extended information listings, dates are formatted according to ISO 8601.
616
* While ``X-Object-Manifest`` can be set and unset, large object support is not yet implemented (**TBD**).
617

    
618
The Pithos Client
619
-----------------
620

    
621
User Experience
622
^^^^^^^^^^^^^^^
623

    
624
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.
625

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

    
628
* 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.
629
* The ``trash`` element, which contains files that have been marked for deletion, but can still be recovered.
630
* The ``shared`` element, which contains all objects shared by the user to other users of the system.
631
* The ``others`` element, which contains all objects that other users share with the user.
632
* 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.).
633
* 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.
634

    
635
Objects in Pithos can be:
636

    
637
* Assigned custom tags.
638
* Moved to trash and then deleted.
639
* Shared with specific permissions.
640
* Made public (shared with non-Pithos users).
641
* Set to monitor changes via version tracking.
642

    
643
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. 
644

    
645
Conventions and Metadata Specification
646
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
647

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

    
650
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 (except ``trash``) 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.
651

    
652
To manage the deletion of files use the same API and the ``X-Object-Meta-Trash`` key. The string ``trash`` can not be used as a tag. The ``trash`` element should be presented as a folder, although with no hierarchy.
653

    
654
The metadata specification is summarized in the following table.
655

    
656
===========================  ==============================
657
Metadata Name                Value
658
===========================  ==============================
659
X-Object-Meta-Trash          Set to ``true`` if the object has been moved to the trash
660
X-Object-Meta-*              Use for other tags that apply to the object
661
===========================  ==============================