Как прочитать необработанный http-пост STRING. Я нашел несколько решений для чтения проанализированной версии сообщения, однако проект, над которым я работаю, отправляет необработанную полезную нагрузку xml без заголовка. Итак, я пытаюсь найти способ прочитать данные сообщения без их анализа в массив ключей => значений.
Python: BaseHTTPRequestHandler — прочитать необработанный пост
Ответы (4)
Я думаю, что self.rfile.read(self.headers.getheader('content-length'))
должен возвращать необработанные данные в виде строки. Согласно документам непосредственно внутри класса BaseHTTPRequestHandler:
- rfile is a file object open for reading positioned at the
start of the optional input data part;
read()
в основном говорит «читать, пока не останется ничего для чтения», но есть еще что читать, пока сокет открыт, поэтому он зависает и ждет входящего контента. Серверы избегают зависания, ВСЕГДА указывая СКОЛЬКО контента для чтения. Извините, я должен был поставить это в первую очередь.
- person smakateer; 26.07.2013
self.rfile.read(int(self.headers.getheader('Content-Length')))
вернет необработанные данные HTTP POST в виде строки.
Разбивая это:
- Заголовок «Content-Length» указывает, сколько байтов содержат данные HTTP POST.
self.headers.getheader('Content-Length')
возвращает длину содержимого (значение заголовка) в виде строки.- Это должно быть преобразовано в целое число перед передачей в качестве параметра в
self.rfile.read()
, поэтому используйте функциюint()
.
Кроме того, обратите внимание, что имя заголовка чувствительно к регистру, поэтому оно должно указываться только как 'Content-Length'.
Изменить: очевидно, что поле заголовка не чувствительно к регистру (по крайней мере, в Python 2.7.5), что, я считаю, является правильным поведением, поскольку https://tools.ietf.org/html/rfc2616 сообщает:
Каждое поле заголовка состоит из имени, за которым следует двоеточие (":") и значение поля. Имена полей нечувствительны к регистру.
self.headers.getheader('content-length')
и self.headers.getheader('content-LENGTH')
- person famzah; 07.11.2015
self.headers.get('content-length')
- person Amarghosh; 12.04.2018
Для python 3.7 у меня сработало следующее:
rawData = (self.rfile.read(int(self.headers['content-length']))).decode('utf-8')
С помощью других ответов на этот вопрос и этого и это. Последняя ссылка на самом деле содержит полное решение.
Метод read()
для объекта io.BufferedIOBase
считывается до EOF. Не все браузеры отправляют символ EOF (источник). Чтение байтов Content-Length — хорошее решение. Мне также помогло использование метода read1()
. Он считывает как можно больше за один неблокирующий вызов API.