aboutsummaryrefslogtreecommitdiffstats
path: root/test/netlib/http
diff options
context:
space:
mode:
Diffstat (limited to 'test/netlib/http')
-rw-r--r--test/netlib/http/http1/test_assemble.py10
-rw-r--r--test/netlib/http/http1/test_read.py18
-rw-r--r--test/netlib/http/http2/test_connections.py37
-rw-r--r--test/netlib/http/test_authentication.py2
-rw-r--r--test/netlib/http/test_cookies.py2
-rw-r--r--test/netlib/http/test_headers.py11
-rw-r--r--test/netlib/http/test_message.py4
-rw-r--r--test/netlib/http/test_multipart.py24
-rw-r--r--test/netlib/http/test_request.py2
-rw-r--r--test/netlib/http/test_response.py9
-rw-r--r--test/netlib/http/test_url.py66
11 files changed, 150 insertions, 35 deletions
diff --git a/test/netlib/http/http1/test_assemble.py b/test/netlib/http/http1/test_assemble.py
index 8dcbae8e..50d29384 100644
--- a/test/netlib/http/http1/test_assemble.py
+++ b/test/netlib/http/http1/test_assemble.py
@@ -10,11 +10,11 @@ from netlib.tutils import treq, raises, tresp
def test_assemble_request():
- c = assemble_request(treq()) == (
+ assert assemble_request(treq()) == (
b"GET /path HTTP/1.1\r\n"
b"header: qvalue\r\n"
- b"Host: address:22\r\n"
- b"Content-Length: 7\r\n"
+ b"content-length: 7\r\n"
+ b"host: address:22\r\n"
b"\r\n"
b"content"
)
@@ -32,10 +32,10 @@ def test_assemble_request_head():
def test_assemble_response():
- c = assemble_response(tresp()) == (
+ assert assemble_response(tresp()) == (
b"HTTP/1.1 200 OK\r\n"
b"header-response: svalue\r\n"
- b"Content-Length: 7\r\n"
+ b"content-length: 7\r\n"
b"\r\n"
b"message"
)
diff --git a/test/netlib/http/http1/test_read.py b/test/netlib/http/http1/test_read.py
index d8106904..5285ac1d 100644
--- a/test/netlib/http/http1/test_read.py
+++ b/test/netlib/http/http1/test_read.py
@@ -1,6 +1,5 @@
from __future__ import absolute_import, print_function, division
from io import BytesIO
-import textwrap
from mock import Mock
from netlib.exceptions import HttpException, HttpSyntaxException, HttpReadDisconnect, TcpDisconnect
from netlib.http import Headers
@@ -8,11 +7,22 @@ from netlib.http.http1.read import (
read_request, read_response, read_request_head,
read_response_head, read_body, connection_close, expected_http_body_size, _get_first_line,
_read_request_line, _parse_authority_form, _read_response_line, _check_http_version,
- _read_headers, _read_chunked
+ _read_headers, _read_chunked, get_header_tokens
)
from netlib.tutils import treq, tresp, raises
+def test_get_header_tokens():
+ headers = Headers()
+ assert get_header_tokens(headers, "foo") == []
+ headers["foo"] = "bar"
+ assert get_header_tokens(headers, "foo") == ["bar"]
+ headers["foo"] = "bar, voing"
+ assert get_header_tokens(headers, "foo") == ["bar", "voing"]
+ headers.set_all("foo", ["bar, voing", "oink"])
+ assert get_header_tokens(headers, "foo") == ["bar", "voing", "oink"]
+
+
def test_read_request():
rfile = BytesIO(b"GET / HTTP/1.1\r\n\r\nskip")
r = read_request(rfile)
@@ -106,6 +116,7 @@ class TestReadBody(object):
rfile = BytesIO(b"123456")
assert list(read_body(rfile, -1, max_chunk_size=1)) == [b"1", b"2", b"3", b"4", b"5", b"6"]
+
def test_connection_close():
headers = Headers()
assert connection_close(b"HTTP/1.0", headers)
@@ -121,6 +132,7 @@ def test_connection_close():
assert connection_close(b"HTTP/1.0", headers)
assert not connection_close(b"HTTP/1.1", headers)
+
def test_expected_http_body_size():
# Expect: 100-continue
assert expected_http_body_size(
@@ -203,6 +215,7 @@ def test_read_request_line():
with raises(HttpReadDisconnect):
t(b"")
+
def test_parse_authority_form():
assert _parse_authority_form(b"foo:42") == (b"foo", 42)
with raises(HttpSyntaxException):
@@ -302,6 +315,7 @@ class TestReadHeaders(object):
headers = self._read(data)
assert headers.fields == ((b"bar", b""),)
+
def test_read_chunked():
req = treq(content=None)
req.headers["Transfer-Encoding"] = "chunked"
diff --git a/test/netlib/http/http2/test_connections.py b/test/netlib/http/http2/test_connections.py
index 7d240c0e..27cc30ba 100644
--- a/test/netlib/http/http2/test_connections.py
+++ b/test/netlib/http/http2/test_connections.py
@@ -1,16 +1,16 @@
-import OpenSSL
import mock
import codecs
-from hyperframe.frame import *
-
-from netlib import tcp, http, utils
+import hyperframe
+from netlib import tcp, http
from netlib.tutils import raises
from netlib.exceptions import TcpDisconnect
from netlib.http.http2.connections import HTTP2Protocol, TCPHandler
+from netlib.http.http2 import framereader
from ... import tservers
+
class TestTCPHandlerWrapper:
def test_wrapped(self):
h = TCPHandler(rfile='foo', wfile='bar')
@@ -111,11 +111,11 @@ class TestPerformServerConnectionPreface(tservers.ServerTestBase):
self.wfile.flush()
# check empty settings frame
- raw = utils.http2_read_raw_frame(self.rfile)
+ raw = framereader.http2_read_raw_frame(self.rfile)
assert raw == codecs.decode('00000c040000000000000200000000000300000001', 'hex_codec')
# check settings acknowledgement
- raw = utils.http2_read_raw_frame(self.rfile)
+ raw = framereader.http2_read_raw_frame(self.rfile)
assert raw == codecs.decode('000000040100000000', 'hex_codec')
# send settings acknowledgement
@@ -214,19 +214,19 @@ class TestApplySettings(tservers.ServerTestBase):
protocol = HTTP2Protocol(c)
protocol._apply_settings({
- SettingsFrame.ENABLE_PUSH: 'foo',
- SettingsFrame.MAX_CONCURRENT_STREAMS: 'bar',
- SettingsFrame.INITIAL_WINDOW_SIZE: 'deadbeef',
+ hyperframe.frame.SettingsFrame.ENABLE_PUSH: 'foo',
+ hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 'bar',
+ hyperframe.frame.SettingsFrame.INITIAL_WINDOW_SIZE: 'deadbeef',
})
assert c.rfile.safe_read(2) == b"OK"
assert protocol.http2_settings[
- SettingsFrame.ENABLE_PUSH] == 'foo'
+ hyperframe.frame.SettingsFrame.ENABLE_PUSH] == 'foo'
assert protocol.http2_settings[
- SettingsFrame.MAX_CONCURRENT_STREAMS] == 'bar'
+ hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS] == 'bar'
assert protocol.http2_settings[
- SettingsFrame.INITIAL_WINDOW_SIZE] == 'deadbeef'
+ hyperframe.frame.SettingsFrame.INITIAL_WINDOW_SIZE] == 'deadbeef'
class TestCreateHeaders(object):
@@ -258,7 +258,7 @@ class TestCreateHeaders(object):
(b'server', b'version')])
protocol = HTTP2Protocol(self.c)
- protocol.http2_settings[SettingsFrame.MAX_FRAME_SIZE] = 8
+ protocol.http2_settings[hyperframe.frame.SettingsFrame.MAX_FRAME_SIZE] = 8
bytes = protocol._create_headers(headers, 1, end_stream=True)
assert len(bytes) == 3
assert bytes[0] == codecs.decode('000008010100000001828487408294e783', 'hex_codec')
@@ -281,7 +281,7 @@ class TestCreateBody(object):
def test_create_body_multiple_frames(self):
protocol = HTTP2Protocol(self.c)
- protocol.http2_settings[SettingsFrame.MAX_FRAME_SIZE] = 5
+ protocol.http2_settings[hyperframe.frame.SettingsFrame.MAX_FRAME_SIZE] = 5
bytes = protocol._create_body(b'foobarmehm42', 1)
assert len(bytes) == 3
assert bytes[0] == codecs.decode('000005000000000001666f6f6261', 'hex_codec')
@@ -312,7 +312,10 @@ class TestReadRequest(tservers.ServerTestBase):
req = protocol.read_request(NotImplemented)
assert req.stream_id
- assert req.headers.fields == ((b':method', b'GET'), (b':path', b'/'), (b':scheme', b'https'))
+ assert req.headers.fields == ()
+ assert req.method == "GET"
+ assert req.path == "/"
+ assert req.scheme == "https"
assert req.content == b'foobar'
@@ -461,7 +464,7 @@ class TestAssembleRequest(object):
b'',
b'/',
b"HTTP/2.0",
- None,
+ (),
None,
))
assert len(bytes) == 1
@@ -476,7 +479,7 @@ class TestAssembleRequest(object):
b'',
b'/',
b"HTTP/2.0",
- None,
+ (),
None,
)
req.stream_id = 0x42
diff --git a/test/netlib/http/test_authentication.py b/test/netlib/http/test_authentication.py
index 1df7cd9c..95d72447 100644
--- a/test/netlib/http/test_authentication.py
+++ b/test/netlib/http/test_authentication.py
@@ -78,7 +78,7 @@ class TestBasicProxyAuth:
assert ba.authenticate(headers)
ba.clean(headers)
- assert not ba.AUTH_HEADER in headers
+ assert ba.AUTH_HEADER not in headers
headers[ba.AUTH_HEADER] = ""
assert not ba.authenticate(headers)
diff --git a/test/netlib/http/test_cookies.py b/test/netlib/http/test_cookies.py
index 6f84c4ce..83b85656 100644
--- a/test/netlib/http/test_cookies.py
+++ b/test/netlib/http/test_cookies.py
@@ -184,7 +184,7 @@ def test_parse_set_cookie_pairs():
assert ret == lst
s2 = cookies._format_set_cookie_pairs(ret)
ret2 = cookies._parse_set_cookie_pairs(s2)
- assert ret2 == lst
+ assert ret2 == lst
def test_parse_set_cookie_header():
diff --git a/test/netlib/http/test_headers.py b/test/netlib/http/test_headers.py
index cd2ca9d1..51819b86 100644
--- a/test/netlib/http/test_headers.py
+++ b/test/netlib/http/test_headers.py
@@ -1,4 +1,4 @@
-from netlib.http import Headers
+from netlib.http import Headers, parse_content_type
from netlib.tutils import raises
@@ -72,3 +72,12 @@ class TestHeaders(object):
replacements = headers.replace(r"Host: ", "X-Host ")
assert replacements == 0
assert headers["Host"] == "example.com"
+
+
+def test_parse_content_type():
+ p = parse_content_type
+ assert p("text/html") == ("text", "html", {})
+ assert p("text") is None
+
+ v = p("text/html; charset=UTF-8")
+ assert v == ('text', 'html', {'charset': 'UTF-8'})
diff --git a/test/netlib/http/test_message.py b/test/netlib/http/test_message.py
index 64592921..f5bf7f0c 100644
--- a/test/netlib/http/test_message.py
+++ b/test/netlib/http/test_message.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
-from netlib.http import decoded, Headers
-from netlib.tutils import tresp, raises
+from netlib.http import decoded
+from netlib.tutils import tresp
def _test_passthrough_attr(message, attr):
diff --git a/test/netlib/http/test_multipart.py b/test/netlib/http/test_multipart.py
new file mode 100644
index 00000000..1d7e0062
--- /dev/null
+++ b/test/netlib/http/test_multipart.py
@@ -0,0 +1,24 @@
+from netlib.http import Headers
+from netlib.http import multipart
+
+
+def test_decode():
+ boundary = 'somefancyboundary'
+ headers = Headers(
+ content_type='multipart/form-data; boundary=' + boundary
+ )
+ content = (
+ "--{0}\n"
+ "Content-Disposition: form-data; name=\"field1\"\n\n"
+ "value1\n"
+ "--{0}\n"
+ "Content-Disposition: form-data; name=\"field2\"\n\n"
+ "value2\n"
+ "--{0}--".format(boundary).encode()
+ )
+
+ form = multipart.decode(headers, content)
+
+ assert len(form) == 2
+ assert form[0] == (b"field1", b"value1")
+ assert form[1] == (b"field2", b"value2")
diff --git a/test/netlib/http/test_request.py b/test/netlib/http/test_request.py
index fae7aefe..c03db339 100644
--- a/test/netlib/http/test_request.py
+++ b/test/netlib/http/test_request.py
@@ -13,7 +13,7 @@ class TestRequestData(object):
with raises(ValueError):
treq(headers="foobar")
- assert isinstance(treq(headers=None).headers, Headers)
+ assert isinstance(treq(headers=()).headers, Headers)
class TestRequestCore(object):
diff --git a/test/netlib/http/test_response.py b/test/netlib/http/test_response.py
index cfd093d4..b3c2f736 100644
--- a/test/netlib/http/test_response.py
+++ b/test/netlib/http/test_response.py
@@ -2,12 +2,10 @@ from __future__ import absolute_import, print_function, division
import email
-import six
import time
from netlib.http import Headers
from netlib.http.cookies import CookieAttrs
-from netlib.odict import ODict, ODictCaseless
from netlib.tutils import raises, tresp
from .test_message import _test_passthrough_attr, _test_decoded_attr
@@ -17,7 +15,7 @@ class TestResponseData(object):
with raises(ValueError):
tresp(headers="foobar")
- assert isinstance(tresp(headers=None).headers, Headers)
+ assert isinstance(tresp(headers=()).headers, Headers)
class TestResponseCore(object):
@@ -26,7 +24,7 @@ class TestResponseCore(object):
"""
def test_repr(self):
response = tresp()
- assert repr(response) == "Response(200 OK, unknown content type, 7B)"
+ assert repr(response) == "Response(200 OK, unknown content type, 7b)"
response.content = None
assert repr(response) == "Response(200 OK, no content)"
@@ -61,7 +59,8 @@ class TestResponseUtils(object):
def test_get_cookies_with_parameters(self):
resp = tresp()
- resp.headers = Headers(set_cookie="cookiename=cookievalue;domain=example.com;expires=Wed Oct 21 16:29:41 2015;path=/; HttpOnly")
+ cookie = "cookiename=cookievalue;domain=example.com;expires=Wed Oct 21 16:29:41 2015;path=/; HttpOnly"
+ resp.headers = Headers(set_cookie=cookie)
result = resp.cookies
assert len(result) == 1
assert "cookiename" in result
diff --git a/test/netlib/http/test_url.py b/test/netlib/http/test_url.py
new file mode 100644
index 00000000..26b37230
--- /dev/null
+++ b/test/netlib/http/test_url.py
@@ -0,0 +1,66 @@
+from netlib import tutils
+from netlib.http import url
+
+
+def test_parse():
+ with tutils.raises(ValueError):
+ url.parse("")
+
+ s, h, po, pa = url.parse(b"http://foo.com:8888/test")
+ assert s == b"http"
+ assert h == b"foo.com"
+ assert po == 8888
+ assert pa == b"/test"
+
+ s, h, po, pa = url.parse("http://foo/bar")
+ assert s == b"http"
+ assert h == b"foo"
+ assert po == 80
+ assert pa == b"/bar"
+
+ s, h, po, pa = url.parse(b"http://user:pass@foo/bar")
+ assert s == b"http"
+ assert h == b"foo"
+ assert po == 80
+ assert pa == b"/bar"
+
+ s, h, po, pa = url.parse(b"http://foo")
+ assert pa == b"/"
+
+ s, h, po, pa = url.parse(b"https://foo")
+ assert po == 443
+
+ with tutils.raises(ValueError):
+ url.parse(b"https://foo:bar")
+
+ # Invalid IDNA
+ with tutils.raises(ValueError):
+ url.parse("http://\xfafoo")
+ # Invalid PATH
+ with tutils.raises(ValueError):
+ url.parse("http:/\xc6/localhost:56121")
+ # Null byte in host
+ with tutils.raises(ValueError):
+ url.parse("http://foo\0")
+ # Port out of range
+ _, _, port, _ = url.parse("http://foo:999999")
+ assert port == 80
+ # Invalid IPv6 URL - see http://www.ietf.org/rfc/rfc2732.txt
+ with tutils.raises(ValueError):
+ url.parse('http://lo[calhost')
+
+
+def test_unparse():
+ assert url.unparse("http", "foo.com", 99, "") == "http://foo.com:99"
+ assert url.unparse("http", "foo.com", 80, "/bar") == "http://foo.com/bar"
+ assert url.unparse("https", "foo.com", 80, "") == "https://foo.com:80"
+ assert url.unparse("https", "foo.com", 443, "") == "https://foo.com"
+
+
+def test_urlencode():
+ assert url.encode([('foo', 'bar')])
+
+
+def test_urldecode():
+ s = "one=two&three=four"
+ assert len(url.decode(s)) == 2