Кажется, что HttpURLConnection в Java добавляет в запрос символ 0018? - PullRequest
0 голосов
/ 15 декабря 2018

Я пытаюсь отправить изображение через HTTP.

Я проверил его через Chrome, используя Wireshark, чтобы увидеть детали запроса.Разделение между заголовками и составным содержимым составляет \r\n.

Однако моя реализация в Java, похоже, имеет разделение \r\n и символ 0018, что в соответствии с FileFormat.info - это символ CANCEL.

Я использую HttpURLConnection Java (доступ из Kotlin, но это не должно быть проблемой), вот примеркод, используемый для записи в содержимое файла:

val endl = "\r\n"
val hyphens = "--"
val boundary = "----${System.currentTimeMillis()}---"

// conn is an HttpURLConnection
val output = conn.outputStream
val writer = DataOutputStream(output)
writer.flush()

writer.writeUTF(hyphens + boundary + endl) // first time writing
writer.writeUTF("Content-Disposition: form-data; name: [REDACTED]" + endl)
writer.writeUTF("Content-Type: [REDACTED]" + endl)
writer.writeUTF(endl)

// [REDACTED: Writing the contents of the file]

writer.writeUTF(endl)
writer.writeUTF(hyphens + boundary + hyphens + endl)

writer.flush()
writer.close()

(полный код для этого примера можно найти здесь , строки 99-144)

Символ0018 вставляется непосредственно перед этим примером кода и сразу после заголовков (которые пишутся с использованием HttpURLConnection.setRequestProperty, поэтому я не верю, что они могут быть проблемой ... на всякий случай, вы можете найти этот код здесь , строки 64-91).

Вот начало тела запроса:

------1544883782650---
DContent-Disposition: form-data; name: "avatar"; filename: "wf.png"
Content-Type: image/png

(вы можете увидеть символ ОТМЕНА в начале первой строки,прямо перед границей).

По сравнению с запросом мade by Chrome:

------WebKitFormBoundaryAhYDuYuz5IuXB95v
Content-Disposition: form-data; name="avatar"; filename="discord.png"
Content-Type: image/png

Почему-то в Chrome нет этих странных символов.

Примечание.Я только что заметил, что Chrome использует form-data; name="avatar"; filename="discord.png", а я использую form-data; name: "avatar"; filename: "wf.png";Я отредактировал его и перепроверил, это не проблема.

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Документация из writeUTF гласит:

Сначала в выходной поток записываются два байта, как если бы это было сделано методом writeShort с указанием количества байтов, которые должны следовать.Это значение - количество фактически записанных байтов, а не длина строки.После длины каждый символ строки выводится последовательно с использованием измененной кодировки UTF-8 для символа.

То, что вы видите в начале каждой строки, это, вероятно, маркировка из 2 символовколичество следующих байтов.

Я думаю, DataOutputStream не идеально подходит для вашего случая использования.Используйте обычный write(byte[] bytes) метод OutputStream после преобразования заголовка String s с s.getBytes("UTF-8").

0 голосов
/ 16 декабря 2018

Из javadoc https://docs.oracle.com/javase/8/docs/api/java/io/DataOutputStream.html#writeUTF-java.lang.String- с добавлением акцента:

Сначала два байта записываются в выходной поток, как если бы методом writeShort давая количество байтов для следования .Это значение - количество фактически записанных байтов, а не длина строки.После длины каждый символ строки выводится последовательно с использованием модифицированной кодировки UTF-8 для символа....

Data{Input,Output}Stream не предназначены для текста и не должны использоваться для текста.MIME в целом и multipart в частности, в основном текстовые или, по крайней мере, совместимые с текстом, чтобы сделать его совместимым с электронной почтой, которая традиционно была текстовой, хотя HTTP является независимым (он поддерживает как текстовые, так и двоичные файлы).

...