#coding = utf-8
from http.server import BaseHTTPRequestHandler, HTTPServer class RequestHandler(BaseHTTPRequestHandler):
Page = '''
<html>
<body>
<p>Hello, world!</p>
</body>
</html>
'''
#重载do_GET方法
def do_GET(self):
self.send_response(200) #发送状态码,200是ok
self.send_header('Content-Type', 'text/html')
'''
发送http头部信息,text/html指HTML格式
另外还有诸如text/plain纯文本格式,image/gif GIF图片格式
通过头部信息浏览器就知道如何处理所发来的内容了
另外还有self.send_header('Content-Encoding','gzip')是指让浏览器按照压缩方式处理内容
另外还有很多。。。
'''
self.end_headers()
self.wfile.write(self.Page.encode()) #---------------------------------------------------------------------- if __name__ == '__main__':
serverAddress = ('', 8080)
server = HTTPServer(serverAddress, RequestHandler)
server.serve_forever()

简单的web服务器

如果我把self.send_response(200)状态码改为404,那么就会出现下述情况:

 #coding = utf-8
from http.server import BaseHTTPRequestHandler, HTTPServer class RequestHandler(BaseHTTPRequestHandler):
#<tr>代表一行,<td>代表一列
Page = '''
<html>
<body>
<table>
<tr> <td>Header</td> <td>Value</td> </tr>
<tr> <td>Date and time</td> <td>{date_time}</td> </tr>
<tr> <td>Client host</td> <td>{client_host}</td> </tr>
<tr> <td>Client port</td> <td>{client_port}</td> </tr>
<tr> <td>Command</td> <td>{command}</td> </tr>
<tr> <td>Path</td> <td>{path}</td> </tr>
</table>
</body>
</html>
''' def do_GET(self):
page = self.create_page()
self.send_content(page) def send_content(self, page):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write(page.encode()) 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)
'''
字符串格式化函数
通过字典设置参数
site = {'name': '菜鸟教程', 'url': 'www.runoob.com'}
print('网站名:{name}, 地址:{url}'.format(**site))
'''
return page #---------------------------------------------------------------------- if __name__ == '__main__':
serverAddress = ('', 8080)
server = HTTPServer(serverAddress, RequestHandler)
server.serve_forever()

显示请求的信息

 #coding = utf-8
from http.server import BaseHTTPRequestHandler, HTTPServer
import sys, os class serverException(Exception):
'''服务器内部错误'''
pass class RequestHandler(BaseHTTPRequestHandler):
errorPage = """\
<html>
<body>
<h1>Error accessing {path}</h1>
<p>{msg}</p>
</body>
</html>
""" def do_GET(self):
try:
fullPath = os.getcwd() + self.path
if not os.path.exists(fullPath): #不存在就报错
raise serverException("'{0}' not found".format(self.path))
elif os.path.isfile(fullPath): #如果是文件,则打开
self.handle_file(fullPath)
else: #其余情况
raise serverException("Unknown object '{0}'".format(self.path))
except Exception as msg:
self.handle_error(msg) def handle_error(self, msg):
content = self.errorPage.format(path=self.path, msg=msg)
self.send_content(content, 404) def send_content(self, page, status=200):
self.send_response(status)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write(page.encode()) def handle_file(self, fullPath):
try:
f = open(fullPath, 'r') #python3要注意是以r读还是rb读
content = f.read()
self.send_content(content)
except IOError as msg:
msg = "'{0}' cannot be read: {1}".format(self.path, msg)
self.handle_error(msg) #---------------------------------------------------------------------- if __name__ == '__main__':
serverAddress = ('', 8080)
server = HTTPServer(serverAddress, RequestHandler)
server.serve_forever()

响应静态页面

在这里的话需要把plain.html这个文件放在代码相同目录下。
测试情况如下:

 #coding = utf-8
from http.server import BaseHTTPRequestHandler, HTTPServer
import sys, os class serverException(Exception):
'''服务器内部错误'''
pass '''
将不同的情况单独写成一个类,最后将这些类保存在一个列表之中,这样最后遍历列表即可,不需要if-elif了
'''
class case_no_file(object):
'''路径不存在'''
def test(self, handler):
return not os.path.exists(handler.fullPath)
def act(self, handler):
raise serverException("'{0}' not found".format(handler.path)) class case_is_file(object):
'''路径是文件'''
def test(self, handler):
return os.path.isfile(handler.fullPath)
def act(self, handler):
handler.handle_file(handler.fullPath) class case_always_fail(object):
'''不满足时的默认处理类'''
def test(self, handler):
return True
def act(self, handler):
raise serverException("Unknown object '{0}'".format(handler.Path)) class case_directory_index_file(object):
'''进入根目录时显示主页'''
def index_path(self, handler):
return os.path.join(handler.fullPath, 'index.html') #前后合并
def test(self, handler):
return os.path.isdir(handler.fullPath) and os.path.isfile(self.index_path(handler))
def act(self, handler):
handler.handle_file(self.index_path(handler)) class RequestHandler(BaseHTTPRequestHandler):
caseList = [case_no_file(),
case_is_file(),
case_directory_index_file(),
case_always_fail()] errorPage = """\
<html>
<body>
<h1>Error accessing {path}</h1>
<p>{msg}</p>
</body>
</html>
""" def do_GET(self):
try:
self.fullPath = os.getcwd() + self.path
for case in self.caseList:
if case.test(self):
case.act(self)
break
except Exception as msg:
self.handle_error(msg) def handle_error(self, msg):
content = self.errorPage.format(path=self.path, msg=msg)
self.send_content(content, 404) def send_content(self, page, status=200):
self.send_response(status)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write(page.encode()) def handle_file(self, fullPath):
try:
f = open(fullPath, 'r') #python3要注意是以r读还是rb读
content = f.read()
self.send_content(content)
except IOError as msg:
msg = "'{0}' cannot be read: {1}".format(self.path, msg)
self.handle_error(msg) #---------------------------------------------------------------------- if __name__ == '__main__':
serverAddress = ('', 8080)
server = HTTPServer(serverAddress, RequestHandler)
server.serve_forever()

在url根目录显示主页

之前所做的是静态页面的显示,如果要显示动态页面的话就不能写成html的文件了,在这里可以使用CGI协议与脚本来实现动态页面。

服务器在收到客户端的请求后执行指定的CGI应用程序,CGI应用程序执行后再转换成服务器和浏览器能够理解的内容,比如说HTML页面。

下面的例子就是做一个展示当前时间的页面,先是用python实现了一个CGI脚本time.py,当浏览器请求这个CGI脚本的时候,服务器就会去执行time.py,然后得到执行结果的一段HTML形式的字符,最后就输出即可。

在这里就用到了python库中的subprocess模块,它的功能使fork一个子进程,然后运行一个外部程序。

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)

它的作用是执行args中的命令,并将其输出成字符串返回。

 #!/usr/bin/env python
import time print('''\
<html>
<body>
<p>Generated {0}</p>
</body>
</html>
'''.format(time.asctime()))

time.py

 #coding = utf-8
from http.server import BaseHTTPRequestHandler, HTTPServer
import sys, os
import subprocess class serverException(Exception):
'''服务器内部错误'''
pass '''
将不同的情况单独写成一个类,最后将这些类保存在一个列表之中,这样最后遍历列表即可,不需要if-elif了
'''
class case_no_file(object):
'''路径不存在'''
def test(self, handler):
return not os.path.exists(handler.fullPath)
def act(self, handler):
raise serverException("'{0}' not found".format(handler.path)) class case_is_file(object):
'''路径是文件'''
def test(self, handler):
return os.path.isfile(handler.fullPath)
def act(self, handler):
handler.handle_file(handler.fullPath) class case_always_fail(object):
'''不满足时的默认处理类'''
def test(self, handler):
return True
def act(self, handler):
raise serverException("Unknown object '{0}'".format(handler.Path)) class case_directory_index_file(object):
'''进入根目录时显示主页'''
def index_path(self, handler):
return os.path.join(handler.fullPath, 'index.html') #前后合并
def test(self, handler):
return os.path.isdir(handler.fullPath) and os.path.isfile(self.index_path(handler))
def act(self, handler):
handler.handle_file(self.index_path(handler)) class case_cgi_file(object):
'''脚本文件处理'''
def test(self, handler):
return os.path.isfile(handler.fullPath) and handler.fullPath.endswith('.py')
def act(self, handler):
handler.run_cgi(handler.fullPath) class RequestHandler(BaseHTTPRequestHandler):
caseList = [case_no_file(),
case_cgi_file(),
case_is_file(),
case_directory_index_file(),
case_always_fail()] errorPage = """\
<html>
<body>
<h1>Error accessing {path}</h1>
<p>{msg}</p>
</body>
</html>
""" def do_GET(self):
try:
self.fullPath = os.getcwd() + self.path
for case in self.caseList:
if case.test(self):
case.act(self)
break
except Exception as msg:
self.handle_error(msg) def handle_error(self, msg):
content = self.errorPage.format(path=self.path, msg=msg)
self.send_content(content, 404) def send_content(self, page, status=200):
self.send_response(status)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write(page.encode()) def handle_file(self, fullPath):
try:
f = open(fullPath, 'r') #python3要注意是以r读还是rb读
content = f.read()
self.send_content(content)
except IOError as msg:
msg = "'{0}' cannot be read: {1}".format(self.path, msg)
self.handle_error(msg) def run_cgi(self, fullPath):
data = subprocess.check_output(['python', fullPath])
self.send_content(data.decode()) #---------------------------------------------------------------------- if __name__ == '__main__':
serverAddress = ('', 8080)
server = HTTPServer(serverAddress, RequestHandler)
server.serve_forever()

main.py

python写web服务器的更多相关文章

  1. Python搭建Web服务器,与Ajax交互,接收处理Get和Post请求的简易结构

    用python搭建web服务器,与ajax交互,接收处理Get和Post请求:简单实用,没有用框架,适用于简单需求,更多功能可进行扩展. python有自带模块BaseHTTPServer.CGIHT ...

  2. JavaSE 手写 Web 服务器(二)

    原文地址:JavaSE 手写 Web 服务器(二) 博客地址:http://www.extlight.com 一.背景 在上一篇文章 <JavaSE 手写 Web 服务器(一)> 中介绍了 ...

  3. JavaSE 手写 Web 服务器(一)

    原文地址:JavaSE 手写 Web 服务器(一) 博客地址:http://www.extlight.com 一.背景 某日,在 Java 技术群中看到网友讨论 tomcat 容器相关内容,然后想到自 ...

  4. (转)Python的web服务器

    1.浏览器请求动态页面过程 2.WSGI Python Web Server Gateway Interface (或简称 WSGI,读作“wizgy”). WSGI允许开发者将选择web框架和web ...

  5. python之Web服务器案例

    HTTP协议简介 1. 使用谷歌/火狐浏览器分析 在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来.而浏览器和服务器之间的传输协议是HTTP,所以: ...

  6. Python的web服务器

    1.浏览器请求动态页面过程 2.WSGI Python Web Server Gateway Interface (或简称 WSGI,读作“wizgy”). WSGI允许开发者将选择web框架和web ...

  7. Python基础Web服务器案例

    一.WSGI 1.PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI) 是Python应用程序或框架和Web服务器之间的一种接口, ...

  8. python对web服务器做压力测试并做出图形直观显示

    压力测试有很多工具啊.apache的,还有jmeter, 还有loadrunner,都比较常用. 其实你自己用python写的,也足够用. 压力测试过程中要统计时间. 比如每秒的并发数,每秒的最大响应 ...

  9. 用python写web一定要去破解的异步请求问题.经历web.py和tornado,完破!

    1.问题 上个学期,给学校写了一个数据服务,主要从oracle里面读取一些数据供查询使用,非常快速的用web.py搭建了起来.调试顺利,测试正常,上线!接下来就是挨骂了,我铁定知道会卡,但是没想到会那 ...

随机推荐

  1. Vue:将px转化为rem,适配移动端vant-UI等框架(px2rem-loader)

    转载:https://www.cnblogs.com/WQLong/p/7798822.html 1.下载lib-flexible 使用的是vue-cli+webpack,通过npm来安装的 npm ...

  2. JS-向数组指定位置添加元素

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. oracle表分区、表分析及oracle数据泵文件导入导出

    1.先说oracle表分区是什么吧 你有500万份文件,你要把他存在磁盘上,好嘛,我们就一个文件夹,500万分文件在那儿杵着,我们想找到要的那个打开,嘿嘿,我们得找到什么时候. 这时候,有个人告诉你, ...

  4. linux下mysql 8.0忘记密码后重置密码

    1://免密码登陆 找到mysql配置文件:my.cnf, 在[mysqld]模块添加:skip-grant-tables   保存退出: 2://使配置生效 重启mysql服务:  service ...

  5. maven war工程重命名

    1,按f2对项目进行改名 2,改变其web.xml 的项目名 3,org.eclipse.wst.common.component 改变其项目名

  6. Android Camera2 Opengles2.0 实时滤镜(冷暖色/放大镜/模糊/美颜)

    https://blog.csdn.net/keen_zuxwang/article/details/78363464 demo: http://download.csdn.net/download/ ...

  7. 再论sklearn分类器

    https://www.cnblogs.com/hhh5460/p/5132203.html 这几天在看 sklearn 的文档,发现他的分类器有很多,这里做一些简略的记录. 大致可以将这些分类器分成 ...

  8. Linux内核启动流程与模块机制

    本文旨在简单的介绍一下Linux的启动流程与模块机制: Linux启动的C入口位于/Linux.2.6.22.6/init/main.c::start_kernel() 下图简要的描述了一下内核初始化 ...

  9. percona-server-5.7.18-14安装

    说明 percona-server-5.7 的安装对硬件配置的要求较高,至少需要4G内存或者2G物理内存+2Gswap. 编译安装过程中注意所在分区的空间大小,编译安装需要使用到大量的临时空间. 环境 ...

  10. face_recognition 基础接口

    face_recognition 基础接口 face_recognition使用世界上最简单的人脸识别库,在Python或命令行中识别和操作人脸. 使用dlib最先进的人脸识别技术构建而成,并具有深度 ...