mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 10:16:27 +00:00
JSON pretty-printing.
Also rename the display modes ("pretty" instead of "indent"), and expand the built-in documentation.
This commit is contained in:
parent
46ec8f52e7
commit
18d4c3a9e9
@ -224,7 +224,7 @@ class ConnectionViewHeader(WWrap):
|
|||||||
|
|
||||||
VIEW_BODY_RAW = 0
|
VIEW_BODY_RAW = 0
|
||||||
VIEW_BODY_BINARY = 1
|
VIEW_BODY_BINARY = 1
|
||||||
VIEW_BODY_INDENT = 2
|
VIEW_BODY_PRETTY = 2
|
||||||
|
|
||||||
VIEW_FLOW_REQUEST = 0
|
VIEW_FLOW_REQUEST = 0
|
||||||
VIEW_FLOW_RESPONSE = 1
|
VIEW_FLOW_RESPONSE = 1
|
||||||
@ -418,8 +418,8 @@ class ConnectionView(WWrap):
|
|||||||
self.state.view_body_mode = VIEW_BODY_RAW
|
self.state.view_body_mode = VIEW_BODY_RAW
|
||||||
elif v == "h":
|
elif v == "h":
|
||||||
self.state.view_body_mode = VIEW_BODY_BINARY
|
self.state.view_body_mode = VIEW_BODY_BINARY
|
||||||
elif v == "i":
|
elif v == "p":
|
||||||
self.state.view_body_mode = VIEW_BODY_INDENT
|
self.state.view_body_mode = VIEW_BODY_PRETTY
|
||||||
self.master.refresh_connection(self.flow)
|
self.master.refresh_connection(self.flow)
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
@ -442,7 +442,7 @@ class ConnectionView(WWrap):
|
|||||||
"View",
|
"View",
|
||||||
(
|
(
|
||||||
("raw", "r"),
|
("raw", "r"),
|
||||||
("indent", "i"),
|
("pretty", "p"),
|
||||||
("hex", "h"),
|
("hex", "h"),
|
||||||
),
|
),
|
||||||
self._changeview
|
self._changeview
|
||||||
@ -881,8 +881,8 @@ class ConsoleMaster(flow.FlowMaster):
|
|||||||
self.spawn_external_viewer(serr, None)
|
self.spawn_external_viewer(serr, None)
|
||||||
self.refresh_connection(f)
|
self.refresh_connection(f)
|
||||||
|
|
||||||
def _trailer(self, content, txt):
|
def _trailer(self, clen, txt):
|
||||||
rem = len(content) - VIEW_CUTOFF
|
rem = clen - VIEW_CUTOFF
|
||||||
if rem > 0:
|
if rem > 0:
|
||||||
txt.append(urwid.Text(""))
|
txt.append(urwid.Text(""))
|
||||||
txt.append(
|
txt.append(
|
||||||
@ -893,12 +893,12 @@ class ConsoleMaster(flow.FlowMaster):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def _view_conn_normal(self, content, txt):
|
def _view_conn_raw(self, content, txt):
|
||||||
for i in content[:VIEW_CUTOFF].splitlines():
|
for i in utils.cleanBin(content[:VIEW_CUTOFF]).splitlines():
|
||||||
txt.append(
|
txt.append(
|
||||||
urwid.Text(("text", i))
|
urwid.Text(("text", i))
|
||||||
)
|
)
|
||||||
self._trailer(content, txt)
|
self._trailer(len(content), txt)
|
||||||
|
|
||||||
def _view_conn_binary(self, content, txt):
|
def _view_conn_binary(self, content, txt):
|
||||||
for offset, hex, s in utils.hexdump(content[:VIEW_CUTOFF]):
|
for offset, hex, s in utils.hexdump(content[:VIEW_CUTOFF]):
|
||||||
@ -909,14 +909,40 @@ class ConsoleMaster(flow.FlowMaster):
|
|||||||
" ",
|
" ",
|
||||||
("text", s),
|
("text", s),
|
||||||
]))
|
]))
|
||||||
self._trailer(content, txt)
|
self._trailer(len(content), txt)
|
||||||
|
|
||||||
def _view_conn_pretty(self, content, txt):
|
def _view_conn_xmlish(self, content, txt):
|
||||||
for i in utils.pretty_xmlish(content[:VIEW_CUTOFF]):
|
for i in utils.pretty_xmlish(content[:VIEW_CUTOFF]):
|
||||||
txt.append(
|
txt.append(
|
||||||
urwid.Text(("text", i)),
|
urwid.Text(("text", i)),
|
||||||
)
|
)
|
||||||
self._trailer(content, txt)
|
self._trailer(len(content), txt)
|
||||||
|
|
||||||
|
def _view_conn_json(self, lines, txt):
|
||||||
|
sofar = 0
|
||||||
|
for i in lines:
|
||||||
|
sofar += len(i)
|
||||||
|
txt.append(
|
||||||
|
urwid.Text(("text", i)),
|
||||||
|
)
|
||||||
|
if sofar > VIEW_CUTOFF:
|
||||||
|
break
|
||||||
|
self._trailer(sum(len(i) for i in lines), txt)
|
||||||
|
|
||||||
|
|
||||||
|
def _find_pretty_view(self, content, hdrItems, txt):
|
||||||
|
ctype = None
|
||||||
|
for i in hdrItems:
|
||||||
|
if i[0] == "content-type":
|
||||||
|
ctype = i[1]
|
||||||
|
break
|
||||||
|
if utils.isXML(content):
|
||||||
|
return self._view_conn_xmlish(content, txt)
|
||||||
|
if ctype and "application/json" in ctype:
|
||||||
|
lines = utils.pretty_json(content)
|
||||||
|
if lines:
|
||||||
|
return self._view_conn_json(lines, txt)
|
||||||
|
return self._view_conn_raw(content, txt)
|
||||||
|
|
||||||
@utils.LRUCache(20)
|
@utils.LRUCache(20)
|
||||||
def _cached_conn_text(self, content, hdrItems, viewmode):
|
def _cached_conn_text(self, content, hdrItems, viewmode):
|
||||||
@ -934,19 +960,10 @@ class ConsoleMaster(flow.FlowMaster):
|
|||||||
if content:
|
if content:
|
||||||
if viewmode == VIEW_BODY_BINARY:
|
if viewmode == VIEW_BODY_BINARY:
|
||||||
self._view_conn_binary(content, txt)
|
self._view_conn_binary(content, txt)
|
||||||
elif viewmode == VIEW_BODY_INDENT:
|
elif viewmode == VIEW_BODY_PRETTY:
|
||||||
if utils.isXML(content):
|
self._find_pretty_view(content, hdrItems, txt)
|
||||||
self._view_conn_pretty(content, txt)
|
|
||||||
else:
|
|
||||||
if utils.isBin(content):
|
|
||||||
self._view_conn_binary(content, txt)
|
|
||||||
else:
|
|
||||||
self._view_conn_normal(content, txt)
|
|
||||||
else:
|
else:
|
||||||
if utils.isBin(content):
|
self._view_conn_raw(content, txt)
|
||||||
self._view_conn_binary(content, txt)
|
|
||||||
else:
|
|
||||||
self._view_conn_normal(content, txt)
|
|
||||||
return urwid.ListBox(txt)
|
return urwid.ListBox(txt)
|
||||||
|
|
||||||
def _readflow(self, path):
|
def _readflow(self, path):
|
||||||
@ -1206,7 +1223,10 @@ class ConsoleMaster(flow.FlowMaster):
|
|||||||
keys = [
|
keys = [
|
||||||
("b", "save request/response body"),
|
("b", "save request/response body"),
|
||||||
("e", "edit request/response"),
|
("e", "edit request/response"),
|
||||||
("m", "change view mode (raw, indent, hex)"),
|
("m", "change view mode (raw, pretty, hex)"),
|
||||||
|
(None, " raw: raw data"),
|
||||||
|
(None, " pretty: pretty-print XML, HTML and JSON"),
|
||||||
|
(None, " hex: hex dump"),
|
||||||
("p", "previous flow"),
|
("p", "previous flow"),
|
||||||
("v", "view body in external viewer"),
|
("v", "view body in external viewer"),
|
||||||
("|", "run script"),
|
("|", "run script"),
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import re, os, subprocess, datetime, textwrap, errno, sys, time, functools
|
import re, os, subprocess, datetime, textwrap, errno, sys, time, functools
|
||||||
|
import json
|
||||||
|
|
||||||
CERT_SLEEP_TIME = 1
|
CERT_SLEEP_TIME = 1
|
||||||
|
|
||||||
@ -111,6 +112,14 @@ def pretty_xmlish(s):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_json(s):
|
||||||
|
try:
|
||||||
|
p = json.loads(s)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
return json.dumps(p, sort_keys=True, indent=4).split("\n")
|
||||||
|
|
||||||
|
|
||||||
def hexdump(s):
|
def hexdump(s):
|
||||||
"""
|
"""
|
||||||
Returns a set of typles:
|
Returns a set of typles:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import textwrap, cStringIO, os, time, re
|
import textwrap, cStringIO, os, time, re, json
|
||||||
import libpry
|
import libpry
|
||||||
from libmproxy import utils
|
from libmproxy import utils
|
||||||
|
|
||||||
@ -283,6 +283,13 @@ class upretty_xmlish(libpry.AutoTree):
|
|||||||
assert utils.pretty_xmlish(s) == ["gobbledygook"]
|
assert utils.pretty_xmlish(s) == ["gobbledygook"]
|
||||||
|
|
||||||
|
|
||||||
|
class upretty_json(libpry.AutoTree):
|
||||||
|
def test_one(self):
|
||||||
|
s = json.dumps({"foo": 1})
|
||||||
|
assert utils.pretty_json(s)
|
||||||
|
assert not utils.pretty_json("moo")
|
||||||
|
|
||||||
|
|
||||||
class udummy_ca(libpry.AutoTree):
|
class udummy_ca(libpry.AutoTree):
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
d = self.tmpdir()
|
d = self.tmpdir()
|
||||||
@ -368,6 +375,7 @@ tests = [
|
|||||||
uHeaders(),
|
uHeaders(),
|
||||||
uData(),
|
uData(),
|
||||||
upretty_xmlish(),
|
upretty_xmlish(),
|
||||||
|
upretty_json(),
|
||||||
udummy_ca(),
|
udummy_ca(),
|
||||||
udummy_cert(),
|
udummy_cert(),
|
||||||
uLRUCache(),
|
uLRUCache(),
|
||||||
|
Loading…
Reference in New Issue
Block a user