aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/master.py24
-rw-r--r--mitmproxy/net/http/request.py49
-rw-r--r--mitmproxy/tools/console/flowlist.py5
-rw-r--r--release/README.md27
-rw-r--r--setup.py4
-rw-r--r--test/mitmproxy/net/http/test_request.py28
-rw-r--r--test/mitmproxy/test_flow.py2
7 files changed, 105 insertions, 34 deletions
diff --git a/mitmproxy/master.py b/mitmproxy/master.py
index 19d069bc..887a9240 100644
--- a/mitmproxy/master.py
+++ b/mitmproxy/master.py
@@ -12,7 +12,6 @@ from mitmproxy import http
from mitmproxy import log
from mitmproxy.proxy.protocol import http_replay
from mitmproxy.types import basethread
-import mitmproxy.net.http
from . import ctx as mitmproxy_ctx
@@ -117,27 +116,18 @@ class Master:
self.should_exit.set()
self.addons.done()
- def create_request(self, method, scheme, host, port, path):
+ def create_request(self, method, url):
"""
- this method creates a new artificial and minimalist request also adds it to flowlist
+ Create a new artificial and minimalist request also adds it to flowlist.
+
+ Raises:
+ ValueError, if the url is malformed.
"""
+ req = http.HTTPRequest.make(method, url)
c = connections.ClientConnection.make_dummy(("", 0))
- s = connections.ServerConnection.make_dummy((host, port))
+ s = connections.ServerConnection.make_dummy((req.host, req.port))
f = http.HTTPFlow(c, s)
- headers = mitmproxy.net.http.Headers()
-
- req = http.HTTPRequest(
- "absolute",
- method,
- scheme,
- host,
- port,
- path,
- b"HTTP/1.1",
- headers,
- b""
- )
f.request = req
self.load_flow(f)
return f
diff --git a/mitmproxy/net/http/request.py b/mitmproxy/net/http/request.py
index b961e1e4..90a1f924 100644
--- a/mitmproxy/net/http/request.py
+++ b/mitmproxy/net/http/request.py
@@ -1,6 +1,6 @@
import re
import urllib
-from typing import Optional
+from typing import Optional, AnyStr, Dict, Iterable, Tuple, Union
from mitmproxy.types import multidict
from mitmproxy.utils import strutils
@@ -77,6 +77,53 @@ class Request(message.Message):
self.method, hostport, path
)
+ @classmethod
+ def make(
+ cls,
+ method: str,
+ url: str,
+ content: AnyStr = b"",
+ headers: Union[Dict[AnyStr, AnyStr], Iterable[Tuple[bytes, bytes]]] = ()
+ ):
+ """
+ Simplified API for creating request objects.
+ """
+ req = cls(
+ "absolute",
+ method,
+ "",
+ "",
+ "",
+ "",
+ "HTTP/1.1",
+ (),
+ b""
+ )
+
+ req.url = url
+
+ # Headers can be list or dict, we differentiate here.
+ if isinstance(headers, dict):
+ req.headers = nheaders.Headers(**headers)
+ elif isinstance(headers, Iterable):
+ req.headers = nheaders.Headers(headers)
+ else:
+ raise TypeError("Expected headers to be an iterable or dict, but is {}.".format(
+ type(headers).__name__
+ ))
+
+ # Assign this manually to update the content-length header.
+ if isinstance(content, bytes):
+ req.content = content
+ elif isinstance(content, str):
+ req.text = content
+ else:
+ raise TypeError("Expected content to be str or bytes, but is {}.".format(
+ type(content).__name__
+ ))
+
+ return req
+
def replace(self, pattern, repl, flags=0, count=0):
"""
Replaces a regular expression pattern with repl in the headers, the
diff --git a/mitmproxy/tools/console/flowlist.py b/mitmproxy/tools/console/flowlist.py
index d2e28d35..5fe86975 100644
--- a/mitmproxy/tools/console/flowlist.py
+++ b/mitmproxy/tools/console/flowlist.py
@@ -1,6 +1,5 @@
import urwid
-import mitmproxy.net.http.url
from mitmproxy import exceptions
from mitmproxy.tools.console import common
from mitmproxy.tools.console import signals
@@ -339,12 +338,10 @@ class FlowListBox(urwid.ListBox):
def new_request(self, url, method):
try:
- parts = mitmproxy.net.http.url.parse(str(url))
+ f = self.master.create_request(method, url)
except ValueError as e:
signals.status_message.send(message = "Invalid URL: " + str(e))
return
- scheme, host, port, path = parts
- f = self.master.create_request(method, scheme, host, port, path)
self.master.view.focus.flow = f
def keypress(self, size, key):
diff --git a/release/README.md b/release/README.md
index 02fabfe9..a30221c8 100644
--- a/release/README.md
+++ b/release/README.md
@@ -1,14 +1,25 @@
# Release Checklist
+Make sure run all these steps on the correct branch you want to create a new release for!
+- Verify `mitmproxy/version.py`
- Update CHANGELOG
-- Verify that all CI tests pass for current master
-- Tag the release, and push to Github
+- Verify that all CI tests pass
+- Tag the release and push to Github
- Wait for tag CI to complete
-- Download assets from snapshots.mitmproxy.org
-- Create release notice on Github
-- Upload wheel to pypi (`twine upload wheelname`)
+
+## GitHub Release
+- Create release notice on Github [https://github.com/mitmproxy/mitmproxy/releases/new](here)
+- Attach all files from the new release folder on https://snapshots.mitmproxy.org
+
+## PyPi
+- Upload wheel to pypi: `twine upload <mitmproxy-...-.whl`
+
+## Docker
- Update docker-releases repo
- Create a new branch based of master for major versions.
- - Add a commit that pins dependencies like so: https://github.com/mitmproxy/docker-releases/commit/3d6a9989fde068ad0aea257823ac3d7986ff1613. The requirements can be obtained by creating a fresh venv, pip-installing the new wheel in there, and then running `pip freeze`.
-- Update `latest` tag on https://hub.docker.com/r/mitmproxy/mitmproxy/~/settings/automated-builds/
-- Bump the version in https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/version.py and update https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/io_compat.py in the next commit
+ - Update the dependencies in [alpine/requirements.txt](https://github.com/mitmproxy/docker-releases/commit/3d6a9989fde068ad0aea257823ac3d7986ff1613#diff-9b7e0eea8ae74688b1ac13ea080549ba)
+ * Creating a fresh venv, pip-installing the new wheel in there, and then export all packages:
+ * `virtualenv -ppython3.5 venv && source venv/bin/activate && pip install mitmproxy && pip freeze`
+- Update `latest` tag [https://hub.docker.com/r/mitmproxy/mitmproxy/~/settings/automated-builds/](here)
+
+After everything is done, you might want to bump the version on master in [https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/version.py](mitmproxy/version.py) if you just created a major release.
diff --git a/setup.py b/setup.py
index bbbac95e..6f17a62e 100644
--- a/setup.py
+++ b/setup.py
@@ -64,7 +64,7 @@ setup(
"click>=6.2, <7",
"certifi>=2015.11.20.1", # no semver here - this should always be on the last release!
"construct>=2.8, <2.9",
- "cryptography>=1.3, <1.8",
+ "cryptography>=1.3, <1.9",
"cssutils>=1.0.1, <1.1",
"h2>=2.5.1, <3",
"html2text>=2016.1.8, <=2016.9.19",
@@ -74,7 +74,7 @@ setup(
"passlib>=1.6.5, <1.8",
"pyasn1>=0.1.9, <0.3",
"pyOpenSSL>=16.0, <17.0",
- "pyparsing>=2.1.3, <2.2",
+ "pyparsing>=2.1.3, <2.3",
"pyperclip>=1.5.22, <1.6",
"requests>=2.9.1, <3",
"ruamel.yaml>=0.13.2, <0.14",
diff --git a/test/mitmproxy/net/http/test_request.py b/test/mitmproxy/net/http/test_request.py
index 90ec31fe..ce49002c 100644
--- a/test/mitmproxy/net/http/test_request.py
+++ b/test/mitmproxy/net/http/test_request.py
@@ -1,7 +1,7 @@
from unittest import mock
import pytest
-from mitmproxy.net.http import Headers
+from mitmproxy.net.http import Headers, Request
from mitmproxy.test.tutils import treq
from .test_message import _test_decoded_attr, _test_passthrough_attr
@@ -35,6 +35,32 @@ class TestRequestCore:
request.host = None
assert repr(request) == "Request(GET /path)"
+ def test_make(self):
+ r = Request.make("GET", "https://example.com/")
+ assert r.method == "GET"
+ assert r.scheme == "https"
+ assert r.host == "example.com"
+ assert r.port == 443
+ assert r.path == "/"
+
+ r = Request.make("GET", "https://example.com/", "content", {"Foo": "bar"})
+ assert r.content == b"content"
+ assert r.headers["content-length"] == "7"
+ assert r.headers["Foo"] == "bar"
+
+ Request.make("GET", "https://example.com/", content=b"content")
+ with pytest.raises(TypeError):
+ Request.make("GET", "https://example.com/", content=42)
+
+ r = Request.make("GET", "https://example.com/", headers=[(b"foo", b"bar")])
+ assert r.headers["foo"] == "bar"
+
+ r = Request.make("GET", "https://example.com/", headers=({"foo": "baz"}))
+ assert r.headers["foo"] == "baz"
+
+ with pytest.raises(TypeError):
+ Request.make("GET", "https://example.com/", headers=42)
+
def test_replace(self):
r = treq()
r.path = b"foobarfoo"
diff --git a/test/mitmproxy/test_flow.py b/test/mitmproxy/test_flow.py
index 1fb33bb2..4f87a6ae 100644
--- a/test/mitmproxy/test_flow.py
+++ b/test/mitmproxy/test_flow.py
@@ -115,7 +115,7 @@ class TestFlowMaster:
def test_create_flow(self):
fm = master.Master(None, DummyServer())
- assert fm.create_request("GET", "http", "example.com", 80, "/")
+ assert fm.create_request("GET", "http://example.com/")
def test_all(self):
s = tservers.TestState()