通过 http 连接到免费的 pythonanywhere 实例
Connecting to free pythonanywhere instance via http
我正在尝试与托管在 PythonAnywhere 上的 Web 应用程序对话。这是一个低带宽、低频率的连接,所以我可以使用 http 接口——而且它在浏览器的 http 上也能正常工作。但是,我似乎无法在云中的 PythonAnywhere 主机 运行ning 上获得相同的服务 运行ning。
如果我 运行 本地服务器,这有效:
import socket
s = socket.socket()
s.connect(('127.0.0.1', 8080))
s.send('GET /check/nicky HTTP/1.1\r\n\r\n')
print (s.recv(1024))
# 'HTTP/1.0 200 OK\r\nDate: Sat, 01 Jun 2019 23:45:14 GMT\r\nServer: WSGIServer/0.2 CPython/3.7.2\r\nContent-Type: application/json\r\nContent-Length: 19\r\n\r\n{"nicky": [0, 120]}'
但是,如果我在 pythonanywhere URL 上使用 socket.getaddrinfo()
(替换上面 s.connect()
中的地址),我会得到一个 'bad request' 响应:
'HTTP/1.1 400 Bad Request\r\nServer: openresty/1.9.15.1\r\nDate: Sat, 01 Jun 2019 23:49:48 GMT\r\nContent-Type: text/html\r\nContent-Length: 179\r\nConnection: close\r\n\r\n<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body bgcolor="white">\r\n<center><h1>400 Bad Request</h1></center>\r\n<hr><center>openresty/1.9.15.1</center>\r\n</body>\r\n</html>\r\n'
如果我在浏览器中键入相同的请求,服务器运行良好——但尝试以编程方式执行此操作总是以这种方式失败。
这是某种我不知道的代理或端口转发魔法吗?有问题的 pythonanwhere 帐户是免费赠品。
** 以防万一 ** @Steffen Ulrich 的诊断是正确的。我最终使用了 https://github.com/micropython/micropython-lib/tree/master/urequests,请求的 micropython 克隆,这解决了问题。
s.send('GET /check/nicky HTTP/1.1\r\n\r\n')
..
'HTTP/1.1 400 Bad Request\r\nServer: openresty/1.9.15.1\r\n ...
服务器是对的。您发送的不是正确的 HTTP 请求。对于 HTTP/1.1
,HTTP header.
中的 Host
字段是必需的
如果你添加这个请求可能会工作,但你可能 运行 陷入各种其他麻烦,比如缺少对分块响应的支持 body,假设一切都将在一次读取中完成.. .
虽然您可能会尝试在自己的代码中处理所有这些问题,但我建议您改用现有的 HTTP 库,例如 requests.
如果您真的想编写自己的 HTTP 层,我真的建议您在实施之前阅读并理解该标准,这就是标准的用途。对于 HTTP/1.1
,这些是 RFC 7230 和以下 RFC。
我正在尝试与托管在 PythonAnywhere 上的 Web 应用程序对话。这是一个低带宽、低频率的连接,所以我可以使用 http 接口——而且它在浏览器的 http 上也能正常工作。但是,我似乎无法在云中的 PythonAnywhere 主机 运行ning 上获得相同的服务 运行ning。
如果我 运行 本地服务器,这有效:
import socket
s = socket.socket()
s.connect(('127.0.0.1', 8080))
s.send('GET /check/nicky HTTP/1.1\r\n\r\n')
print (s.recv(1024))
# 'HTTP/1.0 200 OK\r\nDate: Sat, 01 Jun 2019 23:45:14 GMT\r\nServer: WSGIServer/0.2 CPython/3.7.2\r\nContent-Type: application/json\r\nContent-Length: 19\r\n\r\n{"nicky": [0, 120]}'
但是,如果我在 pythonanywhere URL 上使用 socket.getaddrinfo()
(替换上面 s.connect()
中的地址),我会得到一个 'bad request' 响应:
'HTTP/1.1 400 Bad Request\r\nServer: openresty/1.9.15.1\r\nDate: Sat, 01 Jun 2019 23:49:48 GMT\r\nContent-Type: text/html\r\nContent-Length: 179\r\nConnection: close\r\n\r\n<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body bgcolor="white">\r\n<center><h1>400 Bad Request</h1></center>\r\n<hr><center>openresty/1.9.15.1</center>\r\n</body>\r\n</html>\r\n'
如果我在浏览器中键入相同的请求,服务器运行良好——但尝试以编程方式执行此操作总是以这种方式失败。
这是某种我不知道的代理或端口转发魔法吗?有问题的 pythonanwhere 帐户是免费赠品。
** 以防万一 ** @Steffen Ulrich 的诊断是正确的。我最终使用了 https://github.com/micropython/micropython-lib/tree/master/urequests,请求的 micropython 克隆,这解决了问题。
s.send('GET /check/nicky HTTP/1.1\r\n\r\n') .. 'HTTP/1.1 400 Bad Request\r\nServer: openresty/1.9.15.1\r\n ...
服务器是对的。您发送的不是正确的 HTTP 请求。对于 HTTP/1.1
,HTTP header.
Host
字段是必需的
如果你添加这个请求可能会工作,但你可能 运行 陷入各种其他麻烦,比如缺少对分块响应的支持 body,假设一切都将在一次读取中完成.. .
虽然您可能会尝试在自己的代码中处理所有这些问题,但我建议您改用现有的 HTTP 库,例如 requests.
如果您真的想编写自己的 HTTP 层,我真的建议您在实施之前阅读并理解该标准,这就是标准的用途。对于 HTTP/1.1
,这些是 RFC 7230 和以下 RFC。