diff options
Diffstat (limited to 'mitmproxy')
-rw-r--r-- | mitmproxy/contentviews/json.py | 41 | ||||
-rw-r--r-- | mitmproxy/tools/console/palettes.py | 23 |
2 files changed, 55 insertions, 9 deletions
diff --git a/mitmproxy/contentviews/json.py b/mitmproxy/contentviews/json.py index 15c624ad..a5a7d03b 100644 --- a/mitmproxy/contentviews/json.py +++ b/mitmproxy/contentviews/json.py @@ -1,16 +1,39 @@ +import re import json -from typing import Optional + +import typing from mitmproxy.contentviews import base +PARSE_ERROR = object() + -def pretty_json(s: bytes) -> Optional[bytes]: +def parse_json(s: bytes) -> typing.Any: try: - p = json.loads(s.decode('utf-8')) + return json.loads(s.decode('utf-8')) except ValueError: - return None - pretty = json.dumps(p, sort_keys=True, indent=4, ensure_ascii=False) - return pretty.encode("utf8", "strict") + return PARSE_ERROR + + +def format_json(data: typing.Any) -> typing.Iterator[base.TViewLine]: + encoder = json.JSONEncoder(indent=4, sort_keys=True, ensure_ascii=False) + current_line: base.TViewLine = [] + for chunk in encoder.iterencode(data): + if "\n" in chunk: + rest_of_last_line, chunk = chunk.split("\n", maxsplit=1) + # rest_of_last_line is a delimiter such as , or [ + current_line.append(('text', rest_of_last_line)) + yield current_line + current_line = [] + if re.match(r'\s*"', chunk): + current_line.append(('json_string', chunk)) + elif re.match(r'\s*\d', chunk): + current_line.append(('json_number', chunk)) + elif re.match(r'\s*(true|null|false)', chunk): + current_line.append(('json_boolean', chunk)) + else: + current_line.append(('text', chunk)) + yield current_line class ViewJSON(base.View): @@ -22,6 +45,6 @@ class ViewJSON(base.View): ] def __call__(self, data, **metadata): - pj = pretty_json(data) - if pj: - return "JSON", base.format_text(pj) + data = parse_json(data) + if data is not PARSE_ERROR: + return "JSON", format_json(data) diff --git a/mitmproxy/tools/console/palettes.py b/mitmproxy/tools/console/palettes.py index 0a1dd8df..a680a5a7 100644 --- a/mitmproxy/tools/console/palettes.py +++ b/mitmproxy/tools/console/palettes.py @@ -34,6 +34,9 @@ class Palette: # Hex view 'offset', + # JSON view + 'json_string', 'json_number', 'json_boolean', + # Grid Editor 'focusfield', 'focusfield_error', 'field_error', 'editfield', @@ -169,6 +172,11 @@ class LowDark(Palette): # Hex view offset = ('dark cyan', 'default'), + # JSON view + json_string = ('dark blue', 'default'), + json_number = ('light magenta', 'default'), + json_boolean = ('dark magenta', 'default'), + # Grid Editor focusfield = ('black', 'light gray'), focusfield_error = ('dark red', 'light gray'), @@ -269,6 +277,11 @@ class LowLight(Palette): # Hex view offset = ('dark blue', 'default'), + # JSON view + json_string = ('dark blue', 'default'), + json_number = ('light magenta', 'default'), + json_boolean = ('dark magenta', 'default'), + # Grid Editor focusfield = ('black', 'light gray'), focusfield_error = ('dark red', 'light gray'), @@ -379,6 +392,11 @@ class SolarizedLight(LowLight): # Hex view offset = (sol_cyan, 'default'), + # JSON view + json_string = (sol_cyan, 'default'), + json_number = (sol_blue, 'default'), + json_boolean = (sol_magenta, 'default'), + # Grid Editor focusfield = (sol_base00, sol_base2), focusfield_error = (sol_red, sol_base2), @@ -452,6 +470,11 @@ class SolarizedDark(LowDark): # Hex view offset = (sol_cyan, 'default'), + # JSON view + json_string = (sol_cyan, 'default'), + json_number = (sol_blue, 'default'), + json_boolean = (sol_magenta, 'default'), + # Grid Editor focusfield = (sol_base0, sol_base02), focusfield_error = (sol_red, sol_base02), |