-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathhttpdecho.py
113 lines (94 loc) · 3.2 KB
/
httpdecho.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
"""
A Simple Python HTTP server that echos the request in the response.
"""
import socket
import argparse
from six.moves.urllib import parse
import email.message
try:
from email.generator import BytesGenerator
except ImportError:
# BBB Python 2 compatibility
from email.generator import Generator as BytesGenerator
from six.moves import BaseHTTPServer
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--address', '-a', default='localhost',
help='Hostname or IP address to accept requests on.')
parser.add_argument(
'--port', '-p', help='Port to accept requests on. '
'If not specified, use the first available port after 8000.')
class EchoHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"""
A Simple Python HTTP server that echos the request in the response.
"""
def do_GET(self):
"""
Echo a request without a body.
"""
message = self.get_message()
self.send_head()
BytesGenerator(self.wfile).flatten(message, unixfrom=False)
do_HEAD = do_GET
do_OPTIONS = do_GET
do_DELETE = do_GET
def do_POST(self):
"""
Echo a request with a body.
"""
message = self.get_message()
message.set_payload(self.rfile.read(
int(self.headers['Content-Length'])))
self.send_head()
BytesGenerator(self.wfile).flatten(message, unixfrom=False)
do_PUT = do_POST
do_PATCH = do_POST
def send_head(self):
"""
Send all the basic, required headers.
"""
self.send_response(200)
self.send_header("Content-Type", 'text/rfc822-headers; charset=UTF-8')
self.send_header("Last-Modified", self.date_time_string())
self.end_headers()
def get_message(self):
"""
Assemble the basic message including query parameters.
"""
message = email.message.Message()
message['Method'] = self.command
message['Path'] = self.path
server_url = parse.SplitResult('http', '{0}:{1}'.format(
self.server.server_name, self.server.server_port), '', '', '')
request_url = parse.urlsplit(server_url.geturl() + self.path)
for header, value in parse.parse_qs(request_url.query).items():
message.add_header(header, value[0])
return message
def main(args=None, default_port=8000):
"""
Run the echo HTTP server.
"""
args = parser.parse_args(args)
port = args.port
if port is None:
port = default_port
bound = False
while not bound:
try:
httpd = BaseHTTPServer.HTTPServer(
(args.address, port), EchoHTTPRequestHandler)
except socket.error:
port += 1
if port > 65535:
raise ValueError('No available port found')
else:
bound = True
else:
httpd = BaseHTTPServer.HTTPServer(
(args.address, int(port)), EchoHTTPRequestHandler)
print('Echoing HTTP at http://{0}:{1} ...'.format(args.address, port))
httpd.serve_forever()
if __name__ == '__main__':
main()