From 3a25ef7048e6e1a8a7654c14debbc96d2667aed9 Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Sun, 01 Sep 2013 11:22:55 +0000 Subject: Make sure that request content is fetched before exiting from spawned route --- diff --git a/sugar_network/toolkit/router.py b/sugar_network/toolkit/router.py index dd22b83..117d8cc 100644 --- a/sugar_network/toolkit/router.py +++ b/sugar_network/toolkit/router.py @@ -187,11 +187,7 @@ class Request(dict): @property def content(self): - if self._content is _NOT_SET: - if self.content_type == 'application/json': - self._content = json.load(self.environ['wsgi.input']) - else: - self._content = None + self.ensure_content() return self._content @content.setter @@ -299,6 +295,16 @@ class Request(dict): request.subcall = self.subcall return self.subcall(request, response) + def ensure_content(self): + if self._content is not _NOT_SET: + return + if self.content_stream is None: + self._content = None + elif self.content_type == 'application/json': + self._content = json.load(self.content_stream) + else: + self._content = self.content_stream.read() + def __repr__(self): return '' % \ (self.method, self.path, self.cmd, dict(self)) @@ -580,6 +586,7 @@ class Router(object): if route_.mime_type == 'text/event-stream' and \ self._allow_spawn and 'spawn' in request: _logger.debug('Spawn event stream for %r', request) + request.ensure_content() coroutine.spawn(self._event_stream, request, result) result = None except Exception, exception: diff --git a/tests/units/toolkit/router.py b/tests/units/toolkit/router.py index ad90cf5..131e587 100755 --- a/tests/units/toolkit/router.py +++ b/tests/units/toolkit/router.py @@ -594,7 +594,6 @@ class RouterTest(tests.Test): self.value = value def read(self, size): - print self.pos, size, len(self.value) assert self.pos + size <= len(self.value) result = self.value[self.pos:self.pos + size] self.pos += size @@ -1354,6 +1353,37 @@ class RouterTest(tests.Test): events) del events[:] + def test_ReadRequestOnEventStreamSpawn(self): + events = [] + + class Routes(object): + + @route('GET', mime_type='text/event-stream') + def get(self, request): + yield {} + yield {'request': request.content} + + def broadcast(self, event): + events.append(event.copy()) + + reply = Router(Routes(), allow_spawn=True)({ + 'PATH_INFO': '/', + 'REQUEST_METHOD': 'GET', + 'QUERY_STRING': 'spawn', + 'CONTENT_LENGTH': '5', + 'wsgi.input': StringIO('probe'), + }, + lambda status, headers: None) + self.assertEqual([], [i for i in reply]) + + coroutine.sleep(.1) + self.assertEqual([ + {'method': 'GET'}, + {'method': 'GET', 'request': 'probe'}, + ], + events) + del events[:] + if __name__ == '__main__': tests.main() -- cgit v0.9.1