def test_get_server_cert__with_sock(self, mock_get_certificate_hash_bytes): raw = HTTPResponse() raw._fp = mock.MagicMock() raw_response = type("RawResponse", (), {"raw": raw}) response = requests_ntlm2.core.get_server_cert(raw_response) assert response is not None mock_get_certificate_hash_bytes.assert_called_once()
def mock_challenge( self, challenge: typing.Optional[AcmeChallenge] = None, status: int = HTTPStatus.OK, content: typing.Optional[typing.Union[io.BytesIO, bytes]] = None, call_count: int = 1, token: typing.Optional[str] = None, ) -> typing.Iterator[requests_mock.mocker.Mocker]: """Mock a request to satisfy an ACME challenge.""" challenge = challenge or self.chall auth = challenge.auth if content is None: content = io.BytesIO(challenge.expected) if token is None: token = challenge.encoded_token.decode("utf-8") url = f"http://{auth.value}/.well-known/acme-challenge/{token}" with requests_mock.Mocker() as req_mock: matcher = req_mock.get(url, raw=HTTPResponse(body=content, status=status, preload_content=False)) yield req_mock self.assertEqual(matcher.call_count, call_count)
def _on_request(self, adapter, request, **kwargs): match = self._find_match(request) # TODO(dcramer): find the correct class for this if match is None: error_msg = 'Connection refused: {0} {1}'.format(request.method, request.url) response = ConnectionError(error_msg) response.request = request self._calls.add(request, response) raise response if 'body' in match and isinstance(match['body'], Exception): self._calls.add(request, match['body']) raise match['body'] headers = {} if match['content_type'] is not None: headers['Content-Type'] = match['content_type'] if 'callback' in match: # use callback status, r_headers, body = match['callback'](request) if isinstance(body, six.text_type): body = body.encode('utf-8') body = BufferIO(body) headers.update(r_headers) elif 'body' in match: if match['adding_headers']: headers.update(match['adding_headers']) status = match['status'] body = BufferIO(match['body']) response = HTTPResponse( status=status, reason=six.moves.http_client.responses[status], body=body, headers=headers, preload_content=False, # Need to not decode_content to mimic requests decode_content=False, ) response = adapter.build_response(request, response) if not match.get('stream'): response.content # NOQA try: resp_cookies = Cookies.from_request(response.headers['set-cookie']) response.cookies = cookiejar_from_dict(dict( (v.name, v.value) for _, v in resp_cookies.items() )) except (KeyError, TypeError): pass self._calls.add(request, response) return response
def _on_request(self, request, **kwargs): match = self._find_match(request) # TODO(dcramer): find the correct class for this if match is None: error_msg = 'Connection refused: {0}'.format(request.url) response = ConnectionError(error_msg) self._calls.add(request, response) raise response headers = { 'Content-Type': match['content_type'], } if match['adding_headers']: headers.update(match['adding_headers']) response = HTTPResponse( status=match['status'], body=BufferIO(match['body']), headers=headers, preload_content=False, ) adapter = HTTPAdapter() response = adapter.build_response(request, response) if not match['stream']: response.content # NOQA self._calls.add(request, response) return response
def get_response(self, request): headers = self.get_headers() result = self.callback(request) if isinstance(result, Exception): raise result status, r_headers, body = result if isinstance(body, Exception): raise body # If the callback set a content-type remove the one # set in add_callback() so that we don't have multiple # content type values. if "Content-Type" in r_headers: headers.pop("Content-Type", None) body = _handle_body(body) headers.extend(r_headers) return HTTPResponse( status=status, reason=six.moves.http_client.responses.get(status), body=body, headers=headers, original_response=OriginalResponseShim(headers), preload_content=False, )
def test_upload_and_push_external_exception(mapp, testapp, reqmock): import requests api = mapp.create_and_use() mapp.upload_file_pypi("pkg1-2.6.tgz", b"123", "pkg1", "2.6") responses = [] def process_request(self, request, kwargs): if not responses: raise requests.urllib3.exceptions.NewConnectionError(None, "") response = responses.pop(0) r = HTTPAdapter().build_response(request, response) return r reqmock.process_request = process_request.__get__(reqmock) # first test should fail during register req = dict(name="pkg1", version="2.6", posturl="http://whatever.com/", username="******", password="******") body = json.dumps(req).encode("utf-8") r = testapp.request(api.index, method="POST", body=body, expect_errors=True) assert r.status_code == 502 assert r.json['type'] == 'actionlog' assert len(r.json['result']) == 1 assert r.json['result'][0][0] == -1 assert r.json['result'][0][1] == 'exception on register:' assert 'NewConnectionError' in r.json['result'][0][2] # second test should fail during release upload responses.append( HTTPResponse( body=BytesIO(b"msg"), status=410, preload_content=False, reason= "Project pre-registration is no longer required or supported, so continue directly to uploading files." )) req = dict(name="pkg1", version="2.6", posturl="http://whatever.com/", username="******", password="******") body = json.dumps(req).encode("utf-8") r = testapp.request(api.index, method="POST", body=body, expect_errors=True) assert r.status_code == 200 assert r.json['type'] == 'actionlog' assert len(r.json['result']) == 2 assert r.json['result'][0][0] == 410 assert r.json['result'][0][1] == 'register' assert r.json['result'][1][0] == -1 assert r.json['result'][1][1] == 'exception on release upload:' assert 'NewConnectionError' in r.json['result'][1][2]
def get_response(self, request: "PreparedRequest") -> HTTPResponse: headers = self.get_headers() result = self.callback(request) if isinstance(result, Exception): raise result status, r_headers, body = result if isinstance(body, Exception): raise body # If the callback set a content-type remove the one # set in add_callback() so that we don't have multiple # content type values. has_content_type = False if isinstance(r_headers, dict) and "Content-Type" in r_headers: has_content_type = True elif isinstance(r_headers, list): has_content_type = any( [h for h in r_headers if h and h[0].lower() == "content-type"] ) if has_content_type: headers.pop("Content-Type", None) body = _handle_body(body) headers.extend(r_headers) return HTTPResponse( status=status, reason=client.responses.get(status, None), body=body, headers=headers, original_response=OriginalResponseShim(headers), preload_content=False, )
def response_setstate(self, state): for name, value in state.items(): if name != 'raw_original_response': setattr(self, name, value) setattr(self, 'raw', HTTPResponse()) self.raw._original_response = state['raw_original_response']
def get_response(self, request: "PreparedRequest") -> HTTPResponse: if self.body and isinstance(self.body, Exception): raise self.body headers = self.get_headers() status = self.status assert not isinstance(self.body, (Response, BaseException)) body = _handle_body(self.body) if ( self.auto_calculate_content_length and isinstance(body, BytesIO) and "Content-Length" not in headers ): content_length = len(body.getvalue()) headers["Content-Length"] = str(content_length) return HTTPResponse( status=status, reason=client.responses.get(status, None), body=body, headers=headers, original_response=OriginalResponseShim(headers), preload_content=False, )
def test_decode_gzip(self, r_g): def compressed_gzip_body(): stream = cStringIO.StringIO() compressor = gzip.GzipFile(fileobj=stream, mode='w') compressor.write(u"é".encode('utf-8') * 100) compressor.close() stream.seek(0) return stream normal_response_object = Mock() # Build an HTTPResponse object like the one requests uses, with # a gzip compressed body. `decode_content` needs to be False to # properly emulate requests behaviour : it's the caller's # responsability to decode, since it's supposed to be a raw stream. body = compressed_gzip_body() normal_response_object.raw = HTTPResponse( status=200, preload_content=False, headers={ 'content-encoding': 'gzip', 'content-type': 'application/blah; charset=utf-8' }, body=body, decode_content=False) normal_response_object.encoding = 'UTF-8' normal_response_object.status_code = 200 r_g.return_value = normal_response_object eq_(appbase.try_get_resource(self.err, None, "http://foo.bar/", ""), u"é" * 100) self.assert_silent()
def test_download_file(self): package = models.Package(name='localshop') package.save() release = models.Release( package=package, version='0.1') release.save() release_file = models.ReleaseFile( release=release, python_version='source', url='http://pypi.python.org/packages/source/l/localshop/' \ 'localshop-0.1.tar.gz' ) release_file.save() with mock.patch('requests.get') as mock_obj: mock_obj.return_value = mock.Mock() mock_obj.return_value.raw = HTTPResponse() mock_obj.return_value.raw._fp = StringIO('test') tasks.download_file(release_file.pk) release_file = models.ReleaseFile.objects.get(pk=release_file.pk) self.assertEqual(release_file.distribution.read(), 'test') self.assertEqual(release_file.distribution.name, 'source/l/localshop/localshop-0.1.tar.gz')
def download(self, method, url, erc, custom_refresh, **kwargs): dirpath = kwargs.pop('dirpath', None) if not (dirpath) or not (os.path.isdir(dirpath)): dirpath = os.getcwd() save_file = kwargs.pop('save_file', False) with self.request(method, url, erc, 0, **kwargs) as resp: if save_file and resp.headers and resp.headers.get( 'Content-Disposition'): try: content = resp.headers.get('Content-Disposition') content_file_list = re.findall('filename=(.*)', content) if len(content_file_list) > 0: content_file_name = content_file_list[0].replace( '"', '') else: content_file_name = 'result_file' file_name = os.path.join(dirpath, content_file_name) with open(file_name, 'wb') as f: logger.debug('Downloading {}'.format(file_name)) for chunk in resp.iter_content(chunk_size=1024): if chunk: f.write(chunk) except Exception as e: raise DownloadFailure(resp, e) logger.debug('Downloaded') # Needed to create a copy of the raw response # if not copied it would not recover data and other properties return HTTPResponse(resp.raw)
def create_response(request, **kwargs): """ :param int status_code: The status code to return upon a successful match. Defaults to 200. :param HTTPResponse raw: A HTTPResponse object to return upon a successful match. :param io.IOBase body: An IO object with a read() method that can return a body on successful match. :param bytes content: A byte string to return upon a successful match. :param unicode text: A text string to return upon a successful match. :param object json: A python object to be converted to a JSON string and returned upon a successful match. :param dict headers: A dictionary object containing headers that are returned upon a successful match. :param CookieJar cookies: A cookie jar with cookies to set on the response. """ connection = kwargs.pop('connection', _FakeConnection()) _check_body_arguments(**kwargs) raw = kwargs.pop('raw', None) body = kwargs.pop('body', None) content = kwargs.pop('content', None) text = kwargs.pop('text', None) json = kwargs.pop('json', None) headers = kwargs.pop('headers', {}) encoding = None if content is not None and not isinstance(content, six.binary_type): raise TypeError('Content should be binary data') if text is not None and not isinstance(text, six.string_types): raise TypeError('Text should be string data') if json is not None: text = jsonutils.dumps(json) if text is not None: encoding = get_encoding_from_headers(headers) or 'utf-8' content = text.encode(encoding) if content is not None: body = _IOReader(content) if not raw: raw = HTTPResponse(status=kwargs.get('status_code', _DEFAULT_STATUS), headers=headers, reason=kwargs.get('reason'), body=body or _IOReader(six.b('')), decode_content=False, preload_content=False, original_response=compat._fake_http_response) response = _http_adapter.build_response(request, raw) response.connection = connection if encoding and not response.encoding: response.encoding = encoding _extract_cookies(request, response, kwargs.get('cookies')) return response
def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): """Stream PreparedRequest object. Returns Response object.""" conn = self.get_connection(request.url, proxies) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) try: if hasattr(conn, 'proxy_pool'): conn = conn.proxy_pool low_conn = conn._get_conn(timeout=timeout) low_conn.putrequest(request.method, url, skip_accept_encoding=True) for header, value in request.headers.items(): low_conn.putheader(header, value) low_conn.endheaders() for i in request.body: low_conn.send(i) r = low_conn.getresponse() resp = HTTPResponse.from_httplib(r, pool=conn, connection=low_conn, preload_content=False, decode_content=False) except socket.error as sockerr: raise ConnectionError(sockerr) except MaxRetryError as e: raise ConnectionError(e) except (_SSLError, _HTTPError) as e: if isinstance(e, _SSLError): raise SSLError(e) elif isinstance(e, TimeoutError): raise Timeout(e) else: raise Timeout('Request timed out.') r = self.build_response(request, resp) if not stream: r.content return r
def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): """Stream PreparedRequest object. Returns Response object.""" conn = self.get_connection(request.url, proxies) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) try: if hasattr(conn, 'proxy_pool'): conn = conn.proxy_pool low_conn = conn._get_conn(timeout=timeout) low_conn.putrequest(request.method, url, skip_accept_encoding=True) for header, value in request.headers.items(): low_conn.putheader(header, value) low_conn.endheaders() for i in request.body: low_conn.send(i) r = low_conn.getresponse() resp = HTTPResponse.from_httplib(r, pool=conn, connection=low_conn, preload_content=False, decode_content=False ) except socket.error as sockerr: raise ConnectionError(sockerr) except MaxRetryError as e: raise ConnectionError(e) except (_SSLError, _HTTPError) as e: if isinstance(e, _SSLError): raise SSLError(e) elif isinstance(e, TimeoutError): raise Timeout(e) else: raise Timeout('Request timed out.') r = self.build_response(request, resp) if not stream: r.content return r
def _on_request(self, session, request, **kwargs): match = self._find_match(request) # TODO(dcramer): find the correct class for this if match is None: error_msg = 'Connection refused: {0}'.format(request.url) response = ConnectionError(error_msg) self._calls.add(request, response) raise response headers = {} if match.get('content_type'): headers['Content-Type'] = match['content_type'] if 'callback' in match: # use callback status, r_headers, body = match['callback'](request) if not isinstance(body, BufferIO): body = BufferIO(body.encode('utf-8')) headers.update(r_headers) elif 'body' in match: if match['adding_headers']: headers.update(match['adding_headers']) status = match['status'] if not isinstance(match['body'], BufferIO): body = BufferIO(match['body']) else: body = match['body'] response = HTTPResponse( status=status, body=body, headers=headers, preload_content=False, ) adapter = session.get_adapter(request.url) response = adapter.build_response(request, response) if not match.get('stream'): response.content # NOQA self._calls.add(request, response) return response
def test_get_cbt_data(self, mock_get_server_cert): cert_bytes = trustme.CA().cert_pem.bytes() mock_get_server_cert.return_value = cert_bytes response = HTTPResponse() cbt_data = requests_ntlm2.core.get_cbt_data(response) mock_get_server_cert.assert_called_once_with(response) assert isinstance( cbt_data, ntlm_auth.gss_channel_bindings.GssChannelBindingsStruct) key = ntlm_auth.gss_channel_bindings.GssChannelBindingsStruct.APPLICATION_DATA assert cbt_data.fields[key] == b"tls-server-end-point:" + cert_bytes assert cbt_data.get_data().startswith( b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x05\x00\x00" b"tls-server-end-point:")
def get_response(self, request): if self.body and isinstance(self.body, Exception): raise self.body headers = self.get_headers() status = self.status body = _handle_body(self.body) return HTTPResponse( status=status, reason=six.moves.http_client.responses.get(status), body=body, headers=headers, preload_content=False, )
def get_response(self, request): headers = self.get_headers() result = self.callback(request) if isinstance(result, Exception): raise result status, r_headers, body = result body = _handle_body(body) headers.update(r_headers) return HTTPResponse( status=status, reason=six.moves.http_client.responses.get(status), body=body, headers=headers, preload_content=False, )
def _send_request_safe_mode(self, method, url, **kwargs): """ Send an HTTP request, and catch any exception that might occur due to connection problems. Safe mode has been removed from requests 1.x. """ try: return requests.Session.request(self, method, url, **kwargs) except (MissingSchema, InvalidSchema, InvalidURL): raise except RequestException as e: r = LocustResponse() r.error = e r.raw = HTTPResponse() # otherwise, tests fail r.status_code = 0 # with this status_code, content returns None r.request = Request(method, url).prepare() return r
def get(self, url, params=None, **kwargs): """Sends a GET request. Args: url(basestring): The URL of the API endpoint. params(dict): The parameters for the HTTP GET request. **kwargs: erc(int): The expected (success) response code for the request. others: Passed on to the requests package. Raises: ApiError: If anything other than the expected response code is returned by the DNA Center API endpoint. """ check_type(url, basestring, may_be_none=False) check_type(params, dict) # Expected response code erc = kwargs.pop('erc', EXPECTED_RESPONSE_CODE['GET']) stream = kwargs.get('stream', None) dirpath = kwargs.pop('dirpath', None) if not (dirpath) or not (os.path.isdir(dirpath)): dirpath = os.getcwd() save_file = kwargs.pop('save_file', False) with self.request('GET', url, erc, 0, params=params, **kwargs) as resp: if stream: if save_file and resp.headers and resp.headers.get('fileName'): try: file_name = os.path.join(dirpath, resp.headers.get('fileName')) with open(file_name, 'wb') as f: logger.debug('Downloading {}'.format(file_name)) for chunk in resp.iter_content(chunk_size=1024): if chunk: f.write(chunk) except Exception as e: raise DownloadFailure(resp, e) logger.debug('Downloaded') # Needed to create a copy of the raw response # if not copied it would not recover data and other properties return HTTPResponse(resp.raw) return extract_and_parse_json(resp) return extract_and_parse_json(resp)
def _send_request_safe_mode(self, method, url, **kwargs): """ Send an HTTP request, and catch any exception that might occur due to connection problems. This is equivalent of python-requests' safe_mode, which due to a bug, does currently *not* work together with Sessions. Once the issue is fixed in python-requests, this method should be removed. See: https://github.com/kennethreitz/requests/issues/888 """ try: return super(HttpSession, self).request(method, url, **kwargs) except (MissingSchema, InvalidSchema, InvalidURL): raise except (RequestException, ConnectionError, HTTPError, socket.timeout, socket.gaierror) as e: r = Response() r.error = e r.raw = HTTPResponse() # otherwise, tests fail r.status_code = 0 # with this status_code, content returns None return r
def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a (`connect timeout, read timeout <user/advanced.html#timeouts>`_) tuple. :type timeout: float or tuple :param verify: (optional) Whether to verify SSL certificates. :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. """ conn = self.get_connection(request.url, proxies, verify, cert) url = self.request_url(request, proxies) self.add_headers(request) chunked = not (request.body is None or 'Content-Length' in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError as e: # this may raise a string formatting error. err = ("Invalid timeout {0}. Pass a (connect, read) " "timeout tuple, or a single float to set " "both timeouts to the same value".format(timeout)) raise ValueError(err) else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: if not chunked: resp = conn.urlopen(method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout) # Send the request. else: if hasattr(conn, 'proxy_pool'): conn = conn.proxy_pool low_conn = conn._get_conn(timeout=timeout) try: low_conn.putrequest(request.method, url, skip_accept_encoding=True) for header, value in request.headers.items(): low_conn.putheader(header, value) low_conn.endheaders() for i in request.body: low_conn.send(hex(len(i))[2:].encode('utf-8')) low_conn.send(b'\r\n') low_conn.send(i) low_conn.send(b'\r\n') low_conn.send(b'0\r\n\r\n') r = low_conn.getresponse() resp = HTTPResponse.from_httplib(r, pool=conn, connection=low_conn, preload_content=False, decode_content=False) except: # If we hit any problems here, clean up the connection. # Then, reraise so that we can handle the actual exception. low_conn.close() raise else: # All is well, return the connection to the pool. conn._put_conn(low_conn) except (ProtocolError, socket.error) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) raise ConnectionError(e, request=request) except _ProxyError as e: raise ProxyError(e) except (_SSLError, _HTTPError) as e: if isinstance(e, _SSLError): raise SSLError(e, request=request) elif isinstance(e, ReadTimeoutError): raise ReadTimeout(e, request=request) else: raise return self.build_response(request, resp)
def test_upload_and_push_warehouse(mapp, testapp, reqmock): # the new PyPI backend "warehouse" changes some things and they already # start to affect current PyPI behaviour api = mapp.create_and_use() mapp.upload_file_pypi("pkg1-2.6.tgz", b"123", "pkg1", "2.6") zipcontent = zip_dict({"index.html": "<html/>"}) mapp.upload_doc("pkg1.zip", zipcontent, "pkg1", "") r = testapp.xget(200, api.simpleindex + "pkg1/") a = getfirstlink(r.text) assert "pkg1-2.6.tgz" in a.get("href") # get root index page r = testapp.xget(200, api.index) responses = [ # the "register" call isn't needed anymore. All the metadata is # sent together with file_upload anyway. So we get a 410 with the # following reason HTTPResponse( body=BytesIO(b"msg"), status=410, preload_content=False, reason= "Project pre-registration is no longer required or supported, so continue directly to uploading files." ), HTTPResponse(body=BytesIO(b"msg"), status=200, preload_content=False), HTTPResponse(body=BytesIO(b"msg"), status=200, preload_content=False) ] requests = [] def process_request(self, request, kwargs): response = responses.pop(0) r = HTTPAdapter().build_response(request, response) requests.append(request) return r reqmock.process_request = process_request.__get__(reqmock) # push OK req = dict(name="pkg1", version="2.6", posturl="http://whatever.com/", username="******", password="******") body = json.dumps(req).encode("utf-8") r = testapp.request(api.index, method="POST", body=body, expect_errors=True) assert r.status_code == 200 assert len(requests) == 3 for i in range(3): assert requests[i].url == req["posturl"] req = requests[1] assert b"metadata_version" in req.body assert b"sha256_digest" in req.body assert b"pkg1-2.6.tgz" in req.body req = requests[2] assert b"metadata_version" in req.body # XXX properly decode www-url-encoded body and check zipcontent assert b"pkg1.zip" in req.body assert zipcontent in req.body
def _resp(adapter, request, *args, **kwargs): headers = {'Content-Length': '0'} response = HTTPResponse(status=504, body='', headers=headers) response = adapter.build_response(request, response) return response
def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a (`connect timeout, read timeout <user/advanced.html#timeouts>`_) tuple. :type timeout: float or tuple :param verify: (optional) Whether to verify SSL certificates. :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. """ conn = self.get_connection(request.url, proxies, verify, cert) url = self.request_url(request, proxies) self.add_headers(request) chunked = not (request.body is None or 'Content-Length' in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError as e: # this may raise a string formatting error. err = ("Invalid timeout {0}. Pass a (connect, read) " "timeout tuple, or a single float to set " "both timeouts to the same value".format(timeout)) raise ValueError(err) else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: if not chunked: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout ) # Send the request. else: if hasattr(conn, 'proxy_pool'): conn = conn.proxy_pool low_conn = conn._get_conn(timeout=timeout) try: low_conn.putrequest(request.method, url, skip_accept_encoding=True) for header, value in request.headers.items(): low_conn.putheader(header, value) low_conn.endheaders() for i in request.body: low_conn.send(hex(len(i))[2:].encode('utf-8')) low_conn.send(b'\r\n') low_conn.send(i) low_conn.send(b'\r\n') low_conn.send(b'0\r\n\r\n') r = low_conn.getresponse() resp = HTTPResponse.from_httplib( r, pool=conn, connection=low_conn, preload_content=False, decode_content=False ) except: # If we hit any problems here, clean up the connection. # Then, reraise so that we can handle the actual exception. low_conn.close() raise else: # All is well, return the connection to the pool. conn._put_conn(low_conn) except (ProtocolError, socket.error) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) raise ConnectionError(e, request=request) except _ProxyError as e: raise ProxyError(e) except (_SSLError, _HTTPError) as e: if isinstance(e, _SSLError): raise SSLError(e, request=request) elif isinstance(e, ReadTimeoutError): raise ReadTimeout(e, request=request) else: raise return self.build_response(request, resp)
def _on_request(self, session, request, **kwargs): match = self._find_match(request) # TODO(dcramer): find the correct class for this if match is None: error_msg = 'Connection refused: {0} {1}'.format( request.method, request.url) response = ConnectionError(error_msg) self._calls.add(request, response) raise response if 'body' in match and isinstance(match['body'], Exception): self._calls.add(request, match['body']) raise match['body'] headers = { 'Content-Type': match['content_type'], } if 'callback' in match: # use callback status, r_headers, body = match['callback'](request) if isinstance(body, six.text_type): body = body.encode('utf-8') body = BufferIO(body) headers.update(r_headers) elif 'body' in match: if match['adding_headers']: headers.update(match['adding_headers']) status = match['status'] body = BufferIO(match['body']) response = HTTPResponse( status=status, body=body, headers=headers, preload_content=False, ) adapter = session.get_adapter(request.url) response = adapter.build_response(request, response) if not match.get('stream'): response.content # NOQA try: resp_cookies = Cookies.from_request(response.headers['set-cookie']) response.cookies = cookiejar_from_dict( dict((v.name, v.value) for _, v in resp_cookies.items())) session.cookies = response.cookies except (KeyError, TypeError): pass self._calls.add(request, response) if kwargs.get('allow_redirects') and response.is_redirect: # include redirect resolving logic from requests.sessions.Session keep_kws = ('stream', 'timeout', 'cert', 'proxies') resolve_kwargs = dict([(k, v) for (k, v) in kwargs.items() if k in keep_kws]) # this recurses if response.is_redirect, # but limited by session.max_redirects gen = session.resolve_redirects(response, request, **resolve_kwargs) history = [resp for resp in gen] # Shuffle things around if there's history. if history: # Insert the first (original) request at the start history.insert(0, response) # Get the last request made response = history.pop() response.history = history return response
def test_get_cbt_data__no_peer_cert(self, mock_get_server_cert): mock_get_server_cert.return_value = None response = HTTPResponse() cbt_data = requests_ntlm2.core.get_cbt_data(response) mock_get_server_cert.assert_called_once_with(response) assert cbt_data is None
def test_get_server_cert(self): raw_response = type("RawResponse", (), {"raw": HTTPResponse()}) response = requests_ntlm2.core.get_server_cert(raw_response) assert response is None