mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
Update the slow retrieval server, integration tests, and the download module to address issues with unexpected exceptions and bytes.
106 lines
2.7 KiB
Python
Executable file
106 lines
2.7 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
"""
|
|
<Program Name>
|
|
slow_retrieval_server.py
|
|
|
|
<Author>
|
|
Konstantin Andrianov.
|
|
|
|
<Started>
|
|
March 13, 2012.
|
|
|
|
<Copyright>
|
|
See LICENSE for licensing information.
|
|
|
|
<Purpose>
|
|
Server that throttles data by sending one byte at a time (specified time
|
|
interval 'DELAY'). The server is used in 'test_slow_retrieval_attack.py'.
|
|
"""
|
|
|
|
# Help with Python 3 compatibility, where the print statement is a function, an
|
|
# implicit relative import is invalid, and the '/' operator performs true
|
|
# division. Example: print 'hello world' raises a 'SyntaxError' exception.
|
|
from __future__ import print_function
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import random
|
|
|
|
import tuf._vendor.six as six
|
|
|
|
|
|
# Modify the HTTPServer class to pass the 'test_mode' argument to
|
|
# do_GET() function.
|
|
class HTTPServer_Test(six.moves.BaseHTTPServer.HTTPServer):
|
|
def __init__(self, server_address, Handler, test_mode):
|
|
six.moves.BaseHTTPServer.HTTPServer.__init__(self, server_address, Handler)
|
|
self.test_mode = test_mode
|
|
|
|
|
|
|
|
# HTTP request handler.
|
|
class Handler(six.moves.BaseHTTPServer.BaseHTTPRequestHandler):
|
|
|
|
# Overwrite do_GET.
|
|
def do_GET(self):
|
|
current_dir = os.getcwd()
|
|
try:
|
|
filepath = os.path.join(current_dir, self.path.lstrip('/'))
|
|
data = None
|
|
with open(filepath, 'r') as fileobj:
|
|
data = fileobj.read()
|
|
|
|
self.send_response(200)
|
|
self.send_header('Content-length', str(len(data)))
|
|
self.end_headers()
|
|
|
|
if self.server.test_mode == 'mode_1':
|
|
# Before sending any data, the server does nothing for a long time.
|
|
DELAY = 40
|
|
time.sleep(DELAY)
|
|
self.wfile.write(data)
|
|
|
|
return
|
|
|
|
# 'mode_2'
|
|
else:
|
|
DELAY = 1
|
|
# Throttle the file by sending a character every few seconds.
|
|
# NOTE: The for-loop below completes early if the download file
|
|
# (len(data)) is small. 'download.py' waits at least
|
|
# 'tuf.conf.SLOW_START_GRACE_PERIOD' seconds before triggering a
|
|
# potential slow retrieval error.
|
|
for i in range(len(data)):
|
|
self.wfile.write(data[i].encode('utf-8'))
|
|
time.sleep(DELAY)
|
|
|
|
return
|
|
|
|
except IOError as e:
|
|
self.send_error(404, 'File Not Found!')
|
|
|
|
|
|
|
|
def get_random_port():
|
|
port = random.randint(30000, 45000)
|
|
return port
|
|
|
|
|
|
|
|
def run(port, test_mode):
|
|
server_address = ('localhost', port)
|
|
httpd = HTTPServer_Test(server_address, Handler, test_mode)
|
|
httpd.handle_request()
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
port = int(sys.argv[1])
|
|
test_mode = sys.argv[2]
|
|
assert test_mode in ('mode_1', 'mode_2')
|
|
run(port, test_mode)
|