mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2025-01-30 23:09:44 +00:00
Basic websocket connection, code cleanup.
This commit is contained in:
parent
4f56b76b2c
commit
f7da58ca9b
@ -2,11 +2,10 @@
|
||||
This module provides more sophisticated flow tracking and provides filtering and interception facilities.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import base64
|
||||
import hashlib, Cookie, cookielib, re, threading
|
||||
import os
|
||||
import flask
|
||||
import requests
|
||||
import hashlib
|
||||
import Cookie
|
||||
import cookielib
|
||||
import re
|
||||
from netlib import odict, wsgi
|
||||
import netlib.http
|
||||
from . import controller, protocol, tnetstring, filt, script, version
|
||||
@ -151,10 +150,13 @@ class StreamLargeBodies(object):
|
||||
def run(self, flow, is_request):
|
||||
r = flow.request if is_request else flow.response
|
||||
code = flow.response.code if flow.response else None
|
||||
expected_size = netlib.http.expected_http_body_size(r.headers, is_request, flow.request.method, code)
|
||||
expected_size = netlib.http.expected_http_body_size(
|
||||
r.headers, is_request, flow.request.method, code
|
||||
)
|
||||
if not (0 <= expected_size <= self.max_size):
|
||||
r.stream = True
|
||||
|
||||
|
||||
class ClientPlaybackState:
|
||||
def __init__(self, flows, exit):
|
||||
self.flows, self.exit = flows, exit
|
||||
@ -645,11 +647,11 @@ class FlowMaster(controller.Master):
|
||||
f.error = None
|
||||
self.process_new_request(f)
|
||||
rt = http.RequestReplayThread(
|
||||
self.server.config,
|
||||
f,
|
||||
self.masterq,
|
||||
self.should_exit
|
||||
)
|
||||
self.server.config,
|
||||
f,
|
||||
self.masterq,
|
||||
self.should_exit
|
||||
)
|
||||
rt.start() # pragma: no cover
|
||||
if block:
|
||||
rt.join()
|
||||
|
@ -12,10 +12,10 @@ class Error(stateobject.SimpleStateObject):
|
||||
"""
|
||||
An Error.
|
||||
|
||||
This is distinct from an protocol error response (say, a HTTP code 500), which
|
||||
is represented by a normal HTTPResponse object. This class is responsible
|
||||
for indicating errors that fall outside of normal protocol communications,
|
||||
like interrupted connections, timeouts, protocol errors.
|
||||
This is distinct from an protocol error response (say, a HTTP code 500),
|
||||
which is represented by a normal HTTPResponse object. This class is
|
||||
responsible for indicating errors that fall outside of normal protocol
|
||||
communications, like interrupted connections, timeouts, protocol errors.
|
||||
|
||||
Exposes the following attributes:
|
||||
|
||||
@ -42,7 +42,9 @@ class Error(stateobject.SimpleStateObject):
|
||||
|
||||
@classmethod
|
||||
def _from_state(cls, state):
|
||||
f = cls(None) # the default implementation assumes an empty constructor. Override accordingly.
|
||||
# the default implementation assumes an empty constructor. Override
|
||||
# accordingly.
|
||||
f = cls(None)
|
||||
f._load_state(state)
|
||||
return f
|
||||
|
||||
@ -133,31 +135,35 @@ class ProtocolHandler(object):
|
||||
|
||||
def handle_messages(self):
|
||||
"""
|
||||
This method gets called if a client connection has been made. Depending on the proxy settings,
|
||||
a server connection might already exist as well.
|
||||
This method gets called if a client connection has been made. Depending
|
||||
on the proxy settings, a server connection might already exist as well.
|
||||
"""
|
||||
raise NotImplementedError # pragma: nocover
|
||||
|
||||
def handle_server_reconnect(self, state):
|
||||
"""
|
||||
This method gets called if a server connection needs to reconnect and there's a state associated
|
||||
with the server connection (e.g. a previously-sent CONNECT request or a SOCKS proxy request).
|
||||
This method gets called after the connection has been restablished but before SSL is established.
|
||||
This method gets called if a server connection needs to reconnect and
|
||||
there's a state associated with the server connection (e.g. a
|
||||
previously-sent CONNECT request or a SOCKS proxy request). This method
|
||||
gets called after the connection has been restablished but before SSL is
|
||||
established.
|
||||
"""
|
||||
raise NotImplementedError # pragma: nocover
|
||||
|
||||
def handle_error(self, error):
|
||||
"""
|
||||
This method gets called should there be an uncaught exception during the connection.
|
||||
This might happen outside of handle_messages, e.g. if the initial SSL handshake fails in transparent mode.
|
||||
This method gets called should there be an uncaught exception during the
|
||||
connection. This might happen outside of handle_messages, e.g. if the
|
||||
initial SSL handshake fails in transparent mode.
|
||||
"""
|
||||
raise error # pragma: nocover
|
||||
|
||||
|
||||
class LiveConnection(object):
|
||||
"""
|
||||
This facade allows interested parties (FlowMaster, inline scripts) to interface with a live connection,
|
||||
without requiring to expose the internals of the ConnectionHandler.
|
||||
This facade allows interested parties (FlowMaster, inline scripts) to
|
||||
interface with a live connection, without requiring to expose the internals
|
||||
of the ConnectionHandler.
|
||||
"""
|
||||
def __init__(self, c):
|
||||
self.c = c
|
||||
@ -193,7 +199,9 @@ class LiveConnection(object):
|
||||
if not self._backup_server_conn and not persistent_change:
|
||||
self._backup_server_conn = self.c.server_conn
|
||||
self.c.server_conn = None
|
||||
else: # This is at least the second temporary change. We can kill the current connection.
|
||||
else:
|
||||
# This is at least the second temporary change. We can kill the
|
||||
# current connection.
|
||||
self.c.del_server_connection()
|
||||
|
||||
self.c.set_server_address(address)
|
||||
@ -204,8 +212,9 @@ class LiveConnection(object):
|
||||
return False
|
||||
|
||||
def restore_server(self):
|
||||
# TODO: Similar to _backup_server_conn, introduce _cache_server_conn, which keeps the changed connection open
|
||||
# This may be beneficial if a user is rewriting all requests from http to https or similar.
|
||||
# TODO: Similar to _backup_server_conn, introduce _cache_server_conn,
|
||||
# which keeps the changed connection open This may be beneficial if a
|
||||
# user is rewriting all requests from http to https or similar.
|
||||
if not self._backup_server_conn:
|
||||
return
|
||||
|
||||
|
@ -58,6 +58,7 @@ class Options(object):
|
||||
class WebMaster(flow.FlowMaster):
|
||||
def __init__(self, server, options):
|
||||
self.options = options
|
||||
self.app = app.Application(self.options.wdebug)
|
||||
flow.FlowMaster.__init__(self, server, WebState())
|
||||
|
||||
def tick(self):
|
||||
@ -70,9 +71,7 @@ class WebMaster(flow.FlowMaster):
|
||||
)
|
||||
iol = tornado.ioloop.IOLoop.instance()
|
||||
|
||||
http_server = tornado.httpserver.HTTPServer(
|
||||
app.Application(self.options.wdebug)
|
||||
)
|
||||
http_server = tornado.httpserver.HTTPServer(self.app)
|
||||
http_server.listen(self.options.wport)
|
||||
|
||||
tornado.ioloop.PeriodicCallback(self.tick, 5).start()
|
||||
@ -82,6 +81,7 @@ class WebMaster(flow.FlowMaster):
|
||||
self.shutdown()
|
||||
|
||||
def handle_request(self, f):
|
||||
print f
|
||||
flow.FlowMaster.handle_request(self, f)
|
||||
if f:
|
||||
f.reply()
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
import os.path
|
||||
import tornado.web
|
||||
import tornado.websocket
|
||||
import logging
|
||||
|
||||
|
||||
class IndexHandler(tornado.web.RequestHandler):
|
||||
@ -8,10 +9,29 @@ class IndexHandler(tornado.web.RequestHandler):
|
||||
self.render("index.html")
|
||||
|
||||
|
||||
class ClientConnection(tornado.websocket.WebSocketHandler):
|
||||
connections = set()
|
||||
|
||||
def open(self):
|
||||
ClientConnection.connections.add(self)
|
||||
|
||||
def on_close(self):
|
||||
ClientConnection.connections.remove(self)
|
||||
|
||||
@classmethod
|
||||
def broadcast(cls, type, data):
|
||||
for conn in cls.connections:
|
||||
try:
|
||||
conn.write_message(type, data)
|
||||
except:
|
||||
logging.error("Error sending message", exc_info=True)
|
||||
|
||||
|
||||
class Application(tornado.web.Application):
|
||||
def __init__(self, debug):
|
||||
handlers = [
|
||||
(r"/", IndexHandler),
|
||||
(r"/updates", ClientConnection),
|
||||
]
|
||||
settings = dict(
|
||||
template_path=os.path.join(os.path.dirname(__file__), "templates"),
|
||||
|
@ -198,17 +198,14 @@ _.extend(_EventLogStore.prototype, EventEmitter.prototype, {
|
||||
var EventLogStore = new _EventLogStore();
|
||||
AppDispatcher.register(EventLogStore.handle.bind(EventLogStore));
|
||||
|
||||
function _Connection(root) {"use strict";
|
||||
if (!root) {
|
||||
root = location.origin + "/api/v1";
|
||||
}
|
||||
this.root = root;
|
||||
}
|
||||
_Connection.prototype.init=function() {"use strict";
|
||||
function _Connection(url) {
|
||||
this.url = url;
|
||||
}
|
||||
_Connection.prototype.init=function() {
|
||||
this.openWebSocketConnection();
|
||||
};
|
||||
_Connection.prototype.openWebSocketConnection=function() {"use strict";
|
||||
this.ws = new WebSocket(this.root.replace("http", "ws") + "/ws");
|
||||
_Connection.prototype.openWebSocketConnection=function() {
|
||||
this.ws = new WebSocket(this.url.replace("http", "ws"));
|
||||
var ws = this.ws;
|
||||
|
||||
ws.onopen = this.onopen.bind(this);
|
||||
@ -216,21 +213,21 @@ _Connection.prototype.openWebSocketConnection=function() {"use strict";
|
||||
ws.onerror = this.onerror.bind(this);
|
||||
ws.onclose = this.onclose.bind(this);
|
||||
};
|
||||
_Connection.prototype.onopen=function(open) {"use strict";
|
||||
_Connection.prototype.onopen=function(open) {
|
||||
console.log("onopen", this, arguments);
|
||||
};
|
||||
_Connection.prototype.onmessage=function(message) {"use strict";
|
||||
_Connection.prototype.onmessage=function(message) {
|
||||
//AppDispatcher.dispatchServerAction(...);
|
||||
console.log("onmessage", this, arguments);
|
||||
};
|
||||
_Connection.prototype.onerror=function(error) {"use strict";
|
||||
_Connection.prototype.onerror=function(error) {
|
||||
console.log("onerror", this, arguments);
|
||||
};
|
||||
_Connection.prototype.onclose=function(close) {"use strict";
|
||||
_Connection.prototype.onclose=function(close) {
|
||||
console.log("onclose", this, arguments);
|
||||
};
|
||||
|
||||
var Connection = new _Connection();
|
||||
var Connection = new _Connection(location.origin + "/updates");
|
||||
|
||||
/** @jsx React.DOM */
|
||||
|
||||
|
@ -1,14 +1,11 @@
|
||||
function _Connection(root) {"use strict";
|
||||
if (!root) {
|
||||
root = location.origin + "/api/v1";
|
||||
}
|
||||
this.root = root;
|
||||
}
|
||||
_Connection.prototype.init=function() {"use strict";
|
||||
function _Connection(url) {
|
||||
this.url = url;
|
||||
}
|
||||
_Connection.prototype.init=function() {
|
||||
this.openWebSocketConnection();
|
||||
};
|
||||
_Connection.prototype.openWebSocketConnection=function() {"use strict";
|
||||
this.ws = new WebSocket(this.root.replace("http", "ws") + "/ws");
|
||||
_Connection.prototype.openWebSocketConnection=function() {
|
||||
this.ws = new WebSocket(this.url.replace("http", "ws"));
|
||||
var ws = this.ws;
|
||||
|
||||
ws.onopen = this.onopen.bind(this);
|
||||
@ -16,18 +13,18 @@ _Connection.prototype.openWebSocketConnection=function() {"use strict";
|
||||
ws.onerror = this.onerror.bind(this);
|
||||
ws.onclose = this.onclose.bind(this);
|
||||
};
|
||||
_Connection.prototype.onopen=function(open) {"use strict";
|
||||
_Connection.prototype.onopen=function(open) {
|
||||
console.log("onopen", this, arguments);
|
||||
};
|
||||
_Connection.prototype.onmessage=function(message) {"use strict";
|
||||
_Connection.prototype.onmessage=function(message) {
|
||||
//AppDispatcher.dispatchServerAction(...);
|
||||
console.log("onmessage", this, arguments);
|
||||
};
|
||||
_Connection.prototype.onerror=function(error) {"use strict";
|
||||
_Connection.prototype.onerror=function(error) {
|
||||
console.log("onerror", this, arguments);
|
||||
};
|
||||
_Connection.prototype.onclose=function(close) {"use strict";
|
||||
_Connection.prototype.onclose=function(close) {
|
||||
console.log("onclose", this, arguments);
|
||||
};
|
||||
|
||||
var Connection = new _Connection();
|
||||
var Connection = new _Connection(location.origin + "/updates");
|
||||
|
Loading…
Reference in New Issue
Block a user