tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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)