예제 #1
0
def test_response_content_retains_error():
    """Verify that accessing response.content retains an error.

    See https://github.com/kennethreitz/requests/issues/4965
    """

    data = "Some random stuff to read from remove server.\n"

    def response_handler(sock):
        req = consume_socket_content(sock, timeout=0.5)

        # Send invalid chunked data (length mismatch)
        sock.send(b'HTTP/1.1 200 OK\r\n'
                  b'Transfer-Encoding: chunked\r\n'
                  b'\r\n2\r\n42\r\n8\r\n123\r\n'  # 5 bytes missing
                  )

    close_server = threading.Event()
    server = Server(response_handler, wait_to_close_event=close_server)

    with server as (host, port):
        url = 'http://{}:{}/path'.format(host, port)
        r = requests.post(url, stream=True)
        with pytest.raises(ChunkedEncodingError):
            r.content

    # Access the bad response data again, I would expect the same
    # error again.

    try:
        content = r.content
    except ChunkedEncodingError:
        pass  # fine, same exception
    else:
        assert False, "error response has content: {0!r}".format(content)
    close_server.set()
예제 #2
0
def test_digestauth_only_on_4xx():
    """Ensure we only send digestauth on 4xx challenges.

    See https://github.com/psf/requests/issues/3772.
    """
    text_200_chal = (
        b'HTTP/1.1 200 OK\r\n'
        b'Content-Length: 0\r\n'
        b'WWW-Authenticate: Digest nonce="6bf5d6e4da1ce66918800195d6b9130d"'
        b', opaque="372825293d1c26955496c80ed6426e9e", '
        b'realm="*****@*****.**", qop=auth\r\n\r\n')

    auth = requests.auth.HTTPDigestAuth('user', 'pass')

    def digest_response_handler(sock):
        # Respond to GET with a 200 containing www-authenticate header.
        request_content = consume_socket_content(sock, timeout=0.5)
        assert request_content.startswith(b"GET / HTTP/1.1")
        sock.send(text_200_chal)

        # Verify the client didn't respond with auth.
        request_content = consume_socket_content(sock, timeout=0.5)
        assert request_content == b''

        return request_content

    close_server = threading.Event()
    server = Server(digest_response_handler, wait_to_close_event=close_server)

    with server as (host, port):
        url = 'http://{}:{}/'.format(host, port)
        r = requests.get(url, auth=auth)
        # Verify server didn't receive auth from us.
        assert r.status_code == 200
        assert len(r.history) == 0
        close_server.set()
예제 #3
0
def test_redirect_rfc1808_to_non_ascii_location():
    path = u'š'
    expected_path = quote(path.encode('utf8')).encode('ascii')
    expected_path_py3 = b'%C3%85%C2%A1'
    redirect_request = []  # stores the second request to the server

    def redirect_resp_handler(sock):
        consume_socket_content(sock, timeout=0.5)
        location = u'//{0}:{1}/{2}'.format(host, port, path)
        sock.send(b'HTTP/1.1 301 Moved Permanently\r\n'
                  b'Content-Length: 0\r\n'
                  b'Location: ' + location.encode('utf8') + b'\r\n'
                  b'\r\n')
        redirect_request.append(consume_socket_content(sock, timeout=0.5))
        sock.send(b'HTTP/1.1 200 OK\r\n\r\n')

    close_server = threading.Event()
    server = Server(redirect_resp_handler, wait_to_close_event=close_server)

    with server as (host, port):
        url = u'http://{0}:{1}'.format(host, port)
        r = requests.get(url=url, allow_redirects=True)
        assert r.status_code == 200
        assert len(r.history) == 1
        assert r.history[0].status_code == 301

        # currently Python3 not handling non-ASCII redirects (issue #3888)
        if is_py3:
            assert redirect_request[0].startswith(b'GET /' +
                                                  expected_path_py3 +
                                                  b' HTTP/1.1')
        else:
            assert redirect_request[0].startswith(b'GET /' + expected_path +
                                                  b' HTTP/1.1')

        close_server.set()
예제 #4
0
def test_digestauth_401_count_reset_on_redirect():
    """Ensure we correctly reset num_401_calls after a successful digest auth,
    followed by a 302 redirect to another digest auth prompt.

    See https://github.com/kennethreitz/requests/issues/1979.
    """
    text_401 = (
        b'HTTP/1.1 401 UNAUTHORIZED\r\n'
        b'Content-Length: 0\r\n'
        b'WWW-Authenticate: Digest nonce="6bf5d6e4da1ce66918800195d6b9130d"'
        b', opaque="372825293d1c26955496c80ed6426e9e", '
        b'realm="*****@*****.**", qop=auth\r\n\r\n')

    text_302 = (b'HTTP/1.1 302 FOUND\r\n'
                b'Content-Length: 0\r\n'
                b'Location: /\r\n\r\n')

    text_200 = (b'HTTP/1.1 200 OK\r\n' b'Content-Length: 0\r\n\r\n')

    expected_digest = (b'Authorization: Digest username="******", '
                       b'realm="*****@*****.**", '
                       b'nonce="6bf5d6e4da1ce66918800195d6b9130d", uri="/"')

    auth = requests.auth.HTTPDigestAuth('user', 'pass')

    def digest_response_handler(sock):
        # Respond to initial GET with a challenge.
        request_content = consume_socket_content(sock, timeout=0.5)
        assert request_content.startswith(b"GET / HTTP/1.1")
        sock.send(text_401)

        # Verify we receive an Authorization header in response, then redirect.
        request_content = consume_socket_content(sock, timeout=0.5)
        assert expected_digest in request_content
        sock.send(text_302)

        # Verify Authorization isn't sent to the redirected host,
        # then send another challenge.
        request_content = consume_socket_content(sock, timeout=0.5)
        assert b'Authorization:' not in request_content
        sock.send(text_401)

        # Verify Authorization is sent correctly again, and return 200 OK.
        request_content = consume_socket_content(sock, timeout=0.5)
        assert expected_digest in request_content
        sock.send(text_200)

        return request_content

    close_server = threading.Event()
    server = Server(digest_response_handler, wait_to_close_event=close_server)

    with server as (host, port):
        url = 'http://{0}:{1}/'.format(host, port)
        r = requests.get(url, auth=auth)
        # Verify server succeeded in authenticating.
        assert r.status_code == 200
        # Verify Authorization was sent in final request.
        assert 'Authorization' in r.request.headers
        assert r.request.headers['Authorization'].startswith('Digest ')
        # Verify redirect happened as we expected.
        assert r.history[0].status_code == 302
        close_server.set()