# coding:utf-8
from socket import *
from multiprocessing import Process
import re
import os
import sys
#文件路径
ROOT_DIR = "./html"
WSGI__DIR = "./WSGI"
class Httpserver(object):
def __init__(self):
self.server_socket = socket(AF_INET, SOCK_STREAM)
self.server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
def bind(self,port):
self.server_socket.bind(('', port))
def start(self):
self.server_socket.listen(128)
while True:
client_socket, client_ip_port_tuple = self.server_socket.accept()
print ('[%s-%s客户端连接]' % (client_ip_port_tuple))
p = Process(target=self.fun, args=(client_socket,))
p.start()
client_socket.close()
def start_response(self, status_code, headers):
''' status_code = '200 OK'
headers =[('Content-Type','text/plain')]
start_response(status_code,headers)
'''
for header in headers:
response_header = 'HTTP/1.1 ' + status_code + '\r\n' + '%s: %s\r\n'%header
self.response_header = response_header
def fun(self,client_socket):
recv_data = client_socket.recv(1024)
recv_data_line_list = recv_data.splitlines()
response_start_line = recv_data_line_list[0].decode('utf-8')
for xx in recv_data_line_list:
print (xx.decode('utf-8'))
print ('*' * 60)
print (response_start_line)
response_header = 'Server: My Server\r\n'
# GET /index.html HTTP/1.1
file_name = re.match(r'\w+ +(/[^ ]*) \w+/\d+\.\d+', response_start_line).group(1)
method = re.match(r'(\w+) +/[^ ]* \w+/\d+\.\d+', response_start_line).group(1)
# 例:/ctime.py
if file_name.endswith('.py'):
try:
#导入的是不带后缀文件名
m = __import__(file_name[1:-3])
except Exception:
self.response_header = "HTTP/1.1 404 Not Found\r\n"
response_body = "not found"
else:
env = {
"PATH_INFO": file_name,
"METHOD": method
}
response_body = m.application(env, self.start_response)
response = self.response_header +'\r\n' + response_body
else :
if file_name == '/':
file_name = '/index.html'
try:
# 打开文件读取文件内容
with open(ROOT_DIR + file_name, 'rb') as f:
data = f.read().decode('utf-8')
except IOError:
response_start_line = 'HTTP/1.1 404 File not found\r\n'
response_header = 'Server: My Server\r\n'
response_body = 'File is not exist !'
else:
response_start_line = 'HTTP/1.1 200 OK\r\n'
response_header = 'Server: My Server\r\n'
response_body = data
response = response_start_line + response_header + '\r\n' + response_body
print ('*' * 60)
print (response)
print ('*' * 60)
client_socket.send(response.encode('utf-8'))
client_socket.close()
def main():
sys.path.insert(1, WSGI__DIR)
http_server = Httpserver()
http_server.bind(8000)
http_server.start()
if __name__ == '__main__':
main()
ctime.py
import time
def application(env, start_response):
status_code = '200 OK'
headers =[
('Content-Type','text/plain')
]
start_response(status_code,headers)
return time.ctime()
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<h1>Python</h1>
<p>第一次测试,由于regex的错误找了几小时的错误!</p>
</body>
</html>
运行结果:
总结:
1.start_response 定义在主程序中定义,却在脚本中调用。返回起始行和响应头
要强调的是
def start_response(self, status_code, headers):
'''
status_code = '200 OK'
headers =[('Content-Type','text/plain')]
start_response(status_code,headers)
'''
for header in headers:
response_header = 'HTTP/1.1 ' + status_code + '\r\n' + '%s: %s\r\n'%header
self.response_header = response_header
2.application 在脚本中定义接收两个参数 变量env 和 函数名start_response,却在主程序中调用。并返回response_body
3.start_response的调用是写在application函数体中的~
def application(env, start_response):
status_code = '200 OK'
headers =[
('Content-Type','text/plain')
]
start_response(status_code,headers)
return time.ctime()
执行顺序就是:先执行application 然后在 application 中又执行了 start_response