我想构建一个简单的服务器,该服务器根据请求的路径调度请求。所以我写了以下代码:
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import socket
class Handler:
"""处理对应资源的请求"""
def __init__(self, dispatcher):
self.dispatcher = dispatcher
def handle(self):
"""根据dispatcher解析出来的path,调用对应的方法"""
command = 'do_' + self.dispatcher.command
print(command)
if not hasattr(self, command):
return;
method = getattr(self, command)
method(self)
def do_GET(self):
response = {
'message': 'message'
}
dispatcher.protocol_version = 'HTTP/1.1'
dispatcher.send_response(200, 'OK')
dispatcher.send_header('Content-type', 'text/plain')
dispatcher.wfile.write(bytes(json.dumps(response), 'utf-8'))
class dispatcher(BaseHTTPRequestHandler):
"""
根据url的不同分发请求
"""
def handle_one_request(self):
try:
self.raw_requestline = self.rfile.readline(65537)
if len(self.raw_requestline) > 65536:
self.requestline = ''
self.request_version = ''
self.command = ''
self.send_error(HTTPStatus.REQUEST_URI_TOO_LONG)
return
if not self.raw_requestline:
self.close_connection = True
return
if not self.parse_request():
# An error code has been sent, just exit
return
print(self.command)
print(self.path)
if self.path.startswith('/wrong'):
Handler(self).handle()
self.wfile.flush() #actually send the response if not already done.
except socket.timeout as e:
#a read or a write timed out. Discard this connection
self.log_error("Request timed out: %r", e)
self.close_connection = True
return
if __name__ == '__main__':
server = HTTPServer(('', 8080), dispatcher)
server.serve_forever()
dispatcher
将解析传入的请求并获取路径,以便它可以决定要调用哪个处理程序(尽管目前只有一个)。
在handler
类中,它将基于http方法调用相应的方法。在do_GET
方法中,它将在调度程序中调用某些方法,这就是问题所在。
运行该程序并执行curl http://localhost:8080/wrong
时,出现以下异常:
GET
/wrong
do_GET
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 50072)
Traceback (most recent call last):
File "/usr/lib/python3.5/socketserver.py", line 313, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python3.5/socketserver.py", line 341, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python3.5/socketserver.py", line 354, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python3.5/socketserver.py", line 681, in __init__
self.handle()
File "/usr/lib/python3.5/http/server.py", line 422, in handle
self.handle_one_request()
File "hello.py", line 51, in handle_one_request
Handler(self).handle()
File "hello.py", line 18, in handle
method()
File "hello.py", line 25, in do_GET
dispatcher.send_response(200, 'OK')
File "/usr/lib/python3.5/http/server.py", line 487, in send_response
self.log_request(code)
AttributeError: 'int' object has no attribute 'log_request'
----------------------------------------
log_request
在dispatcher
的超类中定义如下:
def log_request(self, code='-', size='-'):
# blablabla
,它在dispatcher.send_response中被调用。
我想问题是解释器将200
视为self
。
如果我的猜测是正确的,为什么会这样?
如果不是,是什么原因导致此异常?
我知道这个问题仍然在语法层面,但是如果有人可以帮助我,我将不胜感激。