aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/console/common.py
diff options
context:
space:
mode:
Diffstat (limited to 'libmproxy/console/common.py')
-rw-r--r--libmproxy/console/common.py135
1 files changed, 60 insertions, 75 deletions
diff --git a/libmproxy/console/common.py b/libmproxy/console/common.py
index fa21c93e..bc8a2aad 100644
--- a/libmproxy/console/common.py
+++ b/libmproxy/console/common.py
@@ -1,18 +1,18 @@
from __future__ import absolute_import
+
import urwid
import urwid.util
import os
+
from .. import utils
from ..protocol.http import CONTENT_MISSING, decoded
+from . import signals
try:
import pyperclip
except:
pyperclip = False
-VIEW_LIST = 0
-VIEW_FLOW = 1
-
VIEW_FLOW_REQUEST = 0
VIEW_FLOW_RESPONSE = 1
@@ -29,6 +29,14 @@ METHOD_OPTIONS = [
]
+def is_keypress(k):
+ """
+ Is this input event a keypress?
+ """
+ if isinstance(k, basestring):
+ return True
+
+
def highlight_key(s, k):
l = []
parts = s.split(k, 1)
@@ -41,6 +49,8 @@ def highlight_key(s, k):
KEY_MAX = 30
+
+
def format_keyvals(lst, key="key", val="text", indent=0):
"""
Format a list of (key, value) tuples.
@@ -103,10 +113,8 @@ else:
SYMBOL_RETURN = u"<-"
-
def raw_format_flow(f, focus, extended, padding):
f = dict(f)
-
pile = []
req = []
if extended:
@@ -122,7 +130,7 @@ def raw_format_flow(f, focus, extended, padding):
req.append(fcol(SYMBOL_REPLAY, "replay"))
req.append(fcol(f["req_method"], "method"))
- preamble = sum(i[1] for i in req) + len(req) -1
+ preamble = sum(i[1] for i in req) + len(req) - 1
if f["intercepted"] and not f["acked"]:
uc = "intercept"
@@ -182,23 +190,19 @@ def raw_format_flow(f, focus, extended, padding):
def save_data(path, data, master, state):
if not path:
return
- state.last_saveload = path
path = os.path.expanduser(path)
try:
with file(path, "wb") as f:
f.write(data)
except IOError, v:
- master.statusbar.message(v.strerror)
+ signals.status_message.send(message=v.strerror)
def ask_save_path(prompt, data, master, state):
- master.path_prompt(
- prompt,
- state.last_saveload,
- save_data,
- data,
- master,
- state
+ signals.status_prompt_path.send(
+ prompt = prompt,
+ callback = save_data,
+ args = (data, master, state)
)
@@ -238,28 +242,27 @@ def copy_flow(part, scope, flow, master, state):
if not data:
if scope == "q":
- master.statusbar.message("No request content to copy.")
+ signals.status_message.send(message="No request content to copy.")
elif scope == "s":
- master.statusbar.message("No response content to copy.")
+ signals.status_message.send(message="No response content to copy.")
else:
- master.statusbar.message("No contents to copy.")
+ signals.status_message.send(message="No contents to copy.")
return
try:
master.add_event(str(len(data)))
pyperclip.copy(data)
- except RuntimeError:
+ except (RuntimeError, UnicodeDecodeError):
def save(k):
if k == "y":
- ask_save_path("Save data: ", data, master, state)
-
- master.prompt_onekey(
- "Cannot copy binary data to clipboard. Save as file?",
- (
+ ask_save_path("Save data", data, master, state)
+ signals.status_prompt_onekey.send(
+ prompt = "Cannot copy binary data to clipboard. Save as file?",
+ keys = (
("yes", "y"),
("no", "n"),
),
- save
+ callback = save
)
@@ -271,39 +274,35 @@ def ask_copy_part(scope, flow, master, state):
if scope != "s":
choices.append(("url", "u"))
- master.prompt_onekey(
- "Copy",
- choices,
- copy_flow,
- scope,
- flow,
- master,
- state
+ signals.status_prompt_onekey.send(
+ prompt = "Copy",
+ keys = choices,
+ callback = copy_flow,
+ args = (scope, flow, master, state)
)
def ask_save_body(part, master, state, flow):
"""
- Save either the request or the response body to disk.
- part can either be "q" (request), "s" (response) or None (ask user if necessary).
+ Save either the request or the response body to disk. part can either be
+ "q" (request), "s" (response) or None (ask user if necessary).
"""
request_has_content = flow.request and flow.request.content
response_has_content = flow.response and flow.response.content
if part is None:
- # We first need to determine whether we want to save the request or the response content.
+ # We first need to determine whether we want to save the request or the
+ # response content.
if request_has_content and response_has_content:
- master.prompt_onekey(
- "Save",
- (
+ signals.status_prompt_onekey.send(
+ prompt = "Save",
+ keys = (
("request", "q"),
("response", "s"),
),
- ask_save_body,
- master,
- state,
- flow
+ callback = ask_save_body,
+ args = (master, state, flow)
)
elif response_has_content:
ask_save_body("s", master, state, flow)
@@ -311,18 +310,24 @@ def ask_save_body(part, master, state, flow):
ask_save_body("q", master, state, flow)
elif part == "q" and request_has_content:
- ask_save_path("Save request content: ", flow.request.get_decoded_content(), master, state)
+ ask_save_path(
+ "Save request content",
+ flow.request.get_decoded_content(),
+ master,
+ state
+ )
elif part == "s" and response_has_content:
- ask_save_path("Save response content: ", flow.response.get_decoded_content(), master, state)
+ ask_save_path(
+ "Save response content",
+ flow.response.get_decoded_content(),
+ master,
+ state
+ )
else:
- master.statusbar.message("No content to save.")
+ signals.status_message.send(message="No content to save.")
-class FlowCache:
- @utils.LRUCache(200)
- def format_flow(self, *args):
- return raw_format_flow(*args)
-flowcache = FlowCache()
+flowcache = utils.LRUCache(800)
def format_flow(f, focus, extended=False, hostheader=False, padding=2):
@@ -348,7 +353,6 @@ def format_flow(f, focus, extended=False, hostheader=False, padding=2):
duration = 0
if f.response.timestamp_end and f.request.timestamp_start:
duration = f.response.timestamp_end - f.request.timestamp_start
- size = f.response.size()
roundtrip = utils.pretty_duration(duration)
d.update(dict(
@@ -362,26 +366,7 @@ def format_flow(f, focus, extended=False, hostheader=False, padding=2):
d["resp_ctype"] = t[0].split(";")[0]
else:
d["resp_ctype"] = ""
- return flowcache.format_flow(tuple(sorted(d.items())), focus, extended, padding)
-
-
-def int_version(v):
- SIG = 3
- v = urwid.__version__.split("-")[0].split(".")
- x = 0
- for i in range(min(SIG, len(v))):
- x += int(v[i]) * 10**(SIG-i)
- return x
-
-
-# We have to do this to be portable over 0.9.8 and 0.9.9 If compatibility
-# becomes a pain to maintain, we'll just mandate 0.9.9 or newer.
-class WWrap(urwid.WidgetWrap):
- if int_version(urwid.__version__) >= 990:
- def set_w(self, x):
- self._w = x
- def get_w(self):
- return self._w
- w = property(get_w, set_w)
-
-
+ return flowcache.get(
+ raw_format_flow,
+ tuple(sorted(d.items())), focus, extended, padding
+ )