我编写了这段代码,以仅使用python套接字手动发出GET请求。早在2016年,当我编写它时,它的运行情况就很好了,但是现在我再次需要它,并且我不断收到错误代码400错误的请求。我尝试切换python版本,但仍然相同。我一直在研究Stackoverflow的问题,或多或少地询问与我相同的事情,但是我无法使其正常工作。如果有人可以帮助我,我将不胜感激。这是我的代码,我删除了所有IO,仅发布了网络代码。
URL_PATTERN = re.compile("^(.*://)?([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$")
HEADER_END = re.compile("\r\n\r\n")
URL_DATA = re.match(URL_PATTERN, INPUT_URL)
PROTOCOL = URL_DATA.groups()[0][:-3]
HOSTNAME = URL_DATA.groups()[1]
PATHNAME = URL_DATA.groups()[3] if URL_DATA.groups()[3] != "" else "/"
PORT = 80 if PROTOCOL == "http" else 443
BUFFER_SIZE = 4096
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOSTNAME, PORT))
s.send("GET " + PATHNAME + " HTTP/1.1\r\nHost: " + HOSTNAME + "\r\nConnection: close\r\n\r\n")
resp = s.recv(BUFFER_SIZE)
HEADER_INDEX = re.search(HEADER_END, resp).start()
HTTP_RESPONSE_HEADER = resp[:HEADER_INDEX]
s.close()
当我在URL https://doc.rust-lang.org/book/2018-edition/foreword.html上运行程序时
我程序中的变量具有值:
端口:443
协议:https
主机名:doc.rust-lang.org
PATHNAME :/ book / 2018-edition / foreword.html
然后我得到了400错误的请求代码。我不明白自己在做错什么,将不胜感激。
答案 0 :(得分:2)
我认为这全都与SSL有关。作为参考,您可以检查此问题Python socket server handle HTTPS request。
我建议您使用:
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
并创建一个安全套接字:
s_sock = context.wrap_socket(s, server_hostname=HOSTNAME)
s_sock.connect((HOSTNAME, PORT))
另外,您可能需要对消息进行编码。
最后,您的代码如下所示:
import re
import socket
import ssl
URL_PATTERN = re.compile("^(.*://)?([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$")
HEADER_END = re.compile("\r\n\r\n")
INPUT_URL = "https://doc.rust-lang.org/book/2018-edition/foreword.html"
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
URL_DATA = re.match(URL_PATTERN, INPUT_URL)
PROTOCOL = URL_DATA.groups()[0][:-3]
HOSTNAME = URL_DATA.groups()[1]
PATHNAME = URL_DATA.groups()[3] if URL_DATA.groups()[3] != "" else "/"
PORT = 80 if PROTOCOL == "http" else 443
BUFFER_SIZE = 4096
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s_sock = context.wrap_socket(s, server_hostname=HOSTNAME)
s_sock.connect((HOSTNAME, PORT))
message = "GET " + PATHNAME + " HTTP/1.1\r\nHost: " + HOSTNAME + "\r\nConnection: close\r\n\r\n"
s_sock.send(message.encode('utf-8'))
resp = bytearray()
while True:
part = s_sock.recv(BUFFER_SIZE)
if not part:
break
resp += part
s_sock.close()
resp_string = str(resp, 'utf-8')
HEADER_INDEX = re.search(HEADER_END, resp_string).start()
HTTP_RESPONSE_HEADER = resp_string[:HEADER_INDEX]