Вопрос

В поисках небольшой помощи я в настоящее время написал 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.

Теперь вы можете написать свой ответ.

Не стал бы писать свою собственную реализацию.Если хотите, посмотрите на следующие существующие компоненты:

Как сказал Кароробертс, вам необходимо проверить длину контента, отправленного в POST.Но вы все равно можете использовать BufferedReader.

Просто нужно проверить размер заголовка Content-Length, и после завершения чтения всех заголовков вы можете установить массив символов этого размера и выполнить чтение содержимого POST:

char[] буфер = новый char[contentLength];request.read(буфер);

Где запрос — это BufferedReader.Если вам нужен контент POST в строке, вы можете использовать:String.valueOf(буфер);

Примечание:BufferedReader.read возвращает целое число прочитанных символов, поэтому вы можете проверить его на предмет несоответствий с заголовком Content-Length.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top