Fix flow initialization order error

Resolves #210
This commit is contained in:
Aldo Cortesi 2014-02-08 17:17:35 +13:00
parent b642b4870b
commit a85974eaa8
4 changed files with 15 additions and 14 deletions

View File

@ -568,13 +568,11 @@ class ConsoleMaster(flow.FlowMaster):
self.ui.set_terminal_properties(256) self.ui.set_terminal_properties(256)
self.ui.register_palette(self.palette) self.ui.register_palette(self.palette)
self.flow_list_walker = flowlist.FlowListWalker(self, self.state) self.flow_list_walker = flowlist.FlowListWalker(self, self.state)
self.view = None self.view = None
self.statusbar = None self.statusbar = None
self.header = None self.header = None
self.body = None self.body = None
self.help_context = None self.help_context = None
self.prompting = False self.prompting = False
self.onekey = False self.onekey = False
@ -597,7 +595,6 @@ class ConsoleMaster(flow.FlowMaster):
print >> sys.stderr, traceback.format_exc() print >> sys.stderr, traceback.format_exc()
print >> sys.stderr, "mitmproxy has crashed!" print >> sys.stderr, "mitmproxy has crashed!"
print >> sys.stderr, "Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy" print >> sys.stderr, "Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy"
# If True, quit just pops out to flow list view.
print >> sys.stderr, "Shutting down..." print >> sys.stderr, "Shutting down..."
sys.stderr.flush() sys.stderr.flush()
self.shutdown() self.shutdown()
@ -1028,7 +1025,6 @@ class ConsoleMaster(flow.FlowMaster):
e = urwid.Text(str(e)) e = urwid.Text(str(e))
elif level == "error": elif level == "error":
e = urwid.Text(("error", str(e))) e = urwid.Text(("error", str(e)))
self.eventlist.append(e) self.eventlist.append(e)
if len(self.eventlist) > EVENTLOG_SIZE: if len(self.eventlist) > EVENTLOG_SIZE:
self.eventlist.pop(0) self.eventlist.pop(0)

View File

@ -5,7 +5,7 @@
import base64 import base64
import hashlib, Cookie, cookielib, re, threading import hashlib, Cookie, cookielib, re, threading
import os import os
from flask import request import flask
import requests import requests
import tnetstring, filt, script import tnetstring, filt, script
from netlib import odict, wsgi from netlib import odict, wsgi
@ -455,7 +455,7 @@ class FlowMaster(controller.Master):
else: else:
@app.mapp.before_request @app.mapp.before_request
def patch_environ(*args, **kwargs): def patch_environ(*args, **kwargs):
request.environ["mitmproxy.master"] = self flask.request.environ["mitmproxy.master"] = self
# the only absurd way to shut down a flask/werkzeug server. # the only absurd way to shut down a flask/werkzeug server.
# http://flask.pocoo.org/snippets/67/ # http://flask.pocoo.org/snippets/67/
@ -464,7 +464,7 @@ class FlowMaster(controller.Master):
@app.mapp.route('/shutdown/<secret>') @app.mapp.route('/shutdown/<secret>')
def shutdown(secret): def shutdown(secret):
if secret == shutdown_secret: if secret == shutdown_secret:
request.environ.get('werkzeug.server.shutdown')() flask.request.environ.get('werkzeug.server.shutdown')()
# Workaround: Monkey-patch shutdown function to stop the app. # Workaround: Monkey-patch shutdown function to stop the app.
# Improve this when we switch flask werkzeug for something useful. # Improve this when we switch flask werkzeug for something useful.

View File

@ -877,11 +877,17 @@ class HTTPHandler(ProtocolHandler, TemporaryServerChangeMixin):
def handle_flow(self): def handle_flow(self):
flow = HTTPFlow(self.c.client_conn, self.c.server_conn, self.change_server) flow = HTTPFlow(self.c.client_conn, self.c.server_conn, self.change_server)
try: try:
flow.request = HTTPRequest.from_stream(self.c.client_conn.rfile, req = HTTPRequest.from_stream(self.c.client_conn.rfile,
body_size_limit=self.c.config.body_size_limit) body_size_limit=self.c.config.body_size_limit)
self.c.log("request", [flow.request._assemble_first_line(flow.request.form_in)]) self.c.log("request", [req._assemble_first_line(req.form_in)])
self.process_request(flow.request) self.process_request(flow, req)
# Be careful NOT to assign the request to the flow before
# process_request completes. This is because the call can raise an
# exception. If the requets object is already attached, this results
# in an Error object that has an attached request that has not been
# sent through to the Master.
flow.request = req
request_reply = self.c.channel.ask("request", flow.request) request_reply = self.c.channel.ask("request", flow.request)
flow.server_conn = self.c.server_conn flow.server_conn = self.c.server_conn
@ -1004,7 +1010,7 @@ class HTTPHandler(ProtocolHandler, TemporaryServerChangeMixin):
self.c.log("Upgrade to SSL completed.") self.c.log("Upgrade to SSL completed.")
raise ConnectionTypeChange raise ConnectionTypeChange
def process_request(self, request): def process_request(self, flow, request):
if self.c.mode == "regular": if self.c.mode == "regular":
self.authenticate(request) self.authenticate(request)
if request.form_in == "authority" and self.c.client_conn.ssl_established: if request.form_in == "authority" and self.c.client_conn.ssl_established:
@ -1015,7 +1021,7 @@ class HTTPHandler(ProtocolHandler, TemporaryServerChangeMixin):
directly_addressed_at_mitmproxy = (self.c.mode == "regular" and not self.c.config.forward_proxy) directly_addressed_at_mitmproxy = (self.c.mode == "regular" and not self.c.config.forward_proxy)
if directly_addressed_at_mitmproxy: if directly_addressed_at_mitmproxy:
self.c.set_server_address((request.host, request.port), AddressPriority.FROM_PROTOCOL) self.c.set_server_address((request.host, request.port), AddressPriority.FROM_PROTOCOL)
request.flow.server_conn = self.c.server_conn # Update server_conn attribute on the flow flow.server_conn = self.c.server_conn # Update server_conn attribute on the flow
self.c.client_conn.wfile.write( self.c.client_conn.wfile.write(
'HTTP/1.1 200 Connection established\r\n' + 'HTTP/1.1 200 Connection established\r\n' +
('Proxy-agent: %s\r\n' % self.c.server_version) + ('Proxy-agent: %s\r\n' % self.c.server_version) +
@ -1033,7 +1039,7 @@ class HTTPHandler(ProtocolHandler, TemporaryServerChangeMixin):
if not self.c.config.forward_proxy: if not self.c.config.forward_proxy:
request.form_out = "origin" request.form_out = "origin"
self.c.set_server_address((request.host, request.port), AddressPriority.FROM_PROTOCOL) self.c.set_server_address((request.host, request.port), AddressPriority.FROM_PROTOCOL)
request.flow.server_conn = self.c.server_conn # Update server_conn attribute on the flow flow.server_conn = self.c.server_conn # Update server_conn attribute on the flow
else: else:
raise http.HttpError(400, "Invalid request form (absolute-form or authority-form required)") raise http.HttpError(400, "Invalid request form (absolute-form or authority-form required)")

View File

@ -44,7 +44,6 @@ class TestHTTPRequest:
r = HTTPRequest.from_stream(s) r = HTTPRequest.from_stream(s)
assert r._assemble() == "CONNECT address:22 HTTP/1.1\r\nHost: address:22\r\n\r\n" assert r._assemble() == "CONNECT address:22 HTTP/1.1\r\nHost: address:22\r\n\r\n"
def test_absolute_form(self): def test_absolute_form(self):
s = StringIO("GET oops-no-protocol.com HTTP/1.1") s = StringIO("GET oops-no-protocol.com HTTP/1.1")
tutils.raises("Bad HTTP request line", HTTPRequest.from_stream, s) tutils.raises("Bad HTTP request line", HTTPRequest.from_stream, s)