Indentation, style, whitespace

This commit is contained in:
Aldo Cortesi 2015-03-13 23:14:37 +11:00
parent 60dce08d54
commit a4f500c82e
4 changed files with 128 additions and 40 deletions

View File

@ -1,7 +1,9 @@
from __future__ import absolute_import from __future__ import absolute_import
import urwid import urwid
import urwid.util import urwid.util
import os import os
from .. import utils from .. import utils
from ..protocol.http import CONTENT_MISSING, decoded from ..protocol.http import CONTENT_MISSING, decoded
@ -284,15 +286,16 @@ def ask_copy_part(scope, flow, master, state):
def ask_save_body(part, master, state, flow): def ask_save_body(part, master, state, flow):
""" """
Save either the request or the response body to disk. Save either the request or the response body to disk. part can either be
part can either be "q" (request), "s" (response) or None (ask user if necessary). "q" (request), "s" (response) or None (ask user if necessary).
""" """
request_has_content = flow.request and flow.request.content request_has_content = flow.request and flow.request.content
response_has_content = flow.response and flow.response.content response_has_content = flow.response and flow.response.content
if part is None: 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: if request_has_content and response_has_content:
master.prompt_onekey( master.prompt_onekey(
"Save", "Save",
@ -311,9 +314,19 @@ def ask_save_body(part, master, state, flow):
ask_save_body("q", master, state, flow) ask_save_body("q", master, state, flow)
elif part == "q" and request_has_content: 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: 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: else:
master.statusbar.message("No content to save.") master.statusbar.message("No content to save.")

View File

@ -1,14 +1,23 @@
from __future__ import absolute_import from __future__ import absolute_import
import logging, subprocess, re, cStringIO, traceback, json, urwid import cStringIO
import json
import logging
import lxml.html
import lxml.etree
from PIL import Image from PIL import Image
from PIL.ExifTags import TAGS from PIL.ExifTags import TAGS
import re
import subprocess
import traceback
import urwid
import lxml.html, lxml.etree
import netlib.utils import netlib.utils
from . import common from . import common
from .. import utils, encoding, flow from .. import utils, encoding, flow
from ..contrib import jsbeautifier, html2text from ..contrib import jsbeautifier, html2text
from ..contrib.wbxml.ASCommandResponse import ASCommandResponse from ..contrib.wbxml.ASCommandResponse import ASCommandResponse
try: try:
import pyamf import pyamf
from pyamf import remoting, flex from pyamf import remoting, flex
@ -62,6 +71,7 @@ class ViewAuto:
name = "Auto" name = "Auto"
prompt = ("auto", "a") prompt = ("auto", "a")
content_types = [] content_types = []
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
ctype = hdrs.get_first("content-type") ctype = hdrs.get_first("content-type")
if ctype: if ctype:
@ -78,6 +88,7 @@ class ViewRaw:
name = "Raw" name = "Raw"
prompt = ("raw", "r") prompt = ("raw", "r")
content_types = [] content_types = []
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
txt = _view_text(content[:limit], len(content), limit) txt = _view_text(content[:limit], len(content), limit)
return "Raw", txt return "Raw", txt
@ -87,6 +98,7 @@ class ViewHex:
name = "Hex" name = "Hex"
prompt = ("hex", "e") prompt = ("hex", "e")
content_types = [] content_types = []
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
txt = [] txt = []
for offset, hexa, s in netlib.utils.hexdump(content[:limit]): for offset, hexa, s in netlib.utils.hexdump(content[:limit]):
@ -105,8 +117,14 @@ class ViewXML:
name = "XML" name = "XML"
prompt = ("xml", "x") prompt = ("xml", "x")
content_types = ["text/xml"] content_types = ["text/xml"]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
parser = lxml.etree.XMLParser(remove_blank_text=True, resolve_entities=False, strip_cdata=False, recover=False) parser = lxml.etree.XMLParser(
remove_blank_text=True,
resolve_entities=False,
strip_cdata=False,
recover=False
)
try: try:
document = lxml.etree.fromstring(content, parser) document = lxml.etree.fromstring(content, parser)
except lxml.etree.XMLSyntaxError: except lxml.etree.XMLSyntaxError:
@ -121,7 +139,7 @@ class ViewXML:
lxml.etree.tostring(p) lxml.etree.tostring(p)
) )
p = p.getprevious() p = p.getprevious()
doctype=docinfo.doctype doctype = docinfo.doctype
if prev: if prev:
doctype += "\n".join(prev).strip() doctype += "\n".join(prev).strip()
doctype = doctype.strip() doctype = doctype.strip()
@ -147,6 +165,7 @@ class ViewJSON:
name = "JSON" name = "JSON"
prompt = ("json", "s") prompt = ("json", "s")
content_types = ["application/json"] content_types = ["application/json"]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
lines = utils.pretty_json(content) lines = utils.pretty_json(content)
if lines: if lines:
@ -167,12 +186,20 @@ class ViewHTML:
name = "HTML" name = "HTML"
prompt = ("html", "h") prompt = ("html", "h")
content_types = ["text/html"] content_types = ["text/html"]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
if utils.isXML(content): if utils.isXML(content):
parser = lxml.etree.HTMLParser(strip_cdata=True, remove_blank_text=True) parser = lxml.etree.HTMLParser(
strip_cdata=True,
remove_blank_text=True
)
d = lxml.html.fromstring(content, parser=parser) d = lxml.html.fromstring(content, parser=parser)
docinfo = d.getroottree().docinfo docinfo = d.getroottree().docinfo
s = lxml.etree.tostring(d, pretty_print=True, doctype=docinfo.doctype) s = lxml.etree.tostring(
d,
pretty_print=True,
doctype=docinfo.doctype
)
return "HTML", _view_text(s[:limit], len(s), limit) return "HTML", _view_text(s[:limit], len(s), limit)
@ -180,6 +207,7 @@ class ViewHTMLOutline:
name = "HTML Outline" name = "HTML Outline"
prompt = ("html outline", "o") prompt = ("html outline", "o")
content_types = ["text/html"] content_types = ["text/html"]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
content = content.decode("utf-8") content = content.decode("utf-8")
h = html2text.HTML2Text(baseurl="") h = html2text.HTML2Text(baseurl="")
@ -194,6 +222,7 @@ class ViewURLEncoded:
name = "URL-encoded" name = "URL-encoded"
prompt = ("urlencoded", "u") prompt = ("urlencoded", "u")
content_types = ["application/x-www-form-urlencoded"] content_types = ["application/x-www-form-urlencoded"]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
lines = utils.urldecode(content) lines = utils.urldecode(content)
if lines: if lines:
@ -209,6 +238,7 @@ class ViewMultipart:
name = "Multipart Form" name = "Multipart Form"
prompt = ("multipart", "m") prompt = ("multipart", "m")
content_types = ["multipart/form-data"] content_types = ["multipart/form-data"]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
v = hdrs.get_first("content-type") v = hdrs.get_first("content-type")
if v: if v:
@ -322,12 +352,14 @@ class ViewJavaScript:
"application/javascript", "application/javascript",
"text/javascript" "text/javascript"
] ]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
opts = jsbeautifier.default_options() opts = jsbeautifier.default_options()
opts.indent_size = 2 opts.indent_size = 2
res = jsbeautifier.beautify(content[:limit], opts) res = jsbeautifier.beautify(content[:limit], opts)
return "JavaScript", _view_text(res, len(res), limit) return "JavaScript", _view_text(res, len(res), limit)
class ViewCSS: class ViewCSS:
name = "CSS" name = "CSS"
prompt = ("css", "c") prompt = ("css", "c")
@ -355,6 +387,7 @@ class ViewImage:
"image/vnd.microsoft.icon", "image/vnd.microsoft.icon",
"image/x-icon", "image/x-icon",
] ]
def __call__(self, hdrs, content, limit): def __call__(self, hdrs, content, limit):
try: try:
img = Image.open(cStringIO.StringIO(content)) img = Image.open(cStringIO.StringIO(content))
@ -380,7 +413,9 @@ class ViewImage:
) )
clean = [] clean = []
for i in parts: for i in parts:
clean.append([netlib.utils.cleanBin(i[0]), netlib.utils.cleanBin(i[1])]) clean.append(
[netlib.utils.cleanBin(i[0]), netlib.utils.cleanBin(i[1])]
)
fmt = common.format_keyvals( fmt = common.format_keyvals(
clean, clean,
key = "header", key = "header",
@ -388,6 +423,7 @@ class ViewImage:
) )
return "%s image"%img.format, fmt return "%s image"%img.format, fmt
class ViewProtobuf: class ViewProtobuf:
"""Human friendly view of protocol buffers """Human friendly view of protocol buffers
The view uses the protoc compiler to decode the binary The view uses the protoc compiler to decode the binary
@ -403,7 +439,10 @@ class ViewProtobuf:
@staticmethod @staticmethod
def is_available(): def is_available():
try: try:
p = subprocess.Popen(["protoc", "--version"], stdout=subprocess.PIPE) p = subprocess.Popen(
["protoc", "--version"],
stdout=subprocess.PIPE
)
out, _ = p.communicate() out, _ = p.communicate()
return out.startswith("libprotoc") return out.startswith("libprotoc")
except: except:
@ -427,6 +466,7 @@ class ViewProtobuf:
txt = _view_text(decoded[:limit], len(decoded), limit) txt = _view_text(decoded[:limit], len(decoded), limit)
return "Protobuf", txt return "Protobuf", txt
class ViewWBXML: class ViewWBXML:
name = "WBXML" name = "WBXML"
prompt = ("wbxml", "w") prompt = ("wbxml", "w")

View File

@ -1,6 +1,10 @@
from __future__ import absolute_import from __future__ import absolute_import
import copy, re, os
import copy
import re
import os
import urwid import urwid
from . import common from . import common
from .. import utils, filt, script from .. import utils, filt, script
from netlib import http_uastrings from netlib import http_uastrings
@ -121,7 +125,9 @@ class GridWalker(urwid.ListWalker):
try: try:
val = val.decode("string-escape") val = val.decode("string-escape")
except ValueError: except ValueError:
self.editor.master.statusbar.message("Invalid Python-style string encoding.", 1000) self.editor.master.statusbar.message(
"Invalid Python-style string encoding.", 1000
)
return return
errors = self.lst[self.focus][1] errors = self.lst[self.focus][1]
emsg = self.editor.is_error(self.focus_col, val) emsg = self.editor.is_error(self.focus_col, val)
@ -155,7 +161,9 @@ class GridWalker(urwid.ListWalker):
def start_edit(self): def start_edit(self):
if self.lst: if self.lst:
self.editing = GridRow(self.focus_col, True, self.editor, self.lst[self.focus]) self.editing = GridRow(
self.focus_col, True, self.editor, self.lst[self.focus]
)
self.editor.master.statusbar.update(footer_editing) self.editor.master.statusbar.update(footer_editing)
self._modified() self._modified()
@ -187,7 +195,12 @@ class GridWalker(urwid.ListWalker):
if self.editing: if self.editing:
return self.editing, self.focus return self.editing, self.focus
elif self.lst: elif self.lst:
return GridRow(self.focus_col, False, self.editor, self.lst[self.focus]), self.focus return GridRow(
self.focus_col,
False,
self.editor,
self.lst[self.focus]
), self.focus
else: else:
return None, None return None, None
@ -213,10 +226,13 @@ class GridListBox(urwid.ListBox):
FIRST_WIDTH_MAX = 40 FIRST_WIDTH_MAX = 40
FIRST_WIDTH_MIN = 20 FIRST_WIDTH_MIN = 20
class GridEditor(urwid.WidgetWrap): class GridEditor(urwid.WidgetWrap):
title = None title = None
columns = None columns = None
headings = None headings = None
def __init__(self, master, value, callback, *cb_args, **cb_kwargs): def __init__(self, master, value, callback, *cb_args, **cb_kwargs):
value = copy.deepcopy(value) value = copy.deepcopy(value)
self.master, self.value, self.callback = master, value, callback self.master, self.value, self.callback = master, value, callback
@ -325,7 +341,9 @@ class GridEditor(urwid.WidgetWrap):
self.master.path_prompt("Read file: ", "", self.read_file) self.master.path_prompt("Read file: ", "", self.read_file)
elif key == "R": elif key == "R":
if self.walker.get_current_value() is not None: if self.walker.get_current_value() is not None:
self.master.path_prompt("Read unescaped file: ", "", self.read_file, True) self.master.path_prompt(
"Read unescaped file: ", "", self.read_file, True
)
elif key == "e": elif key == "e":
o = self.walker.get_current_value() o = self.walker.get_current_value()
if o is not None: if o is not None:
@ -362,7 +380,9 @@ class GridEditor(urwid.WidgetWrap):
("tab", "next field"), ("tab", "next field"),
("enter", "edit field"), ("enter", "edit field"),
] ]
text.extend(common.format_keyvals(keys, key="key", val="text", indent=4)) text.extend(
common.format_keyvals(keys, key="key", val="text", indent=4)
)
text.append( text.append(
urwid.Text( urwid.Text(
[ [
@ -384,6 +404,7 @@ class HeaderEditor(GridEditor):
title = "Editing headers" title = "Editing headers"
columns = 2 columns = 2
headings = ("Key", "Value") headings = ("Key", "Value")
def make_help(self): def make_help(self):
h = GridEditor.make_help(self) h = GridEditor.make_help(self)
text = [] text = []
@ -391,7 +412,9 @@ class HeaderEditor(GridEditor):
keys = [ keys = [
("U", "add User-Agent header"), ("U", "add User-Agent header"),
] ]
text.extend(common.format_keyvals(keys, key="key", val="text", indent=4)) text.extend(
common.format_keyvals(keys, key="key", val="text", indent=4)
)
text.append(urwid.Text([("text", "\n")])) text.append(urwid.Text([("text", "\n")]))
text.extend(h) text.extend(h)
return text return text
@ -426,6 +449,7 @@ class ReplaceEditor(GridEditor):
title = "Editing replacement patterns" title = "Editing replacement patterns"
columns = 3 columns = 3
headings = ("Filter", "Regex", "Replacement") headings = ("Filter", "Regex", "Replacement")
def is_error(self, col, val): def is_error(self, col, val):
if col == 0: if col == 0:
if not filt.parse(val): if not filt.parse(val):
@ -442,6 +466,7 @@ class SetHeadersEditor(GridEditor):
title = "Editing header set patterns" title = "Editing header set patterns"
columns = 3 columns = 3
headings = ("Filter", "Header", "Value") headings = ("Filter", "Header", "Value")
def is_error(self, col, val): def is_error(self, col, val):
if col == 0: if col == 0:
if not filt.parse(val): if not filt.parse(val):
@ -455,7 +480,9 @@ class SetHeadersEditor(GridEditor):
keys = [ keys = [
("U", "add User-Agent header"), ("U", "add User-Agent header"),
] ]
text.extend(common.format_keyvals(keys, key="key", val="text", indent=4)) text.extend(
common.format_keyvals(keys, key="key", val="text", indent=4)
)
text.append(urwid.Text([("text", "\n")])) text.append(urwid.Text([("text", "\n")]))
text.extend(h) text.extend(h)
return text return text
@ -491,6 +518,7 @@ class ScriptEditor(GridEditor):
title = "Editing scripts" title = "Editing scripts"
columns = 1 columns = 1
headings = ("Command",) headings = ("Command",)
def is_error(self, col, val): def is_error(self, col, val):
try: try:
script.Script.parse_command(val) script.Script.parse_command(val)

View File

@ -1,5 +1,7 @@
from __future__ import absolute_import from __future__ import absolute_import
import urwid import urwid
from . import common from . import common
from .. import filt, version from .. import filt, version
@ -8,6 +10,7 @@ footer = [
('heading_key', "q"), ":back ", ('heading_key', "q"), ":back ",
] ]
class HelpView(urwid.ListBox): class HelpView(urwid.ListBox):
def __init__(self, master, help_context, state): def __init__(self, master, help_context, state):
self.master, self.state = master, state self.master, self.state = master, state
@ -122,7 +125,9 @@ class HelpView(urwid.ListBox):
("T", "set tcp proxying pattern"), ("T", "set tcp proxying pattern"),
("u", "set sticky auth expression"), ("u", "set sticky auth expression"),
] ]
text.extend(common.format_keyvals(keys, key="key", val="text", indent=4)) text.extend(
common.format_keyvals(keys, key="key", val="text", indent=4)
)
text.append(urwid.Text([("head", "\n\nFilter expressions:\n")])) text.append(urwid.Text([("head", "\n\nFilter expressions:\n")]))
f = [] f = []
@ -167,7 +172,9 @@ class HelpView(urwid.ListBox):
("~q ~b test", "Requests where body contains \"test\""), ("~q ~b test", "Requests where body contains \"test\""),
("!(~q & ~t \"text/html\")", "Anything but requests with a text/html content type."), ("!(~q & ~t \"text/html\")", "Anything but requests with a text/html content type."),
] ]
text.extend(common.format_keyvals(examples, key="key", val="text", indent=4)) text.extend(
common.format_keyvals(examples, key="key", val="text", indent=4)
)
return text return text
def keypress(self, size, key): def keypress(self, size, key):