Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Readonly #710

Merged
merged 2 commits into from
Dec 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ CHANGES
- Implement class based views #684

- Drop unused function `parse_remote_addr()` #708

- Close session on exception #707
73 changes: 58 additions & 15 deletions aiohttp/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
import string
import sys
import zlib
from abc import abstractmethod, ABCMeta
from wsgiref.handlers import format_date_time

import aiohttp
from . import errors, hdrs
from .multidict import CIMultiDict, upstr
from .log import internal_logger
from .helpers import reify

__all__ = ('HttpMessage', 'Request', 'Response',
'HttpVersion', 'HttpVersion10', 'HttpVersion11',
Expand Down Expand Up @@ -475,7 +477,7 @@ def filter_pipe(filter, filter2, *,
chunk = yield EOL_MARKER


class HttpMessage:
class HttpMessage(metaclass=ABCMeta):
"""HttpMessage allows to write headers and payload to a stream.

For example, lets say we want to read file then compress it with deflate
Expand Down Expand Up @@ -526,8 +528,6 @@ class HttpMessage:
SERVER_SOFTWARE = 'Python/{0[0]}.{0[1]} aiohttp/{1}'.format(
sys.version_info, aiohttp.__version__)

status = None
status_line = b''
upgrade = False # Connection: UPGRADE
websocket = False # Upgrade: WEBSOCKET
has_chunked_hdr = False # Transfer-encoding: chunked
Expand All @@ -538,7 +538,7 @@ class HttpMessage:

def __init__(self, transport, version, close):
self.transport = transport
self.version = version
self._version = version
self.closing = close
self.keepalive = None
self.chunked = False
Expand All @@ -549,6 +549,19 @@ def __init__(self, transport, version, close):
self.headers_length = 0
self._output_size = 0

@property
@abstractmethod
def status_line(self):
return b''

@abstractmethod
def autochunked(self):
return False

@property
def version(self):
return self._version

@property
def body_length(self):
return self.output_length - self.headers_length
Expand Down Expand Up @@ -633,9 +646,7 @@ def send_headers(self, _sep=': ', _end='\r\n'):
assert not self.headers_sent, 'headers have been sent already'
self.headers_sent = True

if self.chunked or (self.length is None and
self.version >= HttpVersion11 and
self.status not in (304, 204)):
if self.chunked or self.autochunked():
self.writer = self._write_chunked_payload()
self.headers[hdrs.TRANSFER_ENCODING] = 'chunked'

Expand Down Expand Up @@ -827,13 +838,29 @@ def __init__(self, transport, status,
http_version=HttpVersion11, close=False, reason=None):
super().__init__(transport, http_version, close)

self.status = status
self._status = status
if reason is None:
reason = self.calc_reason(status)

self.reason = reason
self.status_line = 'HTTP/{}.{} {} {}\r\n'.format(
http_version[0], http_version[1], status, reason)
self._reason = reason

@property
def status(self):
return self._status

@property
def reason(self):
return self._reason

@reify
def status_line(self):
version = self.version
return 'HTTP/{}.{} {} {}\r\n'.format(
version[0], version[1], self.status, self.reason)

def autochunked(self):
return (self.length is None and
self.version >= HttpVersion11)

def _add_default_headers(self):
super()._add_default_headers()
Expand All @@ -857,7 +884,23 @@ def __init__(self, transport, method, path,

super().__init__(transport, http_version, close)

self.method = method
self.path = path
self.status_line = '{0} {1} HTTP/{2[0]}.{2[1]}\r\n'.format(
method, path, http_version)
self._method = method
self._path = path

@property
def method(self):
return self._method

@property
def path(self):
return self._path

@reify
def status_line(self):
return '{0} {1} HTTP/{2[0]}.{2[1]}\r\n'.format(
self.method, self.path, self.version)

def autochunked(self):
return (self.length is None and
self.version >= HttpVersion11 and
self.status not in (304, 204))
1 change: 0 additions & 1 deletion tests/test_http_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def test_start_request(self):
self.transport, 'GET', '/index.html', close=True)

self.assertIs(msg.transport, self.transport)
self.assertIsNone(msg.status)
self.assertTrue(msg.closing)
self.assertEqual(msg.status_line, 'GET /index.html HTTP/1.1\r\n')

Expand Down