def __init__(self, method, handler, *, expect_handler=None, resource=None): if expect_handler is None: expect_handler = _defaultExpectHandler assert asyncio.iscoroutinefunction(expect_handler), "Coroutine is expected, got {!r}".format(expect_handler) method = upstr(method) if method not in self.METHODS: raise ValueError("{} is not allowed HTTP method".format(method)) assert callable(handler), handler if asyncio.iscoroutinefunction(handler): pass elif inspect.isgeneratorfunction(handler): warnings.warn("Bare generators are deprecated, " "use @coroutine wrapper", DeprecationWarning) elif isinstance(handler, type) and issubclass(handler, AbstractView): pass else: @asyncio.coroutine def handler_wrapper(*args, **kwargs): result = old_handler(*args, **kwargs) if asyncio.iscoroutine(result): result = yield from result return result old_handler = handler handler = handler_wrapper self._method = method self._handler = handler self._expect_handler = expect_handler self._resource = resource
def __init__(self, *, connector=None, loop=None, cookies=None, headers=None, skip_auto_headers=None, auth=None, request_class=ClientRequest, response_class=ClientResponse, ws_response_class=ClientWebSocketResponse, version=aiohttp.HttpVersion11): if connector is None: connector = aiohttp.TCPConnector(loop=loop) loop = connector._loop # never None else: if loop is None: loop = connector._loop # never None elif connector._loop is not loop: raise ValueError("loop argument must agree with connector") self._loop = loop if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) self._cookie_jar = CookieJar(loop=loop) # For Backward compatability with `share_cookies` connectors if connector._share_cookies: self._cookie_jar.update_cookies(connector.cookies) if cookies is not None: self._cookie_jar.update_cookies(cookies) self._connector = connector self._default_auth = auth self._version = version # Convert to list of tuples if headers: headers = CIMultiDict(headers) else: headers = CIMultiDict() self._default_headers = headers if skip_auto_headers is not None: self._skip_auto_headers = frozenset( [upstr(i) for i in skip_auto_headers]) else: self._skip_auto_headers = frozenset() self._request_class = request_class self._response_class = response_class self._ws_response_class = ws_response_class
def __init__(self, *, connector=None, loop=None, cookies=None, headers=None, skip_auto_headers=None, auth=None, request_class=ClientRequest, response_class=ClientResponse, ws_response_class=ClientWebSocketResponse, version=aiohttp.HttpVersion11): if connector is None: connector = aiohttp.TCPConnector(loop=loop) loop = connector._loop # never None else: if loop is None: loop = connector._loop # never None elif connector._loop is not loop: raise ValueError("loop argument must agree with connector") self._loop = loop if loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) self._cookies = http.cookies.SimpleCookie() # For Backward compatability with `share_cookies` connectors if connector._share_cookies: self._update_cookies(connector.cookies) if cookies is not None: self._update_cookies(cookies) self._connector = connector self._default_auth = auth self._version = version # Convert to list of tuples if headers: headers = CIMultiDict(headers) else: headers = CIMultiDict() self._default_headers = headers if skip_auto_headers is not None: self._skip_auto_headers = frozenset([upstr(i) for i in skip_auto_headers]) else: self._skip_auto_headers = frozenset() self._request_class = request_class self._response_class = response_class self._ws_response_class = ws_response_class
def add_header(self, name, value): """Analyze headers. Calculate content length, removes hop headers, etc.""" assert not self.headers_sent, 'headers have been sent already' assert isinstance(name, str), \ 'Header name should be a string, got {!r}'.format(name) assert set(name).issubset(ASCIISET), \ 'Header name should contain ASCII chars, got {!r}'.format(name) assert isinstance(value, str), \ 'Header {!r} should have string value, got {!r}'.format( name, value) name = upstr(name) value = value.strip() if name == hdrs.CONTENT_LENGTH: self.length = int(value) if name == hdrs.TRANSFER_ENCODING: self.has_chunked_hdr = value.lower().strip() == 'chunked' if name == hdrs.CONNECTION: val = value.lower() # handle websocket if 'upgrade' in val: self.upgrade = True # connection keep-alive elif 'close' in val: self.keepalive = False elif 'keep-alive' in val: self.keepalive = True elif name == hdrs.UPGRADE: if 'websocket' in value.lower(): self.websocket = True self.headers[name] = value elif name not in self.HOP_HEADERS: # ignore hop-by-hop headers self.headers.add(name, value)
def __init__(self, method, handler, *, expect_handler=None, resource=None): if expect_handler is None: expect_handler = _defaultExpectHandler assert asyncio.iscoroutinefunction(expect_handler), \ 'Coroutine is expected, got {!r}'.format(expect_handler) method = upstr(method) if method not in self.METHODS: raise ValueError("{} is not allowed HTTP method".format(method)) assert callable(handler), handler if asyncio.iscoroutinefunction(handler): pass elif inspect.isgeneratorfunction(handler): warnings.warn( "Bare generators are deprecated, " "use @coroutine wrapper", DeprecationWarning) elif (isinstance(handler, type) and issubclass(handler, AbstractView)): pass else: @asyncio.coroutine def handler_wrapper(*args, **kwargs): result = old_handler(*args, **kwargs) if asyncio.iscoroutine(result): result = yield from result return result old_handler = handler handler = handler_wrapper self._method = method self._handler = handler self._expect_handler = expect_handler self._resource = resource
def test_skip_default_useragent_header(make_request): req = make_request("get", "http://python.org/", skip_auto_headers=set([upstr("user-agent")])) assert "User-Agent" not in req.headers
def test_skip_default_useragent_header(make_request): req = make_request('get', 'http://python.org/', skip_auto_headers=set([upstr('user-agent')])) assert 'User-Agent' not in req.headers
def _format_o(key, args): return args[2].headers.get(multidict.upstr(key), '-')
def _format_e(key, args): return (args[1] or {}).get(multidict.upstr(key), '-')
"""HTTP Headers constants.""" from multidict import upstr METH_ANY = upstr('*') METH_CONNECT = upstr('CONNECT') METH_HEAD = upstr('HEAD') METH_GET = upstr('GET') METH_DELETE = upstr('DELETE') METH_OPTIONS = upstr('OPTIONS') METH_PATCH = upstr('PATCH') METH_POST = upstr('POST') METH_PUT = upstr('PUT') METH_TRACE = upstr('TRACE') METH_ALL = { METH_CONNECT, METH_HEAD, METH_GET, METH_DELETE, METH_OPTIONS, METH_PATCH, METH_POST, METH_PUT, METH_TRACE } ACCEPT = upstr('ACCEPT') ACCEPT_CHARSET = upstr('ACCEPT-CHARSET') ACCEPT_ENCODING = upstr('ACCEPT-ENCODING') ACCEPT_LANGUAGE = upstr('ACCEPT-LANGUAGE') ACCEPT_RANGES = upstr('ACCEPT-RANGES') ACCESS_CONTROL_MAX_AGE = upstr('ACCESS-CONTROL-MAX-AGE') ACCESS_CONTROL_ALLOW_CREDENTIALS = upstr('ACCESS-CONTROL-ALLOW-CREDENTIALS') ACCESS_CONTROL_ALLOW_HEADERS = upstr('ACCESS-CONTROL-ALLOW-HEADERS') ACCESS_CONTROL_ALLOW_METHODS = upstr('ACCESS-CONTROL-ALLOW-METHODS') ACCESS_CONTROL_ALLOW_ORIGIN = upstr('ACCESS-CONTROL-ALLOW-ORIGIN') ACCESS_CONTROL_EXPOSE_HEADERS = upstr('ACCESS-CONTROL-EXPOSE-HEADERS') ACCESS_CONTROL_REQUEST_HEADERS = upstr('ACCESS-CONTROL-REQUEST-HEADERS')
def _format_i(key, args): if not args[0]: return '(no headers)' return args[0].headers.get(multidict.upstr(key), '-')
def _request(self, method, url, *, params=None, data=None, headers=None, skip_auto_headers=None, auth=None, allow_redirects=True, max_redirects=10, encoding='utf-8', version=None, compress=None, chunked=None, expect100=False, read_until_eof=True): if version is not None: warnings.warn("HTTP version should be specified " "by ClientSession constructor", DeprecationWarning) else: version = self._version if self.closed: raise RuntimeError('Session is closed') redirects = 0 history = [] if not isinstance(method, upstr): method = upstr(method) # Merge with default headers and transform to CIMultiDict headers = self._prepare_headers(headers) if auth is None: auth = self._default_auth # It would be confusing if we support explicit Authorization header # with `auth` argument if (headers is not None and auth is not None and hdrs.AUTHORIZATION in headers): raise ValueError("Can't combine `Authorization` header with " "`auth` argument") skip_headers = set(self._skip_auto_headers) if skip_auto_headers is not None: for i in skip_auto_headers: skip_headers.add(upstr(i)) while True: req = self._request_class( method, url, params=params, headers=headers, skip_auto_headers=skip_headers, data=data, cookies=self.cookies, encoding=encoding, auth=auth, version=version, compress=compress, chunked=chunked, expect100=expect100, loop=self._loop, response_class=self._response_class) conn = yield from self._connector.connect(req) try: resp = req.send(conn.writer, conn.reader) try: yield from resp.start(conn, read_until_eof) except: resp.close() conn.close() raise except (aiohttp.HttpProcessingError, aiohttp.ServerDisconnectedError) as exc: raise aiohttp.ClientResponseError() from exc except OSError as exc: raise aiohttp.ClientOSError(*exc.args) from exc self._update_cookies(resp.cookies) # For Backward compatability with `share_cookie` connectors if self._connector._share_cookies: self._connector.update_cookies(resp.cookies) # redirects if resp.status in (301, 302, 303, 307) and allow_redirects: redirects += 1 history.append(resp) if max_redirects and redirects >= max_redirects: resp.close() break else: # TODO: close the connection if BODY is large enough # Redirect with big BODY is forbidden by HTTP protocol # but malformed server may send illegal response. # Small BODIES with text like "Not Found" are still # perfectly fine and should be accepted. yield from resp.release() # For 301 and 302, mimic IE behaviour, now changed in RFC. # Details: https://github.com/kennethreitz/requests/pull/269 if resp.status != 307: method = hdrs.METH_GET data = None if headers.get(hdrs.CONTENT_LENGTH): headers.pop(hdrs.CONTENT_LENGTH) r_url = (resp.headers.get(hdrs.LOCATION) or resp.headers.get(hdrs.URI)) scheme = urllib.parse.urlsplit(r_url)[0] if scheme not in ('http', 'https', ''): resp.close() raise ValueError('Can redirect only to http or https') elif not scheme: r_url = urllib.parse.urljoin(url, r_url) url = r_url params = None yield from resp.release() continue break resp._history = tuple(history) return resp
"""HTTP Headers constants.""" from multidict import upstr METH_ANY = upstr("*") METH_CONNECT = upstr("CONNECT") METH_HEAD = upstr("HEAD") METH_GET = upstr("GET") METH_DELETE = upstr("DELETE") METH_OPTIONS = upstr("OPTIONS") METH_PATCH = upstr("PATCH") METH_POST = upstr("POST") METH_PUT = upstr("PUT") METH_TRACE = upstr("TRACE") METH_ALL = {METH_CONNECT, METH_HEAD, METH_GET, METH_DELETE, METH_OPTIONS, METH_PATCH, METH_POST, METH_PUT, METH_TRACE} ACCEPT = upstr("ACCEPT") ACCEPT_CHARSET = upstr("ACCEPT-CHARSET") ACCEPT_ENCODING = upstr("ACCEPT-ENCODING") ACCEPT_LANGUAGE = upstr("ACCEPT-LANGUAGE") ACCEPT_RANGES = upstr("ACCEPT-RANGES") ACCESS_CONTROL_MAX_AGE = upstr("ACCESS-CONTROL-MAX-AGE") ACCESS_CONTROL_ALLOW_CREDENTIALS = upstr("ACCESS-CONTROL-ALLOW-CREDENTIALS") ACCESS_CONTROL_ALLOW_HEADERS = upstr("ACCESS-CONTROL-ALLOW-HEADERS") ACCESS_CONTROL_ALLOW_METHODS = upstr("ACCESS-CONTROL-ALLOW-METHODS") ACCESS_CONTROL_ALLOW_ORIGIN = upstr("ACCESS-CONTROL-ALLOW-ORIGIN") ACCESS_CONTROL_EXPOSE_HEADERS = upstr("ACCESS-CONTROL-EXPOSE-HEADERS") ACCESS_CONTROL_REQUEST_HEADERS = upstr("ACCESS-CONTROL-REQUEST-HEADERS") ACCESS_CONTROL_REQUEST_METHOD = upstr("ACCESS-CONTROL-REQUEST-METHOD") AGE = upstr("AGE")
def _request(self, method, url, *, params=None, data=None, headers=None, skip_auto_headers=None, auth=None, allow_redirects=True, max_redirects=10, encoding='utf-8', version=None, compress=None, chunked=None, expect100=False, read_until_eof=True): if version is not None: warnings.warn( "HTTP version should be specified " "by ClientSession constructor", DeprecationWarning) else: version = self._version if self.closed: raise RuntimeError('Session is closed') redirects = 0 history = [] if not isinstance(method, upstr): method = upstr(method) # Merge with default headers and transform to CIMultiDict headers = self._prepare_headers(headers) if auth is None: auth = self._default_auth # It would be confusing if we support explicit Authorization header # with `auth` argument if (headers is not None and auth is not None and hdrs.AUTHORIZATION in headers): raise ValueError("Can't combine `Authorization` header with " "`auth` argument") skip_headers = set(self._skip_auto_headers) if skip_auto_headers is not None: for i in skip_auto_headers: skip_headers.add(upstr(i)) while True: cookies = self._cookie_jar.filter_cookies(url) req = self._request_class(method, url, params=params, headers=headers, skip_auto_headers=skip_headers, data=data, cookies=cookies, encoding=encoding, auth=auth, version=version, compress=compress, chunked=chunked, expect100=expect100, loop=self._loop, response_class=self._response_class) conn = yield from self._connector.connect(req) try: resp = req.send(conn.writer, conn.reader) try: yield from resp.start(conn, read_until_eof) except: resp.close() conn.close() raise except (aiohttp.HttpProcessingError, aiohttp.ServerDisconnectedError) as exc: raise aiohttp.ClientResponseError() from exc except OSError as exc: raise aiohttp.ClientOSError(*exc.args) from exc self._cookie_jar.update_cookies(resp.cookies, resp.url) # For Backward compatability with `share_cookie` connectors if self._connector._share_cookies: self._connector.update_cookies(resp.cookies) # redirects if resp.status in (301, 302, 303, 307) and allow_redirects: redirects += 1 history.append(resp) if max_redirects and redirects >= max_redirects: resp.close() break else: # TODO: close the connection if BODY is large enough # Redirect with big BODY is forbidden by HTTP protocol # but malformed server may send illegal response. # Small BODIES with text like "Not Found" are still # perfectly fine and should be accepted. yield from resp.release() # For 301 and 302, mimic IE behaviour, now changed in RFC. # Details: https://github.com/kennethreitz/requests/pull/269 if resp.status != 307: method = hdrs.METH_GET data = None if headers.get(hdrs.CONTENT_LENGTH): headers.pop(hdrs.CONTENT_LENGTH) r_url = (resp.headers.get(hdrs.LOCATION) or resp.headers.get(hdrs.URI)) scheme = urllib.parse.urlsplit(r_url)[0] if scheme not in ('http', 'https', ''): resp.close() raise ValueError('Can redirect only to http or https') elif not scheme: r_url = urllib.parse.urljoin(url, r_url) url = r_url params = None yield from resp.release() continue break resp._history = tuple(history) return resp
# -*- coding: utf-8 -*- # # Copyright (C) 2015-2016 Alexander Shorin # All rights reserved. # # This software is licensed as described in the file LICENSE, which # you should have received as part of this distribution. # from aiohttp.hdrs import * # noqa from multidict import upstr #: Defines CouchDB Proxy Auth username X_AUTH_COUCHDB_USERNAME = upstr('X-Auth-CouchDB-UserName') #: Defines CouchDB Proxy Auth list of roles separated by a comma X_AUTH_COUCHDB_ROLES = upstr('X-Auth-CouchDB-Roles') #: Defines CouchDB Proxy Auth token X_AUTH_COUCHDB_TOKEN = upstr('X-Auth-CouchDB-Token')