From 0f9ae89f82a872f7449b8e2d72b7d6f63fa0180d Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Fri, 05 Jul 2013 02:49:00 +0000 Subject: Return HEAD metadata in per-prop attributes --- 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, -- cgit v0.9.1