如何解决`HTTPServer` 或 `BaseHTTPRequestHandler` 中是否存在缓存或分叉?
这可能是我的代码执行错误,但我发现虽然我可以从文字数据提供 GET 请求,但我无法更新该数据并使其在后续 GET 请求中显示为已更新。我也不能让 POST 请求更新数据。
所以它的行为就像在 Python 的 HTTPServer 或 BaseHTTPRequestHandler 的某个地方发生了缓存或分叉。
预先感谢您查看它,但是,温和地,不,我不想使用非核心 3.8 模块或使用完全不同的框架或某些 Flask 重写。我认为这应该有效,但它以一种我无法发现原因的方式行为不端。如果我使用 C 或 Go 的内置库,它会期望它不会那么令人头疼(对我来说)。
为了演示,您将运行以下 python 实现,并加载 http://127.0.0.1:8081/ 两次或三次:
"""
A Quick test server on 8081.
"""
from http.server import HTTPServer,BaseHTTPRequestHandler
import cgi
import json
import os
import sys
ADDR = '127.0.0.1'
PORT = 8081
def run(server_class=HTTPServer,handler_class=BaseHTTPRequestHandler):
server_address = (ADDR,PORT)
with server_class(server_address,handler_class) as httpd:
print("serving at",ADDR,"on",PORT,f"[ http://{ADDR}:{PORT} ]")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print(" stopping web server due to interrupt signal...")
httpd.socket.close()
class SimpleHandler(BaseHTTPRequestHandler):
"""
Implements responses to GET POST
"""
def __init__(self,request,client_address,server):
"""Sets up the server's memory,a favicon,and one text pseudo-file."""
self.files = {
'/oh': ['text/plain',"It's me",],'/favicon.ico': [
'image/svg+xml','<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><text y="1em" font-size="48">⁇</text></svg>',}
self.head = '<link rel="icon" type="image/svg+xml" sizes="48x48" '\
'href="/favicon.ico">'
super(SimpleHandler,self).__init__(request,server)
def _set_headers(self,content_type='application/json',response=200):
self.send_response(response)
self.send_header("Content-type",content_type)
self.end_headers()
def _html(self,message,title='Simple Server',extra=""):
"""This generates HTML with `message` in the h1 of body."""
content = f"<html><head><title>{title}</title>{self.head}</head>" \
f"<body><h1>{message}</h1>{extra}</body></html>"
return content.encode("utf8") # NOTE: must return a bytes object!
def do_GET(self):
"""Respond to a GET request."""
if self.path == "/":
self._set_headers('text/html')
fnames = [f'<li><a href="{fn}">{fn}</a></li>' for fn in self.files.keys()]
fnames.sort()
self.wfile.write(self._html(
"Welcome",extra='Try:'
'<ul>'
'<li><a href="/hello">/hello</a></li>'
f'{"".join(fnames)}'
'</ul>'
))
elif self.path == "/hello":
self._set_headers('text/html')
self.wfile.write(self._html("hello you"))
elif self.path in self.files:
content_type,content = self.files[self.path]
self.send_response(200)
self._set_headers(content_type)
self.wfile.write(content.encode())
else:
self.send_error(404)
# Note this update doesn't seem to happen to the in memory dict.
self.files[f"/{len(self.files)}"] = [
"text/html",self._html(len(self.files))]
def do_HEAD(self):
if self.path in ["/","/hello"]:
self._set_headers('text/html')
elif self.path in self.files:
content_type,_ = self.files[self.path]
self._set_headers(content_type)
else:
self.send_error(404)
def do_POST(self):
"""Should update pseudo-files with posted file contents."""
ctype,pdict = cgi.parse_header(
self.headers.get('content-type',self.headers.get_content_type()))
print("POSTED with content type",ctype)
content = None
if ctype == 'application/x-www-form-urlencoded':
print(" * This multipart/form-data method might not work")
content = {"content": str(self.rfile.read(int(self.headers['Content-Length'])).decode())}
elif ctype == 'multipart/form-data':
print(" * This multipart/form-data method might not work")
fields = cgi.parse_multipart(self.rfile,pdict)
content = {"content": fields.get('content')}
elif ctype == 'application/json':
data_string = self.rfile.read(int(self.headers['Content-Length']))
content = json.loads(data_string)
else:
self.send_error(404)
print(" * Received content:",content)
# Note this update doesn't seem to happen to the in memory dict.
self.files[self.path] = ['application/json',content]
self._set_headers(response=201)
self.wfile.write(json.dumps(content).encode())
if __name__ == '__main__':
print('FYI:')
print(' LANG =',os.getenv('LANG'))
print(' Default Charset Encoding =',sys.getdefaultencoding())
path_to_script = os.path.dirname(os.path.realpath(__file__))
print('Serving from path:',path_to_script)
os.chdir(path_to_script)
run(handler_class=SimpleHandler)
即使在加载 http://127.0.0.1:8081/ 之前,您也可以尝试向 self.files
dict 添加一些内容。 E.G.
curl -v -H 'content-type: application/json' \
--data-binary '{"this": "should work"}' http://127.0.0.1:8081/new_file
您可以看到服务器响应,并打印收到的数据,现在应该在 self.files
中,因此 /
应该显示它。
您可以将其与:
curl -v --data-urlencode 'content={"this": "should work"}' http://127.0.0.1:8081/new_file2
但这些都没有添加 self.files['/new_file']
或 '/new_file2'
,只是不清楚为什么。
应该能够请求 /new_file
或 /new_file2
,而那些是 404。
使用 do_GET
中的最后几行,多个 GET
/
请求应显示更多列出的项目。
$ curl http://127.0.0.1:8081
<html><head><title>Simple Server</title><link rel="icon" type="image/svg+xml" sizes="48x48" href="/favicon.ico"></head><body><h1>Welcome</h1>Try:<ul><li><a href="/hello">/hello</a></li><li><a href="/favicon.ico">/favicon.ico</a></li><li><a href="/oh">/oh</a></li></ul></body></html>
$ curl http://127.0.0.1:8081
<html><head><title>Simple Server</title><link rel="icon" type="image/svg+xml" sizes="48x48" href="/favicon.ico"></head><body><h1>Welcome</h1>Try:<ul><li><a href="/hello">/hello</a></li><li><a href="/favicon.ico">/favicon.ico</a></li><li><a href="/oh">/oh</a></li></ul></body></html>
将那些添加新键和值的行移动到 self.files
到 do_GET
的顶部表明它确实更新了,但只有一次,这看起来仍然很奇怪:
$ curl http://127.0.0.1:8081
<html><head><title>Simple Server</title><link rel="icon" type="image/svg+xml" sizes="48x48" href="/favicon.ico"></head><body><h1>Welcome</h1>Try:<ul><li><a href="/hello">/hello</a></li><li><a href="/2">/2</a></li><li><a href="/favicon.ico">/favicon.ico</a></li><li><a href="/oh">/oh</a></li></ul></body></html>
$ curl http://127.0.0.1:8081
<html><head><title>Simple Server</title><link rel="icon" type="image/svg+xml" sizes="48x48" href="/favicon.ico"></head><body><h1>Welcome</h1>Try:<ul><li><a href="/hello">/hello</a></li><li><a href="/2">/2</a></li><li><a href="/favicon.ico">/favicon.ico</a></li><li><a href="/oh">/oh</a></li></ul></body></html>
解决方法
好的,结果是为每个请求创建了一个新的 // temp value
var numTemp1 = 0
var numTemp2 = 0
// Randomizing numbers for easy Multiplication
@Published var num1 = Int.random(in: 0...5)
@Published var num2 = Int.random(in: 0...5)
,因此我不得不将 SimpleHandler
移出外部作用域,并且还要注意 {{1} 期间设置的内容}} 的 self.files
。这基本上使行为符合我的预期。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。