1. Please understand the HTTP protocol yourself
http://www.cnblogs.com/reboot51/p/8358129.html (click to jump)
2. Create socket service, listen to specified IP and port
3. Wait for client connection in blocking mode
4. Read the client request data and parse it
5. Prepare the server run context
6. Processing client Request data
7. read files according to user request path
8. Return the response result to the client
9. Program Entrance
10. Directory Structure
11. Operation
Python wsgiserver.py App:run
12. Source Code
a.wsgiserver.py file
#Encoding:utf-8ImportSocketImportStringioImportSYSImportLogging fromDatetimeImportDatetimelogger= Logging.getlogger (__name__)classWsgiserver (object): Address_family=socket.af_inet Socket_type=socket. Sock_stream request_queue_size= 30recv_size= 1024def __init__(self, server_address): Self._listen_socket= _listen_socket =Socket.socket (self.address_family, Self.socket_type) _l Isten_socket.setsockopt (socket. Sol_socket, SOCKET. SO_REUSEADDR,1) _listen_socket.bind (server_address) _listen_socket.listen (self.request_queue_size) _host, _port=_listen_socket.getsockname () self._server_name=Socket.getfqdn (_host) Self._server_port=_port Self._headers_set=[] self._application=None self._client=None Self._request_data=None Self._request_method=None Self._path=None self._request_version=None Self._start_response=Nonedefset_application (self, application): Self._application=ApplicationdefServer_forever (self): _listen_socket=Self._listen_socket Logger.info ('Listen on%s:%s', Self._server_name, Self._server_port) while1: Try: self._client, _addr=_listen_socket.accept () self._handle_request (_ADDR)exceptKeyboardinterrupt as E:logger.info ('Interrupt') Break exceptbaseexception as E:logger.error (e)def_handle_request (Self, client_addr): Self._request_data= _request_data =self._client.recv (self.recv_size) self._parse_request_data (_request_data) _env=self._get_environment (client_addr) _result=self._application (_env, Self.start_response) self._finish_response (_result)def_parse_request_data (Self, request_data): _request_line= str (request_data.splitlines () [0]). Rstrip ('\ r \ n') (Self._request_method, Self._path, self._request_version)=_request_line.split ()def_get_environment (Self, client_addr): _env={} _env['wsgi.version'] = (1, 0) _env['Wsgi.url_scheme'] ='http'_env['Wsgi.input'] = Stringio.stringio (self._request_data) _env['wsgi.errors'] =Sys.stderr _env['Wsgi.multithread'] =False _env['wsgi.multiprocess'] =False _env['wsgi.run_once'] =False _env['Request_method'] =self._request_method.upper () _env['Path_info'] =Self._path _env['server_name'] =self._server_name _env['Server_port'] =Self._server_port _env['http_client_ip'] =Client_addr[0] Logger.info ('%s %s%s%s', _env['http_client_ip'], DateTime.Now (). Strftime ('%y-%m-%d%h:%m:%s'), _env['Request_method'], _env['Path_info']) return_envdefStart_response (self, status, Response_headers, Exc_info=none): _server_headers = [ ('Date','Sun, 7 June 23:07:04 GMT'), ('Server','Wsgiserver 0.1')] Self._headers_set= [Status, Response_headers +_server_headers]def_finish_response (self, result): _status, _response_headers=Self._headers_set _response='http/1.1 {status}\r\n'. Format (Status=_status) for_headerinch_response_headers: _response+='{0}:{1}\r\n'. Format (*_header) _response+='\ r \ n' for_datainchResult: _response+=_data Self._client.sendall (_response) self._client.close ()defMake_server (server_address, application): Server=wsgiserver (server_address) server.set_application (application)returnServerif __name__=='__main__': Logging.basicconfig ( level=logging. DEBUG) Server_addr= ('0.0.0.0', 43002) App_path= Sys.argv[1] module, application= App_path.split (':') Module=__import__(module) application=getattr (module, application) httpd=Make_server (SERVER_ADDR, application) httpd.server_forever ()
b.app.py file
#Encoding:utf-8ImportOSclasspagenotfoundexception (baseexception):PassdefRender (filename, dirname='HTML'): _path=os.path.join (dirname, filename)ifos.path.exists (_path): With open (_path,'RB') as handler:returnHandler.read ()RaisePagenotfoundexception ('File not found:%s'%_path)defRun (env, start_response): _path= Env.get ('Path_info') Response="' Try: _path='index.html' if_path = ='/' Else_path[1:] if_path.endswith ('. CSS'): Start_response ('OK', [('Content-type','Text/css')]) elif_path.endswith ('. js'): Start_response ('OK', [('Content-type','Text/javascript')] elif_path.endswith ('. html'): Start_response ('OK', [('Content-type','text/html')]) Else: Start_response ('OK', [('Content-type','Text/plain'), ('content-disposition','attachment; filename=%s'%Os.path.basename (_path)]) Response=render (_path)exceptPagenotfoundexception as E:response= Render ('404.html') return[Response,'\ r \ n']
Python implements a simple Web server