# Written by Vamei
# A messy HTTP server based on TCP socket
import socket
# Address
HOST = ''
PORT = 8000
text_content = '''
HTTP/1.x 200 OK
Content-Type: text/html
WOW
Wow, Python Server
First name:
'''
f = open('test.jpg','rb')
pic_content = '''
HTTP/1.x 200 OK
Content-Type: image/jpg
'''
pic_content = pic_content + f.read()
# Configure socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
# Serve forever
while True:
s.listen(3)
conn, addr = s.accept()
request = conn.recv(1024) # 1024 is the receiving buffer size
method = request.split(' ')[0]
src = request.split(' ')[1]
print 'Connected by', addr
print 'Request is:', request
# if GET method request
if method == 'GET':
# if ULR is /test.jpg
if src == '/test.jpg':
content = pic_content
else: content = text_content
# send message
conn.sendall(content)
# if POST method request
if method == 'POST':
form = request.split('\r\n')
idx = form.index('') # Find the empty line
entry = form[idx:] # Main content of the request
value = entry[-1].split('=')[-1]
conn.sendall(text_content + '\n ' + value + '')
######
# More operations, such as put the form into database
# ...
######
# close connection
conn.close()
服务器进行的操作很简单,即从POST请求中提取数据,再显示在屏幕上。
运行上面Python服务器,像上一篇文章那样,使用一个浏览器打开。
# Written by Vamei
# use TCPServer
import SocketServer
HOST = ''
PORT = 8000
text_content = '''
HTTP/1.x 200 OK
Content-Type: text/html
WOW
Wow, Python Server
First name:
'''
f = open('test.jpg','rb')
pic_content = '''
HTTP/1.x 200 OK
Content-Type: image/jpg
'''
pic_content = pic_content + f.read()
# This class defines response to each request
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
# self.request is the TCP socket connected to the client
request = self.request.recv(1024)
print 'Connected by',self.client_address[0]
print 'Request is', request
method = request.split(' ')[0]
src = request.split(' ')[1]
if method == 'GET':
if src == '/test.jpg':
content = pic_content
else: content = text_content
self.request.sendall(content)
if method == 'POST':
form = request.split('\r\n')
idx = form.index('') # Find the empty line
entry = form[idx:] # Main content of the request
value = entry[-1].split('=')[-1]
self.request.sendall(text_content + '\n ' + value + '')
######
# More operations, such as put the form into database
# ...
######
# Create the server
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Start the server, and work forever
server.serve_forever()
# Written by Vamei
# Simple HTTPsERVER
import SocketServer
import SimpleHTTPServer
HOST = ''
PORT = 8000
# Create the server, SimpleHTTPRequestHander is pre-defined handler in SimpleHTTPServer package
server = SocketServer.TCPServer((HOST, PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
# Start the server
server.serve_forever()
# Written by Vamei
# A messy HTTP server based on TCP socket
import BaseHTTPServer
import CGIHTTPServer
HOST = ''
PORT = 8000
# Create the server, CGIHTTPRequestHandler is pre-defined handler
server = BaseHTTPServer.HTTPServer((HOST, PORT), CGIHTTPServer.CGIHTTPRequestHandler)
# Start the server
server.serve_forever()
# Written by Vamei
import cgi
form = cgi.FieldStorage()
# Output to stdout, CGIHttpServer will take this as response to the client
print "Content-Type: text/html" # HTML is following
print # blank line, end of headers
print "Hello world!" # Start of content
print "" + repr(form['firstname']) + ""
(post.py需要有执行权限,见评论区)
第一行说明了脚本所使用的语言,即Python。 cgi包用于提取请求中包含的表格信息。脚本只负责将所有的结果输出到标准输出(使用print)。CGIHTTPRequestHandler会收集这些输出,封装成HTTP回复,传送给客户端。
对于POST方法的请求,它的URL需要指向一个CGI脚本(也就是在cgi-bin或者ht-bin中的文件)。CGIHTTPRequestHandler继承自SimpleHTTPRequestHandler,所以也可以处理GET方法和HEAD方法的请求。此时,如果URL指向CGI脚本时,服务器将脚本的运行结果传送到客户端;当此时URL指向静态文件时,服务器将文件的内容传送到客户端。
更进一步,我可以让CGI脚本执行数据库操作,比如将接收到的数据放入到数据库中,以及更丰富的程序操作。相关内容从略。