-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathHttpHead.py
More file actions
206 lines (184 loc) · 7.39 KB
/
HttpHead.py
File metadata and controls
206 lines (184 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# -*- coding:utf-8 -*-
import os
import xml.dom.minidom
# 返回码
class ErrorCode(object):
OK = "HTTP/1.1 200 OK\r\n"
NOT_FOUND = "HTTP/1.1 404 Not Found\r\n"
# 将字典转成字符串
def dict2str(d):
s = ''
for i in d:
s = s + i+': '+d[i]+'\r\n'
return s
class Session(object):
def __init__(self):
self.data = dict()
self.cook_file = None
def getCookie(self, key):
if key in self.data.keys():
return self.data[key]
return None
def setCookie(self, key, value):
self.data[key] = value
def loadFromXML(self):
import xml.dom.minidom as minidom
root = minidom.parse(self.cook_file).documentElement
for node in root.childNodes:
if node.nodeName == '#text':
continue
else:
self.setCookie(node.nodeName, node.childNodes[0].nodeValue)
def write2XML(self):
import xml.dom.minidom as minidom
dom = xml.dom.minidom.getDOMImplementation().createDocument(None, 'Root', None)
root = dom.documentElement
for key in self.data:
node = dom.createElement(key)
node.appendChild(dom.createTextNode(self.data[key]))
root.appendChild(node)
print(self.cook_file)
with open(self.cook_file, 'w') as f:
dom.writexml(f, addindent='\t', newl='\n', encoding='utf-8')
class HttpRequest(object):
RootDir = 'root'
NotFoundHtml = RootDir+'/404.html'
CookieDir = 'root/cookie/'
def __init__(self):
self.method = None
self.url = None
self.protocol = None
self.head = dict()
self.Cookie = None
self.request_data = dict()
self.response_line = ''
self.response_head = dict()
self.response_body = ''
self.session = None
def passRequestLine(self, request_line):
header_list = request_line.split(' ')
self.method = header_list[0].upper()
self.url = header_list[1]
if self.url == '/':
self.url = '/index.html'
self.protocol = header_list[2]
def passRequestHead(self, request_head):
head_options = request_head.split('\r\n')
for option in head_options:
key, val = option.split(': ', 1)
self.head[key] = val
# print key, val
if 'Cookie' in self.head:
self.Cookie = self.head['Cookie']
def passRequest(self, request):
request = request.decode('utf-8')
if len(request.split('\r\n', 1)) != 2:
return
request_line, body = request.split('\r\n', 1)
request_head = body.split('\r\n\r\n', 1)[0] # 头部信息
self.passRequestLine(request_line)
self.passRequestHead(request_head)
# 所有post视为动态请求
# get如果带参数也视为动态请求
# 不带参数的get视为静态请求
if self.method == 'POST':
self.request_data = {}
request_body = body.split('\r\n\r\n', 1)[1]
parameters = request_body.split('&') # 每一行是一个字段
for i in parameters:
if i=='':
continue
key, val = i.split('=', 1)
self.request_data[key] = val
self.dynamicRequest(HttpRequest.RootDir + self.url)
if self.method == 'GET':
if self.url.find('?') != -1: # 含有参数的get
self.request_data = {}
req = self.url.split('?', 1)[1]
s_url = self.url.split('?', 1)[0]
parameters = req.split('&')
for i in parameters:
key, val = i.split('=', 1)
self.request_data[key] = val
self.dynamicRequest(HttpRequest.RootDir + s_url)
else:
self.staticRequest(HttpRequest.RootDir + self.url)
# 只提供制定类型的静态文件
def staticRequest(self, path):
# print path
if not os.path.isfile(path):
f = open(HttpRequest.NotFoundHtml, 'r')
self.response_line = ErrorCode.NOT_FOUND
self.response_head['Content-Type'] = 'text/html'
self.response_body = f.read()
else:
extension_name = os.path.splitext(path)[1] # 扩展名
extension_set = {'.css', '.html', '.js'}
if extension_name == '.png':
f = open(path, 'rb')
self.response_line = ErrorCode.OK
self.response_head['Content-Type'] = 'text/png'
self.response_body = f.read()
elif extension_name in extension_set:
f = open(path, 'r')
self.response_line = ErrorCode.OK
self.response_head['Content-Type'] = 'text/html'
self.response_body = f.read()
elif extension_name == '.py':
self.dynamicRequest(path)
# 其他文件不返回
else:
f = open(HttpRequest.NotFoundHtml, 'r')
self.response_line = ErrorCode.NOT_FOUND
self.response_head['Content-Type'] = 'text/html'
self.response_body = f.read()
def processSession(self):
self.session = Session()
# 没有提交cookie,创建cookie
if self.Cookie is None:
self.Cookie = self.generateCookie()
cookie_file = self.CookieDir + self.Cookie
self.session.cook_file = cookie_file
self.session.write2XML()
else:
cookie_file = self.CookieDir + self.Cookie
self.session.cook_file = cookie_file
if os.path.exists(cookie_file):
self.session.loadFromXML()
# 当前cookie不存在,自动创建
else:
self.Cookie = self.generateCookie()
cookie_file = self.CookieDir+self.Cookie
self.session.cook_file = cookie_file
self.session.write2XML()
return self.session
def generateCookie(self):
import time, hashlib
cookie = str(int(round(time.time() * 1000)))
hl = hashlib.md5()
hl.update(cookie.encode(encoding='utf-8'))
return cookie
def dynamicRequest(self, path):
# 如果找不到或者后缀名不是py则输出404
if not os.path.isfile(path) or os.path.splitext(path)[1] != '.py':
f = open(HttpRequest.NotFoundHtml, 'r')
self.response_line = ErrorCode.NOT_FOUND
self.response_head['Content-Type'] = 'text/html'
self.response_body = f.read()
else:
# 获取文件名,并且将/替换成.
file_path = path.split('.', 1)[0].replace('/', '.')
self.response_line = ErrorCode.OK
m = __import__(file_path)
m.main.SESSION = self.processSession()
if self.method == 'POST':
m.main.POST = self.request_data
m.main.GET = None
else:
m.main.POST = None
m.main.GET = self.request_data
self.response_body = m.main.app()
self.response_head['Content-Type'] = 'text/html'
self.response_head['Set-Cookie'] = self.Cookie
def getResponse(self):
return self.response_line+dict2str(self.response_head)+'\r\n'+self.response_body