-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtornadohttpd.py
148 lines (123 loc) · 5.13 KB
/
tornadohttpd.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
# tornadohttpd.py
# a simple web server based on TornadoWeb
# https://github.com/tornadoweb/tornado
#
# For testing purposes, not intended for production use ;-)
#
# if you want to use this commercially, refer to TornadoWeb licenses
#
# Jeff Muday, Wake Forest University
#
docstring = """
Usage:
python tornadohttpd.py --port <int:port> --dir <relative or absolute base directory of files>
example:
python tornadohttpd.py --port 8080 --dir ./www
Notes:
1) if port argument is ommitted default port is 8080
2) server does not check if existing server is running on that port
3) On most systems, if you are an unprivileged user,
you will have to use a high port greater than 1024
4) By default, the files served come out of the base program directory e.g. './'
Thank you TornadoWeb Team!
https://github.com/tornadoweb/tornado
"""
import datetime
import mimetypes
import os
import os.path
import sys
import time
import tornado.httpserver
import tornado.ioloop
import tornado.log
import tornado.options
import tornado.web
BASE_PATH = './'
INDEX_FILES = ['index.html', 'index.htm']
class FileHandler(tornado.web.RequestHandler):
def get(self, requestpath):
"""get/render the path"""
# normalize the path
path = os.path.normpath(os.path.join(BASE_PATH, requestpath))
# case 1, path is a directory ==> look for index file
if os.path.isdir(path):
# see if a preferred index file is in the directory
# and we can redirect to the alternate path
alt_path = ''
for f in INDEX_FILES:
temp_path = os.path.normpath(os.path.join(path, f))
if os.path.isfile(temp_path):
alt_path = os.path.join('/', requestpath, f)
if alt_path:
# redirect to the alternate path (directory index file)
self.redirect(alt_path)
else:
# no alt_path ==> render a directory listing
self.write('<h2>Directory Listing of {}</h2>\n'.format(requestpath))
self.write('<table>\n')
for f in os.listdir(path):
fpath = os.path.normpath(os.path.join(path, f))
rpath = os.path.normpath(os.path.join(requestpath, f))
fstat = os.lstat(fpath)
ftime = tornado.web.escape.xhtml_escape(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(fstat.st_mtime)))
row = '<tr><td><a href="/{}">{}</a></td><td>{}</td></tr>\n'.format(rpath, f, ftime)
self.write(row)
self.write('</table><br /><hr>')
self.write('<b>Powered by TornadoHTTP, TornadoWeb</b> @ {}'.format(datetime.datetime.now()))
self.finish()
# case 2, path is a file ==> render file
if os.path.isfile(path):
mime_type = mimetypes.guess_type(path)
self.set_header("Content-Type", mime_type[0] or 'text/plain')
# note you will have to add some code to buffer big media files.
# Ben Darnell has some directions on this, look those over.
outfile = open(path, "rb")
for line in outfile:
self.write(line)
self.finish()
# case 3, path DOES NOT exist ==> 404 error
if not(os.path.exists(path)):
raise tornado.web.HTTPError(404)
else:
# something else bad happened ==> 400 error
raise tornado.web.HTTPError(400)
def simple_http_server(port=8080):
"""run a simple http server, default port=8080"""
tornado.log.enable_pretty_logging()
application = tornado.web.Application([
(r"/(.*)", FileHandler),
])
print("Tornado HTTP server starting on port {}".format(port))
print("(control-c to quit, may also require browser connection refresh)")
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(port)
tornado.ioloop.IOLoop.instance().start()
def usage():
"""show usage"""
print(docstring)
sys.exit(0)
def main():
"""main server starting point, check command line for --port argument"""
global BASE_PATH
if '--help' in sys.argv or '-h' in sys.argv:
usage()
if '--dir' in sys.argv:
try:
BASE_PATH = sys.argv[sys.argv.index('--dir') + 1]
if not os.path.exists(BASE_PATH):
print("ERROR: directory path does not exist!")
usage()
except:
print("ERROR: must supply a valid directory path")
usage()
port = 8080
if '--port' in sys.argv:
try:
port = int(sys.argv[sys.argv.index('--port')+1])
except:
print("ERROR: port must be an integer value")
usage()
simple_http_server(port)
if __name__ == "__main__":
main()