diff options
Diffstat (limited to 'testing/web-platform/tests/fledge/tentative/resources/trusted-bidding-signals.py')
-rw-r--r-- | testing/web-platform/tests/fledge/tentative/resources/trusted-bidding-signals.py | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/testing/web-platform/tests/fledge/tentative/resources/trusted-bidding-signals.py b/testing/web-platform/tests/fledge/tentative/resources/trusted-bidding-signals.py new file mode 100644 index 0000000000..cdd7052a96 --- /dev/null +++ b/testing/web-platform/tests/fledge/tentative/resources/trusted-bidding-signals.py @@ -0,0 +1,124 @@ +import json +from urllib.parse import unquote_plus + +# Script to generate trusted bidding signals. The responses depends on the +# keys and interestGroupNames - some result in entire response failures, others +# affect only their own value. Keys are preferentially used over +# interestGroupName, since keys are composible, but some tests need to cover +# there being no keys. +def main(request, response): + hostname = None + keys = None + interestGroupNames = None + + # Manually parse query params. Can't use request.GET because it unescapes as well as splitting, + # and commas mean very different things from escaped commas. + for param in request.url_parts.query.split("&"): + pair = param.split("=", 1) + if len(pair) != 2: + return fail(response, "Bad query parameter: " + param) + # Browsers should escape query params consistently. + if "%20" in pair[1]: + return fail(response, "Query parameter should escape using '+': " + param) + + # Hostname can't be empty. The empty string can be a key or interest group name, though. + if pair[0] == "hostname" and hostname == None and len(pair[1]) > 0: + hostname = pair[1] + continue + if pair[0] == "keys" and keys == None: + keys = list(map(unquote_plus, pair[1].split(","))) + continue + if pair[0] == "interestGroupNames" and interestGroupNames == None: + interestGroupNames = list(map(unquote_plus, pair[1].split(","))) + continue + return fail(response, "Unexpected query parameter: " + param) + + # "interestGroupNames" and "hostname" are mandatory. + if not hostname: + return fail(response, "hostname missing") + if not interestGroupNames: + return fail(response, "interestGroupNames missing") + + response.status = (200, b"OK") + + # The JSON representation of this is used as the response body. This does + # not currently include a "perInterestGroupData" object. + responseBody = {"keys": {}} + + # Set when certain special keys are observed, used in place of the JSON + # representation of `responseBody`, when set. + body = None + + contentType = "application/json" + xAllowFledge = "true" + dataVersion = None + if keys: + for key in keys: + value = "default value" + if key == "close-connection": + # Close connection without writing anything, to simulate a + # network error. The write call is needed to avoid writing the + # default headers. + response.writer.write("") + response.close_connection = True + return + elif key.startswith("replace-body:"): + # Replace entire response body. Continue to run through other + # keys, to allow them to modify request headers. + body = key.split(':', 1)[1] + elif key.startswith("data-version:"): + dataVersion = key.split(':', 1)[1] + elif key == "http-error": + response.status = (404, b"Not found") + elif key == "no-content-type": + contentType = None + elif key == "wrong-content-type": + contentType = 'text/plain' + elif key == "wrongContentType": + contentType = 'text/plain' + elif key == "bad-allow-fledge": + xAllowFledge = "sometimes" + elif key == "fledge-not-allowed": + xAllowFledge = "false" + elif key == "no-allow-fledge": + xAllowFledge = None + elif key == "no-value": + continue + elif key == "wrong-value": + responseBody["keys"]["another-value"] = "another-value" + continue + elif key == "null-value": + value = None + elif key == "num-value": + value = 1 + elif key == "string-value": + value = "1" + elif key == "array-value": + value = [1, "foo", None] + elif key == "object-value": + value = {"a":"b", "c":["d"]} + elif key == "interest-group-names": + value = json.dumps(interestGroupNames) + elif key == "hostname": + value = request.GET.first(b"hostname", b"not-found").decode("ASCII") + responseBody["keys"][key] = value + + if "data-version" in interestGroupNames: + dataVersion = "4" + + if contentType: + response.headers.set("Content-Type", contentType) + if xAllowFledge: + response.headers.set("X-Allow-FLEDGE", xAllowFledge) + if dataVersion: + response.headers.set("Data-Version", dataVersion) + response.headers.set("X-fledge-bidding-signals-format-version", "2") + + if body != None: + return body + return json.dumps(responseBody) + +def fail(response, body): + response.status = (400, "Bad Request") + response.headers.set(b"Content-Type", b"text/plain") + return body |