Получить HTTP-запрос, как передано по сети (Джанго) - PullRequest
0 голосов
/ 06 октября 2018

Можно ли получить запрос http как строку байта, как если бы у вас был объект запроса django?

Конечно, простой текст (не шифруется, если используется https).

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

В лучшем случае я хотел бы получить доступ к реальной строке байтов.Создание строки байтов из request.META, request.GET и друзей, скорее всего, будет отличаться от оригинала.

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

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

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

Вы можете просто попытаться восстановить запрос следующим образом.

def reconstruct_request(request):
    headers = ''
    for header, value in request.META.items():
        if not header.startswith('HTTP'):
            continue
        header = '-'.join([h.capitalize() for h in header[5:].lower().split('_')])
        headers += '{}: {}\n'.format(header, value)

    return (
        '{method} HTTP/1.1\n'
        'Content-Length: {content_length}\n'
        'Content-Type: {content_type}\n'
        '{headers}\n\n'
        '{body}'
    ).format(
        method=request.method,
        content_length=request.META['CONTENT_LENGTH'],
        content_type=request.META['CONTENT_TYPE'],
        headers=headers,
        body=request.body,
)

ПРИМЕЧАНИЕ это не полный пример, только подтверждение концепции

0 голосов
/ 09 октября 2018

Основной ответ - нет, у Django нет доступа к необработанному запросу, фактически у него даже нет кода для анализа необработанного HTTP-запроса.

Это потому, что обработка Django (как и многих других веб-фреймворков Python) HTTP-запроса / ответа в своей основе является приложением WSGI ( спецификация WSGI ).

Эторабота внешнего / прокси-сервера (например, Apache или nginx) и сервера приложений (например, uWSGI или gunicorn) - «массировать» запрос (например, преобразовывать и удалять заголовки) и преобразовывать его в объект, который может обрабатываться Django.

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

Отредактируйте wsgi.py вашего проекта и добавьте несколько базовых промежуточных программ WSGI "":

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')

class MyMiddleware:
    def __init__(self, app):
        self._app = app

    def __call__(self, environ, start_response):
        import pdb; pdb.set_trace()
        return self._app(environ, start_response)

# Wrap Django's WSGI application
application = MyMiddleware(get_wsgi_application())

Теперь, если вы запустите свой devserver (./manage.py runserver) и отправите запрос в ваше приложение Django.Вы попадете в отладчик.

Единственное, что здесь интересует - это диктат environ.Обойдите его, и вы увидите, что это почти то же самое, что вы найдете в «1019» Джанго.(Содержание диктовки environ подробно описано в этом разделе спецификации WSGI .)

Зная это, лучшее, что вы можете получить, это собрать воедино предметы из environдиктовать что-то, что удаленно напоминает HTTP-запрос.

Но почему?Если у вас есть диктант environ, у вас есть вся информация, необходимая для репликации запроса Django.Фактически нет необходимости переводить это обратно в HTTP-запрос.

На самом деле, как вы теперь знаете, HTTP-запрос вообще не нужен для вызова приложения WSGI Django.Все, что вам нужно, - это диктант environ с необходимыми ключами и возможностью вызова, чтобы Django мог передавать ответ.

Итак, для анализа запросов (и даже возможности их воспроизведения) вам нужно только уметьвоссоздать действительный environ dict.

. Для этого в Django проще всего будет сериализовать request.META и request.body в JSON-диктовку.

Если вам действительно что-то нужнокоторый напоминает HTTP-запрос (и вы не можете подняться на уровень выше, например, веб-сервер для регистрации этой информации), вам просто нужно собрать это воедино из информации, доступной в request.META и request.body, с оговорками, которыеэто не реалистичное представление исходного HTTP-запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...