Вы не должны пытаться обрабатывать строки в этой части тела, вы должны отправлять двоичные данные, видеть их как чтение байтов из ресурса и отправку байтов тезисов без изменений.
Итакособенно не применяется кодировка, нет utf-8, нет base64, HTTP не является протоколом с ограничением ascii7, таким как smtp, где применяется кодировка base64 для обеспечения использования только символов ascii7.
По определению,нет строковой версии этих данных, и, глядя на необработанную передачу HTTP (например, с Wireshark), вы должны увидеть двоичные данные, байты и прочее.
Именно поэтому большинство HTTP-серверов используют C для управления HTTP, они анализируютHTTP-байт на байт (поскольку заголовки протокола являются только ascii 7, определенно не многобайтовыми символами), и они также могут легко читать / записывать произвольные двоичные данные для тела (или даже использовать системные вызовы, такие как readfile дляпусть ядро управляет двоичной частью).
Теперь о примерах .
Когда выse Content-Length и без составных элементов тело имеет длину (длина содержимого) в байтах, поэтому клиент, анализирующий ваши отправленные данные, просто прочитает это количество байтов и будет обрабатывать все эти необработанные данные как телоконтент (который может иметь тип MIME и информацию о кодировке, но это просто информация для слоев, установленных поверх протокола HTTP).
При использовании Transfer-Encoding: chunked ,Необработанное двоичное тело разделяется на части, каждая часть затем имеет префикс шестнадцатеричного числа (размер фрагмента) и маркер конца строки.С окончательным нулевым маркером в конце.
Если мы возьмем пример википедии :
4\r\n
Wiki\r\n
5\r\n
pedia\r\n
E\r\n
in\r\n
\r\n
chunks.\r\n
0\r\n
\r\n
Мы могли бы заменить каждую букву ascii7 любым байтом, даже байтомэто не имело бы представления ascii7, я буду использовать символ * для каждого байта реального тела:
4\r\n
****\r\n
5\r\n
*****\r\n
E\r\n
**************\r\n
0\r\n
\r\n
Все остальные символы являются частью протокола HTTP (здесь передача фрагментированного тела).Я также мог бы использовать \n
представление двоичных данных и отправлять только нулевой байт для каждого байта тела, это было бы:
4\r\n
\0\0\0\0\0\r\n
5\r\n
\0\0\0\0\0\0\r\n
E\r\n
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\r\n
0\r\n
\r\n
Это просто представление, мы также могли бы использовать \xNN
или \NN
представления, в действительности это байты, 8 бит (слишком ленив, чтобы написать представление 0/1 этого тела :-)).
Если текст примера, вместо того, чтобы быть:
Wikipedia in\r\n
\r\n
chunks.
Он мог бы быть более сложным, с многобайтовыми символами (здесь é в utf-8):
Wikipédia in\r\n
\r\n
chunks.
Этот é фактически 11000011:10101001
в utf-8, два байта: \xc3\xa9
в \xNN
представлении) вместо простого символа 01100101
/ \x65
/ e
.Тело HTTP теперь (см., Что размер второго блока равен 6, а не 5):
4\r\n
Wiki\r\n
6\r\n
p\xc3\xa9dia\r\n
E\r\n
in\r\n
\r\n
chunks.\r\n
0\r\n
\r\n
Но это допустимо только в том случае, если исходные данные были эффективно в utf-8, возможно, была другой кодировкой.По умолчанию, если на вашем веб-сервере нет определенных параметров конфигурации, где вы применяете преобразование исходного документа в определенную кодировку, на самом деле веб-сервер не выполняет преобразование исходного документа, вы берете то, что имеете,и вы можете добавить заголовок, чтобы сообщить клиенту, какая кодировка была определена в исходном документе.
Наконец, у нас есть multipart способ передачи тела, как в вашем вопросе, это многокак и чанкованная версия, за исключением того, что здесь используются границы и промежуточные заголовки, но для двоичных данных между этими границами, заголовками и управляющими символами конца строки это одно и то же правило, все внутри - только байты ...