【问题标题】:Connecting to free pythonanywhere instance via http通过 http 连接到免费的 pythonanywhere 实例
【发布时间】:2019-10-18 01:23:03
【问题描述】:

我正在尝试与 PythonAnywhere 上托管的网络应用程序交谈。这是一个低带宽、低频率的连接,所以我可以使用 http 接口——而且它可以通过浏览器的 http 正常工作。但是,我似乎无法访问在云中运行的 PythonAnywhere 主机上运行的相同服务。

如果我在本地运行服务器,则可以:

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() 中的地址),我会收到“错误请求”响应:

'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 克隆,这解决了问题。

【问题讨论】:

  • 不幸的是,PythonAnywhere 似乎不支持旨在在 PythonAnywhere 系统之外访问的套接字服务器,仅支持使用 WSGI 协议的 HTTP 服务器。有关详细信息,请参阅 herehere
  • 谢谢。服务器本身是一个提供 http 请求的瓶子应用程序。我正在尝试将它用作 http 微服务——我只是无法让它在 PA 上响应

标签: python sockets pythonanywhere


【解决方案1】:
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 标头中需要Host 字段。

如果你添加这个请求可能会工作,但你可能会遇到各种其他麻烦,比如缺少对分块响应正文的支持,假设所有事情都将在一次读取中完成......

虽然您可能会尝试在自己的代码中处理所有这些问题,但我建议您改用现有的 HTTP 库,例如 requests

如果您真的想编写自己的 HTTP 层,我真的建议您在实施之前阅读并理解标准,这就是标准的用途。对于 HTTP/1.1,这些是 RFC 7230 并遵循 RFC。

【讨论】:

  • 在这种情况下,客户端代码将在 micropython 上运行,而不是在原版 py3 上运行——内存非常宝贵,我希望只有非常小的响应(大约 100 个字符的文本)。有一个我试图避免的 micropython 版本或请求。难题仍然是,如果我在本地运行相同的应用程序,这段代码仍然有效——只有当应用程序托管在 PythonAnywhere 上时它才会失败
  • @theodox:您的本地服务器可能会简单地忽略标准的部分内容,而 PythonAnywhere 不会。如果多个服务器位于同一个 IP 和端口上,Host 标头是必不可少的。如果您想要一些最小和更简单的东西,请使用HTTP/1.0 而不是HTTP/1.1,因为这样您就不必处理 HTTP keep-alive(HTTP/1.1 默认打开,HTTP/1.0 关闭)和分块传输编码.
  • 在手动创建标头后,我发现了一个 micropython 请求的子集实现,并且成功了。谢谢你的线索!
猜你喜欢
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-29
  • 2021-03-10
  • 2019-05-31
  • 2018-10-28
相关资源
最近更新 更多