-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpyhttpd
executable file
·126 lines (114 loc) · 3.51 KB
/
pyhttpd
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
#!/usr/bin/env python
# pyhttpd - portable python HTTP server utility
import os
import sys
from optparse import OptionParser
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
# Check if running as root
if os.geteuid() == 0:
is_root = True
port = 80
else:
is_root = False
port = 8080
## Parse command line options
parser = OptionParser()
parser.add_option('-D', '--daemon', dest='fork', action='store_true', default=False, help='Fork process to the background')
# Options: bind
parser.add_option('-b', '--bind', dest='host', default='0.0.0.0', help='Bind server to this ip address')
parser.add_option('-p', '--port', dest='port', default=port, help='Listen for connection on this port')
# Options: server modes
parser.add_option('-t', '--text', dest='text', help='Text to return in "text" mode')
parser.add_option('-r', '--redirect', dest='url', help='Location to redirect to when in "redirect" mode')
parser.add_option('-f', '--file', dest='file', help='Print the contents of this file when in "file" mode')
parser.add_option('-d', '--dir', dest='dir', help='Serve the contents of this directory when in "dir" mode')
(opts, args) = parser.parse_args()
## Sanatize and sort input
host = str(opts.host)
port = int(opts.port)
address = (host, port)
content_type = 'text/html'
# Text mode
if opts.text:
mode = 'text'
text = str(opts.text)
# Single file mode
elif opts.file:
mode = 'file'
#@todo check file exists
f = open(str(opts.file), 'r')
text = f.read()
f.close()
# Redirect mode
elif opts.url:
mode = 'redirect'
url = str(opts.url)
# Directory listing mode
elif opts.dir:
mode = 'dir'
# @todo check dir exists
dir = str(opts.dir)
# Default mode
else:
mode = 'text'
text = 'Hi!'
## Server handler class
class MyHandler(BaseHTTPRequestHandler):
# GET requests
def do_GET(self):
# Mode: redirect
if mode == 'redirect':
self.send_response(301)
self.send_header('Location', url)
self.end_headers()
# Mode: text
elif mode == 'text' or mode == 'file':
self.send_response(200)
self.send_header('Content-type',content_type)
self.end_headers()
self.wfile.write(text + '\n')
# Mode: directory listing
elif mode == 'dir':
#@todo directory listing
print('something with ' + dir)
# Mode: idk
else:
print('Unknown mode, exiting')
sys.exit(1)
# Main function
def main():
try:
server = HTTPServer(address, MyHandler)
print('Started the server on ' + host + ':' + str(port))
server.serve_forever()
except KeyboardInterrupt:
print('\n' + 'Shutting down due to Keyboard interrupt')
server.shutdown()
## Do the UNIX double-fork magic
def daemon(func):
try: # First fork
pid = os.fork()
if pid > 0:
return # parent process, return and keep running
except OSError, e:
print('Failed to fork parent process, exiting')
sys.exit(1)
os.setsid()
try: # Second fork
pid = os.fork()
if pid > 0:
print('Forked process to pid ' + str(pid))
sys.exit(0)
except OSError, e:
print('Failed to fork process, exiting')
sys.exit(1)
func() # Function to be forked
os._exit(os.EX_OK) # Cleanly exit when all done
## Constructor
if __name__ == '__main__':
# Run forked or regular?
if not opts.fork:
main()
else:
daemon(main)
# pyhttpd