博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 搭建web服务器
阅读量:4216 次
发布时间:2019-05-26

本文共 9263 字,大约阅读时间需要 30 分钟。

使用 httpie 在命令行进行测试

1、最基本的:

# _*_coding :utf-8 _*_import httpiefrom http.server import BaseHTTPRequestHandler,HTTPServerclass RequestHandler(BaseHTTPRequestHandler):    '''处理请求并返回页面'''    # 页面模板    Page = '''\                        

Hello, web!

''' def do_GET(self): self.send_response(200) self.send_header("Content-type","text/html") self.send_header("Content-length",str(len(self.Page))) #字符串类型 self.end_headers() self.wfile.write(self.Page.encode())if __name__ == '__main__': print("server start...") serverAddr = ('',9999) #链接不上可能是端口号被占用 换个试试 server = HTTPServer(serverAddr,RequestHandler) server.serve_forever()

2、封装创建page,发送报文的方法

# _*_coding :utf-8 _*_import httpiefrom http.server import BaseHTTPRequestHandler,HTTPServerclass RequestHandler(BaseHTTPRequestHandler):    '''处理请求并返回页面'''    # 页面模板    Page = '''                                    
Header Value
Date and time {date_time}
Client host {client_host}
Client port {client_port}
Command {command}
Path {path}
''' def do_GET(self): page = self.create_page() self.send_content(page) def create_page(self): values = { 'date_time': self.date_time_string(), 'client_host': self.client_address[0], 'client_port': self.client_address[1], 'command': self.command, 'path': self.path } page = self.Page.format(**values) #dict为参数的传递方式 ** return page def send_content(self,page): self.send_response(200) self.send_header("Content-type", "text/html") self.send_header("Content-length", str(len(self.Page))) # 字符串类型 self.end_headers() self.wfile.write(page.encode()) #这里必须转化威字节(bytes)类型 否则报错if __name__ == '__main__': print("server start...") serverAddr = ('',9999) #链接不上可能是端口号被占用 换个试试 server = HTTPServer(serverAddr,RequestHandler) server.serve_forever()

3、增加了对路径的异常处理:

# _*_coding :utf-8 _*_import httpieimport sys,osfrom http.server import BaseHTTPRequestHandler,HTTPServerclass RequestHandler(BaseHTTPRequestHandler):    '''处理请求并返回页面'''    # 页面模板    Page = '''                                    
Header Value
Date and time {date_time}
Client host {client_host}
Client port {client_port}
Command {command}
Path {path}
''' Error_Page = """\

Error accessing {path}

{msg}

""" def do_GET(self): try: #文件完整路径 full_path = os.getcwd() + self.path #如果该路径不存在... if not os.path.exists(full_path): # 抛出异常:文件未找到 raise ServerException("'{0}' not found".format(self.path)) # 如果该路径是一个文件 elif os.path.isfile(full_path): # 调用 handle_file 处理该文件 self.handle_file(full_path) # 如果该路径不是一个文件 # 抛出异常:该路径为不知名对象 else: raise ServerException("Unknown object '{0}'".format(self.path)) except Exception as msg: #msg则是上面抛出的信息 self.handle_error(msg) def create_page(self): values = { 'date_time': self.date_time_string(), 'client_host': self.client_address[0], 'client_port': self.client_address[1], 'command': self.command, 'path': self.path } page = self.Page.format(**values) #dict为参数的传递方式 ** return page def send_content(self,page): #这里不再是个server1一样了 需要传参数page self.send_response(200) self.send_header("Content-type", "text/html") self.send_header("Content-length", str(len(self.Page))) # 字符串类型 self.end_headers() self.wfile.write(page.encode()) #这里必须转化威字节(bytes)类型 否则报错 def handle_file(self,full_path): try: with open(full_path,"r") as reader: #读字节 故在sent_content()中不需要转化为bytes了 content = reader.read() self.send_content(content) except IOError as msg: msg = "'{0}' cannot be read :{1}".format(self.path,msg) self.handle_error(msg) def handle_error(self,msg): content = self.Error_Page.format(path = self.path,msg = msg) self.send_content(content)class ServerException(Exception): '''服务器内部错误''' passif __name__ == '__main__': print("server start...") serverAddr = ('',9999) #链接不上可能是端口号被占用 换个试试 server = HTTPServer(serverAddr,RequestHandler) server.serve_forever()

plain.html为自己创建的静态网页

4、增加了代码的重构,更加简明,易扩展

#-*- coding:utf-8 -*-import sys, os, subprocessfrom http.server import HTTPServer,BaseHTTPRequestHandler#-------------------------------------------------------------------------------class ServerException(Exception):    '''服务器内部错误'''    pass#-------------------------------------------------------------------------------class base_case(object):    '''条件处理基类'''    def handle_file(self, handler, full_path):        try:            with open(full_path, 'r') as reader: #这里不要直接读城b 的否则会与下面的decode冲突                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):        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):    '''文件或目录不存在'''    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):    '''可执行脚本'''    def run_cgi(self, handler):        data = subprocess.check_output(["python", handler.full_path])        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):    '''文件存在的情况'''    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):    '''在根路径下返回主页文件'''    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_always_fail(base_case):    '''默认处理'''    def test(self, handler):        return True    def act(self, handler):        raise ServerException("Unknown object '{0}'".format(handler.path))#-------------------------------------------------------------------------------class RequestHandler(BaseHTTPRequestHandler):    '''    请求路径合法则返回相应处理    否则返回错误页面    '''    Cases = [case_no_file(),             case_cgi_file(),             case_existing_file(),             case_directory_index_file(),             case_always_fail()]    # 错误页面模板    Error_Page = """                        

Error accessing {path}

{msg}

""" def do_GET(self): try: # 得到完整的请求路径 self.full_path = os.getcwd() + self.path # 遍历所有的情况并处理 for case in self.Cases: if case.test(self): case.act(self) break # 处理异常 except Exception as msg: self.handle_error(msg) def handle_error(self, msg): content = self.Error_Page.format(path=self.path, msg=msg) self.send_content(content, 404) # 发送数据到客户端 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.encode())#-------------------------------------------------------------------------------if __name__ == '__main__': print("server start...") serverAddress = ('', 9999) server = HTTPServer(serverAddress, RequestHandler) server.serve_forever()

此时的 状态为 404了

参考:https://zhuanlan.zhihu.com/p/21323273?utm_source=qq&utm_medium=social

你可能感兴趣的文章
STM32开源代码——UART串口程序
查看>>
个人项目——STM32接入机智云教程
查看>>
STemWin学习笔记——字体
查看>>
STemWin学习笔记——XBF格式字体显示
查看>>
STemWin学习笔记——TTF格式字体显示
查看>>
STemWIn学习笔记——汉字显示(外部存储器)
查看>>
Python学习笔记——Python提高-2
查看>>
Python学习笔记——多任务-进程
查看>>
Python学习笔记——多任务-线程
查看>>
Vim学习笔记——前言
查看>>
Vim学习笔记——小试牛刀
查看>>
Vim学习笔记——帮助
查看>>
Python学习笔记——网络通信过程
查看>>
Python学习笔记——正则表达式
查看>>
Python学习笔记——数据结构与算法
查看>>
Python学习笔记——顺序表
查看>>
Python学习笔记——链表
查看>>
MarkDown学习笔记——语法
查看>>
Python学习笔记——栈和队列
查看>>
Python学习笔记——排序与搜索
查看>>