HTTP-сервер на чистых сокетах в python - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь написать очень простой http-сервер на python. Рабочая версия выглядит так:

def run(self, host='localhost',port=8000):
    with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host,port))
        s.listen(1)
        while True:
            connection, adress = s.accept()
            with connection:
                data = b''
                while True:
                    recived = connection.recv(1024)
                    data += recived
                    if len(recived) < 1024:
                        break

                if data != b'':
                    handle_request(data,connection)

Это работает, но у меня есть некоторое недопонимание, что происходит. Как я понимаю, сокет "s" принимает соединение от клиента -> и возвращает новый объект сокета "соединение", из которого я могу прочитать то, что клиент отправляет мне, и отправить ответ. Я читаю данные из соединения, пока клиент не отправит пустую строку b ''. После этой части TCP завершается, и я передаю полученные байты обработчику, который анализирует полученные данные как HTTP.

Вопросы: на данный момент я читаю все данные, которые клиент отправляет мне, но если я хочу ограничить максимальный размер HTTP-запроса, я должен просто сделать что-то вроде этого:

..................................

    with connection:
        data = b''
        request_size_limit=1024*100 # some desired http request max size
        while True:
            recived = connection.recv(1024)
            data += recived
            if len(recived) < 1024 or len(data) > request_size_limit:
                break             
            if data != b'':
                handle_request(data,connection)
  1. Если я делаю что-то вроде этого, как я могу сообщить клиенту, что, например, у меня есть максимум 1024 * 1024 свободных байтов ОЗУ, и я не могу обрабатывать запросы больше этого?
  2. Если клиенты хотят отправить больше этого предела, он должен отправить несколько отдельных запросов, которые будут содержать 1 часть необходимых данных?
  3. Или, например, для большого запроса POST я должен проанализировать каждое recv (1024), пока я нашел последовательность \ r \ n \ r \ n, проверить длину содержимого и длину содержимого recv () по частям 1024b в некотором файле и продолжить после?

1 Ответ

0 голосов
/ 17 ноября 2018

A1) Если вы не можете обработать запрос, потому что он слишком большой, подумайте о закрытии соединения. В качестве альтернативы вы можете прочитать (и отказаться) все, что они отправляют, а затем ответить на запрос 413, взятый большим.

A2) Вам нужно будет разработать протокол для одновременной отправки только части запроса. HTTP не делает это изначально.

A3) Если вы можете прочитать весь запрос по частям и сохранить его в файл, значит, у вас есть решение для ограничения оперативной памяти 1024 * 1024, не так ли?

Но исправьте проблемы с чтением фрагментированных данных из сокета.

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