From ca74ec3c774345bccc0e4e90fe6c231ce598663c Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sun, 19 Apr 2020 16:44:52 +0200 Subject: json contentview: minor improvements --- mitmproxy/contentviews/json.py | 62 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'mitmproxy') diff --git a/mitmproxy/contentviews/json.py b/mitmproxy/contentviews/json.py index dbe600aa..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 - return p + 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): @@ -21,30 +44,7 @@ class ViewJSON(base.View): "application/vnd.api+json" ] - @staticmethod - def _format(pj): - li = [] - for chunk in json.JSONEncoder(indent=4, sort_keys=True, ensure_ascii=False).iterencode(pj): - k = re.split("\\n", chunk) - if(len(k) > 1): - if(len(k[0]) > 0): - li.append(('text', k[0])) - yield li - li = [] - chunk = k[1] - else: - chunk = k[0] - if(re.match('^\s*\".*\"$', chunk)): - li.append(('json_string', chunk)) - elif(re.match('\s*[0-9]+[.]{0,1}[0-9]*', chunk)): - li.append(('json_number', chunk)) - elif(re.match('\s*true|null|false', chunk)): - li.append(('json_boolean', chunk)) - else: - li.append(('text', chunk)) - yield li - def __call__(self, data, **metadata): - pj = pretty_json(data) - if pj is not None: - return "JSON", self._format(pj) + data = parse_json(data) + if data is not PARSE_ERROR: + return "JSON", format_json(data) -- cgit v1.2.3