1. Understand CGI and WSGI
(1)CGI
CGI (Common Gateway Interface) is a general gateway interface, that is, the interface protocol. The front end sends a URL (carrying request type, parameters, cookie s and other information) request to the server. The server writes various parameters of the request into the process environment variables, such as REQUEST_METHOD,PATH_INFO, and then start the CGI module and send it to the CGI program, CGI program (which can be written in various languages, such as C, C + +, VB and Delphi) parses various parameters from environment variables, and then outputs the content to standard output (for example, cout a piece of HTML code). These contents are not printed on the console, but finally respond to your browser and render the web page. Every time you send a request to CGI, a CGI process will be generated. This is the so-called fork and exec mode, which is often the crux of the concurrency bottleneck. Reverse proxy and large distributed systems can be used to a certain extent Reduce these pressures to a certain extent.
(2)WSGI
WSGI (Python Web Server Gateway Interface, abbreviated as WSGI) is a web server gateway interface, which is also an interface protocol. The front end sends a URL to the server (carrying request type, parameters, cookie s and other information) request. The server passes various parameters of the request to the WSGI module. WSGI pythonizes various parameters, encapsulates them as request objects, passes them to the WSGI Application registered according to the WSGI interface standard, and returns the response parameter to the client.
2. Introduction to wsgiref Library
Wsgiref is a python built-in library that implements a simple WSGI Server and WSGI Application. Using this library, we can easily implement a custom web architecture without considering the TCP/HTTP layer protocol. The source code of the library is located in the / django/lib/wsgiref folder. The library provides five modules:
* util -- Miscellaneous useful functions and wrappers * headers -- Manage response headers * handlers -- base classes for server/gateway implementations * simple_server -- a simple BaseHTTPServer that supports WSGI * validate -- validation wrapper that sits between an app and a server to detect errors in either
The following is mainly about simple_ The key functions and usage of the server module are described
3. wsgiref.simple_server class usage and partial source code analysis
(1) Let's start with the previous code
The code comes from simple_ server. Last 7 lines of PY
if __name__ == '__main__': with make_server('', 8000, demo_app) as httpd: sa = httpd.socket.getsockname() print("Serving HTTP on", sa[0], "port", sa[1], "...") import webbrowser webbrowser.open('http://localhost:8000/xyz?abc') httpd.handle_request() # serve one request, then exit
This code expresses two meanings: start the service - > process‘ http://localhost:8000/xyz?abc 'request
(2) Analyze the service startup process of make_server

server_class passes in two parameters, The first tuple (host,ip), the second WSGIRequestHandler class, the first parameter is used to start the service of socketserver.TCPServer (Mark 1 in the figure), and the second parameter WSGIRequestHandler is used to initialize the self.RequestHandlerClass attribute of BaseServer class (Mark 2 in the figure), which is used to initialize the object with the finish_request() function (Mark 3 in the figure), the main purpose is to realize the subsequent callback function call
(3) Analyze the process of handle_request() function
The implementation process of this function is in the base class BaseServer. This function mainly implements the following functions (epoll asynchronous concurrency is not discussed here. Please refer to my previous blog for relevant epoll contents):
get_request()—->verify_request()—->process_request()—->shutdown_request()
Just look at the function name to understand the whole process
(4) Now it's time to focus. Let's see how the demo_app callback is implemented
Next, we mainly analyze make_ The third parameter demo of the server() function_ How does app implement the call
Through the source code, we can see that finish_ RequestHandlerClass initialization is implemented in the request () function, that is, WSGIRequestHandler initialization
def finish_request(self, request, client_address): """Finish one request by instantiating RequestHandlerClass.""" self.RequestHandlerClass(request, client_address, self)
Take a picture and you can see everything clearly

a. after the service is started, WSGIServer passes set_app saves the callback function
b. finish_request() instantiates WSGIRequestHandler and calls the constructor of its base class BaseRequestHandle. The constructor also calls the handle processing function. Since the derived class WSGIRequestHandler rewrites the handle method, it actually calls the handle function of WSGIRequestHandler class. As shown in Figure 3 above, get the callback function object and execute it.
def run(self, application): try: self.setup_environ() self.result = application(self.environ, self.start_response) self.finish_response() . . . . . . . . . . . . . .
So far, everything is clear! Next, you can freely process the callback function!
4. DIY web Architecture
Imitate the model - > route - > View - > template model of django architecture to realize http requests and display web pages
(1)models.py
Use redis to create two string structures, name and url
import redis class Model: def __init__(self): conn = redis.Redis() self.name = conn.get('name') self.url = conn.get('url')
(2)urls.py
import views urlpattern = ((r'/fate0729/', views.login),)
(3)views.py
Realize the rendering of the template through the model
from models import Model import re def render(html_path, **wargvs): with open(html_path, 'r') as pf: data = ''.join(pf.readlines()) print(data) if wargvs is not None: # For testing purposes, the fixed format obj. Is used here attr results = re.findall(r'{{(.*)}}', data) for result in results: obj_attr_list = result.partition('.') obj = wargvs.get(obj_attr_list[0]) attr = obj_attr_list[-1] regex = r'{{.*\.%s}}' %(attr) value = getattr(obj,attr).decode('utf-8') print(attr,value) data = re.sub(regex,str(value), data) return data.encode('utf-8') def login(request): model = Model() return render('web.html', **{'model':model})
(4)main.py
from wsgiref.simple_server import make_server import urls def routers(): urlpattern=urls.urlpattern return urlpattern def applications(environ,start_response): path=environ.get("PATH_INFO") start_response('200 OK', [('Content-Type', 'text/html'),('Charset', 'utf8')]) urlpattern=routers() func=None for item in urlpattern: if path==item[0]: func=item[1] break if func: return [func(environ)] else: return [b"<h1>404!<h1>"] if __name__ == '__main__': conn = make_server('127.0.0.1', 8001, applications) print('server is working...') conn.serve_forever()
(5) Testing
python main.py
Open the browser and enter: 127.0 0.1/fate0729/

Publisher: full stack programmer, stack length, please indicate the source for Reprint: https://javaforall.cn/120042.html Original link: https://javaforall.cn