def main(request, response): is_revalidation = request.headers.get(b"If-None-Match", None) token = request.GET.first(b"token", None) is_query = request.GET.first(b"query", None) != None with request.server.stash.lock: value = request.server.stash.take(token) count = 0 if value != None: count = int(value) if is_query: if count < 2: request.server.stash.put(token, count) else: if is_revalidation is not None: count = count + 1 request.server.stash.put(token, count) if is_query: headers = [(b"Count", isomorphic_encode(str(count))), (b"Test", isomorphic_encode(str(request.raw_headers)))] content = "" return 200, headers, content else: unique_id = id_token() headers = [(b"Content-Type", b"text/html"), (b"Cache-Control", b"private, max-age=0, stale-while-revalidate=60"), (b"ETag", b'"swr"'), (b"Unique-Id", isomorphic_encode(unique_id))] content = "<body>{}</body>".format(unique_id) return 200, headers, content
def main(request, response): headers = [ (b"Access-Control-Allow-Origin", b"*"), (b"Access-Control-Allow-Credentials", b"true"), (b"Access-Control-Allow-Methods", b"GET, POST, PUT, FOO"), (b"Access-Control-Allow-Headers", b"x-test, x-foo"), (b"Access-Control-Expose-Headers", b"x-request-method, x-request-content-type, x-request-query, x-request-content-length, x-request-data" ) ] if b"delay" in request.GET: delay = int(request.GET.first(b"delay")) time.sleep(delay) if b"safelist_content_type" in request.GET: headers.append((b"Access-Control-Allow-Headers", b"content-type")) headers.append((b"X-Request-Method", isomorphic_encode(request.method))) headers.append( (b"X-Request-Query", isomorphic_encode(request.url_parts.query) if request.url_parts.query else b"NO")) headers.append((b"X-Request-Content-Length", request.headers.get(b"Content-Length", b"NO"))) headers.append((b"X-Request-Content-Type", request.headers.get(b"Content-Type", b"NO"))) headers.append((b"X-Request-Data", request.body)) return headers, b"Test"
def get_response(raw_headers, filter_value, filter_name): result = b"" # Type of raw_headers is <httplib.HTTPMessage> in Python 2 and <http.client.HTTPMessage> in # Python 3. <http.client.HTTPMessage> doesn't have 'headers" attribute or equivalent # [https://bugs.python.org/issue4773]. # In Python 2, variable raw_headers.headers returns a completely uninterpreted list of lines # contained in the header. In Python 3, raw_headers.raw_items() returns the (name, value) # header pairs without modification. Here is to construct an equivalent "headers" variable to # support tests in Python 3. if PY3: header_list = [] for field in raw_headers.raw_items(): header = b"%s: %s\r\n" % (isomorphic_encode( field[0]), isomorphic_encode(field[1])) header_list.append(header) else: header_list = raw_headers.headers for line in header_list: if line[-2:] != b'\r\n': return b"Syntax error: missing CRLF: " + line line = line[:-2] if b': ' not in line: return b"Syntax error: no colon and space found: " + line name, value = line.split(b': ', 1) if filter_value: if value == filter_value: result += name + b"," elif name.lower() == filter_name: result += name + b": " + value + b"\n" return result
def handle_test(uuid, request, response): server_state = request.server.stash.take(uuid) or [] try: requests = json.loads(b64decode(request.headers.get(b'Test-Requests', b""))) except: response.status = (400, b"Bad Request") response.headers.set(b"Content-Type", b"text/plain") return b"No or bad Test-Requests request header" config = requests[len(server_state)] if not config: response.status = (404, b"Not Found") response.headers.set(b"Content-Type", b"text/plain") return b"Config not found" noted_headers = {} now = time.time() for header in config.get(u'response_headers', []): if header[0].lower() in LOCATIONHDRS: # magic locations if (len(header[1]) > 0): header[1] = u"%s&target=%s" % (request.url, header[1]) else: header[1] = request.url if header[0].lower() in DATEHDRS and isinstance(header[1], int): # magic dates header[1] = http_date(now, header[1]) response.headers.set(isomorphic_encode(header[0]), isomorphic_encode(header[1])) if header[0].lower() in NOTEHDRS: noted_headers[header[0].lower()] = header[1] state = { u'now': now, u'request_method': request.method, u'request_headers': dict([[isomorphic_decode(h.lower()), isomorphic_decode(request.headers[h])] for h in request.headers]), u'response_headers': noted_headers } server_state.append(state) request.server.stash.put(uuid, server_state) if u"access-control-allow-origin" not in noted_headers: response.headers.set(b"Access-Control-Allow-Origin", b"*") if u"content-type" not in noted_headers: response.headers.set(b"Content-Type", b"text/plain") response.headers.set(b"Server-Request-Count", len(server_state)) code, phrase = config.get(u"response_status", [200, b"OK"]) if config.get(u"expected_type", u"").endswith(u'validated'): ref_hdrs = server_state[0][u'response_headers'] previous_lm = ref_hdrs.get(u'last-modified', False) if previous_lm and request.headers.get(b"If-Modified-Since", False) == isomorphic_encode(previous_lm): code, phrase = [304, b"Not Modified"] previous_etag = ref_hdrs.get(u'etag', False) if previous_etag and request.headers.get(b"If-None-Match", False) == isomorphic_encode(previous_etag): code, phrase = [304, b"Not Modified"] if code != 304: code, phrase = [999, b'304 Not Generated'] response.status = (code, phrase) content = config.get(u"response_body", uuid) if code in NOBODYSTATUS: return b"" return content
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): """Respond to `/cookie/set/samesite?{value}` by setting four cookies: 1. `samesite_strict={value};SameSite=Strict;path=/;domain={host}` 2. `samesite_lax={value};SameSite=Lax;path=/;domain={host}` 3. `samesite_none={value};SameSite=None;path=/;Secure;domain={host}` 4. `samesite_unspecified={value};path=/;domain={host}` Where {host} is the hostname from which this page is served. (Requesting this resource without a Host header will result in a 500 server error.) Then navigate to a page that will post a message back to the opener with the set cookies""" headers = setNoCacheAndCORSHeaders(request, response) value = isomorphic_encode(request.url_parts.query) host_header = request.headers['host'] hostname = host_header.split(b":")[0] host = isomorphic_encode(hostname) headers.append((b"Content-Type", b"text/html; charset=utf-8")) headers.append( makeCookieHeader(b"samesite_strict", value, { b"SameSite": b"Strict", b"path": b"/", b"domain": host })) headers.append( makeCookieHeader(b"samesite_lax", value, { b"SameSite": b"Lax", b"path": b"/", b"domain": host })) # SameSite=None cookies must be Secure. headers.append( makeCookieHeader(b"samesite_none", value, { b"SameSite": b"None", b"path": b"/", b"Secure": b"", b"domain": host })) headers.append( makeCookieHeader(b"samesite_unspecified", value, { b"path": b"/", b"domain": host })) document = b""" <!DOCTYPE html> <script> // A same-site navigation, which should attach all cookies including SameSite ones. // This is necessary because this page may have been reached via a cross-site navigation, so // we might not have access to some SameSite cookies from here. window.location = "../samesite/resources/echo-cookies.html"; </script> """ return headers, document
def _final_response_body(request): 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 main(request, response): """Set or drop a cookie via GET params. Usage: `/cookie.py?set={cookie}` or `/cookie.py?drop={cookie}` The passed-in cookie string should be encoded via encodeURIComponent, otherwise `parse_qsl` will split on any semicolons (used by the Request.GET property getter). 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) try: if b'drop' in request.GET: cookie = request.GET[b'drop'] cookie += b"; max-age=0" if b'set' in request.GET: cookie = request.GET[b'set'] headers.append((b'Set-Cookie', isomorphic_encode(cookie))) return headers, b'{"success": true}' except Exception as e: return 500, headers, bytes({'error': '{}'.format(e)})
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
def get_response(raw_headers, filter_value, filter_name): result = b"" # raw_headers.raw_items() returns the (name, value) header pairs as # tuples of strings. Convert them to bytes before comparing. # TODO: Get access to the raw headers, so that whitespace between # name, ":" and value can also be checked: # https://github.com/web-platform-tests/wpt/issues/28756 for field in raw_headers.raw_items(): name = isomorphic_encode(field[0]) value = isomorphic_encode(field[1]) if filter_value: if value == filter_value: result += name + b"," elif name.lower() == filter_name: result += name + b": " + value + b"\n" return result
def redirect(url, response): response.add_required_headers = False response.writer.write_status(301) response.writer.write_header(b"access-control-allow-origin", b"*") response.writer.write_header(b"location", isomorphic_encode(url)) response.writer.end_headers() response.writer.write(u"")
def main(request, response): policyDeliveries = json.loads(request.GET.first(b"policyDeliveries", b"[]")) maybe_additional_headers = {} meta = u'' error = u'' for delivery in policyDeliveries: if delivery[u'deliveryType'] == u'meta': if delivery[u'key'] == u'referrerPolicy': meta += u'<meta name="referrer" content="%s">' % delivery[u'value'] else: error = u'invalid delivery key' elif delivery[u'deliveryType'] == u'http-rp': if delivery[u'key'] == u'referrerPolicy': maybe_additional_headers[b'Referrer-Policy'] = isomorphic_encode(delivery[u'value']) else: error = u'invalid delivery key' else: error = u'invalid deliveryType' handler = lambda: util.get_template(u"document.html.template") % ({ u"meta": meta, u"error": error }) util.respond( request, response, payload_generator=handler, content_type=b"text/html", maybe_additional_headers=maybe_additional_headers)
def get_response(raw_headers, filter_value, filter_name): result = b"" # Type of raw_headers is <httplib.HTTPMessage> in Python 2 and <http.client.HTTPMessage> in # Python 3. <http.client.HTTPMessage> doesn't have 'headers" attribute or equivalent # [https://bugs.python.org/issue4773]. # In Python 2, variable raw_headers.headers returns a completely uninterpreted list of lines # contained in the header. In Python 3, raw_headers.as_string() returns entire formatted # message as a string. Here is to construct an equivalent "headers" variable to support tests # in Python 3. if PY3: header_list = [ isomorphic_encode(s + u'\r\n') for s in raw_headers.as_string().splitlines() if s ] else: header_list = raw_headers.headers for line in header_list: if line[-2:] != b'\r\n': return b"Syntax error: missing CRLF: " + line line = line[:-2] if b': ' not in line: return b"Syntax error: no colon and space found: " + line name, value = line.split(b': ', 1) if filter_value: if value == filter_value: result += name + b"," elif name.lower() == filter_name: result += name + b": " + value + b"\n" return result
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()
def readParameter(request, paramName, requireValue): """Read a parameter from the request. Raise if requireValue is set and the parameter has an empty value or is not present.""" params = parse_qs(request.url_parts.query) param = params[paramName][0].strip() if len(param) == 0: raise Exception(u"Empty or missing name parameter.") return isomorphic_encode(param)
def serve_js_from_file(request, response, filename): body = b'' path = os.path.join(os.path.dirname(isomorphic_encode(__file__)), filename) with open(path, 'rb') as f: body = f.read() return ([(b'Cache-Control', b'no-cache, must-revalidate'), (b'Pragma', b'no-cache'), (b'Content-Type', b'application/javascript')], body)
def main(req, res): qs_cookie_val = parse_qs( req.url_parts.query).get(u'set-cookie-notification') if qs_cookie_val: res.set_cookie(b'notification', isomorphic_encode(qs_cookie_val[0])) return b'not really an icon'
def main(request, response): """Handler that causes multiple redirections. Redirect chain is as follows: 1. Initial URL containing multi-redirect.py 2. Redirect to cross-origin URL 3. Redirect to same-origin URL 4. Final URL containing the final same-origin resource. Mandatory parameters: page_origin - The page origin, used for redirection and to set TAO. This is a mandatory parameter. cross_origin - The cross origin used to make this a cross-origin redirect. This is a mandatory parameter. final_resource - Path of the final resource, without origin. This is a mandatory parameter. Optional parameters: tao_steps - Number of redirects for which the TAO header will be present (a number 0 - 3 makes the most sense). Default value is 0. tao_value - The value of the TAO header, when present. Default value is "*". Note that |step| is a parameter used internally for the multi-redirect. It's the step we're at in the redirect chain. """ step = 1 if b"step" in request.GET: try: step = int(request.GET.first(b"step")) except ValueError: pass page_origin = request.GET.first(b"page_origin") cross_origin = request.GET.first(b"cross_origin") final_resource = request.GET.first(b"final_resource") tao_value = b"*" if b"tao_value" in request.GET: tao_value = request.GET.first(b"tao_value") tao_steps = 0 if b"tao_steps" in request.GET: tao_steps = int(request.GET.first(b"tao_steps")) next_tao_steps = tao_steps - 1 redirect_url_path = b"/resource-timing/resources/multi_redirect.py?" redirect_url_path += b"page_origin=" + page_origin redirect_url_path += b"&cross_origin=" + cross_origin redirect_url_path += b"&final_resource=" + urllib.parse.quote( final_resource).encode('ascii') redirect_url_path += b"&tao_value=" + tao_value redirect_url_path += b"&tao_steps=" + isomorphic_encode( str(next_tao_steps)) redirect_url_path += b"&step=" if tao_steps > 0: response.headers.set(b"timing-allow-origin", tao_value) if step == 1: # On the first request, redirect to a cross origin URL redirect_url = cross_origin + redirect_url_path + b"2" elif step == 2: # On the second request, redirect to a same origin URL redirect_url = page_origin + redirect_url_path + b"3" else: # On the third request, redirect to a static response redirect_url = page_origin + final_resource response.status = 302 response.headers.set(b"Location", redirect_url)
def main(request, response): # Set no-cache to ensure the user agent finds a new version for each update. headers = [(b'Cache-Control', b'no-cache, must-revalidate'), (b'Pragma', b'no-cache'), (b'Content-Type', b'application/javascript')] # Return a different script for each access. timestamp = u'// %s %s' % (time.time(), random.random()) body = isomorphic_encode(timestamp) + b'\n' # Inject the file into the response. if b'filename' in request.GET: path = os.path.join(os.path.dirname(isomorphic_encode(__file__)), request.GET[b'filename']) with open(path, 'rb') as f: body += f.read() return headers, body
def main(request, response): code = int(request.GET.first(b"code", 200)) text = request.GET.first(b"text", b"OMG") content = request.GET.first(b"content", b"") type = request.GET.first(b"type", b"") status = (code, text) headers = [(b"Content-Type", type), (b"X-Request-Method", isomorphic_encode(request.method))] return status, headers, content
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()
def main(request, response): """Respond to `/cookie/set/samesite?{value}` by setting the following combination of cookies: 1. `samesite_unsupported={value};SameSite=Unsupported;path=/;Secure` 2. `samesite_unsupported_none={value};SameSite=Unsupported;SameSite=None;path=/;Secure` 3. `samesite_unsupported_lax={value};SameSite=Unsupported;SameSite=Lax;path=/` 4. `samesite_unsupported_strict={value};SameSite=Unsupported;SameSite=Strict;path=/` 5. `samesite_none_unsupported={value};SameSite=None;SameSite=Unsupported;path=/;Secure` 6. `samesite_lax_unsupported={value};SameSite=Lax;SameSite=Unsupported;path=/;Secure` 7. `samesite_strict_unsupported={value};SameSite=Strict;SameSite=Unsupported;path=/;Secure` 8. `samesite_lax_none={value};SameSite=Lax;SameSite=None;path=/;Secure` 9. `samesite_lax_strict={value};SameSite=Lax;SameSite=Strict;path=/` 10. `samesite_strict_lax={value};SameSite=Strict;SameSite=Lax;path=/` Then navigate to a page that will post a message back to the opener with the set cookies""" headers = setNoCacheAndCORSHeaders(request, response) value = isomorphic_encode(request.url_parts.query) headers.append((b"Content-Type", b"text/html; charset=utf-8")) # Unknown value; single attribute headers.append(makeCookieHeader( b"samesite_unsupported", value, {b"SameSite":b"Unsupported", b"path":b"/", b"Secure":b""})) # Multiple attributes; first attribute unknown headers.append(makeCookieHeader( b"samesite_unsupported_none", value, {b"SameSite":b"Unsupported", b"SameSite":b"None", b"path":b"/", b"Secure":b""})) headers.append(makeCookieHeader( b"samesite_unsupported_lax", value, {b"SameSite":b"Unsupported", b"SameSite":b"Lax", b"path":b"/"})) headers.append(makeCookieHeader( b"samesite_unsupported_strict", value, {b"SameSite":b"Unsupported", b"SameSite":b"Strict", b"path":b"/"})) # Multiple attributes; second attribute unknown headers.append(makeCookieHeader( b"samesite_none_unsupported", value, {b"SameSite":b"None", b"SameSite":b"Unsupported", b"path":b"/", b"Secure":b""})) headers.append(makeCookieHeader( b"samesite_lax_unsupported", value, {b"SameSite":b"Lax", b"SameSite":b"Unsupported", b"path":b"/", b"Secure":b""})) headers.append(makeCookieHeader( b"samesite_strict_unsupported", value, {b"SameSite":b"Strict", b"SameSite":b"Unsupported", b"path":b"/", b"Secure":b""})) # Multiple attributes; both known headers.append(makeCookieHeader( b"samesite_lax_none", value, {b"SameSite":b"Lax", b"SameSite":b"None", b"path":b"/", b"Secure":b""})) headers.append(makeCookieHeader( b"samesite_lax_strict", value, {b"SameSite":b"Lax", b"SameSite":b"Strict", b"path":b"/"})) headers.append(makeCookieHeader( b"samesite_strict_lax", value, {b"SameSite":b"Strict", b"SameSite":b"Lax", b"path":b"/"})) document = b""" <!DOCTYPE html> <script> // A same-site navigation, which should attach all cookies including SameSite ones. // This is necessary because this page may have been reached via a cross-site navigation, so // we might not have access to some SameSite cookies from here. window.location = "../samesite/resources/echo-cookies.html"; </script> """ return headers, document
def main(request, response): response.headers.set(b"Cache-Control", b"no-store") dispatch = request.GET.first(b"dispatch", None) uuid = request.GET.first(b"uuid", None) partition_id = request.GET.first(b"partition_id", None) if not uuid or not dispatch or not partition_id: return simple_response(request, response, 404, b"Not found", b"Invalid query parameters") # Unless nocheck_partition is true, check partition_id against server_state, and update server_state. stash = request.server.stash test_failed = False if request.GET.first(b"nocheck_partition", None) != b"True": # Need to grab the lock to access the Stash, since requests are made in parallel. with stash.lock: # Don't use server hostname here, since H2 allows multiple hosts to reuse a connection. # Server IP is not currently available, unfortunately. address_key = isomorphic_encode( str(request.client_address) + u"|" + str(request.url_parts.port)) server_state = stash.take(uuid) or {b"test_failed": False} if address_key in server_state and server_state[ address_key] != partition_id: server_state[b"test_failed"] = True server_state[address_key] = partition_id test_failed = server_state[b"test_failed"] stash.put(uuid, server_state) origin = request.headers.get(b"Origin") if origin: response.headers.set(b"Access-Control-Allow-Origin", origin) response.headers.set(b"Access-Control-Allow-Credentials", b"true") if request.method == u"OPTIONS": return handle_preflight(request, response) if dispatch == b"fetch_file": return handle_fetch_file(request, response, partition_id, uuid) if dispatch == b"check_partition": if test_failed: return simple_response(request, response, 200, b"OK", b"Multiple partition IDs used on a socket") return simple_response(request, response, 200, b"OK", b"ok") if dispatch == b"clean_up": stash.take(uuid) if test_failed: return simple_response(request, response, 200, b"OK", b"Test failed, but cleanup completed.") return simple_response(request, response, 200, b"OK", b"cleanup complete") return simple_response(request, response, 404, b"Not Found", b"Unrecognized dispatch parameter: " + dispatch)
def main(request, response): """Respond to `/cookie/set?{cookie}` by echoing `{cookie}` as a `Set-Cookie` header.""" headers = helpers.setNoCacheAndCORSHeaders(request, response) # Cookies may require whitespace (e.g. in the `Expires` attribute), so the # query string should be decoded. cookie = unquote(request.url_parts.query) headers.append((b"Set-Cookie", isomorphic_encode(cookie))) return headers, b'{"success": true}'
def main(request, response): """Respond to `/cookie/set/secure?{value}` by setting two cookies: alone_secure={value};secure;path=/` alone_insecure={value};path=/""" headers = setNoCacheAndCORSHeaders(request, response) value = isomorphic_encode(request.url_parts.query) headers.append(makeCookieHeader(b"alone_secure", value, {b"secure": b"", b"path": b"/"})) headers.append(makeCookieHeader(b"alone_insecure", value, {b"path": b"/"})) return headers, b'{"success": true}'
def main(request, response): content = [] for key, values in sorted(item for item in request.POST.items() if not hasattr(item[1][0], u"filename")): content.append(b"%s=%s," % (key, values[0])) content.append(b"\n") for key, values in sorted(item for item in request.POST.items() if hasattr(item[1][0], u"filename")): value = values[0] content.append( b"%s=%s:%s:%d," % (key, isomorphic_encode(value.filename), isomorphic_encode(value.headers[u"Content-Type"]) if value.headers[u"Content-Type"] is not None else b"None", len(value.file.read()))) return b"".join(content)
def main(request, response): client_hint_headers = [ b"device-memory", b"dpr", b"width", b"viewport-width", b"rtt", b"downlink", b"ect", b"sec-ch-lang", b"sec-ch-ua", b"sec-ch-ua-arch", b"sec-ch-ua-platform", b"sec-ch-ua-platform-version", b"sec-ch-ua-model", b"sec-ch-prefers-color-scheme", ] client_hints_curr = {i:request.headers.get(i) for i in client_hint_headers} token = request.GET.first(b"token", None) is_query = request.GET.first(b"query", None) is not None with request.server.stash.lock: stash = request.server.stash.take(token) if stash != None: (value, client_hints_prev) = stash count = int(value) else: count = 0 client_hints_prev = {} if is_query: if count < 2: request.server.stash.put(token, (count, client_hints_curr)) else: count = count + 1 request.server.stash.put(token, (count, client_hints_curr)) for header in client_hint_headers: if client_hints_curr[header] is not None: response.headers.set(header+b"-recieved", client_hints_curr[header]) if (header in client_hints_prev) and (client_hints_prev[header] is not None): response.headers.set(header+b"-previous", client_hints_prev[header]) if is_query: headers = [(b"Count", count)] content = u"" return 200, headers, content else: unique_id = id_token() headers = [(b"Content-Type", b"text/html"), (b"Cache-Control", b"private, max-age=0, stale-while-revalidate=60"), (b"Unique-Id", isomorphic_encode(unique_id))] content = u"report('{}')".format(unique_id) return 200, headers, content
def main(request, response): headers = [(b"X-Request-Method", isomorphic_encode(request.method)), (b"X-Request-Content-Length", request.headers.get(b"Content-Length", b"NO")), (b"X-Request-Content-Type", request.headers.get(b"Content-Type", b"NO")), # Avoid any kind of content sniffing on the response. (b"Content-Type", b"text/plain; charset=UTF-8")] content = b"".join(map(escape_byte, request.body)).replace(b"\\x0d\\x0a", b"\r\n") return headers, content
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()
def main(request, response): headers = [(b"X-Request-Method", isomorphic_encode(request.method)), (b"X-Request-Content-Length", request.headers.get(b"Content-Length", b"NO")), (b"X-Request-Content-Type", request.headers.get(b"Content-Type", b"NO")), # Avoid any kind of content sniffing on the response. (b"Content-Type", b"text/plain")] content = request.body return headers, content