python搭建简单的web服务器

由于要做自动化和性能测试,工作中需要有一个能够控制返回消息数据的web服务器,所以用python初步实现了一个简单的web服务器,能够处理HTTP的请求(GET,POST,PUT),并完成响应。
先简单说明下原理,python中实现web服务器大概分两个步骤:

1.      创建一个套接字,绑定到指定的IP和端口,保持监听

2.      创建一个handle类,当收到请求消息时,作出响应

主要使用的类有两个:

HTTPServer:HTTP服务器的基类,提供了HTTP服务器的常用方法,创建服务器时可以直接声明这个类,也可以根据需要从这个类继承。

CGIHTTPRequestHandler:处理请求的handle类,继承自BaseHTTPRequestHandler类,在python文档中说明该类可以处理GET和POST请求,自己试了一下发现也可以处理PUT请求。

有关这两个类的详细描述可以参考python的标准类库说明:https://docs.python.org/2/library/

源码如下:
import socket
from os import curdir,sep

from BaseHTTPServer import HTTPServer

from CGIHTTPServer import CGIHTTPRequestHandler

import json
class HttpHandler(CGIHTTPRequestHandler):

def do_GET(self):

try:

f = open(curdir + sep + self.path)

print self.path

print ‘This is a GET method!‘

self.send_response(200)

self.send_header(‘Content-type‘,

‘text/html‘)

self.end_headers()

self.wfile.write(f.read())

f.close()

except IOError:

self.send_error(404,‘File Not Found:%s‘ % self.path)

def do_POST(self):

try:

print self.path

print ‘This is a POST method!‘

self.data = self.request.recv(1024).strip()

self.data =  json.loads(self.data)

print self.data

sendData = {}

if self.path == ‘/getfile‘:

f = open(curdir + sep + ‘/test_body.txt‘)

fileContent = f.read()

sendData[‘content‘] = fileContent

f.close()

self.send_response(200)

self.send_header(‘Content-type‘,

‘text/html‘)

self.end_headers()

self.wfile.write(sendData)

except:

self.send_error(404,‘Invalid request:%s!‘ % self.path)

def do_PUT(self):

try:

print self.path

print ‘This is a PUT method!‘

self.data = self.request.recv(1024).strip()

print self.data

sendData = {}

if self.path == ‘/getfile‘:

f = open(curdir + sep + ‘/test_body.txt‘)

fileContent = f.read()

sendData[‘content‘] = fileContent

f.close()

self.send_response(200)

self.send_header(‘Content-type‘,

‘text/html‘)

self.end_headers()

self.wfile.write(sendData)

except:

self.send_error(404,‘Invalid request:%s!‘ % self.path)

def main():

try:

localIp = socket.gethostbyname(socket.gethostname())
        server_address = (localIp,8080)

http_server = HTTPServer(server_address,HttpHandler)

sa = http_server.socket.getsockname()

print "Serving HTTP on", sa[0], "port", sa[1], "..."

print ‘Press ^C once or twice to quit.‘

http_server.serve_forever()

except KeyboardInterrupt:

print ‘^C received,shutting down server.‘

http_server.socket.close()

if __name__ == ‘__main__‘:

main()

在main()函数中新建了一个HTTPServer类,绑定到本机的8080端口,并保持监听。当收到请求时,根据请求的方法类型进入不同的do_*函数。函数的处理逻辑很简单,如果发送的URL合法,设置返回码为200,然后读取一个文件的内容,并写入到返回消息中。这样一个简单的web服务器就完成了,可以用RESTClient测试一下。

HTTPS相对于HTTP增加了SSL通道,客户端和服务器端必须有相互信任的证书才可以通信。自己对这方面的内容之前完全不了解,费了很大的功夫才初步把HTTPS的请求调通。

相比于HTTP的服务器,HTTPS改动的地方主要是建立服务器的时候:

class SecureHTTPServer(HTTPServer):

def __init__(self, server_address, HandlerClass):

BaseServer.__init__(self, server_address, HandlerClass)

self.socket = ssl.SSLSocket(socket.socket(self.address_family,self.socket_type),keyfile=‘./server.key‘, certfile=‘./server.crt‘, server_side=True)

self.server_bind()

self.server_activate()

这里新声明了一个SecureHTTPServer类,继承自HTTPServer类,在这个类中重新定义了构造函数,主要是新创建了一个SSLSocket类型的套接字,并指定了这个套接字的keyfile和certfile。keyfile和certfile这两个文件是安装了OpenSSL后手动生成的,执行如下openssl命令在本地生成pem文件:
req -new -x509 -keyout server.pem -out server.pem -day 365 -nodes
将server.pem文件中CERTIFICATE部分拷贝出来另存为server.crt。执行如下命令在本地生成或者删除证书:
keytool -import -alias certificatekey -file server.crt -keystore server.jks
keytool -delete -alias certificatekey -keystore server.jks
将server.jk上传到发送请求的系统作为证书库。

新声明一个handler类来处理收到的请求,并添加了多线程机制:
class SecureHTTPHandler(CGIHTTPRequestHandler):
#     def setup(self):
#         self.connection = self.request
# #         self.rbufsize = 8192   
# #         self.wbufsize = 8192
#         self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
#         self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
    def commonProcess(self):
        #处理请求的通用函数
        try:
      #设置不阻塞
            self.request.setblocking(0)
      #设置超时时间为5秒
            self.request.settimeout(5)
           #自己的处理代码
        f = open(curdir + sep + self.path)
            print self.path
            print ‘This is a GET method!‘
            self.send_response(200)
            self.send_header(‘Content-type‘,
                             ‘text/html‘)
            self.end_headers()
            self.wfile.write(f.read())
            f.close()       
        except:
            logging.error(‘Invalid request:%s!‘ % self.path)
            self.send_error(404,‘Invalid request:%s!‘ % self.path)
           
    def do_GET(self):
        logging.info(‘Received url is %s‘ % self.path)
        logging.info(‘This is a GET method!‘)
        #self.commonProcess()
        t = threading.Thread(target = self.commonProcess,args = ())
        t.start()
        t.join(5)
           
    def do_POST(self):
        logging.info(‘Received url is %s‘ % self.path)
        logging.info(‘This is a POST method!‘)
        #self.commonProcess()
        t = threading.Thread(target = self.commonProcess,args = ())
        t.start()
        t.join(5)  
           
    def do_PUT(self):
        logging.info(‘Received url is %s‘ % self.path)
        logging.info(‘This is a PUT method!‘)
        #self.commonProcess()
        t = threading.Thread(target = self.commonProcess,args = ())
        t.start()
        t.join(5)
在main()函数中要声明这个类的对象来创建服务器:
    https_server = SecureHTTPServer(server_address,SecureHTTPHandler)

以下是客户端的测试代码:
import httplib

def main():

conn = httplib.HTTPSConnection(host = "127.0.0.1", port = 8443, key_file=‘./server.key‘, cert_file=‘./server.crt‘ , source_address = (‘127.0.0.1‘,8080))

print "requesting..."

conn.request(‘PUT‘, ‘/test_body.txt‘)

r1 = conn.getresponse()

#打印响应码和响应状态信息

 print r1.status, r1.reason
另外,python中的twisted框架在处理web服务器时似乎功能很强大,后续可以深入研究一下。

时间: 2024-10-26 04:47:21

python搭建简单的web服务器的相关文章

【重要】怎么自行搭建简单的web服务器

# -*- coding: utf-8 -*- #python 27 #xiaodeng #CGI模块 #怎么自行搭建简单的web服务器 #用途: #内网中,提供文件的共享服务非常有用,在cmd下启动运行服务器命令之后,其他电脑也是可以通过url访问的 #可以实现pdf.zip等压缩文件.exe.apk等软件的下载服务. ###搭建基本流程## #1.假定共享文件的目录为:/home/test,ip为#192.168.1.101 ''' 怎么查看本机IP? import socket mynam

python超简单的web服务器

今天无意google时看见,心里突然想说,python做web服务器,用不用这么简单啊,看来是我大惊小怪了. web1.py 1 2 3 #!/usr/bin/python import SimpleHTTPServer SimpleHTTPServer.test() web2.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!/usr/bin/python import SimpleHTTPServer import SocketServer

linux搭建简单的web服务器

主要想法是:使用虚拟机的Ubuntu系统搭建http服务器,然后在window的浏览器上测试 1.先测试windows和虚拟机上的ubuntu能否相互ping通 2.下载http.tar.gz并拷贝到linux系统的工作目录下 3.解压该文件tar -vxzf http.tar.gz 4.进入该文件的解压目录,然后执行make 5.编译成功后,执行sudo ./myhttp start启动web服务 6.打开windows的浏览器输入对应地址 7.停止http服务,sudo ./myhttp s

python一个简单的web服务器和客户端

服务器: 当客户联系时创建一个连接套接字 从这个连接接收HTTP请求(*) 解释该请求所请求的特定文件      从服务器的文件系统获取该文件 并发送文件内容 如果文件不存在,则返回"404 Not Found"(*) 客户端: 客户端可以与服务器建立TCP连接 客户端通过TCP连接请求服务器端的某一文件 在客户端显示介绍到的文件内容 注:在运行此文件前,server.py目录下需要包含file文件夹,里面装有服务器里的文件,客户端可以向服务器请求file里的文件. readme:首先

Python实现简单的Web服务器 解析

代码来源https://www.shiyanlou.com/courses/552,对它进行理解,注释 #-*- coding:utf-8 -*- import BaseHTTPServer class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): '''处理请求并返回页面''' # 页面模板 Page = ''' <html> <body> <p>Hello, web!</p> </bo

配置xampp搭建简单的web服务器环境

1. 下载xampp,地址:https://www.apachefriends.org/index.html 2. 解压并安装,一直next,直到安装成功.linux环境安装在/opt/lampp下 3. 配置虚拟路径 1)修改/opt/lampp/etc下的httpd-conf文件,window环境应该是apache目录下的httpd-conf文件 <Directory /> #AllowOverride none #Require all denied Order deny,allow A

Nodejs 入门秘籍,搭一个最简单的web服务器。(菜鸟的你也能秒懂)

心血来潮,总结了一个Nodejs入门秘籍.看了你就想学NodeJs了. 一.简单介绍nodejs 初学nodejs  ,直接上简单实例.先简单说明一下:nodejs ,nodejs相当于服务器端的 可以轻易搭建一个服务器端. nodejs是用C++开发的一种运行于服务器端的语言,可以写网站后台程序,可以做服务端应用开发,语法和JAVASCRIPT一样,会JS,就是会NodeJS,区别于,普通JS是脚本运行客户端,而NODEJS中的JS是运行于服务器端,NODEJS的作用相当PHP,ASP等语言.

《Python入门》第一个Python Web程序——简单的Web服务器

上一篇讲了<Python入门>Windows 7下Python Web开发环境搭建笔记,接下来讲一下Python语言Web服务的具体实现:第一个Python Web程序--简单的Web服务器. 与其它Web后端语言不同,Python语言需要自己编写Web服务器. 如果你使用一些现有的框架的话,可以省略这一步: 如果你使用Python CGI编程的话,也可以省略这一步: 用Python建立最简单的web服务器 利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录

python第三方库系列之十六--建立最简单的web服务器

利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录的路径下,输入命令: python -m Web服务器模块 [端口号,默认8000] 例如: python -m SimpleHTTPServer 8080 然后就可以在浏览器中输入 http://localhost:端口号/路径 来访问服务器资源. 例如: http://localhost:8080/index.htm(当然index.htm文件得自己创建) 其他机器也可以通过服务器的IP地址来访问. 这里的