Используйте mitmproxy для обслуживания ответов с диска - PullRequest
0 голосов
/ 01 июля 2019

Я пытаюсь записать загрузку HLS на мой жесткий диск, а затем выполнить ту же загрузку HLS с моего жесткого диска.

Я пытаюсь сделать это с помощью дополнения Python, которое выглядит следующим образом.По сути, я пишу ответ в файл, если он соответствует моим критериям.Затем, если клиент запрашивает данные, которые уже сохранены, я считываю ответ с диска и обслуживаю его напрямую.

Это дополнение работает, как и ожидалось, в том смысле, что оно правильно сохраняет ответы, когда их нет на диске,и затем обслуживает их, когда они делают.

Когда я запускаю mitmproxy -s myaddon.py, потоки показывают, что они берут 0ms, чтобы служить с диска.Поэтому я ожидал, что загрузка будет происходить намного быстрее при обслуживании с диска.Но по какой-то причине это не так.

Чтобы выяснить, почему это происходит, я исследовал две возможности.

1), несмотря на перехват запроса / ответа и обслуживание с диска, запрос все еще выполняетсячерез Интернет, и mitmproxy ждет ответа, чтобы вернуться

2) чтение ответа с диска заняло сравнимое количество времени для извлечения его по сети

для 1) я проверилэто с помощью mitmproxy и прокси Чарльза вместе.Когда ответа не было на диске, я увидел сетевой трафик на Чарльзе.Когда ответ был на диске, я не видел трафика в Чарльзе, поэтому я исключил эту возможность.

Для 2) я проверил со временем стены, сколько времени потребовалось, чтобы прочитать ответ с диска, иэто было примерно ~ 0,0001 секунды, поэтому я тоже не думаю, что это была задержка.

Я пробовал это в двух разных сетях и чувствую, что маловероятно, что время передачи по локальной сети заставляет меняне вижу ожидаемого ускорения.

Как я могу дополнительно диагностировать или сделать это по-другому?

from mitmproxy import http
from mitmproxy import ctx
import time
import os

class MyAddOn:
    def __init__(self):
        self.flows = 0
        self.response_time = 0
        self.request_time = 0

    def _filenameFor(self, flow: http.HTTPFlow):
        path = flow.request.path[1:]
        cwd = os.getcwd()
        filename = os.path.join(cwd, path)

        if "range" in flow.request.headers:
            range = flow.request.headers["range"]
            filename = os.path.join(filename, range)

        return filename


    def request(self, flow: http.HTTPFlow) -> None:
        start = time.time()

        if "myhlsserver.com" not in flow.request.host:
            return
        else:
            filename = self._filenameFor(flow)
            if os.path.isfile(filename):
                with open(filename, 'rb') as f:
                    content = f.read()
                    flow.response = http.HTTPResponse.make(200, content)

            end = time.time()
            time_taken = end - start
            self.response_time += time_taken
            self.flows += 1

            ctx.log.info(('Requests: ', self.flows, ))


    def response(self, flow: http.HTTPFlow) -> None:
        start = time.time()

        if "myhlsserver.com" not in flow.request.host:
            return
        else:
            filename = self._filenameFor(flow)
            if os.path.isfile(filename):
                return
            else:
                directory = os.path.dirname(filename)
                os.makedirs(directory, exist_ok=True)

                with open(filename, "xb") as file:
                    file.write(flow.response.content)

            end = time.time()
            time_taken = end - start
            self.response_time += time_taken

addons = [ MyAddOn() ]
...