Почему прокси-сервер не может получить ответ от сервера

#python #sockets

#python #сокеты

Вопрос:

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

 tcpSerSock.bind(('', 9999))
tcpSerSock.listen(1)
tcpCliSock, addr = tcpSerSock.accept()
print("Received a connection from:", addr)# Fill in start.
message = tcpCliSock.recv(1024).decode(encoding="utf-8")
 

Затем я попытался переслать сообщение с прокси-сервера на сервер, а затем получить файл с сервера, чтобы я мог отправить его с прокси-сервера клиенту.

 proxySock = socket(AF_INET, SOCK_STREAM)
proxySock.connect(('baidu.com', 80))
proxySock.sendall(message.encode(encoding="utf-8"))
respondMsg = proxySock.recv(1024).decode(encoding="utf-8")
 

Однако прокси-сервер не может получить сообщение от сервера, и, похоже, потому, что «сервер сбрасывается». Я провел некоторое исследование и обнаружил, что это может быть связано с отправленным ему сообщением. Сообщение показано ниже, я не знаю, что с ним не так, поскольку оно получено от клиента. Может кто-нибудь помочь мне выяснить, что не так?

 GET /www.baidu.com HTTP/1.1
Host: localhost:9999
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:85.0) Gecko/20100101 Firefox/85.0
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
 

Ответ №1:

 GET /www.baidu.com HTTP/1.1
Host: localhost:9999
 

Это не то сообщение, которое ожидает сервер. Сервер ожидает сообщение, подобное этому

   GET / HTTP/1.1
  Host: www.baidu.com
 

Таким образом, вы не можете просто переслать полученное сообщение на сервер, а должны его изменить. Обратите внимание, что из моего теста сервер не сбрасывает соединение, а вместо этого отвечает

 HTTP/1.1 500 Internal Server Error
Server: bfe
...
 

Помимо этого:

 message = tcpCliSock.recv(1024).decode(encoding="utf-8")
...
proxySock.sendall(message.encode(encoding="utf-8"))
respondMsg = proxySock.recv(1024).decode(encoding="utf-8")
 

Передаваемые данные должны обрабатываться не как UTF-8, а как двоичные. Фактически, исторически HTTP-заголовок разрешал кодировку ISO-8859-1, хотя теперь он определяется только как ASCII. И полезная нагрузка может быть любой.

Комментарии:

1. Большое спасибо, что напомнили мне об этом. Тем не менее, я использую ‘replace’ для изменения сообщения и повторной передачи, но он по-прежнему терпит неудачу. Сначала я использовал try и except, а затем, после их удаления, обнаружил, что в нем написано «Respond msg = proxySock.recv(1024).decode(encoding=»utf-8″) ConnectionResetError: [Ошибка 104] Сброс соединения одноранговым узлом». Все еще очень запутанно. Кроме того, с точки зрения передаваемых данных, если я не использую encode, decode, это также приведет к ошибке.

2. Отредактировано: я использую Wireshark для проверки сообщения, отправленного на сервер, и обнаружил, что вместо него используется POST. Не уверен, является ли это причиной. Поэтому вместо этого я использовал » localhost: 8888/www.example.org «, который наверняка использовал GET, обнаружил, что он может работать.