All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scripts.proxy.py Maven / Gradle / Ivy

Go to download

A bridge between Python's mitmproxy and Java programs. Built on top of mitmproxy-node

There is a newer version: 2.0.2
Show newest version
#!/usr/bin/env python3
"""
Interception proxy using mitmproxy (https://mitmproxy.org).
Communicates to NodeJS via websockets.
"""

import argparse
import asyncio
import queue
import json
import threading
import typing
import traceback
import sys
import struct
import websockets
from mitmproxy import ctx
from mitmproxy import http

def convert_headers_to_bytes(header_entry):
    """
    Converts a tuple of strings into a tuple of bytes.
    """
    return [bytes(header_entry[0], "utf8"), bytes(header_entry[1], "utf8")]

def convert_body_to_bytes(body):
    """
    Converts a HTTP request/response body into a list of numbers.
    """
    if body is None:
        return bytes()
    else:
        return body

def is_text_response(headers):
    if 'content-type' in headers:
        ct = headers['content-type'].lower()
        # Allow all application/ and text/ MIME types.
        return 'application' in ct or 'text' in ct or ct.strip() == ""
    return True

class WebSocketAdapter:
    """
    Relays HTTP/HTTPS requests to a websocket server.
    Enables using MITMProxy from outside of Python.
    """

    def websocket_thread(self):
        """
        Main function of the websocket thread. Runs the websocket event loop
        until MITMProxy shuts down.
        """
        self.worker_event_loop = asyncio.new_event_loop()
        self.worker_event_loop.run_until_complete(self.websocket_loop())

    def __init__(self):
        self.queue = queue.Queue()
        self.intercept_paths = frozenset([])
        self.only_intercept_text_files = False
        self.finished = False
        # Start websocket thread
        threading.Thread(target=self.websocket_thread).start()

    def load(self, loader):
        loader.add_option(
            "intercept", str, "",
            """
            A list of HTTP paths, delimited by a comma, to intercept and pass to Node without hitting the server.
            E.g.: /foo,/bar
            """
        )
        loader.add_option(
            name = "onlyInterceptTextFiles",
            typespec = bool,
            default = False,
            help = "If true, the plugin only intercepts text files and passes through other types of files",
        )
        return

    def configure(self, updates):
        if "intercept" in updates:
            self.intercept_paths = frozenset(ctx.options.intercept.split(","))
            #print("Intercept paths:")
            #print(self.intercept_paths)
        if "onlyInterceptTextFiles" in updates:
            self.only_intercept_text_files = ctx.options.onlyInterceptTextFiles
            #print("Only intercept text files:")
            #print(self.only_intercept_text_files)
        return

    def send_message(self, metadata, data1, data2):
        """
        Sends the given message on the WebSocket connection,
        and awaits a response. Metadata is a JSONable object,
        and data is bytes.
        """
        metadata_bytes = bytes(json.dumps(metadata), 'utf8')
        data1_size = len(data1)
        data2_size = len(data2)
        metadata_size = len(metadata_bytes)

        msg = struct.pack("




© 2015 - 2024 Weber Informatics LLC | Privacy Policy