HTTP-запрос GET не работает в Java, когда HTTP 1.1? - PullRequest
2 голосов
/ 27 марта 2012

, поэтому я сделал небольшой код, который может загрузить 4chan страниц.я получаю необработанную HTML-страницу и анализирую ее для своих нужд.код ниже работал нормально, но вдруг перестал работать.когда я запускаю его, сервер не принимает мой запрос, кажется, он ждет чего-то большего.однако я знаю, что HTTP-запрос будет таким, как показано ниже

GET /ck HTTP/1.1
Host: boards.4chan.org
(extra new line)

. Если я в любом случае изменю этот формат, я восстановлю код состояния «400 неправильных запросов».но если я изменяю HTTP / 1.1 на 1.0, сервер отвечает в статусе «200 ок», и я получаю всю страницу.так что это заставляет меня думать, что ошибка в строке хоста, поскольку это стало обязательным в HTTP / 1.1.но все же я не могу понять, что именно нужно изменить.

вызывающая функция просто так, чтобы получить одну целую доску

downloadHTMLThread( "ck", -1);

или для конкретного потока, просто измените -1 наэтот номер.например, как для ссылки ниже будет иметь, как показано ниже.

//http://boards.4chan.org/ck/res/3507158
//url.getDefaultPort() is 80
//url.getHost() is boards.4chan.org
//url.getFile() is /ck/res/3507158

downloadHTMLThread( "ck", 3507158);

Любой совет будет оценен, спасибо

public static final String BOARDS = "boards.4chan.org";
public static final String IMAGES = "images.4chan.org";
public static final String THUMBS = "thumbs.4chan.org";
public static final String RES = "/res/";
public static final String HTTP = "http://";
public static final String SLASH = "/";

public String downloadHTMLThread( String board, int thread) {
    BufferedReader reader = null;
    PrintWriter out = null;
    Socket socket = null;
    String str = null;
    StringBuilder input = new StringBuilder();

    try {
        URL url = new URL(HTTP+BOARDS+SLASH+board+(thread==-1?SLASH:RES+thread));
        socket = new Socket( url.getHost(), url.getDefaultPort());
        reader = new BufferedReader( new InputStreamReader( socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);

        out.println( "GET " +url.getFile()+ " HTTP/1.1");
        out.println( "HOST: " + url.getHost());
        out.println();

        long start = System.currentTimeMillis();
        while ((str = reader.readLine()) != null) {
            input.append( str).append("\r\n");
        }
        long end = System.currentTimeMillis();

        System.out.println( input);
        System.out.println( "\nTime: " +(end-start)+ " milliseconds");

    } catch (Exception ex) {
         ex.printStackTrace();
         input = null;
    } finally {
        if( reader!=null){
            try {
                reader.close();
            } catch (IOException ioe) {
                // nothing to see here
            }
        }
        if( socket!=null){
            try {
                socket.close();
            } catch (IOException ioe) {
                // nothing to see here
            }
        }
        if( out!=null){
            out.close();
        }
    }
    return input==null? null: input.toString();
}

Ответы [ 3 ]

3 голосов
/ 27 марта 2012

Попробуйте использовать Apache HttpClient вместо своего собственного:

static String getUriContentsAsString(String uri) throws IOException {
  HttpClient client = new DefaultHttpClient();
  HttpResponse response = client.execute(new HttpGet(uri));
  return EntityUtils.toString(response.getEntity());
}

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

2 голосов
/ 27 марта 2012

По коду я думаю, что вы отправляете «ХОСТ» вместо «Хост».Так как это обязательный заголовок в http / 1.1, но игнорируется в http / 1.0, это может быть проблемой.В любом случае, вы можете использовать программу для захвата отправленного пакета (например, wireshark), просто чтобы убедиться.Использование println весьма полезно, но разделитель строк, добавляемый к команде, зависит от системного свойства line.separator.Я думаю (хотя я не уверен), что разделитель строк, используемый в протоколе http, должен быть '\ r \ n'.Если вы захватываете пакет, я думаю, что было бы неплохо проверить, чтобы каждая отправляемая строка заканчивалась на '\ r \ n' (байты x0D0A) (на всякий случай, если ваш разделитель строк ОС отличается)

0 голосов
/ 27 марта 2012

Вместо этого используйте www.4chan.org в качестве хоста. Поскольку board.4chan.org - это редирект 302 на www.4chan.org, вы ничего не сможете почерпнуть из board.4chan.org.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...