trusted-scoring-signals.py (4690B)
1 import json 2 3 from fledge.tentative.resources import fledge_http_server_util 4 5 6 # Script to generate trusted scoring signals. The responses depends on the 7 # query strings in the ads Urls - some result in entire response failures, 8 # others affect only their own value. Each renderUrl potentially has a 9 # signalsParam, which is a comma-delimited list of instructions that can 10 # each affect either the value associated with the renderUrl, or the 11 # response as a whole. 12 def main(request, response): 13 try: 14 params = fledge_http_server_util.decode_trusted_scoring_signals_params(request) 15 except ValueError as ve: 16 fail(response, str(ve)) 17 return 18 19 response.status = (200, b"OK") 20 21 # The JSON representation of this is used as the response body. 22 responseBody = {"renderUrls": {}} 23 24 # Set when certain special keys are observed, used in place of the JSON 25 # representation of `responseBody`, when set. 26 body = None 27 28 contentType = "application/json" 29 adAuctionAllowed = "true" 30 dataVersion = None 31 cors = False 32 for urlList in params.urlLists: 33 for renderUrl in urlList["urls"]: 34 value = "default value" 35 addValue = True 36 37 try: 38 signalsParams = fledge_http_server_util.decode_render_url_signals_params(renderUrl) 39 except ValueError as ve: 40 fail(response, str(ve)) 41 return 42 43 for signalsParam in signalsParams: 44 if signalsParam == "close-connection": 45 # Close connection without writing anything, to simulate a 46 # network error. The write call is needed to avoid writing the 47 # default headers. 48 response.writer.write("") 49 response.close_connection = True 50 return 51 elif signalsParam.startswith("replace-body:"): 52 # Replace entire response body. Continue to run through other 53 # renderUrls, to allow them to modify request headers. 54 body = signalsParam.split(':', 1)[1] 55 elif signalsParam.startswith("data-version:"): 56 dataVersion = signalsParam.split(':', 1)[1] 57 elif signalsParam == "http-error": 58 response.status = (404, b"Not found") 59 elif signalsParam == "no-content-type": 60 contentType = None 61 elif signalsParam == "wrong-content-type": 62 contentType = 'text/plain' 63 elif signalsParam == "bad-ad-auction-allowed": 64 adAuctionAllowed = "sometimes" 65 elif signalsParam == "ad-auction-not-allowed": 66 adAuctionAllowed = "false" 67 elif signalsParam == "no-ad-auction-allow": 68 adAuctionAllowed = None 69 elif signalsParam == "wrong-url": 70 renderUrl = "https://wrong-url.test/" 71 elif signalsParam == "no-value": 72 addValue = False 73 elif signalsParam == "null-value": 74 value = None 75 elif signalsParam == "num-value": 76 value = 1 77 elif signalsParam == "string-value": 78 value = "1" 79 elif signalsParam == "array-value": 80 value = [1, "foo", None] 81 elif signalsParam == "object-value": 82 value = {"a":"b", "c":["d"]} 83 elif signalsParam == "hostname": 84 value = params.hostname 85 elif signalsParam == "headers": 86 value = fledge_http_server_util.headers_to_ascii(request.headers) 87 elif signalsParam == "url": 88 value = request.url 89 elif signalsParam == "cors": 90 cors = True 91 if addValue: 92 if urlList["type"] not in responseBody: 93 responseBody[urlList["type"]] = {} 94 responseBody[urlList["type"]][renderUrl] = value 95 96 # If the signalsParam embedded inside a render URL calls for CORS, add 97 # appropriate response headers. 98 if cors and fledge_http_server_util.handle_cors_headers_fail_if_preflight( 99 request, response): 100 return 101 102 if contentType: 103 response.headers.set("Content-Type", contentType) 104 if adAuctionAllowed: 105 response.headers.set("Ad-Auction-Allowed", adAuctionAllowed) 106 if dataVersion: 107 response.headers.set("Data-Version", dataVersion) 108 109 if body != None: 110 return body 111 return json.dumps(responseBody)