Python實現簡易Web伺服器

來源:互聯網
上載者:User

標籤:path   hand   ring   ons   pat   post   multi   __init__   handle   

 

 1、請自行瞭解HTTP協議

http://www.cnblogs.com/reboot51/p/8358129.html(點擊跳轉)

2、建立Socket服務,監聽指定IP和連接埠

3、以阻塞方式等待用戶端串連

4、讀取用戶端請求資料並進行解析

5、準備伺服器運行上下文

6、處理用戶端請求資料

7、根據使用者請求路徑讀取檔案

8、返迴響應結果給用戶端

 

9、程式入口

10、目錄結構

11、運行

python wsgiserver.py app:run

12、源碼

a.wsgiserver.py檔案

#encoding:utf-8import socketimport StringIOimport sysimport loggingfrom datetime import datetimelogger = logging.getLogger(__name__)class WSGIServer(object):    address_family = socket.AF_INET    socket_type = socket.SOCK_STREAM    request_queue_size = 30    recv_size = 1024    def __init__(self, server_address):        self._listen_socket = _listen_socket = socket.socket(self.address_family,                                                         self.socket_type)       _listen_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 = None    def set_application(self, application):        self._application = application    def server_forever(self):            _listen_socket = self._listen_socket        logger.info(‘listen on %s:%s‘, self._server_name, self._server_port)      while 1:                  try:                self._client, _addr = _listen_socket.accept()                self._handle_request(_addr)            except KeyboardInterrupt as e:                logger.info(‘interrupt‘)                break            except BaseException 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 _env    def start_response(self, status, response_headers, exc_info=None):            _server_headers = [            (‘Date‘, ‘Sun, 7 Jun 2015 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 _header in _response_headers:               _response += ‘{0}:{1}\r\n‘.format(*_header)               _response += ‘\r\n‘        for _data in result:                        _response += _data        self._client.sendall(_response)        self._client.close()def make_server(server_address, application):    server = WSGIServer(server_address)    server.set_application(application)    return server            if __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檔案

#encoding:utf-8import osclass PageNotFoundException(BaseException):    passdef render(filename, dirname=‘html‘):    _path = os.path.join(dirname, filename)    if os.path.exists(_path):            with open(_path, ‘rb‘) as handler:                 return handler.read()                  raise PageNotFoundException(‘file not found:%s‘ % _path)   def run(env, start_response):    _path = env.get(‘PATH_INFO‘)    response = ‘‘    try:        _path = ‘index.html‘ if _path == ‘/‘ else _path[1:]        if _path.endswith(‘.css‘):            start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/css‘)])        elif _path.endswith(‘.js‘):           start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/javascript‘)]        elif _path.endswith(‘.html‘):            start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)])        else:            start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/plain‘), (‘Content-Disposition‘, ‘attachment; filename=%s‘ % os.path.basename(_path))])        response = render(_path)     except PageNotFoundException as e:        response = render(‘404.html‘)            return [response, ‘\r\n‘]

 

 

 

 

 

 

 

 

Python實現簡易Web伺服器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.