| 383 | # which tells the web page, which then opens a window with the test. Doing |
| 384 | # it this way then allows the page to close() itself when done. |
| 385 | def make_test_server(in_queue, out_queue, port): |
| 386 | class TestServerHandler(SimpleHTTPRequestHandler): |
| 387 | # Request header handler for default do_GET() path in |
| 388 | # SimpleHTTPRequestHandler.do_GET(self) below. |
| 389 | def send_head(self): |
| 390 | if self.headers.get('Range'): |
| 391 | path = self.translate_path(self.path) |
| 392 | try: |
| 393 | fsize = os.path.getsize(path) |
| 394 | f = open(path, 'rb') |
| 395 | except OSError: |
| 396 | self.send_error(404, f'File not found {path}') |
| 397 | return None |
| 398 | self.send_response(206) |
| 399 | ctype = self.guess_type(path) |
| 400 | self.send_header('Content-Type', ctype) |
| 401 | pieces = self.headers.get('Range').split('=')[1].split('-') |
| 402 | start = int(pieces[0]) if pieces[0] else 0 |
| 403 | end = int(pieces[1]) if pieces[1] else fsize - 1 |
| 404 | end = min(fsize - 1, end) |
| 405 | length = end - start + 1 |
| 406 | self.send_header('Content-Range', f'bytes {start}-{end}/{fsize}') |
| 407 | self.send_header('Content-Length', str(length)) |
| 408 | self.end_headers() |
| 409 | return f |
| 410 | else: |
| 411 | return SimpleHTTPRequestHandler.send_head(self) |
| 412 | |
| 413 | # Add COOP, COEP, CORP, and no-caching headers |
| 414 | def end_headers(self): |
| 415 | self.send_header('Accept-Ranges', 'bytes') |
| 416 | self.send_header('Access-Control-Allow-Origin', '*') |
| 417 | self.send_header('Cross-Origin-Opener-Policy', 'same-origin') |
| 418 | self.send_header('Cross-Origin-Embedder-Policy', 'require-corp') |
| 419 | self.send_header('Cross-Origin-Resource-Policy', 'cross-origin') |
| 420 | |
| 421 | self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate, private, max-age=0') |
| 422 | self.send_header('Expires', '0') |
| 423 | self.send_header('Pragma', 'no-cache') |
| 424 | self.send_header('Vary', '*') # Safari insists on caching if this header is not present in addition to the above |
| 425 | |
| 426 | return SimpleHTTPRequestHandler.end_headers(self) |
| 427 | |
| 428 | def do_POST(self): # noqa: DC04 |
| 429 | urlinfo = urlparse(self.path) |
| 430 | query = parse_qs(urlinfo.query) |
| 431 | content_length = int(self.headers['Content-Length']) |
| 432 | post_data = self.rfile.read(content_length) |
| 433 | if urlinfo.path == '/log': |
| 434 | # Logging reported by reportStdoutToServer / reportStderrToServer. |
| 435 | # |
| 436 | # To automatically capture stderr/stdout message from browser tests, modify |
| 437 | # `captureStdoutStderr` in `test/browser_reporting.js`. |
| 438 | filename = query['file'][0] |
| 439 | print(f"[client {filename}: '{post_data.decode()}']") |
| 440 | self.send_response(200) |
| 441 | self.end_headers() |
| 442 | elif urlinfo.path == '/upload': |