[tor-commits] [sbws/master] Add simple HTTP server script

pastly at torproject.org pastly at torproject.org
Tue Jun 26 15:36:49 UTC 2018


commit f55b84aca876a9c72ce4d364695457f8a0fd124d
Author: Matt Traudt <sirmatt at ksu.edu>
Date:   Sun Jun 17 21:16:43 2018 -0400

    Add simple HTTP server script
---
 scripts/tools/sbws-http-server.py | 77 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/scripts/tools/sbws-http-server.py b/scripts/tools/sbws-http-server.py
new file mode 100755
index 0000000..d8575d0
--- /dev/null
+++ b/scripts/tools/sbws-http-server.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+# File: sbws-http-server.py
+# Author: Matt Traudt
+# License: CC0
+#
+# This script implements just enough of the HTTP protocol to work with Simple
+# Bandwidth Scanner.
+#
+# All requested URLs exist. All return 1 GiB of garbage data. We always speak
+# HTTP/1.1 because that's necessary for Keep-Alive request headers
+# (used by sbws scanners) to work.
+#
+# HEAD and GET requests are supported to the minimum extent necessary.
+# This essentially means that if the client sends Range request headers just
+# like sbws does, then we'll only send back the number of bytes they requested.
+# Indeed, this was the motivating reason for the complexity of this script;
+# normally I would have used SimpleHTTPRequestHandler unmodified.
+#
+# Don't breathe too hard or this script might break.
+from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
+import http.server
+from http import HTTPStatus
+# import time
+
+FILE_SIZE = 1*1024*1024*1024  # 1 GiB
+
+
+def _get_resp_size_from_range(range_str):
+    assert range_str.startswith('bytes=')
+    range_str = range_str[len('bytes='):]
+    start_byte, end_byte = range_str.split('-')
+    return int(end_byte) - int(start_byte) + 1
+
+
+class MyHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
+    protocol_version = 'HTTP/1.1'
+
+    def __init__(self, *a, **kw):
+        super().__init__(*a, **kw)
+
+    def send_head(self, length):
+        self.send_response(HTTPStatus.OK)
+        self.send_header('Content-Type', 'application/octet-stream')
+        self.send_header('Content-Length', length)
+        # self.send_header('Last-Modified', self.date_time_string(time.time()))
+        self.end_headers()
+
+    def do_GET(self):
+        range_hdr = self.headers['Range']
+        if not range_hdr:
+            num_bytes = FILE_SIZE
+        else:
+            assert range_hdr.startswith('bytes=')
+            num_bytes = _get_resp_size_from_range(range_hdr)
+        self.send_head(num_bytes)
+        self.wfile.write(b'A' * num_bytes)
+
+    def do_HEAD(self):
+        self.send_head(FILE_SIZE)
+
+
+def main(args):
+    addr = ('', args.port)
+    print('Listening on', addr)
+    httpd = http.server.HTTPServer(addr, MyHTTPRequestHandler)
+    httpd.serve_forever()
+
+
+if __name__ == '__main__':
+    parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
+    parser.add_argument(
+        '-p', '--port', default=8000, type=int, help='Port on which to listen')
+    args = parser.parse_args()
+    try:
+        exit(main(args))
+    except KeyboardInterrupt:
+        pass





More information about the tor-commits mailing list