Как перехватить ответ сервера в контейнере mitmproxy и вставить его в файл в формате json? - PullRequest
0 голосов
/ 14 января 2020

Мне нужно перехватывать и заполнять отдельный файл каждый ответ, запрос, который проходит через мой контейнер mitmproxy.

Dockerfile

FROM mitmproxy/mitmproxy:latest

RUN mkdir url_catching
WORKDIR /home/$USER/url_catching
COPY ./url.py .



EXPOSE 8080:8080

ENTRYPOINT ["/usr/bin/mitmdump","-s","./url.py"]

Docker run

sudo docker run --rm -it -p 8080:8080 mitmdump_url:latest

Мой скрипт Pyhton (извините, я новичок в python)

from mitmproxy import http

def response(flow):
    url_request: str = str(flow.request.pretty_url)
    url_request = url_request.replace("/", "_")
    with open(url_request, "ab") as ofile:
        ofile.write(flow.request.pretty_url.encode())
        ofile.write(flow.request.content)
        ofile.write(flow.response.content)

  • в результате я получаю отдельные файлы для каждого запроса и имя его равно URL запроса, но только URL-адрес представлен в удобочитаемом формате, все остальное закодировано или просто пропущено. Так что мне нужно, чтобы прошлый ответ проходил через мой прокси в формате json к файлам.

1 Ответ

1 голос
/ 14 января 2020

request/responde имеет headers + empty line + body/content

Я показываю два метода преобразования headers в string / bytes.

Как обычно строки текста

for key, value in flow.response.headers.items():
    ofile.write('{}: {}\n'.format(key, value).encode())

Результат

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Encoding: gzip
Content-Type: application/json
Date: Tue, 14 Jan 2020 11:51:49 GMT
Referrer-Policy: no-referrer-when-downgrade
Server: nginx
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Length: 181
Connection: keep-alive

Как JSON. Я конвертирую в dict(), потому что заголовки нельзя напрямую конвертировать в JSON

d = dict(flow.request.headers.items())
d = json.dumps(d, indents=2)
ofile.write(d.encode() + b'\n')

Результат

{
  "Host": "httpbin.org",
  "User-Agent": "python-requests/2.22.0",
  "Accept-Encoding": "gzip, deflate",
  "Accept": "*/*",
  "Connection": "keep-alive"
}

Я также пропускаю URL с помощью '/ static /'

from mitmproxy import http
import json

def response(flow):
    url_request: str = str(flow.request.pretty_url)

    if '/static/' not in url_request:
        url_request = url_request.replace("/", "_")
        with open(url_request + '.txt', "ab") as ofile:

            ofile.write(b'--- url ---\n')
            ofile.write(flow.request.pretty_url.encode() + b'\n')

            ofile.write(b'--- request ---\n')

            ofile.write(b'--- headers ---\n')
            #for key, value in flow.request.headers.items():
            #    ofile.write('{}: {}\n'.format(key, value).encode())
            d = dict(flow.request.headers.items())
            d = json.dumps(d, indents=2)
            ofile.write(d.encode() + b'\n')


            ofile.write(b'--- content ---\n')
            ofile.write(flow.request.content + b'\n')

            ofile.write(b'--- response ---\n')

            ofile.write(b'--- headers ---\n')
            for key, value in flow.response.headers.items():
                ofile.write('{}: {}\n'.format(key, value).encode())

            ofile.write(b'--- content ---\n')
            ofile.write(flow.response.content + b'\n')

Чтобы поместить все в один JSON, вам нужно сначала создать словарь со всеми элементами (заголовки, тело и т. Д. c.) И затем использовать json.dumps(all_elements)


Тестовый код

import requests

proxy = {
    'http': 'http://localhost:8080',
    'https': 'http://localhost:8080',
}

urls = [
    'https://httpbin.org/get',
    'https://httpbin.org/gzip',
    'https://httpbin.org/brotli',
    'https://httpbin.org/deflate',
    'https://httpbin.org/encoding/utf8',
]

for url in urls:
    print(url)
    r = requests.get(url, proxies=proxy, verify=False)
    print(r.text)

Один файл с результатами

--- url ---
https://httpbin.org/get
--- request ---
--- headers ---
{
  "Host": "httpbin.org",
  "User-Agent": "python-requests/2.22.0",
  "Accept-Encoding": "gzip, deflate",
  "Accept": "*/*",
  "Connection": "keep-alive"
}
--- content ---

--- response ---
--- headers ---
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Encoding: gzip
Content-Type: application/json
Date: Tue, 14 Jan 2020 12:06:04 GMT
Referrer-Policy: no-referrer-when-downgrade
Server: nginx
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Length: 181
Connection: keep-alive
--- content ---
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.22.0"
  }, 
  "origin": "83.23.66.224, 83.23.66.224", 
  "url": "https://httpbin.org/get"
}
...