-
Notifications
You must be signed in to change notification settings - Fork 0
/
webserver.py
190 lines (142 loc) · 4.71 KB
/
webserver.py
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
#!/usr/bin/env python
# Original by ???
# Changes by Dale Stanbrough
# this finds a matching GET/POST module/function to dispatch to
# based on a list of routes (declared in the routes file)
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from os import curdir, sep
import sys
import importlib
import cgi
# the modules/functions to respond to incoming requests
from routes import routes
#--------------------------------
def getController(method, path):
for each in routes():
# each looks like ('get', '/', 'things::wow')
if each[0].lower() == method.lower() and each[1].lower() == path.lower():
moduleController = each[2]
break
else:
# didn't find a match
raise ValueError
# split this up, and get the module, function names
middle = moduleController.find('::')
# get the module name
moduleName = moduleController[:middle]
# get the function name
controllerName = moduleController[middle + 2:]
module = importlib.import_module(moduleName)
methodToCall = getattr(sys.modules[moduleName], controllerName)
return methodToCall
PORT_NUMBER = 34567
# This class will handles any incoming request from
# the browser
class myHandler (BaseHTTPRequestHandler):
# send a header...
def sendHeader(self, code, mimetype):
self.send_response(code)
self.send_header('Content-type', mimetype)
self.end_headers()
#---------------------------------------------------------
# Handler for the GET requests
def do_GET(self):
assetsDir = "assets"
asset = False
try:
# Check the file extension required and
# set the right mime type
sendReply = False
if self.path.endswith(".html") or self.path.endswith("/"):
mimetype = 'text/html'
sendReply = True
elif self.path.endswith(".jpg"):
mimetype = 'image/jpg'
sendReply = True
asset = True
elif self.path.endswith(".png"):
mimetype = 'image/png'
sendReply = True
asset = True
elif self.path.endswith(".gif"):
mimetype = 'image/gif'
sendReply = True
asset = True
elif self.path.endswith(".js"):
mimetype = 'application/javascript'
sendReply = True
asset = True
elif self.path.endswith(".css"):
mimetype = 'text/css'
sendReply = True
asset = True
# It was a recognized type, send a reply
if sendReply == True:
# should we send an asset, or should we generate a page?
if asset == True:
self.sendHeader(200, mimetype)
# Open the static file requested and send it
# assets all live in an asset directory
assetLocation = curdir + sep + assetsDir + sep + self.path
try:
f = open(assetLocation, 'rb')
except IOError:
self.send_error(404,'Asset %s Not Found at : %s' % (self.path, assetLocation))
return
self.wfile.write(f.read())
f.close()
else:
try:
self.sendHeader(200, mimetype)
method = getController('GET', self.path)
self.wfile.write(method())
except:
# doesn't seem to work for some reason...
self.send_error(404,'Couldn\'t generate page for : %s' % self.path)
return
return
except IOError:
self.send_error(404,'File Not Found: %s' % self.path)
except ValueError:
self.send_error(404,'Couldn\'t find function from Routes file for path: %s' % self.path)
#---------------------------------------------------------
# Handler for the POST requests
def do_POST(self):
# get all the interesting goodness from the incoming post
form = cgi.FieldStorage(
fp = self.rfile,
headers = self.headers,
environ = {'REQUEST_METHOD':'POST',
'CONTENT_TYPE' :'Content-Type',
},
keep_blank_values = True
)
# move the cgi parameters (from the form) into a dictionary
parameters = {}
for key in form.keys():
parameters[key] = form[key].value
# create a response back to the web browser that
# requested this page.
# The reply should be a web page.
# response headers
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
# identify a function that should be called to generate
# the web page
method = getController('POST', self.path)
# call it with the cgi parameters from the form,
# return this value as the main page
self.wfile.write(method(parameters))
return
try:
# Create a web server and define the handler to manage the
# incoming request
server = HTTPServer(('', PORT_NUMBER), myHandler)
#print 'Started httpserver on port ', PORT_NUMBER
print('Started httpserver on port %s' % PORT_NUMBER)
# Wait forever for incoming htto requests
server.serve_forever()
except KeyboardInterrupt:
print('^C received, shutting down the web server')
#server.socket.close() #cant access from the try^^^