Web_server.py
# 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,app):
self.server_socket = socket(AF_INET, SOCK_STREAM)
self.server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
self.application = app
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)
'''
response_header = 'HTTP/1.1 ' + status_code
for header in headers:
response_header += '\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)
env = {
"PATH_INFO": file_name,
"METHOD": method
}
#!!!这里 self.application = app!!!
response_body = self.application(env, self.start_response)
response = self.response_header +'\r\n' + response_body
print ('*' * 60)
print (response)
print ('*' * 60)
client_socket.send(response.encode('utf-8'))
client_socket.close()
def main():
if len(sys.argv) <2:
sys.exit('need arg, foramt--xx.py module_name:instance')
# 例如 python3 Web_server.py Web_framework: app
#module_name:Web_framework instance:app
module_name, instance = sys.argv[1].split(':')
m = __import__(module_name)
app = getattr(m,instance)
sys.path.insert(1, WSGI__DIR)
http_server = Httpserver(app)
http_server.bind(8000)
http_server.start()
if __name__ == '__main__':
main()
这里没有使用import直接在文件头导入fWeb_framework而是使用了__import__导入是为了使用的通用性,比如我下次又要导入一个 Web_framework123.py 那么就需要改写Web_server.py的头部。
索性就通过命令行来达到这一目的同时又不需要改写函数。
同时要注意这里并没有直接导入Web_framework里面的Application类而是它的对象app。因为如果是导入Application类我们又还要导入urls,干脆直接在Web_framework中先创建一个Application类的对象app同时把urls放进去–>app(urls)再导入~
Web_framework.py:
# coding:utf-8
import time
from Web_server import Httpserver
ROOT_DIR = "./html"
#这个类就是框架的主体,通用~~
class Application(object):
def __init__(self,urls):
self.urls = urls
def __call__(self,env,start_response):
path = env.get('PATH_INFO','/')
print ('path:',path)
'''
/static/index.html
'''
if path.startswith('/static'):
file_name = path[7:]
try:
# 打开文件读取文件内容
with open(ROOT_DIR + file_name, 'rb') as f:
data = f.read().decode('utf-8')
except IOError:
status_code = '404 not found'
headers = []
start_response(status_code, headers)
return 'Not Found'
else:
status_code = '200 OK'
headers = []
start_response(status_code, headers)
# print ('data:')
# print (data)
return data
for url, fx in urls:
if path == url:
return fx(env,start_response)
# 404错误
status_code = '404 not found'
headers = []
start_response(status_code, headers)
return 'Not Found'
def show_ctime(env,start_response):
status_code = '200 OK'
headers =[
('Content-Type','text/plain')
]
start_response(status_code,headers)
return time.ctime()
def say_hello(env,start_response):
status_code = '200 OK'
headers =[
('Content-Type','text/plain')
]
start_response(status_code,headers)
return 'hello test test'
def say_hh(env,start_response):
status_code = '200 OK'
headers =[
('Content-Type','text/plain')
]
start_response(status_code,headers)
return '2333'
urls = [
('/', show_ctime),
('/ctime', show_ctime),
('/sayhello', say_hello),
('/sayhh', say_hh)
]
app = Application(urls)
# if __name__ == '__main__':
# urls = [
# ('/', show_ctime),
# ('/ctime', show_ctime),
# ('/sayhello', say_hello),
# ('/sayhh', say_hh)
#
# ]
#
# http_server = Httpserver(app)
# http_server.bind(8000)
# http_server.start()