用python脚本实现的简易http服务器、客户端和https服务器、客户端

因工作需要,在网上搜罗一圈并拼凑一番之后,做出了一个python脚本实现的简易http/https的服务器和客户端。

我主要是用它来作为一个Internet网络传输文件的机制,经简单测试了一下,运转正常。测试基于debian系统。

不说废话,上代码,有问题欢迎讨论。

1、http服务器:

from BaseHTTPServer import HTTPServer,BaseHTTPRequestHandler  
import shutil  
 
class MyHttpHandler(BaseHTTPRequestHandler):  
    def do_GET(self):                     #响应GET请求
        print self.path                   #打印客户端请求GET的路径
        enc="UTF-8" 
        self.send_response(200)           #发送200状态码,表示处理正常
        self.send_header("Content-type", "text/html; charset=%s" % enc)   #发送html头,这里可说明文件类型和字符集等信息
        f = open("/http_content.test","r")       #只读打开一个文件
        strs = f.read()                          #读出文件
        self.send_header("Content-Length", str(len(strs)))    #发送html头   说明文件长度 注意,这里如果长度和实际长度不一致的话,后面客户端处理时就会触发IncompleteRead 这个异常。
        self.end_headers()                #html头部分结束
        self.wfile.write(strs)            #以刚才读出的那个文件的内容作为后续内容发出给http客户端
 
httpd=HTTPServer(('',8080),MyHttpHandler)  
print("Server started port 8080.....")  
httpd.serve_forever()  #启动http服务器

 

2、http客户端

import httplib
conn = httplib.HTTPConnection("ip.ip.ip.ip:8080")   #请求http服务器,这里的ip.ip.ip.ip要换成服务器端所在ip
print "requesting..."
conn.request("GET", "/")   #发出GET请求并制定请求的文件路径
r1 = conn.getresponse()
print r1.status, r1.reason         #打印响应码和响应状态信息
try:
  data1 = r1.read()         #读响应内容
except:
  print "exception!"
finally:
  print "read response!"
print data1               #打印响应内容

conn.close()          #关闭连接

 

3、https服务器
要使用下面这个https服务器实例,要先保证完成以下3个前提配置(我是在debian系统测试的):
a.安装OpenSSL
b.安装pyOpenSSL (apt-get install python-pyopenssl)
c.安装ssl证书(这里生成名为server.pem的文件) openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes

'''
SimpleSecureHTTPServer.py - simple HTTP server supporting SSL.

- replace fpem with the location of your .pem server file.
- the default port is 443.

usage: python SimpleSecureHTTPServer.py
'''
import socket, os
from SocketServer import BaseServer
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
from OpenSSL import SSL

class SecureHTTPServer(HTTPServer):
    #address_family = socket.AF_INET6 #如果有这一行,即可以支持IPV6
    def __init__(self, server_address, HandlerClass):
        BaseServer.__init__(self, server_address, HandlerClass)
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        #server.pem's location (containing the server private key and
        #the server certificate).
        fpem = './server.pem'
        ctx.use_privatekey_file (fpem)
        ctx.use_certificate_file(fpem)
        self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
                                                        self.socket_type))
        self.server_bind()
        self.server_activate()

class SecureHTTPRequestHandler(SimpleHTTPRequestHandler):
    def setup(self):
        self.connection = self.request
        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)

    def do_GET(self):
        f = open("./http_content.test","r")
        strs = f.read()
        self.send_response(200)
        #self.send_header("Content-type", "text/html; charset=%s" % enc)
        self.send_header("Content-Length", str(len(strs)))
        self.end_headers()
        self.wfile.write(strs)

def test(HandlerClass = SecureHTTPRequestHandler,
         ServerClass = SecureHTTPServer):

    server_address=('', 443)
    httpd = ServerClass(server_address, HandlerClass)
    sa = httpd.socket.getsockname()
    print "Serving HTTPS on", sa[0], "port", sa[1], "..."
    httpd.serve_forever()

test()

4、https客户端
#和http客户端几乎完全一样,就是HTTPConnection换成了HTTPSConnection

import httplib
conn = httplib.HTTPSConnection("ip.ip.ip.ip:8080")   #请求https服务器,这里的ip.ip.ip.ip要换成服务器端所在ip
print "requesting..."
conn.request("GET", "/")   #发出GET请求并制定请求的文件路径
r1 = conn.getresponse()
print r1.status, r1.reason         #打印响应码和响应状态信息
try:
  data1 = r1.read()         #读响应内容
except:
  print "exception!"
finally:
  print "read response!"
print data1               #打印响应内容

conn.close()          #关闭连接

 

短时间仓促完成的,有问题欢迎大家和我讨论,不要吝惜你的高见。

2 thoughts on “用python脚本实现的简易http服务器、客户端和https服务器、客户端

  1. 请教大神个问题,这段代码我怎么运行时候总是报错呢:
    webTestServer – - [15/Oct/2014 16:19:34] “GET /test_body.txt HTTP/1.1″ 200 -
    Traceback (most recent call last):
    File “C:\Python27\lib\SocketServer.py”, line 284, in _handle_request_noblock
    self.process_request(request, client_address)
    File “C:\Python27\lib\SocketServer.py”, line 310, in process_request
    self.finish_request(request, client_address)
    File “C:\Python27\lib\SocketServer.py”, line 323, in finish_request
    self.RequestHandlerClass(request, client_address, self)
    File “C:\Python27\lib\SocketServer.py”, line 641, in __init__
    self.finish()
    File “C:\Python27\lib\SocketServer.py”, line 694, in finish
    self.wfile.flush()
    File “C:\Python27\lib\socket.py”, line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
    TypeError: must be string or read-only buffer, not memoryview

  2. 我单步跟踪了一下,执行到self.wfile.write()函数的时候就异常退出了,小弟初学,实在找不出是什么原因,还望不吝赐教,多谢多谢

tuochao 进行回复 取消回复

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>