#-*- 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. Thrift辅助类,用于简化Thrift编程

    CThriftServerHelper用于服务端,CThriftClientHelper用于客户端. IDL定义: service PackageManagerService { } 服务端使用示例: ...

  2. Python3 MySQL 数据库连接 -PyMySQL

    Python 3  操作mysql http://www.runoob.com/python3/python3-mysql.html Python3 MySQL 数据库连接 本文我们为大家介绍 Pyt ...

  3. kafka搜索介绍

    kafka详解  https://blog.csdn.net/liubenlong007/article/details/55211196##1  1.2 Kafka诞生 Kafka由 linked- ...

  4. HBASE的优化、hadoop通用优化,Linux优化,zookeeper优化,基础优化

    HBase 的优化3.1.高可用在 HBase 中 Hmaster 负责监控 RegionServer 的生命周期,均衡 RegionServer 的负载,如果Hmaster 挂掉了,那么整个 HBa ...

  5. Codeforces 691E Xor-sequences(矩阵快速幂)

    You are given n integers a1,  a2,  ...,  an. A sequence of integers x1,  x2,  ...,  xk is called a & ...

  6. XJOI3602 邓哲也的矩阵(优先队列优化DP)

    题目描述: 有一个 n×m的矩阵,现在准备对矩阵进行k次操作,每次操作可以二选一 1: 选择一行,给这一行的每一个数减去p,这种操作会得到的快乐值等于操作之前这一行的和 2: 选择一列,给这一列的每一 ...

  7. WC的基本功能实现.(Java)

    我的GitHub地址:https://github.com/Yuetao1219/lessons WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写 ...

  8. You must restart adb and Eclipse.

    打开Eclipse运行android 程序发现虚拟机启动不了提示  You must restart adb and Eclipse. 如下方式适用于端口占用的情况: 1.netstat -ano|f ...

  9. Tomcat应用配置

    为Tomcat添加管理员 为了更好的管理tomcat服务器,我们通常会给tomcat添加用户管理员,这样就可以登录进入查看发布的项目.以下是实际操作步骤: 在Tomcat的配置目录下找到tomcat- ...

  10. [LeetCode 题解]: Anagrams

    Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be ...