Файл декодирования Python из сокета multipart / form-data - PullRequest
0 голосов
/ 29 июня 2019

Я пытаюсь получить multipart / form-data с необработанным сокетом. Он работает с обычными вводами, но когда я реализую ввод типа файла, я получаю

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position x: invalid start byte

ошибка

код формы

<form action="/login" method="POST" enctype="multipart/form-data">
    <input type="text" name="username" placeholder="Username">
    <input type="password" name="password" placeholder="Password">
    <input type="file" name="files">
    <input type="submit" name="submit" value="Login">
</form>

recv func

    request = conn.recv(10240).decode()

1 Ответ

0 голосов
/ 29 июня 2019
request = conn.recv(10240).decode()

Этот код предполагает, что вы получите полное тело за одно чтение. Но recv не гарантирует этого. Вместо этого вызов возвращает только до 10240 байтов в вашем случае. Фактическое количество байтов зависит от объема отправляемых данных, способа их пакетной передачи, размера буфера сокета и количества данных, которые уже получены (и помещены в буфер сокета).

Правильный способ - заранее узнать, сколько данных нужно прочитать, а затем использовать несколько вызовов recv, пока все данные не будут прочитаны. Это означает, что вам нужно сначала прочитать заголовок HTTP, чтобы извлечь заголовок content-length, который содержит количество байтов в теле. Теоретически, вам также придется иметь дело с частичной кодировкой передачи, но браузеры не используют ее в вашем конкретном случае.

Помимо этого вы получаете байты, которые не находятся в определенной кодировке. Это означает, что использование decode напрямую также неправильно. Вместо этого вам нужно будет проанализировать составное сообщение MIME на основе информации в заголовке (то есть границы MIME) в его различных частях, и тогда вы сможете decode значения в этих частях, но только тогда, когда эти значения фактически закодированы. Например, загруженный файл не должен декодироваться, а должен обрабатываться как байты. Даже другие значения могут не кодироваться в utf-8, как вы предполагаете - точная кодировка зависит от используемого вами HTML-кода, а отображаемый фрагмент не дает достаточной информации об этом.

В целом: если вы действительно не понимаете соответствующие стандарты (HTTP и MIME), вам лучше использовать существующие библиотеки. И если вы понимаете соответствующие стандарты, вы, вероятно, также будете использовать существующие библиотеки, поскольку поняли, насколько сложны эти стандарты и что их внедрение со всеми их крайними случаями будет пустой тратой времени.

...