http POST тело сообщения не получено

В настоящее время я создаю HTTP-сервер Python Socket, и я работаю над своими запросами GET и POST. Моя реализация GET работает нормально, но элемент body запросов POST не отображается. Фрагмент кода:

self.host = ''
self.port = 8080

self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.listener.bind((self.host, self.port))
self.listener.listen(1)

while True:

        client_connection, client_address = self.listener.accept()
        request = client_connection.recv(2048)
        print request

Этот код возвращает заголовок http после обработки запроса на публикацию с веб-страницы:

POST /test.txt HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Origin: http://localhost:8080
Content-Length: 21
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17
Referer: http://localhost:8080/
Accept-Language: nb-no
Accept-Encoding: gzip, deflate

Но тела нет, поэтому вопрос в том, почему я не получаю тело http, когда знаю, что оно отправлено?

Спасибо!

1 ответ

Решение
while True:

        client_connection, client_address = self.listener.accept()
        request = client_connection.recv(2048)
        print request

recv не читает точно 2048 байтов, но читает до 2048 байтов. Если некоторые данные поступают recv вернется с данными, даже если может последовать больше данных. Я предполагаю, что в вашем случае клиент сначала отправляет заголовок HTTP, а затем тело. Если алгоритмы NAGLE отключены на стороне клиента (часто), вероятно, ваш первый recv получит только заголовок и что вам понадобится еще один recv для тела. Это объясняет, что происходит в вашем случае: вы получаете заголовок, но не тело, так как вы не делаете другой recv,

Но даже это будет слишком простой реализацией, которая рано или поздно пойдет не так. Чтобы сделать это правильно, вы должны правильно реализовать протокол HTTP: сначала прочитайте заголовок HTTP, который может потребоваться несколько recv если заголовок большой. Затем нужно разобрать заголовок, выяснить размер тела (Content-length заголовок) и прочитайте оставшиеся байты.

Другие вопросы по тегам