File: target.py

package info (click to toggle)
thunderbird 1%3A140.4.0esr-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 4,609,412 kB
  • sloc: cpp: 7,672,442; javascript: 5,901,613; ansic: 3,898,954; python: 1,413,343; xml: 653,997; asm: 462,286; java: 180,927; sh: 113,489; makefile: 20,460; perl: 14,288; objc: 13,059; yacc: 4,583; pascal: 3,352; lex: 1,720; ruby: 1,222; exp: 762; sql: 715; awk: 580; php: 436; lisp: 430; sed: 70; csh: 10
file content (105 lines) | stat: -rw-r--r-- 3,654 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# This endpoint responds to requests for a target of a (possible) LNA request.
#
# Its behavior can be configured with various search/GET parameters, all of
# which are optional:
#
# - final-headers: Valid values are:
#   - cors: this endpoint responds with valid CORS headers to CORS-enabled
#     non-preflight requests. These should be sufficient for non-preflighted
#     CORS-enabled requests to succeed.
#   - sw: this endpoint responds with a valid Service-Worker header to allow
#     for the request to serve as a Service worker script resource. This is
#     only valid in conjunction with the cors value above.
#   - unspecified: this endpoint responds with no CORS headers to non-preflight
#     requests. This should fail CORS-enabled requests, but be sufficient for
#     no-CORS requests.
#
# The following parameters only affect non-preflight responses:
#
# - redirect: If set, the response code is set to 301 and the `Location`
#   response header is set to this value.
# - mime-type: If set, the `Content-Type` response header is set to this value.
# - file: Specifies a path (relative to this file's directory) to a file. If
#   set, the response body is copied from this file.
# - random-js-prefix: If set to any value, the response body is prefixed with
#   a Javascript comment line containing a random value. This is useful in
#   service worker tests, since service workers are only updated if the new
#   script is not byte-for-byte identical with the old script.
# - body: If set and `file` is not, the response body is set to this value.
#

import os
import random

from wptserve.utils import isomorphic_encode

_ACAO = ("Access-Control-Allow-Origin", "*")
_ACAH = ("Access-Control-Allow-Headers", "Service-Worker")

def _get_response_headers(method, mode, origin):
  acam = ("Access-Control-Allow-Methods", method)

  if mode == b"cors":
    return [acam, _ACAO]

  if mode == b"cors+sw":
    return [acam, _ACAO, _ACAH]

  if mode == b"navigation":
    return [
        acam,
        ("Access-Control-Allow-Origin", origin),
        ("Access-Control-Allow-Credentials", "true"),
    ]

  return []


def _is_loaded_in_fenced_frame(request):
  return request.GET.get(b"is-loaded-in-fenced-frame")

def _final_response_body(request):
  file_name = None
  if file_name is None:
    file_name = request.GET.get(b"file")
  if file_name is None:
    return request.GET.get(b"body") or "success"

  prefix = b""
  if request.GET.get(b"random-js-prefix"):
    value = random.randint(0, 1000000000)
    prefix = isomorphic_encode("// Random value: {}\n\n".format(value))

  path = os.path.join(os.path.dirname(isomorphic_encode(__file__)), file_name)
  with open(path, 'rb') as f:
    contents = f.read()

  return prefix + contents

def _handle_final_request(request, response):
  mode = request.GET.get(b"final-headers")
  origin = request.headers.get("Origin")
  headers = _get_response_headers(request.method, mode, origin)

  redirect = request.GET.get(b"redirect")
  if redirect is not None:
    headers.append(("Location", redirect))
    return (301, headers, b"")

  mime_type = request.GET.get(b"mime-type")
  if mime_type is not None:
    headers.append(("Content-Type", mime_type),)

  if _is_loaded_in_fenced_frame(request):
    headers.append(("Supports-Loading-Mode", "fenced-frame"))

  body = _final_response_body(request)
  return (headers, body)


def main(request, response):
  try:
    return _handle_final_request(request, response)
  except BaseException as e:
    # Surface exceptions to the client, where they show up as assertion errors.
    return (500, [("X-exception", str(e))], "exception: {}".format(e))