aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/contentviews/json.py
blob: dbe600aa21d39cca776383b6518ff3b2443c012a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import re
import json
from typing import Optional

from mitmproxy.contentviews import base


def pretty_json(s: bytes) -> Optional[bytes]:
    try:
        p = json.loads(s.decode('utf-8'))
    except ValueError:
        return None
    return p


class ViewJSON(base.View):
    name = "JSON"
    content_types = [
        "application/json",
        "application/json-rpc",
        "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)