extend api object write to accept xml formatted requests containing hashmap informati...
authorSofia Papagiannaki <papagian@gmail.com>
Wed, 13 Jul 2011 15:47:12 +0000 (18:47 +0300)
committerSofia Papagiannaki <papagian@gmail.com>
Wed, 13 Jul 2011 15:47:12 +0000 (18:47 +0300)
socket_read_iterator raises BadRequest if maximum size is reached

docs/source/devguide.rst
pithos/api/functions.py
pithos/api/util.py

index 51aaf67..8c1892e 100644 (file)
@@ -604,6 +604,15 @@ Example ``format=json`` request:
 
   {"block_hash": "sha1", "hashes": ["7295c41da03d7f916440b98e32c4a2a39351546c", ...], "block_size": 131072, "bytes": 242}
 
+Example ``format=xml`` request:
+
+::
+
+  <?xml version="1.0" encoding="UTF-8"?>
+  <object name="file" bytes="24223726" block_size="131072" block_hash="sha1">
+    <hash>7295c41da03d7f916440b98e32c4a2a39351546c</hash>
+    <hash>...</hash>
+  </object>
 
 ==========================  ===============================
 Reply Header Name           Value
index 6b0b229..0432144 100644 (file)
@@ -40,6 +40,7 @@ from django.http import HttpResponse
 from django.template.loader import render_to_string
 from django.utils import simplejson as json
 from django.utils.http import parse_etags
+from xml.dom import minidom
 
 from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, ItemNotFound, Conflict,
     LengthRequired, PreconditionFailed, RangeNotSatisfiable, UnprocessableEntity)
@@ -622,23 +623,35 @@ def object_write(request, v_account, v_container, v_object):
     if 'Content-Type' not in meta:
         raise LengthRequired('Missing Content-Type header')
     
-    if request.serialization == 'json':
+    if request.serialization != 'text':
         data = ''
         sock = raw_input_socket(request)
         for block in socket_read_iterator(sock, content_length, backend.block_size):
             data = '%s%s' % (data, block)
-        d = json.loads(data)
-        if not hasattr(d, '__getitem__'):
-            raise BadRequest('Invalid data formating')
-        try:
-            hashmap = d['hashes']
-            size = d['bytes']
-        except KeyError:
-            raise BadRequest('Invalid data formatting')
+        
+        if request.serialization == 'json':
+            d = json.loads(data)
+            if not hasattr(d, '__getitem__'):
+                raise BadRequest('Invalid data formating')
+            try:
+                hashmap = d['hashes']
+                size = d['bytes']
+            except KeyError:
+                raise BadRequest('Invalid data formatting')
+        elif request.serialization == 'xml':
+            try:
+                xml = minidom.parseString(data)
+                obj = xml.getElementsByTagName('object')[0]
+                size = obj.attributes['bytes'].value
+                
+                hashes = xml.getElementsByTagName('hash')
+                hashmap = []
+                for hash in hashes:
+                    hashmap.append(hash.firstChild.data)
+            except Exception:
+                raise BadRequest('Invalid data formatting')
+        
         meta.update({'hash': hashmap_hash(hashmap)}) # Update ETag.
-    elif request.serialization == 'xml':
-        # TODO: Support xml.
-        raise BadRequest('Format xml is not supported')
     else:
         md5 = hashlib.md5()
         size = 0
@@ -724,7 +737,6 @@ def object_update(request, v_account, v_container, v_object):
     #                       itemNotFound (404),
     #                       unauthorized (401),
     #                       badRequest (400)
-    
     meta, permissions, public = get_object_headers(request)
     content_type = meta.get('Content-Type')
     if content_type:
@@ -816,7 +828,7 @@ def object_update(request, v_account, v_container, v_object):
         content_length = -1
         if request.META.get('HTTP_TRANSFER_ENCODING') != 'chunked':
             content_length = get_content_length(request)
-        
+            
         if length is None:
             length = content_length
         else:
index 0c3dbf2..99b8ae9 100644 (file)
@@ -472,11 +472,10 @@ def socket_read_iterator(sock, length=0, blocksize=4096):
                     data = data[blocksize:]
                     yield ret
             sock.read(2) # CRLF
-        # TODO: Raise something to note that maximum size is reached.
+        raise BadRequest('Maximum size is reached')
     else:
         if length > MAX_UPLOAD_SIZE:
-            # TODO: Raise something to note that maximum size is reached.
-            pass
+            raise BadRequest('Maximum size is reached')
         while length > 0:
             data = sock.read(min(length, blocksize))
             length -= len(data)