Skip to content

Commit

Permalink
Merge pull request #250 from mind1master/master
Browse files Browse the repository at this point in the history
Memorising of web.Request's read, text, json
  • Loading branch information
asvetlov committed Jan 20, 2015
2 parents 45157ec + 5fe2460 commit 6999e5a
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 18 deletions.
25 changes: 18 additions & 7 deletions aiohttp/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import json
import re
import os
import warnings

from urllib.parse import urlsplit, parse_qsl, urlencode, unquote
from types import MappingProxyType
Expand Down Expand Up @@ -172,6 +173,8 @@ def __init__(self, app, message, payload, transport, reader, writer, *,
self._payload = payload
self._cookies = None

self._read_bytes = None

@property
def method(self):
"""Read only property for getting HTTP method.
Expand Down Expand Up @@ -281,6 +284,12 @@ def cookies(self):

@property
def payload(self):
"""Return raw payload stream."""
warnings.warn('use Request.content instead', DeprecationWarning)
return self._payload

@property
def content(self):
"""Return raw payload stream."""
return self._payload

Expand All @@ -300,13 +309,15 @@ def read(self):
Returns bytes object with full request content.
"""
body = bytearray()
while True:
chunk = yield from self._payload.readany()
body.extend(chunk)
if chunk is EOF_MARKER:
break
return bytes(body)
if self._read_bytes is None:
body = bytearray()
while True:
chunk = yield from self._payload.readany()
body.extend(chunk)
if chunk is EOF_MARKER:
break
self._read_bytes = bytes(body)
return self._read_bytes

@asyncio.coroutine
def text(self):
Expand Down
33 changes: 23 additions & 10 deletions docs/web_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,26 @@ first positional parameter.

Read-only :class:`~aiohttp.multidict.MultiDictProxy` lazy property.

.. attribute:: content

A :class:`~aiohttp.streams.FlowControlStreamReader` instance,
input stream for reading request's *BODY*.

Read-only property.

.. versionadded:: 0.15

.. attribute:: payload

A :class:`~aiohttp.streams.FlowControlStreamReader` instance,
input stream for reading request's *BODY*.

Read-only property.

.. deprecated:: 0.15

Use :attr:`~Request.content` instead.

.. attribute:: content_type

Read-only property with *content* part of *Content-Type* header.
Expand Down Expand Up @@ -173,10 +186,10 @@ first positional parameter.

The method is a :ref:`coroutine <coroutine>`.

.. warning::
.. note::

The method doesn't store read data internally, subsequent
:meth:`~Request.read` call will return empty bytes ``b''``.
The method **does** store read data internally, subsequent
:meth:`~Request.read` call will return the same value.

.. method:: text()

Expand All @@ -187,10 +200,10 @@ first positional parameter.

The method is a :ref:`coroutine <coroutine>`.

.. warning::
.. note::

The method doesn't store read data internally, subsequent
:meth:`~Request.text` call will return empty string ``''``.
The method **does** store read data internally, subsequent
:meth:`~Request.text` call will return the same value.

.. method:: json(*, loader=json.loads)

Expand All @@ -208,10 +221,10 @@ first positional parameter.
and returns :class:`dict` with parsed
JSON (:func:`json.loads` by default).

.. warning::
.. note::

The method doesn't store read data internally, subsequent
:meth:`~Request.json` call will raise an exception.
The method **does** store read data internally, subsequent
:meth:`~Request.json` call will return the same value.

.. method:: post()

Expand All @@ -226,7 +239,7 @@ first positional parameter.
*application/x-www-form-urlencoded* or *multipart/form-data*
returns empty multidict.

.. warning::
.. note::

The method **does** store read data internally, subsequent
:meth:`~Request.post` call will return the same value.
Expand Down
4 changes: 4 additions & 0 deletions tests/test_web_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def test_post_text(self):
def handler(request):
data = yield from request.text()
self.assertEqual('русский', data)
data2 = yield from request.text()
self.assertEqual(data, data2)
return web.Response(text=data)

@asyncio.coroutine
Expand All @@ -101,6 +103,8 @@ def test_post_json(self):
def handler(request):
data = yield from request.json()
self.assertEqual(dct, data)
data2 = yield from request.json()
self.assertEqual(data, data2)
resp = web.Response()
resp.content_type = 'application/json'
resp.body = json.dumps(data).encode('utf8')
Expand Down
4 changes: 3 additions & 1 deletion tests/test_web_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ def test_ctor(self):
# second call should return the same object
self.assertIs(get, req.GET)

self.assertIs(self.payload, req.payload)
with self.assertWarns(DeprecationWarning):
self.assertIs(self.payload, req.payload)
self.assertIs(self.payload, req.content)
self.assertIs(self.transport, req.transport)
self.assertTrue(req.keep_alive)

Expand Down

0 comments on commit 6999e5a

Please sign in to comment.