-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathserver.py
More file actions
92 lines (76 loc) · 3.03 KB
/
server.py
File metadata and controls
92 lines (76 loc) · 3.03 KB
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
try:
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
except ImportError:
from http.server import BaseHTTPRequestHandler, HTTPServer
from random import randint
import json
import ssl
import time
import threading
import unittest
def create_ssl_context():
"""Create SSL context for Python 3.12+ compatibility"""
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.minimum_version = ssl.TLSVersion.TLSv1_2
return context
request_counts = dict()
class Handler(BaseHTTPRequestHandler):
'''Handler definition for the testing server instance.
This handler returns without setting response status code which causes
httplib to raise BadStatusLine exception.
The handler reads the post body and fails for the `fail_count` specified.
After sending specified number of bad responses will sent a valid response.
'''
def do_DELETE(self):
self.send_response(200)
self.end_headers()
def do_POST(self):
self.send_response(200)
self.end_headers()
self.wfile.write(bytes("{}", "utf-8"))
def do_PUT(self):
global request_counts
# extract params
_id = self.path.split("/")[-1]
content_len = int(self.headers.get('content-length', 0))
params = json.loads(self.rfile.read(content_len).decode('utf-8'))
fail_count = params.get('fail_count', 0)
# retrieve number of requests already served
processed = request_counts.get(_id, 0)
if processed > fail_count:
# return a valid response
self.send_response(200)
self.end_headers()
return
# increment number of requests and return invalid response
request_counts[_id] = processed + 1
return
# Silence the server so test output is not cluttered
def log_message(self, format, *args):
return
class HTTPSTestCase(unittest.TestCase):
'''Test case class that starts up a https server and exposes it via the `server` attribute.
The testing server is only created in the setUpClass method so that multiple
tests can use the same server instance. The server is started in a separate
thread and once the tests are completed the server is shutdown and cleaned up.
'''
@classmethod
def setUpClass(cls):
# create a server
cls.server = HTTPServer(("localhost", 0), Handler)
# create SSL context for Python 3.12+ compatibility
context = create_ssl_context()
context.load_cert_chain('./tests/server.pem')
# upgrade to https
cls.server.socket = context.wrap_socket(cls.server.socket, server_side=True)
# start server instance in new thread
cls.server_thread = threading.Thread(target=cls.server.serve_forever)
cls.server_thread.start()
# Wait a bit for the server to bind to port
time.sleep(1)
@classmethod
def tearDownClass(cls):
# shutdown server and close thread
cls.server.shutdown()
cls.server.socket.close()
cls.server_thread.join()