Буферизованный Читатель HTTP POST
-
21-09-2019 - |
Вопрос
В поисках небольшой помощи я в настоящее время написал HTTP-сервер.В настоящее время он нормально обрабатывает запросы GET.Однако при использовании POST буферизованный считыватель, похоже, зависает.Когда запрос остановлен, остальная часть входного потока считывается через буферизованный считыватель.Я нашел несколько вещей в Google.Я попытался изменить CRLF и версию протокола с 1.1 на 1.0 (браузеры автоматически отправляют запросы как 1.1), буду признателен за любые идеи или помощь.Спасибо
Решение 3
Это не безопасно!Но показано, как получить данные POST во время входного потока после начальных заголовков HTTP.
Это также работает только для данных POST, поступающих как «example=true&bad=false» и т. д.
private HashMap hashMap = new HashMap();
private StringBuffer buff = new StringBuffer();
private int c = 0;
private String[] post; public PostInputStream(InputStream in) {
try {
//Initalizes avaliable buff
if (in.available() != 0) {
this.buff.appendCodePoint((this.c = in.read()));
while (0 != in.available()) {
//Console.output(buff.toString());
buff.appendCodePoint((this.c = in.read()));
}
this.post = buff.toString().split("&");
for (int i = 0; i < this.post.length; i++) {
String[] n = this.post[i].split("=");
if (n.length == 2) {
hashMap.put(URLDecoder.decode(n[0], "UTF-8"), URLDecoder.decode(n[1], "UTF-8"));
} else {
Console.error("Malformed Post Request.");
}
}
} else {
Console.error("No POST Data");
}
} catch (Exception e) {
e.printStackTrace();
}
}
Другие советы
Я согласен с Гансом в том, что для этого вам следует использовать стандартную и хорошо протестированную библиотеку.Однако, если вы пишете сервер, чтобы узнать о HTTP, вот некоторая информация о том, как делать то, что вы хотите сделать.
Вы действительно не можете использовать BufferedReader, потому что он буферизует входные данные и может считывать слишком много байтов из сокета.Вот почему ваш код зависает, BufferedReader пытается прочитать больше байтов, чем доступно в сокете (поскольку данные POST не имеют конца строки), и он ожидает больше байтов (которые никогда не будут доступны).
Процесс простого анализа POST-запроса заключается в непосредственном использовании InputStream
Для каждой строки в заголовке считывайте по байту за раз, пока не получите ' ', а затем '\ n'
Найдите строку, которая начинается с "Content-Длина:", извлеките номер в конце этой строки.
Когда вы получаете пустую строку заголовка, с заголовками покончено.
Теперь точно прочитайте количество байтов, которое пришло из заголовка Content-Length.
Теперь вы можете написать свой ответ.
Не стал бы писать свою собственную реализацию.Если хотите, посмотрите на следующие существующие компоненты:
- HTTP-клиент: Apache HttpClient
- реализация HTTP-сервера: Ядро Apache HttpComponents (как упоминал Бомбе)
Как сказал Кароробертс, вам необходимо проверить длину контента, отправленного в POST.Но вы все равно можете использовать BufferedReader.
Просто нужно проверить размер заголовка Content-Length, и после завершения чтения всех заголовков вы можете установить массив символов этого размера и выполнить чтение содержимого POST:
char[] буфер = новый char[contentLength];request.read(буфер);
Где запрос — это BufferedReader.Если вам нужен контент POST в строке, вы можете использовать:String.valueOf(буфер);
Примечание:BufferedReader.read возвращает целое число прочитанных символов, поэтому вы можете проверить его на предмет несоответствий с заголовком Content-Length.