Skip to content

add an optional decompression for content-type: application/zlib #8283

Description

@d3cryptofc

Problem Description

I am using the transparent mode and I am receiving responses encoded with gzip (decoded normally), but the content type is also application/zlib.

Proposal

I propose to add an optional decompression for zlib content types. So, after decoded it, I will see an unformatted JSON too :v

Alternatives

1. Event Hooks (bad)

I created a addon script to decompress and spoof the content type to application/json to use the native JSON preview:

"""
mitmproxy -s zlib-hook.py
"""
import zlib

class DecodeZlib:
    def response(self, flow):
        if 'application/zlib' not in flow.response.headers.get('content-type', ''):
            return

        content = zlib.decompress(flow.response.content)

        if content and (chr(content[0]) in ('[', '{') and chr(content[-1]) in ('}', ']')):
            flow.response.headers['content-type'] = 'application/json'

        flow.response.content = content

addons = [DecodeZlib()]

It works very nice, but it modify the request data and by this side not seems so nice.

2. Custom Content View (should be good)
"""
mitmproxy -s zlib-and-json-cv.py
"""
import zlib
import json

from mitmproxy import contentviews


class ZlibAndJson(contentviews.Contentview):
    name = "zlib +? JSON"

    @staticmethod
    def _is_json_content(content: bytes) -> bool:
        if not content:
            return False

        starts_with_brackets = chr(content[0]) in ("[", "{")
        ends_with_brackets = chr(content[-1]) in ("}", "]")

        return starts_with_brackets and ends_with_brackets

    def prettify(self, data: bytes, metadata: contentviews.Metadata) -> str:
        data = zlib.decompress(data)

        if self._is_json_content(data):
            return json.dumps(json.loads(data), indent=2)
            
        return data.decode()

    def render_priority(self, data: bytes, metadata: contentviews.Metadata) -> float:
        if not metadata.content_type:
            return 0.0

        if "application/zlib" not in metadata.content_type:
            return 0.0

        return 2.0


contentviews.add(ZlibAndJson)

Problems:

  1. syntax_highlight property cannot be dynamic based on the content, like:
@property
def syntax_highlight(self) -> SyntaxHighlight:
  data = ???
  return "yaml" if self._is_json_content(data) else "none"

Additional context

Image

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/featureNew features / enhancements

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions