Python dynamic server web page (WSGI interface is required). The basic implementation steps are as follows:
1. Wait for the client's link, and the server will receive an http protocol request datagram
2. Use regular expression to parse the request datagram (request mode, environment for extracting files)
3. After extracting the file environment, the file name is converted to the module name by truncating the fetching method
4. Use m = import () to get a module with a return value of m
5. Create an env Dictionary: it contains various key value pairs such as request mode and file environment
6. Create a new dynamic script, in which the application function is defined, and it must contain the parameters of env and start'u response (also the call method in the server)
7. Define status code and response headers in this dynamic script (note that they are in dictionary form, such as content type)
8. Then call start'u response (status, headers), but note that this function is defined on the server
9. Write dynamic execution program in dynamic script
The return value of 10. M.application is the body of the response packet. Its data header is integrated in start response
11. The dynamic web page can be displayed by splicing the data header with the data body and sending it to the client
MyWebServer # coding:utf-8 import socket import re import sys from multiprocessing import Process from MyWebFramework import Application #Set static file root HTML_ROOT_DIR = "./html" WSGI_PYTHON_DIR = "./wsgipython" class HTTPServer(object): """""" def __init__(self, application): """Constructor, application Refers to the framework app""" self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.app = application def start(self): self.server_socket.listen(128) while True: client_socket, client_address = self.server_socket.accept() #print("[%s,%s] user connected"% (client [u address [0], client [u address [1])) print("[%s, %s]User connected" % client_address) handle_client_process = Process(target=self.handle_client, args=(client_socket,)) handle_client_process.start() client_socket.close() def start_response(self, status, headers): """ status = "200 OK" headers = [ ("Content-Type", "text/plain") ] star """ response_headers = "HTTP/1.1 " + status + "\r\n" for header in headers: response_headers += "%s: %s\r\n" % header self.response_headers = response_headers def handle_client(self, client_socket): """Processing client requests""" #Get client request data request_data = client_socket.recv(1024) print("request data:", request_data) request_lines = request_data.splitlines() for line in request_lines: print(line) #Parse request message # 'GET / HTTP/1.1' request_start_line = request_lines[0] #Extract the file name requested by the user print("*" * 10) print(request_start_line.decode("utf-8")) file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1) method = re.match(r"(\w+) +/[^ ]* ", request_start_line.decode("utf-8")).group(1) env = { "PATH_INFO": file_name, "METHOD": method } response_body = self.app(env, self.start_response) response = self.response_headers + "\r\n" + response_body #Return response data to client client_socket.send(bytes(response, "utf-8")) #Close client connection client_socket.close() def bind(self, port): self.server_socket.bind(("", port)) def main(): sys.path.insert(1, WSGI_PYTHON_DIR) if len(sys.argv) < 2: sys.exit("python MyWebServer.py Module:app") # python MyWebServer.py MyWebFrameWork:app module_name, app_name = sys.argv[1].split(":") # module_name = "MyWebFrameWork" # app_name = "app" m = __import__(module_name) app = getattr(m, app_name) http_server = HTTPServer(app) # http_server.set_port http_server.bind(8000) http_server.start() if __name__ == "__main__": main()
MyWebFrameWork # coding:utf-8 import time # from MyWebServer import HTTPServer #Set static file root HTML_ROOT_DIR = "./html" class Application(object): """The core part of the framework, that is, the subject program of the framework, and the framework is universal""" def __init__(self, urls): #Set routing information self.urls = urls def __call__(self, env, start_response): path = env.get("PATH_INFO", "/") # /static/index.html if path.startswith("/static"): #To access static files file_name = path[7:] #Open file, read content try: file = open(HTML_ROOT_DIR + file_name, "rb") except IOError: #No routing information found on behalf of, 404 error status = "404 Not Found" headers = [] start_response(status, headers) return "not found" else: file_data = file.read() file.close() status = "200 OK" headers = [] start_response(status, headers) return file_data.decode("utf-8") for url, handler in self.urls: #("/ctime", show_ctime) if path == url: return handler(env, start_response) #No routing information found on behalf of, 404 error status = "404 Not Found" headers = [] start_response(status, headers) return "not found" def show_ctime(env, start_response): status = "200 OK" headers = [ ("Content-Type", "text/plain") ] start_response(status, headers) return time.ctime() def say_hello(env, start_response): status = "200 OK" headers = [ ("Content-Type", "text/plain") ] start_response(status, headers) return "hello itcast" def say_haha(env, start_response): status = "200 OK" headers = [ ("Content-Type", "text/plain") ] start_response(status, headers) return "hello haha" urls = [ ("/", show_ctime), ("/ctime", show_ctime), ("/sayhello", say_hello), ("/sayhaha", say_haha), ] app = Application(urls) # if __name__ == "__main__": # urls = [ # ("/", show_ctime), # ("/ctime", show_ctime), # ("/sayhello", say_hello), # ("/sayhaha", say_haha), # ] # app = Application(urls) # http_server = HTTPServer(app) # http_server.bind(8000) # http_server.start()