2015-12-21 3 views
1

Я новичок в сетевом программировании, и я пытаюсь реализовать простой HTTP-прокси в Java, который должен только пересылать запросы клиента и передавать ответ.Java-прокси, как обрабатывать запросы CONNECT

Для обработки запросов GET я просто прочитал клиентский сокет InputStream, создаю новый сокет для желаемого хоста (который я прочитал из сокета), чтобы затем написать тот же запрос GET, который был сделан клиентом, в OutputStream этого нового сокета , То же самое, что и для получения ответа, я пишу ответ от InputStream сокета-хозяина на OutputStream клиентского сокета.

Но у меня возникли некоторые проблемы, когда я должен обрабатывать запросы на подключение, например, когда я пытаюсь получить доступ к www.google.com из моего браузера, это приводит к чтению этого из клиентского сокета:

CONNECT www.google.com:443 HTTP/1.1 
Host: www.google.com 
Proxy-Connection: keep-alive 
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36 

в моем понимании, я должен подключиться к хосту www.google.com на порт 443. Таким образом, я создаю новый сокет:

Socket socket = new Socket(www.google.fr, 443); 

Но что должно быть запрос? Я просто попытался:

GET/HTTP/1.1 

Но с помощью Wireshark, кажется, что хозяин немедленно прерывает соединение, посылая назад FIN и RST TCP сегментов.

Как я должен правильно обработать эти запросы и получить содержимое веб-страницы?

ответ

2

Запрос должен быть таким, каким отправляет клиент после CONNECT.

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

+0

Так что мне нужно продолжать чтение InputStream одного и того же клиентского сокета для другого запроса (из-за прокси-соединения: keep-alive)? Или этот запрос будет выполнен с использованием другого соединения/сокета? –

+0

Запрос будет производиться с помощью * этого * сокета, конечно, в противном случае, что именно является его точкой? Вам необходимо отправить все, что следует за CONNECT, на сервер, и вам нужно отправить все, что сервер отправит вам обратно клиенту. Одновременно. Это будет SSL, так что вы все равно его не поймете, так что вы ничего не узнаете о keepalive. Просто скопируйте байты, как я сказал. – EJP

+0

Я не отправлял строку статуса HTTP обратно клиенту, и поэтому я не получил запрос, который я хотел после CONNECT. Работаю отлично сейчас, спасибо. –

Смежные вопросы