#-*- coding:utf-8 -*-

import sys, os
from http.server import BaseHTTPRequestHandler, HTTPServer #----------------------------------------------------------------------------------
class ServerException(Exception):
'''服务器内部错误'''
pass #----------------------------------------------------------------------------------
class base_case(object):
"""条件处理基类""" #从地址中读取文件送给send_content()返回请求
def handle_file(self,hander,full_path):
try:
with open(full_path, 'rb') as reader:
content = reader.read()
hander.send_content(content)
except IOError as msg:
msg = "'{0}' cannot be read: {1}".format(full_path, msg)
hander.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)
#如果path存在,返回True;如果path不存在,返回False 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(["python3", handler.full_path],shell=False)
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)
#如果path是一个存在的文件,返回True。否则返回False def act(self, handler):
self.handle_file(handler,handler.full_path) #----------------------------------------------------------------------------------
class case_directory_index_file(base_case):
'''在跟路径下返回主页文件''' #判断目标路径是否是目录&&目录下是否有index.html
def test(self, handler):
return os.path.isdir(handler.full_path) and \
os.path.isfile(self.index_path(handler))
#isdir函数判断某一路径是否为目录 #响应index.html的内容
def act(self, handler):
self.handle_file(handler,self.index_path(handler)) #----------------------------------------------------------------------------------
class case_always_fail(object):
'''所有情况都不符合时的默认处理类''' def test(self, handler):
return True def act(self, handler):
raise ServerException("Unknown object '{0}'".format(handler.path)) #一、创建一个请求处理类
#1.模块的 BaseHTTPRequestHandler类 会帮我们处理对请求的解析
#2.并通过确定请求的方法来调用其对应的函数(方法Get对应do_get方法)
#----------------------------------------------------------------------------------
#RequestHandler 继承了 BaseHTTPRequestHandler 并重写了 do_GET 方法
class RequestHandler(BaseHTTPRequestHandler):
'''
请求路径合法则返回相应处理
否则返回错误页面
'''
Cases = [case_no_file(),
case_cgi_file(),
case_existing_file(),
case_directory_index_file(),
case_always_fail()] # 错误页面模板
Error_Page = """\
<html>
<body>
<h1>Error accessing {path}</h1>
<p>{msg}</p>
</body>
</html>
""" def do_GET(self):
try:
#得到完整的请求路径
#os.getcwd()返回当前进程的工作目录
#BaseHTTPRequestHandler类使请求的相对路径保存在self.path
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.encode("utf-8"),404) #content内容被编码为二进制 # 发送数据到客户端
def send_content(self,content, status=200):
self.send_response(status)
self.send_header("Content-Type", "text/html") #Content-Type 告诉客户端要以处理html文件的方式处理返回的内容
self.send_header("Content-Length", str(len(content)))
self.end_headers() #end_headers 方法会插入一个空白行
self.wfile.write(content) #主函数
if __name__ == '__main__':
serverAddress = ('', 8080)
#二、实例化一个服务器类,传入服务器的地址和请求处理程序类
server = HTTPServer(serverAddress, RequestHandler)
#三、调用handle_request()(一般是调用其他事件循环或者使用select())或serve_forever()
server.serve_forever()

Python练习 | WebServer的更多相关文章

  1. 【webserver】使用python实现webserver,支持上传下载文件

    #!/usr/bin/env python """Simple HTTP Server With Upload. This module builds on BaseHT ...

  2. python 打印Linux中文编码字符

    2018-10-12 12:02:15 星期五 python -c "print '\346\234\215\345\212\241\345\231\250\346\217\220\344\ ...

  3. python uwsgi 部署以及优化

    这篇文章其实两个月之前就应该面世了,但是最近琐事.烦心事太多就一直懒得动笔,拖到现在才写 一.uwsgi.wsgi.fastcgi区别和联系 参见之前的文章 http://www.cnblogs.co ...

  4. python实现网页登录时的rsa加密流程

    对某些网站的登录包进行抓包时发现,客户端对用户名进行了加密,然后传给服务器进行校验. 使用chrome调试功能断点调试,发现网站用javascript对用户名做了rsa加密. 为了实现网站的自动登录, ...

  5. 20145319 《网络渗透》web基础

    20145319 <网络渗透>web基础 实验要求 掌握网页编程的基本知识 html语法 javascript php 前端,后台,数据库之间如何建立连接 掌握数据库的使用 mysql的启 ...

  6. WSGI、flup、fastcgi、web.py、uwsgi

    ==================        网上别人的理解 =================== http://www.douban.com/note/13508388/ 1.Apache/ ...

  7. python开启简单webserver

    python开启简单webserver linux下面使用 python -m SimpleHTTPServer 8000 windows下面使用上面的命令会报错,Python.Exe: No Mod ...

  8. python中一个简单的webserver

     python中一个简单的webserver 2013-02-24 15:37:49 分类: Python/Ruby 支持多线程的webserver   1 2 3 4 5 6 7 8 9 10 11 ...

  9. [Top-Down Approach] Assignment 1: WebServer [Python]

    Today I complete Socket Programming Assignment 1 Web Server Here is the code: #!/usr/bin/python2.7 # ...

随机推荐

  1. mysql多字段唯一索引

    项目中需要用到联合唯一索引: 例如:有以下需求:每个人每一天只有可能产生一条记录:处了程序约定之外,数据库本身也可以设定: 例如:user表中有userID,userName两个字段,如果不希望有2条 ...

  2. Java 理论与实践: 修复 Java 内存模型,第 2 部分(转载)

    在 JSR 133 中 JMM 会有什么改变? 活跃了将近三年的 JSR 133,近期发布了关于如何修复 Java 内存模型(Java Memory Model, JMM)的公开建议.在本系列文章的 ...

  3. Delphi 10.1.2 berlin开发跨平台APP的几点经验

    1.ios不允许app有退出功能,所以不能调用Application.Terminate. 2.info.plist文件的自定义:info.plist文件是由info.plist.TemplateiO ...

  4. Transaction And Lock--在事务中使用TRY CATCH

    1>当XACT_ABORT被设置为ON时,如果TSQL 语句遇到运行时错误,整个事务会被回滚和结束2>当XACT_ABORT被设置为OFF时,如果TSQL 语句遇到运行时错误,只会回滚当前 ...

  5. map的回调函数

    问题:--js   (['1','2','3']).map(parseInt) 第一眼看到这个题目的时候,脑海跳出的答案是 [1, 2, 3],但是真正的答案是[1, NaN, NaN]. 首先让我们 ...

  6. 【windows】dos命令查看某个文件夹下所有文件目录列表

    dos命令  dir展示一个目录中的文件夹和文件列表  /a代表显示隐藏目录

  7. plsql连接oracle客户端(简单,实用方案)附件

    plsql 连接 oracle 需要在本地安装oracle客户端(附件中下载): 将文件下载下来后,放到任意目录,例如 D:\instantclient_10_2 修改 tnsnames.ora 文件 ...

  8. NOS服务监控实践

    本文来自网易云社区 作者:王健 一.  背景 此处所说的服务监控程序,是通过模拟用户的请求,对一个系统的服务质量进行监控的程序.服务监控程序的主要目的是,从用户的角度出发,通过发送端到端的请求,确认系 ...

  9. IE 直接打印 页面的方式

    1. 通过在IE中加载adobe pdf reader 插件 进行直接打印和打印的配置(推荐) <body>   <object id="pdf1" width= ...

  10. C++的可移植性和跨平台开发

    概述 今天聊聊C++的可移植性问题.如果你平时使用C++进行开发,并且你对C++的可移植性问题不是非常清楚,那么我建议你看看这个系列.即使你目前没有跨平台开发的需要,了解可移植性方面的知识对你还是很有 ...