summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/tools/wptserve
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:33 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:33 +0000
commit086c044dc34dfc0f74fbe41f4ecb402b2cd34884 (patch)
treea4f824bd33cb075dd5aa3eb5a0a94af221bbe83a /testing/web-platform/tests/tools/wptserve
parentAdding debian version 124.0.1-1. (diff)
downloadfirefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.tar.xz
firefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.zip
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/tools/wptserve')
-rw-r--r--testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultpy/default.py3
-rw-r--r--testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultpy/default.sub.py3
-rw-r--r--testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultsubpy/default.sub.py3
-rw-r--r--testing/web-platform/tests/tools/wptserve/tests/functional/docroot/foo.any.window-module.html8
-rw-r--r--testing/web-platform/tests/tools/wptserve/tests/functional/test_handlers.py26
-rw-r--r--testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py6
-rw-r--r--testing/web-platform/tests/tools/wptserve/tests/functional/test_server.py68
-rw-r--r--testing/web-platform/tests/tools/wptserve/wptserve/handlers.py16
-rw-r--r--testing/web-platform/tests/tools/wptserve/wptserve/server.py17
9 files changed, 146 insertions, 4 deletions
diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultpy/default.py b/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultpy/default.py
new file mode 100644
index 0000000000..c235aeb58a
--- /dev/null
+++ b/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultpy/default.py
@@ -0,0 +1,3 @@
+def main(request, response):
+ response.headers.set("Content-Type", "text/plain")
+ return "default"
diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultpy/default.sub.py b/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultpy/default.sub.py
new file mode 100644
index 0000000000..32a10d8535
--- /dev/null
+++ b/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultpy/default.sub.py
@@ -0,0 +1,3 @@
+def main(request, response):
+ response.headers.set("Content-Type", "text/plain")
+ return "default.sub"
diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultsubpy/default.sub.py b/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultsubpy/default.sub.py
new file mode 100644
index 0000000000..c549100066
--- /dev/null
+++ b/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/defaultsubpy/default.sub.py
@@ -0,0 +1,3 @@
+def main(request, response):
+ response.headers.set("Content-Type", "text/plain")
+ return "{{host}}"
diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/foo.any.window-module.html b/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/foo.any.window-module.html
new file mode 100644
index 0000000000..59646e6abd
--- /dev/null
+++ b/testing/web-platform/tests/tools/wptserve/tests/functional/docroot/foo.any.window-module.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id=log></div>
+<script type=module src="/foo.any.js"></script>
diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/test_handlers.py b/testing/web-platform/tests/tools/wptserve/tests/functional/test_handlers.py
index 623a0e5b6a..91b05f4fe4 100644
--- a/testing/web-platform/tests/tools/wptserve/tests/functional/test_handlers.py
+++ b/testing/web-platform/tests/tools/wptserve/tests/functional/test_handlers.py
@@ -275,6 +275,17 @@ class TestPythonHandler(TestUsingServer):
self.assertEqual("text/plain", resp.info()["Content-Type"])
self.assertEqual(b"PASS", resp.read())
+ def test_directory(self):
+ route = ("GET", "/defaultpy", wptserve.handlers.python_script_handler)
+ self.server.router.register(*route)
+ resp = self.request("/defaultpy")
+ self.assertEqual(200, resp.getcode())
+ self.assertEqual("text/plain", resp.info()["Content-Type"])
+ # default.py returns "default", default.sub.py returns "default.sub".
+ # Because this should find the first matching default*.py file
+ # lexicographically sorted, this should have gotten "default".
+ self.assertEqual(b"default", resp.read())
+
def test_no_main(self):
with pytest.raises(HTTPError) as cm:
self.request("/no_main.py")
@@ -325,6 +336,15 @@ class TestAsIsHandler(TestUsingServer):
self.assertEqual(b"Content", resp.read())
#Add a check that the response is actually sane
+ def test_directory_fails(self):
+ route = ("GET", "/subdir", wptserve.handlers.as_is_handler)
+ self.server.router.register(*route)
+ with pytest.raises(HTTPError) as cm:
+ self.request("/subdir")
+
+ assert cm.value.code == 500
+ del cm
+
class TestH2Handler(TestUsingH2Server):
def test_handle_headers(self):
@@ -410,6 +430,12 @@ class TestWindowHandler(TestWrapperHandlerUsingServer):
self.run_wrapper_test('foo.window.html',
'text/html', serve.WindowHandler)
+class TestWindowModulesHandler(TestWrapperHandlerUsingServer):
+ dummy_files = {'foo.any.js': b'// META: global=window-module\n'}
+
+ def test_any_window_module_html(self):
+ self.run_wrapper_test('foo.any.window-module.html',
+ 'text/html', serve.WindowModulesHandler)
class TestAnyHtmlHandler(TestWrapperHandlerUsingServer):
dummy_files = {'foo.any.js': b'',
diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py b/testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py
index beb124d1db..c11577acb5 100644
--- a/testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py
+++ b/testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py
@@ -232,6 +232,12 @@ class TestPipesWithVariousHandlers(TestUsingServer):
resp = self.request("/document.txt", query="pipe=gzip")
self.assertEqual(resp.getcode(), 200)
+ def test_sub_default_py(self):
+ route = ("GET", "/defaultsubpy", wptserve.handlers.python_script_handler)
+ self.server.router.register(*route)
+ resp = self.request("/defaultsubpy")
+ self.assertEqual(b"localhost", resp.read())
+
if __name__ == '__main__':
unittest.main()
diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/test_server.py b/testing/web-platform/tests/tools/wptserve/tests/functional/test_server.py
index 939396ddee..39ef5889be 100644
--- a/testing/web-platform/tests/tools/wptserve/tests/functional/test_server.py
+++ b/testing/web-platform/tests/tools/wptserve/tests/functional/test_server.py
@@ -1,10 +1,15 @@
+import os
+import socket
+import ssl
import unittest
+from urllib.error import HTTPError
import pytest
-from urllib.error import HTTPError
+
+from localpaths import repo_root
wptserve = pytest.importorskip("wptserve")
-from .base import TestUsingServer, TestUsingH2Server
+from .base import TestUsingH2Server, TestUsingServer, doc_root
class TestFileHandler(TestUsingServer):
@@ -60,6 +65,65 @@ class TestRequestHandler(TestUsingServer):
self.assertEqual(200, resp.getcode())
+class TestH1TLSHandshake(TestUsingServer):
+ def setUp(self):
+ self.server = wptserve.server.WebTestHttpd(
+ host="localhost",
+ port=0,
+ use_ssl=True,
+ key_file=os.path.join(repo_root, "tools", "certs", "web-platform.test.key"),
+ certificate=os.path.join(
+ repo_root, "tools", "certs", "web-platform.test.pem"
+ ),
+ doc_root=doc_root,
+ )
+ self.server.start()
+
+ def test_no_handshake(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ context.load_verify_locations(
+ os.path.join(repo_root, "tools", "certs", "cacert.pem")
+ )
+
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s_no_handshake:
+ s_no_handshake.connect(("localhost", self.server.port))
+ # Note: this socket is left open, notably not sending the TLS handshake.
+
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
+ sock.settimeout(10)
+ with context.wrap_socket(
+ sock,
+ do_handshake_on_connect=False,
+ server_hostname="web-platform.test",
+ ) as ssock:
+ ssock.connect(("localhost", self.server.port))
+ ssock.do_handshake()
+ # The pass condition here is essentially "don't raise TimeoutError".
+
+
+class TestH2TLSHandshake(TestUsingH2Server):
+ def test_no_handshake(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ context.load_verify_locations(
+ os.path.join(repo_root, "tools", "certs", "cacert.pem")
+ )
+
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s_no_handshake:
+ s_no_handshake.connect(("localhost", self.server.port))
+ # Note: this socket is left open, notably not sending the TLS handshake.
+
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
+ sock.settimeout(10)
+ with context.wrap_socket(
+ sock,
+ do_handshake_on_connect=False,
+ server_hostname="web-platform.test",
+ ) as ssock:
+ ssock.connect(("localhost", self.server.port))
+ ssock.do_handshake()
+ # The pass condition here is essentially "don't raise TimeoutError".
+
+
class TestH2Version(TestUsingH2Server):
# The purpose of this test is to ensure that all TestUsingH2Server tests
# actually end up using HTTP/2, in case there's any protocol negotiation.
diff --git a/testing/web-platform/tests/tools/wptserve/wptserve/handlers.py b/testing/web-platform/tests/tools/wptserve/wptserve/handlers.py
index 6d79230a32..62faf47d64 100644
--- a/testing/web-platform/tests/tools/wptserve/wptserve/handlers.py
+++ b/testing/web-platform/tests/tools/wptserve/wptserve/handlers.py
@@ -2,6 +2,7 @@
import json
import os
+import pathlib
from collections import defaultdict
from urllib.parse import quote, unquote, urljoin
@@ -289,6 +290,10 @@ class PythonScriptHandler:
"""
This loads the requested python file as an environ variable.
+ If the requested file is a directory, this instead loads the first
+ lexicographically sorted file found in that directory that matches
+ "default*.py".
+
Once the environ is loaded, the passed `func` is run with this loaded environ.
:param request: The request object
@@ -298,6 +303,14 @@ class PythonScriptHandler:
"""
path = filesystem_path(self.base_path, request, self.url_base)
+ # Find a default Python file if the specified path is a directory
+ if os.path.isdir(path):
+ default_py_files = sorted(list(filter(
+ pathlib.Path.is_file,
+ pathlib.Path(path).glob("default*.py"))))
+ if default_py_files:
+ path = str(default_py_files[0])
+
try:
environ = {"__file__": path}
with open(path, 'rb') as f:
@@ -416,6 +429,9 @@ class AsIsHandler:
def __call__(self, request, response):
path = filesystem_path(self.base_path, request, self.url_base)
+ if os.path.isdir(path):
+ raise HTTPException(
+ 500, "AsIsHandler cannot process directory, %s" % path)
try:
with open(path, 'rb') as f:
diff --git a/testing/web-platform/tests/tools/wptserve/wptserve/server.py b/testing/web-platform/tests/tools/wptserve/wptserve/server.py
index e1772d00b1..8ce36201ee 100644
--- a/testing/web-platform/tests/tools/wptserve/wptserve/server.py
+++ b/testing/web-platform/tests/tools/wptserve/wptserve/server.py
@@ -130,7 +130,9 @@ class RequestRewriter:
class WebTestServer(http.server.ThreadingHTTPServer):
allow_reuse_address = True
- acceptable_errors = (errno.EPIPE, errno.ECONNABORTED)
+ # Older versions of Python might throw `OSError: [Errno 0] Error`
+ # instead of `SSLEOFError`.
+ acceptable_errors = (errno.EPIPE, errno.ECONNABORTED, 0)
request_queue_size = 2000
# Ensure that we don't hang on shutdown waiting for requests
@@ -214,14 +216,21 @@ class WebTestServer(http.server.ThreadingHTTPServer):
ssl_context.load_cert_chain(keyfile=self.key_file, certfile=self.certificate)
ssl_context.set_alpn_protocols(['h2'])
self.socket = ssl_context.wrap_socket(self.socket,
+ do_handshake_on_connect=False,
server_side=True)
else:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(keyfile=self.key_file, certfile=self.certificate)
self.socket = ssl_context.wrap_socket(self.socket,
+ do_handshake_on_connect=False,
server_side=True)
+ def finish_request(self, request, client_address):
+ if isinstance(self.socket, ssl.SSLSocket):
+ request.do_handshake()
+ super().finish_request(request, client_address)
+
def handle_error(self, request, client_address):
error = sys.exc_info()[1]
@@ -229,7 +238,11 @@ class WebTestServer(http.server.ThreadingHTTPServer):
isinstance(error.args, tuple) and
error.args[0] in self.acceptable_errors) or
(isinstance(error, IOError) and
- error.errno in self.acceptable_errors)):
+ error.errno in self.acceptable_errors) or
+ # `SSLEOFError` and `SSLError` may occur when a client
+ # (e.g., wptrunner's `TestEnvironment`) tests for connectivity
+ # but doesn't perform the handshake.
+ isinstance(error, ssl.SSLEOFError) or isinstance(error, ssl.SSLError)):
pass # remote hang up before the result is sent
else:
msg = traceback.format_exc()