def main(request, response):
    id = request.GET[b'id']
    encoding = request.GET[b'encoding']
    mode = request.GET[b'mode']
    iframe = u""
    if mode == b'NETWORK':
        iframe = u"<iframe src='stash.py?q=%%C3%%A5&id=%s&action=put'></iframe>" % isomorphic_decode(
            id)
    doc = u"""<!doctype html>
<html manifest="manifest.py?id=%s&encoding=%s&mode=%s">
%s
""" % (isomorphic_decode(id), isomorphic_decode(encoding),
       isomorphic_decode(mode), iframe)
    return [(b"Content-Type", b"text/html; charset=%s" % encoding)
            ], doc.encode(isomorphic_decode(encoding))
Beispiel #2
0
def main(request, response):
    # This server is configured so that is accept to receive any requests and
    # any cookies the web browser is willing to send.
    response.headers.set(b"Access-Control-Allow-Credentials", b"true")
    response.headers.set(b'Access-Control-Allow-Methods', b'OPTIONS, GET, POST')
    response.headers.set(b'Access-Control-Allow-Headers', b'Content-Type')
    response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"origin") or '*')

    if b"cacheable" in request.GET:
        response.headers.set(b"Cache-Control", b"max-age=31536000")
    else:
        response.headers.set(b'Cache-Control', b'no-cache, no-store, must-revalidate')

    # CORS preflight
    if request.method == u'OPTIONS':
        return b''

    uuid = request.GET[b'uuid']
    stash = request.server.stash;

    # The stash is accessed concurrently by many clients. A lock is used to
    # avoid unterleaved read/write from different clients.
    with stash.lock:
        queue = stash.take(uuid, '/common/dispatcher') or [];

        # Push into the |uuid| queue, the requested headers.
        if b"show-headers" in request.GET:
            headers = {};
            for key, value in request.headers.items():
                headers[isomorphic_decode(key)] = isomorphic_decode(request.headers[key])
            headers = json.dumps(headers);
            queue.append(headers);
            ret = b'';

        # Push into the |uuid| queue, the posted data.
        elif request.method == u'POST':
            queue.append(request.body)
            ret = b'done'

        # Pull from the |uuid| queue, the posted data.
        else:
            if len(queue) == 0:
                ret = b'not ready'
            else:
                ret = queue.pop(0)

        stash.put(uuid, queue, '/common/dispatcher')
    return ret;
Beispiel #3
0
def main(request, response):
    headers = [(b'Content-Type', b'application/javascript'),
               (b'Cache-Control', b'max-age=86400'),
               (b'Last-Modified', isomorphic_encode(time.strftime(u"%a, %d %b %Y %H:%M:%S GMT", time.gmtime())))]

    test = request.GET[b'test']

    body = u'''
        const mainTime = {time:8f};
        const testName = {test};
        importScripts('update-max-aged-worker-imported-script.py?test={test}');

        addEventListener('message', event => {{
            event.source.postMessage({{
                mainTime,
                importTime,
                test: {test}
            }});
        }});
    '''.format(
        time=time.time(),
        test=json.dumps(isomorphic_decode(test))
    )

    return headers, body
Beispiel #4
0
def main(request, response):
    if b"increment" in request.GET:
        uuid = request.GET[b"increment"]

        # First, increment the stash value keyed by `uuid`, and write it back to the
        # stash. Writing it back to the stash is necessary since `take()` actually
        # removes the value whereas we want to increment it.
        stash_value = request.server.stash.take(uuid)
        if stash_value is None:
            stash_value = 0
        request.server.stash.put(uuid, stash_value + 1)

        # Return a basic image.
        response_headers = [(b"Content-Type", b"image/png")]
        image_path = os.path.join(os.path.dirname(isomorphic_decode(__file__)),
                                  u"image.png")
        return (200, response_headers, open(image_path, mode='rb').read())

    elif b"read" in request.GET:
        uuid = request.GET[b"read"]
        stash_value = request.server.stash.take(uuid)

        if stash_value is None:
            stash_value = 0
        # Write the stash value keyed by `uuid` back to the stash. This is necessary
        # because `take()` actually removes it, but we want a read-only read.
        request.server.stash.put(uuid, stash_value)
        return (200, [], str(stash_value))

    return (404, [], "Not found")
Beispiel #5
0
def main(request, response):
    """
    Simple handler that sets a response header based on which client hint
    request headers were received.
    """

    response.headers.append(b"Access-Control-Allow-Origin", b"*")
    values = request.GET
    name = values.first(b'name')
    type = values.first(b'mimeType')
    dpr = values.first(b'dpr')
    double = None
    if b'double' in values:
        double = values.first(b'double')
    image_path = request.doc_root + u"/".join(
        request.url_parts[2].split(u"/")[:-1]) + u"/" + isomorphic_decode(name)
    f = open(image_path, "rb")
    buff = f.read()
    f.close()
    response.headers.set(b"Content-Type", type)
    response.headers.set(b"Content-DPR", dpr)
    if double:
        response.headers.append(b"Content-DPR", double)
    response.headers.set(b"Content-Length", len(buff))
    response.content = buff
Beispiel #6
0
def main(request, response):
    if b"debug" in request.GET:
        """If '?debug=' is set, return the document for a single test."""
        response.writer.write_status(200)
        response.writer.end_headers()
        html_frame = dump_file(
            path.join(request.doc_root, DEFAULT_RESOURCE_DIR),
            DEBUGGING_HTML_SCAFFOLD)
        test_file = html_frame % (request.GET[b'debug'])
        response.writer.write_content(test_file)
        return

    if b"file" in request.GET:
        """If '?file=' is set, send a cookie and a document which contains the
    expectation of which cookies should be set by the browser in response."""
        cookie_response = CookieTestResponse(
            isomorphic_decode(request.GET[b'file']), request.doc_root)

        response.writer.write_status(200)
        response.writer.write(cookie_response.cookie_setting_header())
        response.writer.end_headers()
        response.writer.write_content(cookie_response.body_with_expectation())
        return
    """Without any arguments, return documentation and run all available tests."""
    response.writer.write_status(200)
    response.writer.end_headers()
    response.writer.write_content(generate_for_all_tests(request.doc_root))
Beispiel #7
0
def main(request, response):
    if b'Status' in request.GET:
        status = int(request.GET[b"Status"])
    else:
        status = 302

    headers = []

    url = isomorphic_decode(request.GET[b'Redirect'])
    headers.append((b"Location", url))

    if b"ACAOrigin" in request.GET:
        for item in request.GET[b"ACAOrigin"].split(b","):
            headers.append((b"Access-Control-Allow-Origin", item))

    for suffix in [b"Headers", b"Methods", b"Credentials"]:
        query = b"ACA%s" % suffix
        header = b"Access-Control-Allow-%s" % suffix
        if query in request.GET:
            headers.append((header, request.GET[query]))

    if b"ACEHeaders" in request.GET:
        headers.append(
            (b"Access-Control-Expose-Headers", request.GET[b"ACEHeaders"]))

    return status, headers, b""
Beispiel #8
0
def main(request, response):
    """Set a cookie via GET params.

    Usage: `/cookie.py?set={cookie}`

    The passed-in cookie string should be stringified via JSON.stringify() (in
    the case of multiple cookie headers sent in an array) and encoded via
    encodeURIComponent, otherwise `parse_qsl` will split on any semicolons
    (used by the Request.GET property getter). Note that values returned by
    Request.GET will decode any percent-encoded sequences sent in a GET param
    (which may or may not be surprising depending on what you're doing).

    Note: here we don't use Response.delete_cookie() or similar other methods
    in this resources directory because there are edge cases that are impossible
    to express via those APIs, namely a bare (`Path`) or empty Path (`Path=`)
    attribute. Instead, we pipe through the entire cookie and append `max-age=0`
    to it.
    """
    headers = setNoCacheAndCORSHeaders(request, response)

    if b'set' in request.GET:
        cookie = isomorphic_decode(request.GET[b'set'])
        cookie = json.loads(cookie)
        cookies = cookie if isinstance(cookie, list) else [cookie]
        for c in cookies:
            set_cookie(headers, c)

    if b'location' in request.GET:
        headers.append((b'Location', request.GET[b'location']))
        return 302, headers, b'{"redirect": true}'

    return headers, b'{"success": true}'
Beispiel #9
0
def main(request, response):
    import datetime, os
    srcpath = os.path.join(os.path.dirname(isomorphic_decode(__file__)), u"well-formed.xml")
    srcmoddt = datetime.datetime.utcfromtimestamp(os.path.getmtime(srcpath))
    response.headers.set(b"Last-Modified", isomorphic_encode(srcmoddt.strftime(u"%a, %d %b %Y %H:%M:%S GMT")))
    response.headers.set(b"Content-Type", b"application/xml")
    return open(srcpath, u"r").read()
Beispiel #10
0
def main(request, response):
    message = {}

    header = request.headers.get(b"Test-Header-Injection")
    message[u'test_header_injection'] = isomorphic_decode(
        header) if header else None

    header = request.headers.get(b"Sec-Required-CSP")
    message[u'required_csp'] = isomorphic_decode(header) if header else None

    second_level_iframe_code = u""
    if b"include_second_level_iframe" in request.GET:
        if b"second_level_iframe_csp" in request.GET and request.GET[
                b"second_level_iframe_csp"] != b"":
            second_level_iframe_code = u'''<script>
            var i2 = document.createElement('iframe');
            i2.src = 'echo-required-csp.py';
            i2.csp = "{0}";
            document.body.appendChild(i2);
            </script>'''.format(
                isomorphic_decode(request.GET[b"second_level_iframe_csp"]))
        else:
            second_level_iframe_code = u'''<script>
            var i2 = document.createElement('iframe');
            i2.src = 'echo-required-csp.py';
            document.body.appendChild(i2);
            </script>'''

    return [(b"Content-Type", b"text/html"), (b"Allow-CSP-From", b"*")], u'''
<!DOCTYPE html>
<html>
<head>
    <!--{2}-->
    <script>
      window.addEventListener('message', function(e) {{
        window.parent.postMessage(e.data, '*');
      }});

      window.parent.postMessage({0}, '*');
    </script>
</head>
<body>
{1}
</body>
</html>
'''.format(json.dumps(message), second_level_iframe_code, str(request.headers))
Beispiel #11
0
def parse_qs_str(query_str):
  if PY3:
    args = parse_qs(isomorphic_decode(query_str), keep_blank_values=True, encoding=u'iso-8859-1')
    binary_args = {}
    for key, val in args.items():
        binary_args[isomorphic_encode(key)] = [isomorphic_encode(x) for x in val]
    return binary_args
  else:
    return parse_qs(query_str, keep_blank_values=True)
def main(request, response):
    path = os.path.join(os.path.dirname(isomorphic_decode(__file__)),
                        u"test-request-mode-worker.js")
    body = open(path, u"rb").read()

    data = {
        isomorphic_decode(key): isomorphic_decode(request.headers[key])
        for key, value in request.headers.items()
    }

    body = body.replace(b"%HEADERS%", json.dumps(data).encode("utf-8"))
    body = body.replace(b"%UUID%", str(uuid.uuid4()).encode("utf-8"))

    headers = []
    headers.append((b"ETag", b"etag"))
    headers.append((b"Content-Type", b'text/javascript'))

    return headers, body
Beispiel #13
0
def main(request, response):
    referrer = request.headers.get(b"referer", b"")
    expected_referrer = request.GET.first(b"expected_referrer", b"")
    response_headers = [(b"Content-Type", b"image/png")]
    if referrer == expected_referrer:
        image_path = os.path.join(os.path.dirname(isomorphic_decode(__file__)),
                                  u"image.png")
        return (200, response_headers, open(image_path, mode='rb').read())
    return (404, response_headers, u"Not found")
def main(request, response):
    header = [(b'Content-Type', b'text/html')]
    if b'test' in request.GET:
        with open(
                os.path.join(os.path.dirname(isomorphic_decode(__file__)),
                             u'blank.html'), u'r') as f:
            body = f.read()
        return (header, body)

    if b'sandbox' in request.GET:
        header.append((b'Content-Security-Policy',
                       b'sandbox %s' % request.GET[b'sandbox']))
    with open(
            os.path.join(os.path.dirname(isomorphic_decode(__file__)),
                         u'sandboxed-iframe-fetch-event-iframe.html'),
            u'r') as f:
        body = f.read()
    return (header, body)
def main(request, response):
    response.headers.set(b"Cache-Control", b"no-store")

    # This should be a simple request; deny preflight
    if request.method != u"POST":
        response.status = 400
        return

    response.headers.set(b"Access-Control-Allow-Credentials", b"true")
    response.headers.set(b"Access-Control-Allow-Origin",
                         request.headers.get(b"origin"))

    for header in [
            b"Accept", b"Accept-Language", b"Content-Language", b"Content-Type"
    ]:
        value = request.headers.get(header)
        response.content += isomorphic_decode(header) + u": " + (
            isomorphic_decode(value) if value else u"<None>") + u'\n'
def main(request, response):
    # The response served is cacheable by the navigator:
    response.headers.set(b"Cache-Control", b"max-age=31536000");

    uuid = request.GET[b'uuid'];
    headers = {};
    for key, value in request.headers.items():
        headers[isomorphic_decode(key)] = isomorphic_decode(request.headers[key])
    headers = json.dumps(headers);

    # The stash is accessed concurrently by many clients. A lock is used to
    # avoid unterleaved read/write from different clients.
    stash = request.server.stash;
    with stash.lock:
        queue = stash.take(uuid, '/coep-credentialless') or [];
        queue.append(headers);
        stash.put(uuid, queue, '/coep-credentialless');
    return b"done";
Beispiel #17
0
def get_template(template_basename):
    script_directory = os.path.dirname(
        os.path.abspath(isomorphic_decode(__file__)))
    template_directory = os.path.abspath(
        os.path.join(script_directory, u"template"))
    template_filename = os.path.join(template_directory, template_basename)

    with open(template_filename, "r") as f:
        return f.read()
Beispiel #18
0
def main(request, response):
    CertChainMimeType = b"application/cert-chain+cbor"

    if request.headers.get(b"Accept") != CertChainMimeType:
        return 400, [], u"Bad Request"

    path = os.path.join(os.path.dirname(isomorphic_decode(__file__)), u"127.0.0.1.sxg.pem.cbor")
    body = open(path, u"rb").read()
    return 200, [(b"Content-Type", CertChainMimeType)], body
Beispiel #19
0
def main(request, response):
    index = isomorphic_encode(request.request_path).index(b"?")
    args = isomorphic_encode(request.request_path[index + 1:]).split(b"&")
    headers = []
    statusSent = False
    headersSent = False
    for arg in args:
        if arg.startswith(b"ignored"):
            continue
        elif arg.endswith(b"ms"):
            sleep.sleep_at_least(float(arg[0:-2]))
        elif arg.startswith(b"redirect:"):
            return (302, u"WEBPERF MARKETING"), [
                (b"Location", unquote(isomorphic_decode(arg[9:])))
            ], u"TEST"

        elif arg.startswith(b"mime:"):
            headers.append(
                (b"Content-Type", unquote(isomorphic_decode(arg[5:]))))

        elif arg.startswith(b"send:"):
            text = unquote(isomorphic_decode(arg[5:]))

            if not statusSent:
                # Default to a 200 status code.
                response.writer.write_status(200)
                statusSent = True
            if not headersSent:
                for key, value in headers:
                    response.writer.write_header(key, value)
                response.writer.end_headers()
                headersSent = True

            response.writer.write_content(text)
        elif arg.startswith(b"status:"):
            code = int(unquote(isomorphic_decode(arg[7:])))
            response.writer.write_status(code)
            if code // 100 == 1:
                # Terminate informational 1XX responses with an empty line.
                response.writer.end_headers()
            else:
                statusSent = True
        elif arg == b"flush":
            response.writer.flush()
Beispiel #20
0
def main(request, response):
    purpose = request.headers.get(b"purpose")
    if (purpose == b'prefetch' and b"code" in request.GET):
        code = int(request.GET.first(b"code"))
    else:
        code = 200

    with open(os.path.join(os.path.dirname(isomorphic_decode(__file__)), "exec.html"), u"r") as fn:
        response.content = fn.read()
    response.status = code
Beispiel #21
0
def main(request, response):
    testinput = request.POST.first(b"testinput")
    if PY3:
        # The test asserts the string representation of this FieldStorage
        # object, but unfortunately the value property has different types in
        # Python 2 and 3. Unify them to native strings.
        testinput.value = isomorphic_decode(testinput.value)
    return ([(b"Content-Type", b"text/html")
             ], u"<script>parent.postMessage(\"" + str(testinput) +
            u"\", '*');</script>")
Beispiel #22
0
def respond(request,
            response,
            status_code=200,
            content_type=b"text/html",
            payload_generator=__noop,
            cache_control=b"no-cache; must-revalidate",
            access_control_allow_origin=b"*",
            maybe_additional_headers=None):
    if preprocess_redirection(request, response):
        return

    if preprocess_stash_action(request, response):
        return

    response.add_required_headers = False
    response.writer.write_status(status_code)

    if access_control_allow_origin != None:
        response.writer.write_header(b"access-control-allow-origin",
                                     access_control_allow_origin)
    response.writer.write_header(b"content-type", content_type)
    response.writer.write_header(b"cache-control", cache_control)

    additional_headers = maybe_additional_headers or {}
    for header, value in additional_headers.items():
        response.writer.write_header(header, value)

    response.writer.end_headers()

    new_headers = {}
    new_val = []
    for key, val in request.headers.items():
        if len(val) == 1:
            new_val = isomorphic_decode(val[0])
        else:
            new_val = [isomorphic_decode(x) for x in val]
        new_headers[isomorphic_decode(key)] = new_val

    server_data = {u"headers": json.dumps(new_headers, indent=4)}

    payload = payload_generator(server_data)
    response.writer.write(payload)
Beispiel #23
0
def main(request, response):
    """Serves the contents in blue.png but with a Cache-Control header.

  Emits a Cache-Control header with max-age set to 1h to allow the browser
  cache the image. Used for testing behaviors involving caching logics.
  """
    image_path = os.path.join(os.path.dirname(isomorphic_decode(__file__)),
                              u"blue.png")
    response.headers.set(b"Cache-Control", b"max-age=3600")
    response.headers.set(b"Content-Type", b"image/png")
    response.content = open(image_path, mode='rb').read()
Beispiel #24
0
def main(request, response):
    headers = [(b"Content-Type", b"text/plain"),
               (b"Cache-Control", b"no-cache"), (b"Pragma", b"no-cache")]

    if b"store" in request.GET:
        request.server.stash.put(
            request.GET[b'token'],
            isomorphic_decode(request.headers.get(b"DNT", b"-1")))
        return 200, headers, ""

    return 200, headers, str(request.server.stash.take(request.GET[b'token']))
Beispiel #25
0
def main(request, response):
    # update() does not bypass cache so set the max-age to 0 such that update()
    # can find a new version in the network.
    headers = [(b'Cache-Control', b'max-age: 0'),
               (b'Content-Type', b'application/javascript')]
    with open(
            os.path.join(os.path.dirname(isomorphic_decode(__file__)),
                         u'update-worker.js'), u'r') as file:
        script = file.read()
    # Return a different script for each access.
    return headers, u'// %s\n%s' % (time.time(), script)
Beispiel #26
0
def main(request, response):
    msg = {}
    headers = [(b'Content-Type', b'text/html')]

    srdp = request.headers.get(b'Sec-Required-Document-Policy')
    if srdp:
        msg[u'requiredPolicy'] = isomorphic_decode(srdp)
        headers.append((b'Document-Policy', srdp))

    frameId = request.GET.first(b'id', None)
    if frameId:
        msg[u'id'] = isomorphic_decode(frameId)

    content = u"""<!DOCTYPE html>
<script>
top.postMessage(%s, "*");
</script>
%s
""" % (json.dumps(msg), isomorphic_decode(srdp) if srdp != None else srdp)

    return (200, u'OK'), headers, content
Beispiel #27
0
def handle_headers(frame, request, response):
    status = 302
    if b'redirect_status' in request.GET:
        status = int(request.GET[b'redirect_status'])
    response.status = status

    if b'location' in request.GET:
        url = isomorphic_decode(request.GET[b'location'])
        response.headers[b'Location'] = isomorphic_encode(url)

    response.headers.update([('Content-Type', 'text/plain')])
    response.write_status_headers()
Beispiel #28
0
def preprocess_stash_action(request, response):
    if b"action" not in request.GET:
        return False

    action = request.GET[b"action"]

    key = request.GET[b"key"]
    stash = request.server.stash
    path = request.GET[b"path"] if b"path" in request.GET \
           else isomorphic_encode(request.url.split(u'?')[0])

    if action == b"put":
        value = isomorphic_decode(request.GET[b"value"])
        stash.take(key=key, path=path)
        stash.put(key=key, value=value, path=path)
        response_data = json.dumps({
            u"status": u"success",
            u"result": isomorphic_decode(key)
        })
    elif action == b"purge":
        value = stash.take(key=key, path=path)
        return False
    elif action == b"take":
        value = stash.take(key=key, path=path)
        if value is None:
            status = u"allowed"
        else:
            status = u"blocked"
        response_data = json.dumps({u"status": status, u"result": value})
    else:
        return False

    response.add_required_headers = False
    response.writer.write_status(200)
    response.writer.write_header(b"content-type", b"text/javascript")
    response.writer.write_header(b"cache-control",
                                 b"no-cache; must-revalidate")
    response.writer.end_headers()
    response.writer.write(response_data)
    return True
def main(request, response):
    """
    Simple handler that returns an HTML response that passes when the required
    Client Hints are received as request headers.
    """
    values = [
        b"Device-Memory", b"DPR", b"Viewport-Width", b"Sec-CH-UA",
        b"Sec-CH-UA-Mobile"
    ]

    result = u"PASS"
    log = u""
    for value in values:
        should = (request.GET[value.lower()] == b"true")
        present = request.headers.get(
            value.lower()) or request.headers.get(value)
        if present:
            log += isomorphic_decode(value) + u" " + str(
                should) + u" " + isomorphic_decode(present) + u", "
        else:
            log += isomorphic_decode(value) + u" " + str(should) + u" " + str(
                present) + u", "
        if (should and not present) or (not should and present):
            if present:
                result = u"FAIL " + isomorphic_decode(value) + u" " + str(
                    should) + u" " + isomorphic_decode(present)
            else:
                result = u"FAIL " + isomorphic_decode(value) + u" " + str(
                    should) + u" " + str(present)
            break

    response.headers.append(b"Access-Control-Allow-Origin", b"*")
    body = u"<script>console.log('" + log + u"'); window.parent.postMessage('" + result + u"', '*');</script>"

    response.content = body
Beispiel #30
0
def handle_fetch_file(request, response, partition_id, uuid):
    subresource_origin = request.GET.first(b"subresource_origin", None)
    rel_path = request.GET.first(b"path", None)

    # This needs to be passed on to subresources so they all have access to it.
    include_credentials = request.GET.first(b"include_credentials", None)
    if not subresource_origin or not rel_path or not include_credentials:
        return simple_response(request, response, 404, b"Not found", b"Invalid query parameters")

    cur_path = os.path.realpath(isomorphic_decode(__file__))
    base_path = os.path.abspath(os.path.join(os.path.dirname(cur_path), os.pardir, os.pardir, os.pardir))
    path = os.path.abspath(os.path.join(base_path, isomorphic_decode(rel_path)))

    # Basic security check.
    if not path.startswith(base_path):
        return simple_response(request, response, 404, b"Not found", b"Invalid path")

    sandbox = request.GET.first(b"sandbox", None)
    if sandbox == b"true":
        response.headers.set(b"Content-Security-Policy", b"sandbox allow-scripts")

    file = open(path, mode="rb")
    body = file.read()
    file.close()

    subresource_path = b"/" + isomorphic_encode(os.path.relpath(isomorphic_decode(__file__), base_path)).replace(b'\\', b'/')
    subresource_params = b"?partition_id=" + partition_id + b"&uuid=" + uuid + b"&subresource_origin=" + subresource_origin + b"&include_credentials=" + include_credentials
    body = body.replace(b"SUBRESOURCE_PREFIX:", subresource_origin + subresource_path + subresource_params)

    other_origin = request.GET.first(b"other_origin", None)
    if other_origin:
        body = body.replace(b"OTHER_PREFIX:", other_origin + subresource_path + subresource_params)

    mimetypes.init()
    mimetype_pair = mimetypes.guess_type(path)
    mimetype = mimetype_pair[0]

    if mimetype == None or mimetype_pair[1] != None:
        return simple_response(request, response, 500, b"Server Error", b"Unknown MIME type")
    return simple_response(request, response, 200, b"OK", body, mimetype)