简易Web服务器
来源:互联网 发布:图像处理相关算法 编辑:程序博客网 时间:2024/05/22 12:18
基础知识点
首先简单认识TCP/IP协议
请访问http://www.cnblogs.com/roverliang/p/5176456.html
TCP/IP协议族中有一个重要的概念是分层,TCP/IP协议按照层次分为以下四层
TCP/IP通信数据流
使用HTTP协议进行数据传输的过程
HTTP请求报文
HTTP响应报文
TCP协议三次握手过程分析
请访问 http://blog.csdn.net/wwwdc1012/article/details/77857265
Python CGI编程 : http://www.runoob.com/python/python-cgi.html
CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上如:HTTP服务器,提供同客户端HTML页面的接口。
Python BaseHTTPServer 模块解析
http://blog.csdn.net/xhw88398569/article/details/49179967
下面为一个简单的Web服务器
该服务器工作流程:
(1) 定义多个可能遇到的多种情况及对应的处理方法:
是否是 cgi
请求 -> 文件是否存在 -> 目录下是否存在index.html -> 目录下是否不存在index.html -> 其他情况
Cases = [case_no_file(), case_cgi_file(), case_existing_file(), case_directory_index_file(), case_directory_no_index_file(), case_always_fail()]
(2) 逐个检查匹配到哪种情况,并处理
for case in self.Cases: if case.test(self): case.act(self) break
import sys, os, BaseHTTPServer#-----------------------------------------------------------# 服务器异常类class ServerException(Exception): '''For internal error reporting.''' pass#-----------------------------------------------------------class base_case(object): '''Parent for case handlers.''' def handle_file(self, handler, full_path): """处理文件,例如读取 index.html 文件,然后输出到响应报文中 """ try: with open(full_path, 'rb') as reader: content = reader.read() handler.send_content(content) except IOError as msg: msg = "'{0}' cannot be read: {1}".format(full_path, msg) handler.handle_error(msg) # 异常信息 def index_path(self, handler): """合成index.html的全路径 """ return os.path.join(handler.full_path, 'index.html') def test(self, handler): assert False, 'Not implemented.' def act(self, handler): assert False, 'Not implemented.'#-----------------------------------------------------------class case_no_file(base_case): '''File or directory does not exist. 给一个路径名称,文件或目录都不存在的情况 ''' def test(self, handler): # 测试路径是否存在 return not os.path.exists(handler.full_path) def act(self, handler): # 不存在时执行的动作,返回服务器异常 raise ServerException("'{0}' not found".format(handler.path))#-----------------------------------------------------------class case_cgi_file(base_case): '''Something runnable. cgi,当服务器上的脚本存在时则执行脚本,返回执行结果 ''' def run_cgi(self, handler): # 执行脚本 cmd = "python " + handler.full_path child_stdin, child_stdout = os.popen2(cmd) child_stdin.close() data = child_stdout.read() child_stdout.close() handler.send_content(data) def test(self, handler): # 测试脚本是否存在 return os.path.isfile(handler.full_path) and \ handler.full_path.endswith('.py') def act(self, handler): self.run_cgi(handler)#-----------------------------------------------------------class case_existing_file(base_case): '''File exists. 给一个文件名,当文件存在时,处理 ''' def test(self, handler): return os.path.isfile(handler.full_path) def act(self, handler): self.handle_file(handler, handler.full_path)#-----------------------------------------------------------class case_directory_index_file(base_case): '''Serve index.html page for a directory. 给一个目录名,当该目录下存在index.html时,处理并返回该index.html ''' def test(self, handler): return os.path.isdir(handler.full_path) and \ os.path.isfile(self.index_path(handler)) def act(self, handler): self.handle_file(handler, self.index_path(handler))#-----------------------------------------------------------class case_directory_no_index_file(base_case): '''Serve listing for a directory without an index.html page. 目录下不存在index.html时,列出该目录下的所有文件,并渲染到简单的模板中 ''' # How to display a directory listing. Listing_Page = '''\ <html> <body> <ul> {0} </ul> </body> </html> ''' def list_dir(self, handler, full_path): try: entries = os.listdir(full_path) bullets = ['<li>{0}</li>'.format(e) for e in entries if not e.startswith('.')] page = self.Listing_Page.format('\n'.join(bullets)) handler.send_content(page) except OSError as msg: msg = "'{0}' cannot be listed: {1}".format(self.path, msg) handler.handle_error(msg) def test(self, handler): return os.path.isdir(handler.full_path) and \ not os.path.isfile(self.index_path(handler)) def act(self, handler): self.list_dir(handler, handler.full_path)#------------------------------------------------------class case_always_fail(base_case): '''Base case if nothing else worked. 当之前所有的情况都失败时,执行这个 ''' def test(self, handler): return True def act(self, handler): raise ServerException("Unknown object '{0}'".format(handler.path))#------------------------------------------------------class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): ''' If the requested path maps to a file, that file is served. If anything goes wrong, an error page is constructed. ''' Cases = [case_no_file(), case_cgi_file(), case_existing_file(), case_directory_index_file(), case_directory_no_index_file(), case_always_fail()] # How to display an error. 显示错误信息的模板 Error_Page = """\ <html> <body> <h1>Error accessing {path}</h1> <p>{msg}</p> </body> </html> """ # Classify and handle request. 处理GET请求 def do_GET(self): try: # Figure out what exactly is being requested. self.full_path = os.getcwd() + self.path # Figure out how to handle it. for case in self.Cases: if case.test(self): case.act(self) break # Handle errors. except Exception as msg: self.handle_error(msg) # Handle unknown objects. def handle_error(self, msg): content = self.Error_Page.format(path=self.path, msg=msg) self.send_content(content, 404) # Send actual content. 设置响应报文 def send_content(self, content, status=200): self.send_response(status) self.send_header("Content-type", "text/html") self.send_header("Content-Length", str(len(content))) self.end_headers() self.wfile.write(content)#-------------------------------------------------------------------------------if __name__ == '__main__': serverAddress = ('', 8080) server = BaseHTTPServer.HTTPServer(serverAddress, RequestHandler) server.serve_forever()
参考:500 lines or less 中文翻译计划 《简易Web服务器》
https://github.com/HT524/500LineorLess_CN/blob/master/%E7%AE%80%E6%98%93web%E6%9C%8D%E5%8A%A1%E5%99%A8%20A%20simple%20web%20server/%E7%AE%80%E6%98%93web%E6%9C%8D%E5%8A%A1%E5%99%A8.md
- 简易Web服务器
- 简易Web服务器
- 简易web服务器
- 简易Web服务器实现
- 简易Web服务器实现
- 简易web服务器
- 手写简易WEB服务器
- 简易Web服务器
- 简易线程池web服务器
- WinC++简易的web服务器
- Linux下简易web服务器实现
- Python搭建简易web服务器,超好用~
- 自己动手开发简易的Web服务器
- JAVA简易WEB服务器(一)
- JAVA简易WEB服务器(二)
- JAVA简易WEB服务器(三)
- JAVA简易WEB服务器(四)
- JAVA简易WEB服务器(五)
- acmcoder简单计算
- Unity_FPS游戏_Boss模块流程_01
- 从一个最简单的例子来看Retrofit(一)
- 人生永远没有太晚的开始
- C++动态申请二维数组
- 简易Web服务器
- hibernate持久化对象的四个状态
- 关于技术和产品的一些体会
- NOIP复赛模板及技巧积累(不定期更新)
- 【排序算法大合集】
- 查看CDH各组件版本
- 西瓜书《机器学习》课后答案——chapter5
- 次小生成树的学习 POJ1679 The Unique MST
- palindrome-partitioning-ii