aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/mitmproxy/test_examples.py9
-rw-r--r--test/mitmproxy/test_flow.py43
-rw-r--r--test/mitmproxy/test_flow_export.py351
-rw-r--r--test/mitmproxy/test_flow_export/locust_get.py29
-rw-r--r--test/mitmproxy/test_flow_export/locust_patch.py37
-rw-r--r--test/mitmproxy/test_flow_export/locust_post.py26
-rw-r--r--test/mitmproxy/test_flow_export/locust_task_get.py14
-rw-r--r--test/mitmproxy/test_flow_export/locust_task_patch.py22
-rw-r--r--test/mitmproxy/test_flow_export/locust_task_post.py11
-rw-r--r--test/mitmproxy/test_flow_export/python_get.py16
-rw-r--r--test/mitmproxy/test_flow_export/python_patch.py24
-rw-r--r--test/mitmproxy/test_flow_export/python_post.py13
-rw-r--r--test/mitmproxy/test_flow_export/python_post_json.py21
-rw-r--r--test/mitmproxy/test_protocol_http2.py73
-rw-r--r--test/mitmproxy/test_server.py6
-rw-r--r--test/mitmproxy/tutils.py3
-rw-r--r--test/netlib/http/test_cookies.py13
-rw-r--r--test/netlib/http/test_request.py14
-rw-r--r--test/netlib/http/test_response.py2
-rw-r--r--test/netlib/test_odict.py10
-rw-r--r--test/netlib/test_utils.py15
-rw-r--r--test/pathod/test_language_websocket.py2
-rw-r--r--test/pathod/test_pathoc.py2
-rw-r--r--test/pathod/test_pathod.py7
-rw-r--r--test/pathod/tutils.py2
25 files changed, 420 insertions, 345 deletions
diff --git a/test/mitmproxy/test_examples.py b/test/mitmproxy/test_examples.py
index b560d9a1..0c117306 100644
--- a/test/mitmproxy/test_examples.py
+++ b/test/mitmproxy/test_examples.py
@@ -5,11 +5,12 @@ from contextlib import contextmanager
from mitmproxy import utils, script
from mitmproxy.proxy import config
+import netlib.utils
from netlib import tutils as netutils
from netlib.http import Headers
from . import tservers, tutils
-example_dir = utils.Data(__name__).path("../../examples")
+example_dir = netlib.utils.Data(__name__).path("../../examples")
class DummyContext(object):
@@ -106,8 +107,8 @@ def test_modify_querystring():
def test_modify_response_body():
with tutils.raises(script.ScriptException):
- with example("modify_response_body.py") as ex:
- pass
+ with example("modify_response_body.py"):
+ assert True
flow = tutils.tflow(resp=netutils.tresp(content="I <3 mitmproxy"))
with example("modify_response_body.py mitmproxy rocks") as ex:
@@ -125,7 +126,7 @@ def test_redirect_requests():
def test_har_extractor():
with tutils.raises(script.ScriptException):
- with example("har_extractor.py") as ex:
+ with example("har_extractor.py"):
pass
times = dict(
diff --git a/test/mitmproxy/test_flow.py b/test/mitmproxy/test_flow.py
index 145e91cf..b9c6a2f6 100644
--- a/test/mitmproxy/test_flow.py
+++ b/test/mitmproxy/test_flow.py
@@ -7,7 +7,7 @@ import netlib.utils
from netlib import odict
from netlib.http import Headers
from mitmproxy import filt, controller, tnetstring, flow
-from mitmproxy.exceptions import FlowReadException
+from mitmproxy.exceptions import FlowReadException, ScriptException
from mitmproxy.models import Error
from mitmproxy.models import Flow
from mitmproxy.models import HTTPFlow
@@ -76,6 +76,21 @@ class TestStickyCookieState:
googlekey = s.jar.keys()[0]
assert len(s.jar[googlekey].keys()) == 2
+ # Test setting of weird cookie keys
+ s = flow.StickyCookieState(filt.parse(".*"))
+ f = tutils.tflow(req=netlib.tutils.treq(host="www.google.com", port=80), resp=True)
+ cs = [
+ "foo/bar=hello",
+ "foo:bar=world",
+ "foo@bar=fizz",
+ "foo,bar=buzz",
+ ]
+ for c in cs:
+ f.response.headers["Set-Cookie"] = c
+ s.handle_response(f)
+ googlekey = s.jar.keys()[0]
+ assert len(s.jar[googlekey].keys()) == len(cs)
+
# Test overwriting of a cookie value
c1 = "somecookie=helloworld; Path=/"
c2 = "somecookie=newvalue; Path=/"
@@ -84,7 +99,7 @@ class TestStickyCookieState:
s.handle_response(f)
googlekey = s.jar.keys()[0]
assert len(s.jar[googlekey].keys()) == 1
- assert s.jar[googlekey]["somecookie"].value == "newvalue"
+ assert s.jar[googlekey]["somecookie"].items()[0][1] == "newvalue"
def test_handle_request(self):
s, f = self._response("SSID=mooo", "www.google.com")
@@ -747,12 +762,16 @@ class TestFlowMaster:
def test_load_script(self):
s = flow.State()
fm = flow.FlowMaster(None, s)
- assert not fm.load_script(tutils.test_data.path("scripts/a.py"))
- assert not fm.load_script(tutils.test_data.path("scripts/a.py"))
- assert not fm.unload_scripts()
- assert fm.load_script("nonexistent")
- assert "ValueError" in fm.load_script(
- tutils.test_data.path("scripts/starterr.py"))
+
+ fm.load_script(tutils.test_data.path("scripts/a.py"))
+ fm.load_script(tutils.test_data.path("scripts/a.py"))
+ fm.unload_scripts()
+ with tutils.raises(ScriptException):
+ fm.load_script("nonexistent")
+ try:
+ fm.load_script(tutils.test_data.path("scripts/starterr.py"))
+ except ScriptException as e:
+ assert "ValueError" in str(e)
assert len(fm.scripts) == 0
def test_getset_ignore(self):
@@ -779,7 +798,7 @@ class TestFlowMaster:
def test_script_reqerr(self):
s = flow.State()
fm = flow.FlowMaster(None, s)
- assert not fm.load_script(tutils.test_data.path("scripts/reqerr.py"))
+ fm.load_script(tutils.test_data.path("scripts/reqerr.py"))
f = tutils.tflow()
fm.handle_clientconnect(f.client_conn)
assert fm.handle_request(f)
@@ -787,7 +806,7 @@ class TestFlowMaster:
def test_script(self):
s = flow.State()
fm = flow.FlowMaster(None, s)
- assert not fm.load_script(tutils.test_data.path("scripts/all.py"))
+ fm.load_script(tutils.test_data.path("scripts/all.py"))
f = tutils.tflow(resp=True)
fm.handle_clientconnect(f.client_conn)
@@ -799,7 +818,7 @@ class TestFlowMaster:
fm.handle_response(f)
assert fm.scripts[0].ns["log"][-1] == "response"
# load second script
- assert not fm.load_script(tutils.test_data.path("scripts/all.py"))
+ fm.load_script(tutils.test_data.path("scripts/all.py"))
assert len(fm.scripts) == 2
fm.handle_clientdisconnect(f.server_conn)
assert fm.scripts[0].ns["log"][-1] == "clientdisconnect"
@@ -808,7 +827,7 @@ class TestFlowMaster:
# unload first script
fm.unload_scripts()
assert len(fm.scripts) == 0
- assert not fm.load_script(tutils.test_data.path("scripts/all.py"))
+ fm.load_script(tutils.test_data.path("scripts/all.py"))
f.error = tutils.terr()
fm.handle_error(f)
diff --git a/test/mitmproxy/test_flow_export.py b/test/mitmproxy/test_flow_export.py
index 75a8090f..035f07b7 100644
--- a/test/mitmproxy/test_flow_export.py
+++ b/test/mitmproxy/test_flow_export.py
@@ -1,152 +1,74 @@
import json
from textwrap import dedent
+import re
import netlib.tutils
from netlib.http import Headers
from mitmproxy import flow_export
from . import tutils
-req_get = netlib.tutils.treq(
- method='GET',
- content='',
-)
-req_post = netlib.tutils.treq(
- method='POST',
- headers=None,
-)
+def clean_blanks(s):
+ return re.sub(r"^(\s+)$", "", s, flags=re.MULTILINE)
-req_patch = netlib.tutils.treq(
- method='PATCH',
- path=b"/path?query=param",
-)
+def python_equals(testdata, text):
+ """
+ Compare two bits of Python code, disregarding non-significant differences
+ like whitespace on blank lines and trailing space.
+ """
+ d = open(tutils.test_data.path(testdata)).read()
+ assert clean_blanks(text).rstrip() == clean_blanks(d).rstrip()
+
+
+req_get = lambda: netlib.tutils.treq(method='GET', content='')
+
+req_post = lambda: netlib.tutils.treq(method='POST', headers=None)
+
+req_patch = lambda: netlib.tutils.treq(method='PATCH', path=b"/path?query=param")
-class TestExportCurlCommand():
+class TestExportCurlCommand():
def test_get(self):
- flow = tutils.tflow(req=req_get)
+ flow = tutils.tflow(req=req_get())
result = """curl -H 'header:qvalue' -H 'content-length:7' 'http://address/path'"""
assert flow_export.curl_command(flow) == result
def test_post(self):
- flow = tutils.tflow(req=req_post)
+ flow = tutils.tflow(req=req_post())
result = """curl -X POST 'http://address/path' --data-binary 'content'"""
assert flow_export.curl_command(flow) == result
def test_patch(self):
- flow = tutils.tflow(req=req_patch)
+ flow = tutils.tflow(req=req_patch())
result = """curl -H 'header:qvalue' -H 'content-length:7' -X PATCH 'http://address/path?query=param' --data-binary 'content'"""
assert flow_export.curl_command(flow) == result
class TestExportPythonCode():
-
def test_get(self):
- flow = tutils.tflow(req=req_get)
- result = dedent("""
- import requests
-
- url = 'http://address/path'
-
- headers = {
- 'header': 'qvalue',
- 'content-length': '7',
- }
-
- response = requests.request(
- method='GET',
- url=url,
- headers=headers,
- )
-
- print(response.text)
- """).strip()
- assert flow_export.python_code(flow) == result
+ flow = tutils.tflow(req=req_get())
+ python_equals("test_flow_export/python_get.py", flow_export.python_code(flow))
def test_post(self):
- flow = tutils.tflow(req=req_post)
- result = dedent("""
- import requests
-
- url = 'http://address/path'
-
- data = '''content'''
-
- response = requests.request(
- method='POST',
- url=url,
- data=data,
- )
-
- print(response.text)
- """).strip()
- assert flow_export.python_code(flow) == result
+ flow = tutils.tflow(req=req_post())
+ python_equals("test_flow_export/python_post.py", flow_export.python_code(flow))
def test_post_json(self):
- req_post.content = '{"name": "example", "email": "example@example.com"}'
- req_post.headers = Headers(content_type="application/json")
- flow = tutils.tflow(req=req_post)
- result = dedent("""
- import requests
-
- url = 'http://address/path'
-
- headers = {
- 'content-type': 'application/json',
- }
-
- json = {
- "name": "example",
- "email": "example@example.com"
- }
-
- response = requests.request(
- method='POST',
- url=url,
- headers=headers,
- json=json,
- )
-
- print(response.text)
- """).strip()
- assert flow_export.python_code(flow) == result
+ p = req_post()
+ p.content = '{"name": "example", "email": "example@example.com"}'
+ p.headers = Headers(content_type="application/json")
+ flow = tutils.tflow(req=p)
+ python_equals("test_flow_export/python_post_json.py", flow_export.python_code(flow))
def test_patch(self):
- flow = tutils.tflow(req=req_patch)
- result = dedent("""
- import requests
-
- url = 'http://address/path'
-
- headers = {
- 'header': 'qvalue',
- 'content-length': '7',
- }
-
- params = {
- 'query': 'param',
- }
-
- data = '''content'''
-
- response = requests.request(
- method='PATCH',
- url=url,
- headers=headers,
- params=params,
- data=data,
- )
-
- print(response.text)
- """).strip()
- assert flow_export.python_code(flow) == result
+ flow = tutils.tflow(req=req_patch())
+ python_equals("test_flow_export/python_patch.py", flow_export.python_code(flow))
class TestRawRequest():
-
def test_get(self):
- flow = tutils.tflow(req=req_get)
+ flow = tutils.tflow(req=req_get())
result = dedent("""
GET /path HTTP/1.1\r
header: qvalue\r
@@ -157,18 +79,17 @@ class TestRawRequest():
assert flow_export.raw_request(flow) == result
def test_post(self):
- flow = tutils.tflow(req=req_post)
+ flow = tutils.tflow(req=req_post())
result = dedent("""
POST /path HTTP/1.1\r
- content-type: application/json\r
host: address:22\r
\r
- {"name": "example", "email": "example@example.com"}
+ content
""").strip()
assert flow_export.raw_request(flow) == result
def test_patch(self):
- flow = tutils.tflow(req=req_patch)
+ flow = tutils.tflow(req=req_patch())
result = dedent("""
PATCH /path?query=param HTTP/1.1\r
header: qvalue\r
@@ -179,212 +100,50 @@ class TestRawRequest():
""").strip()
assert flow_export.raw_request(flow) == result
-class TestExportLocustCode():
+class TestExportLocustCode():
def test_get(self):
- flow = tutils.tflow(req=req_get)
- result = """
-from locust import HttpLocust, TaskSet, task
-
-class UserBehavior(TaskSet):
- def on_start(self):
- ''' on_start is called when a Locust start before any task is scheduled '''
- self.path()
-
- @task()
- def path(self):
- url = self.locust.host + '/path'
-
- headers = {
- 'header': 'qvalue',
- 'content-length': '7',
- }
-
- self.response = self.client.request(
- method='GET',
- url=url,
- headers=headers,
- )
-
- ### Additional tasks can go here ###
-
-
-class WebsiteUser(HttpLocust):
- task_set = UserBehavior
- min_wait = 1000
- max_wait = 3000
- """.strip()
-
- assert flow_export.locust_code(flow) == result
+ flow = tutils.tflow(req=req_get())
+ python_equals("test_flow_export/locust_get.py", flow_export.locust_code(flow))
def test_post(self):
- req_post.content = '''content'''
- req_post.headers = ''
- flow = tutils.tflow(req=req_post)
- result = """
-from locust import HttpLocust, TaskSet, task
-
-class UserBehavior(TaskSet):
- def on_start(self):
- ''' on_start is called when a Locust start before any task is scheduled '''
- self.path()
-
- @task()
- def path(self):
- url = self.locust.host + '/path'
-
- data = '''content'''
-
- self.response = self.client.request(
- method='POST',
- url=url,
- data=data,
- )
-
- ### Additional tasks can go here ###
-
-
-class WebsiteUser(HttpLocust):
- task_set = UserBehavior
- min_wait = 1000
- max_wait = 3000
-
- """.strip()
-
- assert flow_export.locust_code(flow) == result
-
+ p = req_post()
+ p.content = '''content'''
+ p.headers = ''
+ flow = tutils.tflow(req=p)
+ python_equals("test_flow_export/locust_post.py", flow_export.locust_code(flow))
def test_patch(self):
- flow = tutils.tflow(req=req_patch)
- result = """
-from locust import HttpLocust, TaskSet, task
-
-class UserBehavior(TaskSet):
- def on_start(self):
- ''' on_start is called when a Locust start before any task is scheduled '''
- self.path()
-
- @task()
- def path(self):
- url = self.locust.host + '/path'
-
- headers = {
- 'header': 'qvalue',
- 'content-length': '7',
- }
-
- params = {
- 'query': 'param',
- }
-
- data = '''content'''
-
- self.response = self.client.request(
- method='PATCH',
- url=url,
- headers=headers,
- params=params,
- data=data,
- )
-
- ### Additional tasks can go here ###
-
-
-class WebsiteUser(HttpLocust):
- task_set = UserBehavior
- min_wait = 1000
- max_wait = 3000
-
- """.strip()
-
- assert flow_export.locust_code(flow) == result
+ flow = tutils.tflow(req=req_patch())
+ python_equals("test_flow_export/locust_patch.py", flow_export.locust_code(flow))
class TestExportLocustTask():
-
def test_get(self):
- flow = tutils.tflow(req=req_get)
- result = ' ' + """
- @task()
- def path(self):
- url = self.locust.host + '/path'
-
- headers = {
- 'header': 'qvalue',
- 'content-length': '7',
- }
-
- self.response = self.client.request(
- method='GET',
- url=url,
- headers=headers,
- )
- """.strip() + '\n'
-
- assert flow_export.locust_task(flow) == result
+ flow = tutils.tflow(req=req_get())
+ python_equals("test_flow_export/locust_task_get.py", flow_export.locust_task(flow))
def test_post(self):
- flow = tutils.tflow(req=req_post)
- result = ' ' + """
- @task()
- def path(self):
- url = self.locust.host + '/path'
-
- data = '''content'''
-
- self.response = self.client.request(
- method='POST',
- url=url,
- data=data,
- )
- """.strip() + '\n'
-
- assert flow_export.locust_task(flow) == result
-
+ flow = tutils.tflow(req=req_post())
+ python_equals("test_flow_export/locust_task_post.py", flow_export.locust_task(flow))
def test_patch(self):
- flow = tutils.tflow(req=req_patch)
- result = ' ' + """
- @task()
- def path(self):
- url = self.locust.host + '/path'
-
- headers = {
- 'header': 'qvalue',
- 'content-length': '7',
- }
-
- params = {
- 'query': 'param',
- }
-
- data = '''content'''
-
- self.response = self.client.request(
- method='PATCH',
- url=url,
- headers=headers,
- params=params,
- data=data,
- )
- """.strip() + '\n'
-
- assert flow_export.locust_task(flow) == result
+ flow = tutils.tflow(req=req_patch())
+ python_equals("test_flow_export/locust_task_patch.py", flow_export.locust_task(flow))
class TestIsJson():
-
def test_empty(self):
- assert flow_export.is_json(None, None) == False
+ assert flow_export.is_json(None, None) is False
def test_json_type(self):
headers = Headers(content_type="application/json")
- assert flow_export.is_json(headers, "foobar") == False
+ assert flow_export.is_json(headers, "foobar") is False
def test_valid(self):
headers = Headers(content_type="application/foobar")
j = flow_export.is_json(headers, '{"name": "example", "email": "example@example.com"}')
- assert j == False
+ assert j is False
def test_valid(self):
headers = Headers(content_type="application/json")
diff --git a/test/mitmproxy/test_flow_export/locust_get.py b/test/mitmproxy/test_flow_export/locust_get.py
new file mode 100644
index 00000000..72d5932a
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/locust_get.py
@@ -0,0 +1,29 @@
+from locust import HttpLocust, TaskSet, task
+
+class UserBehavior(TaskSet):
+ def on_start(self):
+ ''' on_start is called when a Locust start before any task is scheduled '''
+ self.path()
+
+ @task()
+ def path(self):
+ url = self.locust.host + '/path'
+
+ headers = {
+ 'header': 'qvalue',
+ 'content-length': '7',
+ }
+
+ self.response = self.client.request(
+ method='GET',
+ url=url,
+ headers=headers,
+ )
+
+ ### Additional tasks can go here ###
+
+
+class WebsiteUser(HttpLocust):
+ task_set = UserBehavior
+ min_wait = 1000
+ max_wait = 3000
diff --git a/test/mitmproxy/test_flow_export/locust_patch.py b/test/mitmproxy/test_flow_export/locust_patch.py
new file mode 100644
index 00000000..f64e0857
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/locust_patch.py
@@ -0,0 +1,37 @@
+from locust import HttpLocust, TaskSet, task
+
+class UserBehavior(TaskSet):
+ def on_start(self):
+ ''' on_start is called when a Locust start before any task is scheduled '''
+ self.path()
+
+ @task()
+ def path(self):
+ url = self.locust.host + '/path'
+
+ headers = {
+ 'header': 'qvalue',
+ 'content-length': '7',
+ }
+
+ params = {
+ 'query': 'param',
+ }
+
+ data = '''content'''
+
+ self.response = self.client.request(
+ method='PATCH',
+ url=url,
+ headers=headers,
+ params=params,
+ data=data,
+ )
+
+ ### Additional tasks can go here ###
+
+
+class WebsiteUser(HttpLocust):
+ task_set = UserBehavior
+ min_wait = 1000
+ max_wait = 3000
diff --git a/test/mitmproxy/test_flow_export/locust_post.py b/test/mitmproxy/test_flow_export/locust_post.py
new file mode 100644
index 00000000..df23476a
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/locust_post.py
@@ -0,0 +1,26 @@
+from locust import HttpLocust, TaskSet, task
+
+class UserBehavior(TaskSet):
+ def on_start(self):
+ ''' on_start is called when a Locust start before any task is scheduled '''
+ self.path()
+
+ @task()
+ def path(self):
+ url = self.locust.host + '/path'
+
+ data = '''content'''
+
+ self.response = self.client.request(
+ method='POST',
+ url=url,
+ data=data,
+ )
+
+ ### Additional tasks can go here ###
+
+
+class WebsiteUser(HttpLocust):
+ task_set = UserBehavior
+ min_wait = 1000
+ max_wait = 3000
diff --git a/test/mitmproxy/test_flow_export/locust_task_get.py b/test/mitmproxy/test_flow_export/locust_task_get.py
new file mode 100644
index 00000000..76f144fa
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/locust_task_get.py
@@ -0,0 +1,14 @@
+ @task()
+ def path(self):
+ url = self.locust.host + '/path'
+
+ headers = {
+ 'header': 'qvalue',
+ 'content-length': '7',
+ }
+
+ self.response = self.client.request(
+ method='GET',
+ url=url,
+ headers=headers,
+ )
diff --git a/test/mitmproxy/test_flow_export/locust_task_patch.py b/test/mitmproxy/test_flow_export/locust_task_patch.py
new file mode 100644
index 00000000..d425209c
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/locust_task_patch.py
@@ -0,0 +1,22 @@
+ @task()
+ def path(self):
+ url = self.locust.host + '/path'
+
+ headers = {
+ 'header': 'qvalue',
+ 'content-length': '7',
+ }
+
+ params = {
+ 'query': 'param',
+ }
+
+ data = '''content'''
+
+ self.response = self.client.request(
+ method='PATCH',
+ url=url,
+ headers=headers,
+ params=params,
+ data=data,
+ )
diff --git a/test/mitmproxy/test_flow_export/locust_task_post.py b/test/mitmproxy/test_flow_export/locust_task_post.py
new file mode 100644
index 00000000..989df455
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/locust_task_post.py
@@ -0,0 +1,11 @@
+ @task()
+ def path(self):
+ url = self.locust.host + '/path'
+
+ data = '''content'''
+
+ self.response = self.client.request(
+ method='POST',
+ url=url,
+ data=data,
+ )
diff --git a/test/mitmproxy/test_flow_export/python_get.py b/test/mitmproxy/test_flow_export/python_get.py
new file mode 100644
index 00000000..ee3f48eb
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/python_get.py
@@ -0,0 +1,16 @@
+import requests
+
+url = 'http://address/path'
+
+headers = {
+ 'header': 'qvalue',
+ 'content-length': '7',
+}
+
+response = requests.request(
+ method='GET',
+ url=url,
+ headers=headers,
+)
+
+print(response.text)
diff --git a/test/mitmproxy/test_flow_export/python_patch.py b/test/mitmproxy/test_flow_export/python_patch.py
new file mode 100644
index 00000000..159e802f
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/python_patch.py
@@ -0,0 +1,24 @@
+import requests
+
+url = 'http://address/path'
+
+headers = {
+ 'header': 'qvalue',
+ 'content-length': '7',
+}
+
+params = {
+ 'query': 'param',
+}
+
+data = '''content'''
+
+response = requests.request(
+ method='PATCH',
+ url=url,
+ headers=headers,
+ params=params,
+ data=data,
+)
+
+print(response.text)
diff --git a/test/mitmproxy/test_flow_export/python_post.py b/test/mitmproxy/test_flow_export/python_post.py
new file mode 100644
index 00000000..b13f6441
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/python_post.py
@@ -0,0 +1,13 @@
+import requests
+
+url = 'http://address/path'
+
+data = '''content'''
+
+response = requests.request(
+ method='POST',
+ url=url,
+ data=data,
+)
+
+print(response.text)
diff --git a/test/mitmproxy/test_flow_export/python_post_json.py b/test/mitmproxy/test_flow_export/python_post_json.py
new file mode 100644
index 00000000..7e105bf6
--- /dev/null
+++ b/test/mitmproxy/test_flow_export/python_post_json.py
@@ -0,0 +1,21 @@
+import requests
+
+url = 'http://address/path'
+
+headers = {
+ 'content-type': 'application/json',
+}
+
+json = {
+ "name": "example",
+ "email": "example@example.com"
+}
+
+response = requests.request(
+ method='POST',
+ url=url,
+ headers=headers,
+ json=json,
+)
+
+print(response.text)
diff --git a/test/mitmproxy/test_protocol_http2.py b/test/mitmproxy/test_protocol_http2.py
index 1da140d8..c3950975 100644
--- a/test/mitmproxy/test_protocol_http2.py
+++ b/test/mitmproxy/test_protocol_http2.py
@@ -1,3 +1,5 @@
+# coding=utf-8
+
from __future__ import (absolute_import, print_function, division)
import OpenSSL
@@ -36,7 +38,7 @@ class _Http2ServerBase(netlib_tservers.ServerTestBase):
class handler(netlib.tcp.BaseHandler):
def handle(self):
- h2_conn = h2.connection.H2Connection(client_side=False)
+ h2_conn = h2.connection.H2Connection(client_side=False, header_encoding=False)
preamble = self.rfile.read(24)
h2_conn.initiate_connection()
@@ -122,7 +124,7 @@ class _Http2TestBase(object):
client.convert_to_ssl(alpn_protos=[b'h2'])
- h2_conn = h2.connection.H2Connection(client_side=True)
+ h2_conn = h2.connection.H2Connection(client_side=True, header_encoding=False)
h2_conn.initiate_connection()
client.wfile.write(h2_conn.data_to_send())
client.wfile.flush()
@@ -160,15 +162,19 @@ class TestSimple(_Http2TestBase, _Http2ServerBase):
if isinstance(event, h2.events.ConnectionTerminated):
return False
elif isinstance(event, h2.events.RequestReceived):
- h2_conn.send_headers(1, [
+ assert ('client-foo', 'client-bar-1') in event.headers
+ assert ('client-foo', 'client-bar-2') in event.headers
+
+ h2_conn.send_headers(event.stream_id, [
(':status', '200'),
- ('foo', 'bar'),
+ ('server-foo', 'server-bar'),
+ ('föo', 'bär'),
+ ('X-Stream-ID', str(event.stream_id)),
])
- h2_conn.send_data(1, b'foobar')
- h2_conn.end_stream(1)
+ h2_conn.send_data(event.stream_id, b'foobar')
+ h2_conn.end_stream(event.stream_id)
wfile.write(h2_conn.data_to_send())
wfile.flush()
-
return True
def test_simple(self):
@@ -179,6 +185,8 @@ class TestSimple(_Http2TestBase, _Http2ServerBase):
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
+ ('ClIeNt-FoO', 'client-bar-1'),
+ ('ClIeNt-FoO', 'client-bar-2'),
], body='my request body echoed back to me')
done = False
@@ -200,7 +208,8 @@ class TestSimple(_Http2TestBase, _Http2ServerBase):
assert len(self.master.state.flows) == 1
assert self.master.state.flows[0].response.status_code == 200
- assert self.master.state.flows[0].response.headers['foo'] == 'bar'
+ assert self.master.state.flows[0].response.headers['server-foo'] == 'server-bar'
+ assert self.master.state.flows[0].response.headers['föo'] == 'bär'
assert self.master.state.flows[0].response.body == b'foobar'
@@ -425,3 +434,51 @@ class TestPushPromise(_Http2TestBase, _Http2ServerBase):
assert len(bodies) >= 1
assert b'regular_stream' in bodies
# the other two bodies might not be transmitted before the reset
+
+@requires_alpn
+class TestConnectionLost(_Http2TestBase, _Http2ServerBase):
+
+ @classmethod
+ def setup_class(self):
+ _Http2TestBase.setup_class()
+ _Http2ServerBase.setup_class()
+
+ @classmethod
+ def teardown_class(self):
+ _Http2TestBase.teardown_class()
+ _Http2ServerBase.teardown_class()
+
+ @classmethod
+ def handle_server_event(self, event, h2_conn, rfile, wfile):
+ if isinstance(event, h2.events.RequestReceived):
+ h2_conn.send_headers(1, [(':status', '200')])
+ wfile.write(h2_conn.data_to_send())
+ wfile.flush()
+ return False
+
+ def test_connection_lost(self):
+ client, h2_conn = self._setup_connection()
+
+ self._send_request(client.wfile, h2_conn, stream_id=1, headers=[
+ (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':method', 'GET'),
+ (':scheme', 'https'),
+ (':path', '/'),
+ ('foo', 'bar')
+ ])
+
+ done = False
+ ended_streams = 0
+ pushed_streams = 0
+ responses = 0
+ while not done:
+ try:
+ raw = b''.join(http2_read_raw_frame(client.rfile))
+ events = h2_conn.receive_data(raw)
+ except:
+ break
+ client.wfile.write(h2_conn.data_to_send())
+ client.wfile.flush()
+
+ if len(self.master.state.flows) == 1:
+ assert self.master.state.flows[0].response is None
diff --git a/test/mitmproxy/test_server.py b/test/mitmproxy/test_server.py
index 8843ee62..454736d4 100644
--- a/test/mitmproxy/test_server.py
+++ b/test/mitmproxy/test_server.py
@@ -285,8 +285,7 @@ class TestHTTP(tservers.HTTPProxyTest, CommonMixin, AppMixin):
self.master.set_stream_large_bodies(None)
def test_stream_modify(self):
- self.master.load_script(
- tutils.test_data.path("scripts/stream_modify.py"))
+ self.master.load_script(tutils.test_data.path("scripts/stream_modify.py"))
d = self.pathod('200:b"foo"')
assert d.content == "bar"
self.master.unload_scripts()
@@ -511,8 +510,7 @@ class TestTransparent(tservers.TransparentProxyTest, CommonMixin, TcpMixin):
ssl = False
def test_tcp_stream_modify(self):
- self.master.load_script(
- tutils.test_data.path("scripts/tcp_stream_modify.py"))
+ self.master.load_script(tutils.test_data.path("scripts/tcp_stream_modify.py"))
self._tcpproxy_on()
d = self.pathod('200:b"foo"')
diff --git a/test/mitmproxy/tutils.py b/test/mitmproxy/tutils.py
index d51ac185..2dfd710e 100644
--- a/test/mitmproxy/tutils.py
+++ b/test/mitmproxy/tutils.py
@@ -8,6 +8,7 @@ from contextlib import contextmanager
from unittest.case import SkipTest
+import netlib.utils
import netlib.tutils
from mitmproxy import utils, controller
from mitmproxy.models import (
@@ -163,4 +164,4 @@ def capture_stderr(command, *args, **kwargs):
sys.stderr = out
-test_data = utils.Data(__name__)
+test_data = netlib.utils.Data(__name__)
diff --git a/test/netlib/http/test_cookies.py b/test/netlib/http/test_cookies.py
index 3b520a44..da28850f 100644
--- a/test/netlib/http/test_cookies.py
+++ b/test/netlib/http/test_cookies.py
@@ -228,7 +228,16 @@ def test_refresh_cookie():
c = "MOO=BAR; Expires=Tue, 08-Mar-2011 00:20:38 GMT; Path=foo.com; Secure"
assert "00:21:38" in cookies.refresh_set_cookie_header(c, 60)
+ c = "foo,bar"
+ with raises(ValueError):
+ cookies.refresh_set_cookie_header(c, 60)
+
# https://github.com/mitmproxy/mitmproxy/issues/773
c = ">=A"
- with raises(ValueError):
- cookies.refresh_set_cookie_header(c, 60) \ No newline at end of file
+ assert cookies.refresh_set_cookie_header(c, 60)
+
+ # https://github.com/mitmproxy/mitmproxy/issues/1118
+ c = "foo:bar=bla"
+ assert cookies.refresh_set_cookie_header(c, 0)
+ c = "foo/bar=bla"
+ assert cookies.refresh_set_cookie_header(c, 0)
diff --git a/test/netlib/http/test_request.py b/test/netlib/http/test_request.py
index 50ad2d05..7ed6bd0f 100644
--- a/test/netlib/http/test_request.py
+++ b/test/netlib/http/test_request.py
@@ -107,6 +107,14 @@ class TestRequestUtils(object):
with raises(ValueError):
request.url = "not-a-url"
+ def test_url_options(self):
+ request = treq(method=b"OPTIONS", path=b"*")
+ assert request.url == "http://address:22"
+
+ def test_url_authority(self):
+ request = treq(first_line_format="authority")
+ assert request.url == "address:22"
+
def test_pretty_host(self):
request = treq()
# Without host header
@@ -140,6 +148,10 @@ class TestRequestUtils(object):
request.headers["host"] = "other"
assert request.pretty_url == "http://address:22/path"
+ def test_pretty_url_options(self):
+ request = treq(method=b"OPTIONS", path=b"*")
+ assert request.pretty_url == "http://address:22"
+
def test_pretty_url_authority(self):
request = treq(first_line_format="authority")
assert request.pretty_url == "address:22"
@@ -160,7 +172,7 @@ class TestRequestUtils(object):
def test_get_cookies_none(self):
request = treq()
request.headers = Headers()
- assert len(request.cookies) == 0
+ assert not request.cookies
def test_get_cookies_single(self):
request = treq()
diff --git a/test/netlib/http/test_response.py b/test/netlib/http/test_response.py
index a0c44d90..5440176c 100644
--- a/test/netlib/http/test_response.py
+++ b/test/netlib/http/test_response.py
@@ -98,7 +98,7 @@ class TestResponseUtils(object):
resp = tresp()
v = resp.cookies
v.add("foo", ["bar", ODictCaseless()])
- resp.set_cookies(v)
+ resp.cookies = v
v = resp.cookies
assert len(v) == 1
diff --git a/test/netlib/test_odict.py b/test/netlib/test_odict.py
index f0985ef6..b6fd6401 100644
--- a/test/netlib/test_odict.py
+++ b/test/netlib/test_odict.py
@@ -27,16 +27,6 @@ class TestODict(object):
b.set_state(state)
assert b == od
- def test_in_any(self):
- od = odict.ODict()
- od["one"] = ["atwoa", "athreea"]
- assert od.in_any("one", "two")
- assert od.in_any("one", "three")
- assert not od.in_any("one", "four")
- assert not od.in_any("nonexistent", "foo")
- assert not od.in_any("one", "TWO")
- assert od.in_any("one", "TWO", True)
-
def test_iter(self):
od = odict.ODict()
assert not [i for i in od]
diff --git a/test/netlib/test_utils.py b/test/netlib/test_utils.py
index be2a59fc..1d8f7b0f 100644
--- a/test/netlib/test_utils.py
+++ b/test/netlib/test_utils.py
@@ -1,3 +1,4 @@
+# coding=utf-8
from netlib import utils, tutils
from netlib.http import Headers
@@ -170,3 +171,17 @@ class TestSerializable:
def test_safe_subn():
assert utils.safe_subn("foo", u"bar", "\xc2foo")
+
+
+def test_bytes_to_escaped_str():
+ assert utils.bytes_to_escaped_str(b"foo") == "foo"
+ assert utils.bytes_to_escaped_str(b"\b") == r"\x08"
+ assert utils.bytes_to_escaped_str(br"&!?=\)") == r"&!?=\\)"
+ assert utils.bytes_to_escaped_str(b'\xc3\xbc') == r"\xc3\xbc"
+
+
+def test_escaped_str_to_bytes():
+ assert utils.escaped_str_to_bytes("foo") == b"foo"
+ assert utils.escaped_str_to_bytes(r"\x08") == b"\b"
+ assert utils.escaped_str_to_bytes(r"&!?=\\)") == br"&!?=\)"
+ assert utils.escaped_str_to_bytes(r"ü") == b'\xc3\xbc'
diff --git a/test/pathod/test_language_websocket.py b/test/pathod/test_language_websocket.py
index f1105dfe..29155dba 100644
--- a/test/pathod/test_language_websocket.py
+++ b/test/pathod/test_language_websocket.py
@@ -97,7 +97,7 @@ class TestWebsocketFrame:
assert self.fr("wf:r'foo'").payload == "foo"
- def test_construction(self):
+ def test_construction_2(self):
# Simple server frame
frm = self.fr("wf:b'foo'")
assert not frm.header.mask
diff --git a/test/pathod/test_pathoc.py b/test/pathod/test_pathoc.py
index 8d0f92ac..4e8c89c5 100644
--- a/test/pathod/test_pathoc.py
+++ b/test/pathod/test_pathoc.py
@@ -211,7 +211,7 @@ class TestDaemon(_TestDaemon):
c.stop()
@skip_windows
- @pytest.mark.xfail
+ @pytest.mark.skip(reason="race condition")
def test_wait_finish(self):
c = pathoc.Pathoc(
("127.0.0.1", self.d.port),
diff --git a/test/pathod/test_pathod.py b/test/pathod/test_pathod.py
index 7583148b..05a3962e 100644
--- a/test/pathod/test_pathod.py
+++ b/test/pathod/test_pathod.py
@@ -129,7 +129,7 @@ class CommonTests(tutils.DaemonTests):
l = self.d.last_log()
# FIXME: Other binary data elements
- @pytest.mark.xfail
+ @pytest.mark.skip(reason="race condition")
def test_sizelimit(self):
r = self.get("200:b@1g")
assert r.status_code == 800
@@ -143,7 +143,7 @@ class CommonTests(tutils.DaemonTests):
def test_info(self):
assert tuple(self.d.info()["version"]) == version.IVERSION
- @pytest.mark.xfail
+ @pytest.mark.skip(reason="race condition")
def test_logs(self):
assert self.d.clear_log()
assert not self.d.last_log()
@@ -223,7 +223,7 @@ class CommonTests(tutils.DaemonTests):
)
assert r[1].payload == "test"
- @pytest.mark.xfail
+ @pytest.mark.skip(reason="race condition")
def test_websocket_frame_reflect_error(self):
r, _ = self.pathoc(
["ws:/p/", "wf:-mask:knone:f'wf:b@10':i13,'a'"],
@@ -233,6 +233,7 @@ class CommonTests(tutils.DaemonTests):
# FIXME: Race Condition?
assert "Parse error" in self.d.text_log()
+ @pytest.mark.skip(reason="race condition")
def test_websocket_frame_disconnect_error(self):
self.pathoc(["ws:/p/", "wf:b@10:d3"], ws_read_limit=0)
assert self.d.last_log()
diff --git a/test/pathod/tutils.py b/test/pathod/tutils.py
index 9739afde..f6ed3efb 100644
--- a/test/pathod/tutils.py
+++ b/test/pathod/tutils.py
@@ -116,7 +116,7 @@ tmpdir = netlib.tutils.tmpdir
raises = netlib.tutils.raises
-test_data = utils.Data(__name__)
+test_data = netlib.utils.Data(__name__)
def render(r, settings=language.Settings()):