Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2013-07-05 02:49:00 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2013-07-05 02:49:00 (GMT)
commit0f9ae89f82a872f7449b8e2d72b7d6f63fa0180d (patch)
tree5475c0bf4c057fa2fe2593f9d39aa9fcf7ef1393
parent1c50340a98e5a55efac7c2ccdcd2000293409eec (diff)
Return HEAD metadata in per-prop attributes
-rw-r--r--sugar_network/db/commands.py1
-rw-r--r--sugar_network/db/router.py26
-rw-r--r--sugar_network/db/volume.py4
-rw-r--r--tests/__init__.py2
-rwxr-xr-xtests/units/db/router.py23
-rwxr-xr-xtests/units/db/volume.py11
6 files changed, 51 insertions, 16 deletions
diff --git a/sugar_network/db/commands.py b/sugar_network/db/commands.py
index 5cee8c3..c6ff71a 100644
--- a/sugar_network/db/commands.py
+++ b/sugar_network/db/commands.py
@@ -160,6 +160,7 @@ class Response(dict):
def __init__(self, **kwargs):
"""Initialize parameters dictionary using named arguments."""
dict.__init__(self, kwargs)
+ self.meta = {}
@property
def content_length(self):
diff --git a/sugar_network/db/router.py b/sugar_network/db/router.py
index 19eab12..dea8a6b 100644
--- a/sugar_network/db/router.py
+++ b/sugar_network/db/router.py
@@ -175,17 +175,21 @@ class Router(object):
result_streamed = isinstance(result, types.GeneratorType)
- if js_callback:
- if result_streamed:
- result = ''.join(result)
- result_streamed = False
- result = '%s(%s);' % (js_callback, json.dumps(result))
- response.content_length = len(result)
- elif not result_streamed:
- if response.content_type == 'application/json':
- result = json.dumps(result)
- if 'content-length' not in response:
- response.content_length = len(result) if result else 0
+ if request['method'] != 'HEAD':
+ if js_callback:
+ if result_streamed:
+ result = ''.join(result)
+ result_streamed = False
+ result = '%s(%s);' % (js_callback, json.dumps(result))
+ response.content_length = len(result)
+ elif not result_streamed:
+ if response.content_type == 'application/json':
+ result = json.dumps(result)
+ if 'content-length' not in response:
+ response.content_length = len(result) if result else 0
+
+ for key, value in response.meta.items():
+ response.set('X-SN-%s' % str(key), json.dumps(value))
_logger.trace('Called %s: response=%r result=%r streamed=%r',
request_repr, response, result, result_streamed)
diff --git a/sugar_network/db/volume.py b/sugar_network/db/volume.py
index 7b28b75..18e0b2c 100644
--- a/sugar_network/db/volume.py
+++ b/sugar_network/db/volume.py
@@ -243,7 +243,9 @@ class VolumeCommands(CommandsProcessor):
meta.pop('blob')
meta['url'] = '/'.join([request.static_prefix] + request.path)
response.content_length = meta['blob_size']
- response['SN-property'] = json.dumps(meta)
+
+ response.meta.update(meta)
+ response.last_modified = meta['mtime']
def on_create(self, request, props, event):
if 'guid' in props:
diff --git a/tests/__init__.py b/tests/__init__.py
index ebc53a0..f84325b 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -227,6 +227,8 @@ class Test(unittest.TestCase):
with util.NamedTemporaryFile() as f:
bundle = zipfile.ZipFile(f.name, 'w')
for arcname, data in items:
+ if not isinstance(data, basestring):
+ data = '\n'.join(data)
bundle.writestr(arcname, data)
bundle.close()
return file(f.name, 'rb').read()
diff --git a/tests/units/db/router.py b/tests/units/db/router.py
index 5e9b2a5..5147c71 100755
--- a/tests/units/db/router.py
+++ b/tests/units/db/router.py
@@ -505,6 +505,29 @@ class RouterTest(tests.Test):
],
response)
+ def test_DoNotOverrideContentLengthForHEAD(self):
+
+ class CommandsProcessor(db.CommandsProcessor):
+
+ @db.route('HEAD', '/')
+ def head(self, request, response):
+ response.content_length = 100
+
+ router = Router(CommandsProcessor())
+
+ response = []
+ reply = router({
+ 'PATH_INFO': '/',
+ 'REQUEST_METHOD': 'HEAD',
+ },
+ lambda status, headers: response.extend([status, dict(headers)]))
+ self.assertEqual([], [i for i in reply])
+ self.assertEqual([
+ '200 OK',
+ {'content-length': '100'},
+ ],
+ response)
+
if __name__ == '__main__':
tests.main()
diff --git a/tests/units/db/volume.py b/tests/units/db/volume.py
index 6af78ee..b968069 100755
--- a/tests/units/db/volume.py
+++ b/tests/units/db/volume.py
@@ -4,11 +4,11 @@
import os
import sys
import time
-import json
import shutil
import hashlib
from cStringIO import StringIO
from email.message import Message
+from email.utils import formatdate
from os.path import dirname, join, abspath, exists
src_root = abspath(dirname(__file__))
@@ -1164,7 +1164,8 @@ class VolumeTest(tests.Test):
assert cp.call(request, response) is None
meta = volume['testdocument'].get(guid).meta('prop')
meta.pop('value')
- self.assertEqual(meta, json.loads(response['SN-property']))
+ self.assertEqual(meta, response.meta)
+ self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified)
request = db.Request(method='HEAD', document='testdocument', guid=guid, prop='blob1')
request.static_prefix = 'http://localhost'
@@ -1174,15 +1175,17 @@ class VolumeTest(tests.Test):
meta = volume['testdocument'].get(guid).meta('blob1')
meta.pop('blob')
meta['url'] = 'http://localhost/path'
- self.assertEqual(meta, json.loads(response['SN-property']))
+ self.assertEqual(meta, response.meta)
self.assertEqual(len('blob'), response.content_length)
+ self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified)
request = db.Request(method='HEAD', document='testdocument', guid=guid, prop='blob2')
response = db.Response()
assert cp.call(request, response) is None
meta = volume['testdocument'].get(guid).meta('blob2')
- self.assertEqual(meta, json.loads(response['SN-property']))
+ self.assertEqual(meta, response.meta)
self.assertEqual(100, response.content_length)
+ self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified)
def call(self, method, document=None, guid=None, prop=None,
accept_language=None, content=None, content_stream=None,