Ejemplo n.º 1
0
 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()
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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,
        )
Ejemplo n.º 6
0
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]
Ejemplo n.º 7
0
    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,
        )
Ejemplo n.º 8
0
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']
Ejemplo n.º 9
0
    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()
Ejemplo n.º 11
0
    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')
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
    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
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
0
    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:")
Ejemplo n.º 18
0
    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, )
Ejemplo n.º 19
0
    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, )
Ejemplo n.º 20
0
 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
Ejemplo n.º 21
0
    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)
Ejemplo n.º 22
0
 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
Ejemplo n.º 23
0
    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)
Ejemplo n.º 24
0
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
Ejemplo n.º 25
0
 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
Ejemplo n.º 26
0
    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)
Ejemplo n.º 27
0
    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
Ejemplo n.º 28
0
 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
Ejemplo n.º 29
0
 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