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
заголовок) и прочитайте оставшиеся байты.