Python 带套接字的 GET 请求 - 400 错误请求
Python GET request with sockets - 400 Bad request
我编写此代码是为了仅使用 python 套接字手动发出 GET 请求。它在 2016 年我编写它时运行得非常好,但现在我再次需要它并且我不断收到错误代码 400 错误请求。我尝试切换 python 版本,但它仍然是一样的。我一直在浏览 Whosebug 问题,问的问题或多或少与我所做的相同,但我就是无法让它工作。如果有人能帮助我,我将不胜感激。这是我的代码,我删除了所有 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()
当我运行我的程序在URLhttps://doc.rust-lang.org/book/2018-edition/foreword.html
我程序中的变量具有以下值:
端口: 443
协议:https
主机名:doc.rust-lang.org
路径名: /book/2018-edition/foreword.html
然后我得到了 400 错误的请求代码。我不明白我做错了什么,如果能得到任何帮助,我将不胜感激。
我相信这都是关于 SSL 的。作为参考,您可以查看此问题 .
我建议你使用:
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]
我编写此代码是为了仅使用 python 套接字手动发出 GET 请求。它在 2016 年我编写它时运行得非常好,但现在我再次需要它并且我不断收到错误代码 400 错误请求。我尝试切换 python 版本,但它仍然是一样的。我一直在浏览 Whosebug 问题,问的问题或多或少与我所做的相同,但我就是无法让它工作。如果有人能帮助我,我将不胜感激。这是我的代码,我删除了所有 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()
当我运行我的程序在URLhttps://doc.rust-lang.org/book/2018-edition/foreword.html
我程序中的变量具有以下值:
端口: 443
协议:https
主机名:doc.rust-lang.org
路径名: /book/2018-edition/foreword.html
然后我得到了 400 错误的请求代码。我不明白我做错了什么,如果能得到任何帮助,我将不胜感激。
我相信这都是关于 SSL 的。作为参考,您可以查看此问题 .
我建议你使用:
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]