mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Port some code to Python3
This commit is contained in:
parent
f73370088b
commit
a627dde0d0
24 changed files with 1439 additions and 2341 deletions
|
@ -65,11 +65,11 @@ impl<'a> phf_shared::PhfHash for Bytes<'a> {
|
|||
}
|
||||
|
||||
fn find_python() -> String {
|
||||
env::var("PYTHON2").ok().unwrap_or_else(|| {
|
||||
env::var("PYTHON3").ok().unwrap_or_else(|| {
|
||||
let candidates = if cfg!(windows) {
|
||||
["python2.7.exe", "python27.exe", "python.exe"]
|
||||
["python3.8.exe", "python38.exe", "python.exe"]
|
||||
} else {
|
||||
["python2.7", "python2", "python"]
|
||||
["python3.8", "python3", "python"]
|
||||
};
|
||||
for &name in &candidates {
|
||||
if Command::new(name)
|
||||
|
@ -82,7 +82,7 @@ fn find_python() -> String {
|
|||
}
|
||||
}
|
||||
panic!(
|
||||
"Can't find python (tried {})! Try fixing PATH or setting the PYTHON2 env var",
|
||||
"Can't find python (tried {})! Try fixing PATH or setting the PYTHON3 env var",
|
||||
candidates.join(", ")
|
||||
)
|
||||
})
|
||||
|
|
|
@ -344,7 +344,7 @@ class CGMethodCall(CGThing):
|
|||
distinguishingArg = "HandleValue::from_raw(args.get(%d))" % distinguishingIndex
|
||||
|
||||
def pickFirstSignature(condition, filterLambda):
|
||||
sigs = filter(filterLambda, possibleSignatures)
|
||||
sigs = list(filter(filterLambda, possibleSignatures))
|
||||
assert len(sigs) < 2
|
||||
if len(sigs) > 0:
|
||||
call = getPerSignatureCall(sigs[0], distinguishingIndex)
|
||||
|
@ -2117,7 +2117,7 @@ class CGImports(CGWrapper):
|
|||
members += [constructor]
|
||||
|
||||
if d.proxy:
|
||||
members += [o for o in d.operations.values() if o]
|
||||
members += [o for o in list(d.operations.values()) if o]
|
||||
|
||||
for m in members:
|
||||
if m.isMethod():
|
||||
|
@ -2557,7 +2557,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
|
|||
])
|
||||
|
||||
# Sort unionStructs by key, retrieve value
|
||||
unionStructs = (i[1] for i in sorted(unionStructs.items(), key=operator.itemgetter(0)))
|
||||
unionStructs = (i[1] for i in sorted(list(unionStructs.items()), key=operator.itemgetter(0)))
|
||||
|
||||
return CGImports(CGList(unionStructs, "\n\n"),
|
||||
descriptors=[],
|
||||
|
@ -4455,9 +4455,10 @@ class CGEnum(CGThing):
|
|||
pub enum %s {
|
||||
%s
|
||||
}
|
||||
""" % (ident, ",\n ".join(map(getEnumValueName, enum.values())))
|
||||
""" % (ident, ",\n ".join(map(getEnumValueName, list(enum.values()))))
|
||||
|
||||
pairs = ",\n ".join(['("%s", super::%s::%s)' % (val, ident, getEnumValueName(val)) for val in enum.values()])
|
||||
pairs = ",\n ".join(['("%s", super::%s::%s)' % (val, ident, getEnumValueName(val))
|
||||
for val in list(enum.values())])
|
||||
|
||||
inner = string.Template("""\
|
||||
use crate::dom::bindings::conversions::ConversionResult;
|
||||
|
@ -4640,9 +4641,8 @@ class CGUnionStruct(CGThing):
|
|||
return "Rc"
|
||||
return ""
|
||||
|
||||
templateVars = map(lambda t: (getUnionTypeTemplateVars(t, self.descriptorProvider),
|
||||
getTypeWrapper(t)),
|
||||
self.type.flatMemberTypes)
|
||||
templateVars = [(getUnionTypeTemplateVars(t, self.descriptorProvider),
|
||||
getTypeWrapper(t)) for t in self.type.flatMemberTypes]
|
||||
enumValues = [
|
||||
" %s(%s)," % (v["name"], "%s<%s>" % (wrapper, v["typeName"]) if wrapper else v["typeName"])
|
||||
for (v, wrapper) in templateVars
|
||||
|
@ -4701,7 +4701,7 @@ class CGUnionConversionStruct(CGThing):
|
|||
" Ok(None) => (),\n"
|
||||
"}\n") % (self.type, name, self.type, name)
|
||||
|
||||
interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
|
||||
interfaceMemberTypes = [t for t in memberTypes if t.isNonCallbackInterface()]
|
||||
if len(interfaceMemberTypes) > 0:
|
||||
typeNames = [get_name(memberType) for memberType in interfaceMemberTypes]
|
||||
interfaceObject = CGList(CGGeneric(get_match(typeName)) for typeName in typeNames)
|
||||
|
@ -4709,7 +4709,7 @@ class CGUnionConversionStruct(CGThing):
|
|||
else:
|
||||
interfaceObject = None
|
||||
|
||||
arrayObjectMemberTypes = filter(lambda t: t.isSequence(), memberTypes)
|
||||
arrayObjectMemberTypes = [t for t in memberTypes if t.isSequence()]
|
||||
if len(arrayObjectMemberTypes) > 0:
|
||||
assert len(arrayObjectMemberTypes) == 1
|
||||
typeName = arrayObjectMemberTypes[0].name
|
||||
|
@ -4718,7 +4718,7 @@ class CGUnionConversionStruct(CGThing):
|
|||
else:
|
||||
arrayObject = None
|
||||
|
||||
callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
|
||||
callbackMemberTypes = [t for t in memberTypes if t.isCallback() or t.isCallbackInterface()]
|
||||
if len(callbackMemberTypes) > 0:
|
||||
assert len(callbackMemberTypes) == 1
|
||||
typeName = callbackMemberTypes[0].name
|
||||
|
@ -4726,7 +4726,7 @@ class CGUnionConversionStruct(CGThing):
|
|||
else:
|
||||
callbackObject = None
|
||||
|
||||
dictionaryMemberTypes = filter(lambda t: t.isDictionary(), memberTypes)
|
||||
dictionaryMemberTypes = [t for t in memberTypes if t.isDictionary()]
|
||||
if len(dictionaryMemberTypes) > 0:
|
||||
assert len(dictionaryMemberTypes) == 1
|
||||
typeName = dictionaryMemberTypes[0].name
|
||||
|
@ -4735,7 +4735,7 @@ class CGUnionConversionStruct(CGThing):
|
|||
else:
|
||||
dictionaryObject = None
|
||||
|
||||
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
|
||||
objectMemberTypes = [t for t in memberTypes if t.isObject()]
|
||||
if len(objectMemberTypes) > 0:
|
||||
assert len(objectMemberTypes) == 1
|
||||
typeName = objectMemberTypes[0].name
|
||||
|
@ -4744,7 +4744,7 @@ class CGUnionConversionStruct(CGThing):
|
|||
else:
|
||||
object = None
|
||||
|
||||
mozMapMemberTypes = filter(lambda t: t.isRecord(), memberTypes)
|
||||
mozMapMemberTypes = [t for t in memberTypes if t.isRecord()]
|
||||
if len(mozMapMemberTypes) > 0:
|
||||
assert len(mozMapMemberTypes) == 1
|
||||
typeName = mozMapMemberTypes[0].name
|
||||
|
@ -4790,9 +4790,9 @@ class CGUnionConversionStruct(CGThing):
|
|||
typename = get_name(memberType)
|
||||
return CGGeneric(get_match(typename))
|
||||
other = []
|
||||
stringConversion = map(getStringOrPrimitiveConversion, stringTypes)
|
||||
numericConversion = map(getStringOrPrimitiveConversion, numericTypes)
|
||||
booleanConversion = map(getStringOrPrimitiveConversion, booleanTypes)
|
||||
stringConversion = list(map(getStringOrPrimitiveConversion, stringTypes))
|
||||
numericConversion = list(map(getStringOrPrimitiveConversion, numericTypes))
|
||||
booleanConversion = list(map(getStringOrPrimitiveConversion, booleanTypes))
|
||||
if stringConversion:
|
||||
if booleanConversion:
|
||||
other.append(CGIfWrapper("value.get().is_boolean()", booleanConversion[0]))
|
||||
|
@ -5958,7 +5958,7 @@ class CGInterfaceTrait(CGThing):
|
|||
rettype)
|
||||
|
||||
if descriptor.proxy:
|
||||
for name, operation in descriptor.operations.iteritems():
|
||||
for name, operation in descriptor.operations.items():
|
||||
if not operation or operation.isStringifier():
|
||||
continue
|
||||
|
||||
|
@ -6488,7 +6488,7 @@ class CGDescriptor(CGThing):
|
|||
post='\n')
|
||||
|
||||
if reexports:
|
||||
reexports = ', '.join(map(lambda name: reexportedName(name), reexports))
|
||||
reexports = ', '.join([reexportedName(name) for name in reexports])
|
||||
cgThings = CGList([CGGeneric('pub use self::%s::{%s};' % (toBindingNamespace(descriptor.name), reexports)),
|
||||
cgThings], '\n')
|
||||
|
||||
|
@ -7824,7 +7824,7 @@ impl Clone for TopTypeId {
|
|||
# TypeId enum.
|
||||
return "%s(%sTypeId)" % (name, name) if name in hierarchy else name
|
||||
|
||||
for base, derived in hierarchy.iteritems():
|
||||
for base, derived in hierarchy.items():
|
||||
variants = []
|
||||
if config.getDescriptor(base).concrete:
|
||||
variants.append(CGGeneric(base))
|
||||
|
|
|
@ -73,7 +73,7 @@ class Configuration:
|
|||
def getDescriptors(self, **filters):
|
||||
"""Gets the descriptors that match the given filters."""
|
||||
curr = self.descriptors
|
||||
for key, val in filters.iteritems():
|
||||
for key, val in filters.items():
|
||||
if key == 'webIDLFile':
|
||||
def getter(x):
|
||||
return x.interface.filename()
|
||||
|
@ -104,14 +104,14 @@ class Configuration:
|
|||
else:
|
||||
def getter(x):
|
||||
return getattr(x, key)
|
||||
curr = filter(lambda x: getter(x) == val, curr)
|
||||
curr = [x for x in curr if getter(x) == val]
|
||||
return curr
|
||||
|
||||
def getEnums(self, webIDLFile):
|
||||
return filter(lambda e: e.filename() == webIDLFile, self.enums)
|
||||
return [e for e in self.enums if e.filename() == webIDLFile]
|
||||
|
||||
def getTypedefs(self, webIDLFile):
|
||||
return filter(lambda e: e.filename() == webIDLFile, self.typedefs)
|
||||
return [e for e in self.typedefs if e.filename() == webIDLFile]
|
||||
|
||||
@staticmethod
|
||||
def _filterForFile(items, webIDLFile=""):
|
||||
|
@ -119,7 +119,7 @@ class Configuration:
|
|||
if not webIDLFile:
|
||||
return items
|
||||
|
||||
return filter(lambda x: x.filename() == webIDLFile, items)
|
||||
return [x for x in items if x.filename() == webIDLFile]
|
||||
|
||||
def getDictionaries(self, webIDLFile=""):
|
||||
return self._filterForFile(self.dictionaries, webIDLFile=webIDLFile)
|
||||
|
@ -327,7 +327,7 @@ class Descriptor(DescriptorProvider):
|
|||
if config == '*':
|
||||
iface = self.interface
|
||||
while iface:
|
||||
add('all', map(lambda m: m.name, iface.members), attribute)
|
||||
add('all', [m.name for m in iface.members], attribute)
|
||||
iface = iface.parent
|
||||
else:
|
||||
add('all', [config], attribute)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
""" A WebIDL parser. """
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from ply import lex, yacc
|
||||
import re
|
||||
import os
|
||||
|
@ -57,7 +57,7 @@ def enum(*names, **kw):
|
|||
|
||||
if "base" not in kw:
|
||||
return Foo(names)
|
||||
return Foo(chain(kw["base"].attrs.keys(), names))
|
||||
return Foo(chain(list(kw["base"].attrs.keys()), names))
|
||||
|
||||
|
||||
class WebIDLError(Exception):
|
||||
|
@ -124,6 +124,9 @@ class BuiltinLocation(object):
|
|||
return (isinstance(other, BuiltinLocation) and
|
||||
self.msg == other.msg)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.msg)
|
||||
|
||||
def filename(self):
|
||||
return '<builtin>'
|
||||
|
||||
|
@ -2360,6 +2363,9 @@ class IDLNullableType(IDLParametrizedType):
|
|||
def __eq__(self, other):
|
||||
return isinstance(other, IDLNullableType) and self.inner == other.inner
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.inner)
|
||||
|
||||
def __str__(self):
|
||||
return self.inner.__str__() + "OrNull"
|
||||
|
||||
|
@ -2522,6 +2528,9 @@ class IDLSequenceType(IDLParametrizedType):
|
|||
def __eq__(self, other):
|
||||
return isinstance(other, IDLSequenceType) and self.inner == other.inner
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.inner)
|
||||
|
||||
def __str__(self):
|
||||
return self.inner.__str__() + "Sequence"
|
||||
|
||||
|
@ -2933,6 +2942,9 @@ class IDLWrapperType(IDLType):
|
|||
self._identifier == other._identifier and
|
||||
self.builtin == other.builtin)
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self._identifier, self.builtin))
|
||||
|
||||
def __str__(self):
|
||||
return str(self.name) + " (Wrapper)"
|
||||
|
||||
|
@ -3301,6 +3313,12 @@ class IDLBuiltinType(IDLType):
|
|||
return "MaybeShared" + str(self.name)
|
||||
return str(self.name)
|
||||
|
||||
def __eq__(self, other):
|
||||
return other and self.location == other.location and self.name == other.name and self._typeTag == other._typeTag
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.location, self.name, self._typeTag))
|
||||
|
||||
def prettyName(self):
|
||||
return IDLBuiltinType.PrettyNames[self._typeTag]
|
||||
|
||||
|
@ -3628,7 +3646,7 @@ integerTypeSizes = {
|
|||
|
||||
|
||||
def matchIntegerValueToType(value):
|
||||
for type, extremes in integerTypeSizes.items():
|
||||
for type, extremes in list(integerTypeSizes.items()):
|
||||
(min, max) = extremes
|
||||
if value <= max and value >= min:
|
||||
return BuiltinTypes[type]
|
||||
|
@ -3707,7 +3725,7 @@ class IDLValue(IDLObject):
|
|||
elif self.type.isString() and type.isEnum():
|
||||
# Just keep our string, but make sure it's a valid value for this enum
|
||||
enum = type.unroll().inner
|
||||
if self.value not in enum.values():
|
||||
if self.value not in list(enum.values()):
|
||||
raise WebIDLError("'%s' is not a valid default value for enum %s"
|
||||
% (self.value, enum.identifier.name),
|
||||
[location, enum.location])
|
||||
|
@ -4789,7 +4807,7 @@ class IDLAttribute(IDLInterfaceMember):
|
|||
"CrossOriginWritable",
|
||||
"SetterThrows",
|
||||
]
|
||||
for (key, value) in self._extendedAttrDict.items():
|
||||
for (key, value) in list(self._extendedAttrDict.items()):
|
||||
if key in allowedExtAttrs:
|
||||
if value is not True:
|
||||
raise WebIDLError("[%s] with a value is currently "
|
||||
|
@ -5479,7 +5497,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
[attr.location])
|
||||
if identifier == "CrossOriginCallable" and self.isStatic():
|
||||
raise WebIDLError("[CrossOriginCallable] is only allowed on non-static "
|
||||
"attributes"
|
||||
"attributes",
|
||||
[attr.location, self.location])
|
||||
elif identifier == "Pure":
|
||||
if not attr.noArguments():
|
||||
|
@ -5721,6 +5739,7 @@ class Tokenizer(object):
|
|||
"FLOATLITERAL",
|
||||
"IDENTIFIER",
|
||||
"STRING",
|
||||
"COMMENTS",
|
||||
"WHITESPACE",
|
||||
"OTHER"
|
||||
]
|
||||
|
@ -5753,8 +5772,12 @@ class Tokenizer(object):
|
|||
t.value = t.value[1:-1]
|
||||
return t
|
||||
|
||||
def t_COMMENTS(self, t):
|
||||
r'(\/\*(.|\n)*?\*\/)|(\/\/.*)'
|
||||
pass
|
||||
|
||||
def t_WHITESPACE(self, t):
|
||||
r'[\t\n\r ]+|[\t\n\r ]*((//[^\n]*|/\*.*?\*/)[\t\n\r ]*)+'
|
||||
r'[\t\n\r ]+'
|
||||
pass
|
||||
|
||||
def t_ELLIPSIS(self, t):
|
||||
|
@ -5840,7 +5863,7 @@ class Tokenizer(object):
|
|||
"async": "ASYNC",
|
||||
}
|
||||
|
||||
tokens.extend(keywords.values())
|
||||
tokens.extend(list(keywords.values()))
|
||||
|
||||
def t_error(self, t):
|
||||
raise WebIDLError("Unrecognized Input",
|
||||
|
@ -5849,23 +5872,21 @@ class Tokenizer(object):
|
|||
lexpos=self.lexer.lexpos,
|
||||
filename=self.filename)])
|
||||
|
||||
def __init__(self, outputdir, lexer=None):
|
||||
def __init__(self, lexer=None):
|
||||
if lexer:
|
||||
self.lexer = lexer
|
||||
else:
|
||||
self.lexer = lex.lex(object=self,
|
||||
outputdir=outputdir,
|
||||
lextab='webidllex',
|
||||
reflags=re.DOTALL)
|
||||
self.lexer = lex.lex(object=self)
|
||||
|
||||
|
||||
class SqueakyCleanLogger(object):
|
||||
errorWhitelist = [
|
||||
# Web IDL defines the WHITESPACE token, but doesn't actually
|
||||
# Web IDL defines the WHITESPACE and COMMENTS token, but doesn't actually
|
||||
# use it ... so far.
|
||||
"Token 'WHITESPACE' defined, but not used",
|
||||
# And that means we have an unused token
|
||||
"There is 1 unused token",
|
||||
"Token 'COMMENTS' defined, but not used",
|
||||
# And that means we have unused tokens
|
||||
"There are 2 unused tokens",
|
||||
# Web IDL defines a OtherOrComma rule that's only used in
|
||||
# ExtendedAttributeInner, which we don't use yet.
|
||||
"Rule 'OtherOrComma' defined, but not used",
|
||||
|
@ -7506,22 +7527,11 @@ class Parser(Tokenizer):
|
|||
raise WebIDLError("invalid syntax", [Location(self.lexer, p.lineno, p.lexpos, self._filename)])
|
||||
|
||||
def __init__(self, outputdir='', lexer=None):
|
||||
Tokenizer.__init__(self, outputdir, lexer)
|
||||
Tokenizer.__init__(self, lexer)
|
||||
|
||||
logger = SqueakyCleanLogger()
|
||||
try:
|
||||
self.parser = yacc.yacc(module=self,
|
||||
outputdir=outputdir,
|
||||
tabmodule='webidlyacc',
|
||||
errorlog=logger,
|
||||
debug=False
|
||||
# Pickling the grammar is a speedup in
|
||||
# some cases (older Python?) but a
|
||||
# significant slowdown in others.
|
||||
# We're not pickling for now, until it
|
||||
# becomes a speedup again.
|
||||
# , picklefile='WebIDLGrammar.pkl'
|
||||
)
|
||||
self.parser = yacc.yacc(module=self, errorlog=logger, debug=False)
|
||||
finally:
|
||||
logger.reportGrammarErrors()
|
||||
|
||||
|
@ -7553,12 +7563,12 @@ class Parser(Tokenizer):
|
|||
return type
|
||||
|
||||
def parse(self, t, filename=None):
|
||||
self.lexer.input(t)
|
||||
self._filename = filename
|
||||
self.lexer.input(t.decode(encoding = 'utf-8'))
|
||||
|
||||
# for tok in iter(self.lexer.token, None):
|
||||
# print tok
|
||||
|
||||
self._filename = filename
|
||||
self._productions.extend(self.parser.parse(lexer=self.lexer, tracking=True))
|
||||
self._filename = None
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ http://www.dabeaz.com/ply/
|
|||
|
||||
Licensed under BSD.
|
||||
|
||||
This directory contains just the code and license from PLY version 3.3;
|
||||
This directory contains just the code and license from PLY version 4.0;
|
||||
the full distribution (see the URL) also contains examples, tests,
|
||||
documentation, and a longer README.
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
# PLY package
|
||||
# Author: David Beazley (dave@dabeaz.com)
|
||||
# https://dabeaz.com/ply/index.html
|
||||
|
||||
__version__ = '4.0'
|
||||
__all__ = ['lex','yacc']
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -52,7 +52,7 @@ def main():
|
|||
module = CGBindingRoot(config, prefix, filename).define()
|
||||
if module:
|
||||
with open(os.path.join(out_dir, prefix + ".rs"), "wb") as f:
|
||||
f.write(module)
|
||||
f.write(module.encode("utf-8"))
|
||||
|
||||
|
||||
def make_dir(path):
|
||||
|
@ -66,7 +66,7 @@ def generate(config, name, filename):
|
|||
root = getattr(GlobalGenRoots, name)(config)
|
||||
code = root.define()
|
||||
with open(filename, "wb") as f:
|
||||
f.write(code)
|
||||
f.write(code.encode("utf-8"))
|
||||
|
||||
|
||||
def add_css_properties_attributes(css_properties_json, parser):
|
||||
|
|
|
@ -40,11 +40,11 @@ fn error(message: &str) {
|
|||
}
|
||||
|
||||
fn find_python() -> String {
|
||||
env::var("PYTHON2").ok().unwrap_or_else(|| {
|
||||
env::var("PYTHON3").ok().unwrap_or_else(|| {
|
||||
let candidates = if cfg!(windows) {
|
||||
["python2.7.exe", "python27.exe", "python.exe"]
|
||||
["python3.8.exe", "python38.exe", "python.exe"]
|
||||
} else {
|
||||
["python2.7", "python2", "python"]
|
||||
["python3.8", "python3", "python"]
|
||||
};
|
||||
for &name in &candidates {
|
||||
if Command::new(name)
|
||||
|
@ -57,7 +57,7 @@ fn find_python() -> String {
|
|||
}
|
||||
}
|
||||
panic!(
|
||||
"Can't find python (tried {})! Try fixing PATH or setting the PYTHON2 env var",
|
||||
"Can't find python (tried {})! Try fixing PATH or setting the PYTHON3 env var",
|
||||
candidates.join(", ")
|
||||
)
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2018 The Servo Project Developers. See the COPYRIGHT
|
||||
# file at the top-level directory of this distribution.
|
||||
|
|
|
@ -57,7 +57,7 @@ def tasks(task_for):
|
|||
|
||||
"try-mac": [macos_unit],
|
||||
"try-linux": [linux_tidy_unit, linux_docs_check, linux_release],
|
||||
"try-windows": [windows_unit, windows_arm64, windows_uwp_x64],
|
||||
"try-windows": [windows_arm64, windows_uwp_x64],
|
||||
"try-arm": [windows_arm64],
|
||||
"try-wpt": [linux_wpt],
|
||||
"try-wpt-2020": [linux_wpt_layout_2020],
|
||||
|
@ -130,6 +130,8 @@ windows_build_env = {
|
|||
},
|
||||
"all": {
|
||||
"PYTHON3": "%HOMEDRIVE%%HOMEPATH%\\python3\\python.exe",
|
||||
"PYTHONPATH": "%HOMEDRIVE%%HOMEPATH%\\python3",
|
||||
"PYTHONHOME": "%HOMEDRIVE%%HOMEPATH%\\python3",
|
||||
"LINKER": "lld-link.exe",
|
||||
"MOZTOOLS_PATH_PREPEND": "%HOMEDRIVE%%HOMEPATH%\\git\\cmd",
|
||||
},
|
||||
|
@ -155,11 +157,11 @@ def linux_tidy_unit_untrusted():
|
|||
.with_env(**build_env, **unix_build_env, **linux_build_env)
|
||||
.with_repo_bundle()
|
||||
.with_script("""
|
||||
./mach test-tidy --no-progress --all
|
||||
./mach test-tidy --no-progress --self-test
|
||||
./mach bootstrap-gstreamer
|
||||
./mach build --dev
|
||||
./mach test-unit
|
||||
python3 ./mach test-tidy --no-progress --all
|
||||
python3 ./mach test-tidy --no-progress --self-test
|
||||
python3 ./mach bootstrap-gstreamer
|
||||
python3 ./mach build --dev
|
||||
python3 ./mach test-unit
|
||||
|
||||
./etc/ci/lockfile_changed.sh
|
||||
./etc/memory_reports_over_time.py --test
|
||||
|
@ -175,8 +177,7 @@ def linux_tidy_unit():
|
|||
.with_treeherder("Linux x64", "Tidy+Unit")
|
||||
.with_max_run_time_minutes(75)
|
||||
.with_script("""
|
||||
./mach test-tidy --no-progress --all
|
||||
python3 ./mach test-tidy --no-progress --all --no-wpt
|
||||
python3 ./mach test-tidy --no-progress --all
|
||||
python3 ./mach build --dev
|
||||
python3 ./mach test-unit
|
||||
python3 ./mach package --dev
|
||||
|
@ -201,7 +202,7 @@ def linux_docs_check():
|
|||
linux_build_task("Docs + check")
|
||||
.with_treeherder("Linux x64", "Doc+Check")
|
||||
.with_script("""
|
||||
RUSTDOCFLAGS="--disable-minification" ./mach doc
|
||||
RUSTDOCFLAGS="--disable-minification" python3 ./mach doc
|
||||
(
|
||||
cd target/doc
|
||||
git init
|
||||
|
@ -219,7 +220,7 @@ def linux_docs_check():
|
|||
# The reverse order would not increase the total amount of work to do,
|
||||
# but would reduce the amount of parallelism available.
|
||||
"""
|
||||
./mach check
|
||||
python3 ./mach check
|
||||
""")
|
||||
.with_artifacts("/repo/target/doc/docs.bundle")
|
||||
.find_or_create("docs." + CONFIG.tree_hash())
|
||||
|
@ -243,7 +244,7 @@ def upload_docs():
|
|||
open("/root/.git-credentials", "w").write("https://git:%s@github.com/" % token)
|
||||
""")
|
||||
.with_script("""
|
||||
python -c "$PY"
|
||||
python3 -c "$PY"
|
||||
git init --bare
|
||||
git config credential.helper store
|
||||
git fetch --quiet docs.bundle
|
||||
|
@ -274,9 +275,9 @@ def macos_unit():
|
|||
macos_build_task("Dev build + unit tests")
|
||||
.with_treeherder("macOS x64", "Unit")
|
||||
.with_script("""
|
||||
./mach build --dev --verbose
|
||||
./mach test-unit
|
||||
./mach package --dev
|
||||
python3 ./mach build --dev --verbose
|
||||
python3 ./mach test-unit
|
||||
python3 ./mach package --dev
|
||||
./etc/ci/macos_package_smoketest.sh target/debug/servo-tech-demo.dmg
|
||||
./etc/ci/lockfile_changed.sh
|
||||
""")
|
||||
|
@ -296,8 +297,8 @@ def with_rust_nightly():
|
|||
.with_treeherder("Linux x64", "RustNightly")
|
||||
.with_script("""
|
||||
echo "nightly" > rust-toolchain
|
||||
./mach build --dev
|
||||
./mach test-unit
|
||||
python3 ./mach build --dev
|
||||
python3 ./mach test-unit
|
||||
""")
|
||||
.create()
|
||||
)
|
||||
|
@ -354,10 +355,10 @@ def uwp_nightly(rdp=False):
|
|||
"secrets:get:project/servo/windows-codesign-cert/latest",
|
||||
)
|
||||
.with_script(
|
||||
"python mach build --release --target=x86_64-uwp-windows-msvc",
|
||||
"python mach build --release --target=aarch64-uwp-windows-msvc",
|
||||
"python mach package --release --target=x86_64-uwp-windows-msvc --uwp=x64 --uwp=arm64",
|
||||
"python mach upload-nightly uwp --secret-from-taskcluster",
|
||||
"python3 mach build --release --target=x86_64-uwp-windows-msvc",
|
||||
"python3 mach build --release --target=aarch64-uwp-windows-msvc",
|
||||
"python3 mach package --release --target=x86_64-uwp-windows-msvc --uwp=x64 --uwp=arm64",
|
||||
"python3 mach upload-nightly uwp --secret-from-taskcluster",
|
||||
)
|
||||
.with_artifacts(appx_artifact)
|
||||
.with_max_run_time_minutes(3 * 60)
|
||||
|
@ -418,9 +419,9 @@ def linux_nightly():
|
|||
.with_scopes("secrets:get:project/servo/s3-upload-credentials")
|
||||
# Not reusing the build made for WPT because it has debug assertions
|
||||
.with_script(
|
||||
"./mach build --release",
|
||||
"./mach package --release",
|
||||
"./mach upload-nightly linux --secret-from-taskcluster",
|
||||
"python3 ./mach build --release",
|
||||
"python3 ./mach package --release",
|
||||
"python3 ./mach upload-nightly linux --secret-from-taskcluster",
|
||||
)
|
||||
.with_artifacts("/repo/target/release/servo-tech-demo.tar.gz")
|
||||
.find_or_create("build.linux_x64_nightly" + CONFIG.tree_hash())
|
||||
|
@ -432,8 +433,8 @@ def linux_release():
|
|||
linux_build_task("Release build")
|
||||
.with_treeherder("Linux x64", "Release")
|
||||
.with_script(
|
||||
"./mach build --release",
|
||||
"./mach package --release",
|
||||
"python3 ./mach build --release",
|
||||
"python3 ./mach package --release",
|
||||
)
|
||||
.find_or_create("build.linux_x64_release" + CONFIG.tree_hash())
|
||||
)
|
||||
|
@ -449,10 +450,10 @@ def macos_nightly():
|
|||
"secrets:get:project/servo/github-homebrew-token",
|
||||
)
|
||||
.with_script(
|
||||
"./mach build --release",
|
||||
"./mach package --release",
|
||||
"python3 ./mach build --release",
|
||||
"python3 ./mach package --release",
|
||||
"./etc/ci/macos_package_smoketest.sh target/release/servo-tech-demo.dmg",
|
||||
"./mach upload-nightly mac --secret-from-taskcluster",
|
||||
"python3 ./mach upload-nightly mac --secret-from-taskcluster",
|
||||
)
|
||||
.with_artifacts("repo/target/release/servo-tech-demo.dmg")
|
||||
.find_or_create("build.mac_x64_nightly." + CONFIG.tree_hash())
|
||||
|
@ -489,7 +490,7 @@ def macos_release_build_with_debug_assertions(priority=None):
|
|||
.with_treeherder("macOS x64", "Release+A")
|
||||
.with_priority(priority)
|
||||
.with_script("\n".join([
|
||||
"./mach build --release --verbose --with-debug-assertions",
|
||||
"python3 ./mach build --release --verbose --with-debug-assertions",
|
||||
"./etc/ci/lockfile_changed.sh",
|
||||
"tar -czf target.tar.gz" +
|
||||
" target/release/servo" +
|
||||
|
@ -516,9 +517,9 @@ def linux_release_build_with_debug_assertions(layout_2020):
|
|||
linux_build_task(name_prefix + "Release build, with debug assertions")
|
||||
.with_treeherder("Linux x64", treeherder_prefix + "Release+A")
|
||||
.with_script("""
|
||||
time ./mach rustc -V
|
||||
time ./mach fetch
|
||||
./mach build --release --with-debug-assertions %s -p servo
|
||||
time python3 ./mach rustc -V
|
||||
time python3 ./mach fetch
|
||||
python3 ./mach build --release --with-debug-assertions %s -p servo
|
||||
./etc/ci/lockfile_changed.sh
|
||||
tar -czf /target.tar.gz \
|
||||
target/release/servo \
|
||||
|
@ -537,7 +538,7 @@ def macos_wpt():
|
|||
priority = "high" if CONFIG.git_ref == "refs/heads/auto" else None
|
||||
build_task = macos_release_build_with_debug_assertions(priority=priority)
|
||||
def macos_run_task(name):
|
||||
task = macos_task(name).with_python2().with_python3() \
|
||||
task = macos_task(name).with_python3() \
|
||||
.with_repo_bundle(alternate_object_dir="/var/cache/servo.git/objects")
|
||||
return with_homebrew(task, ["etc/taskcluster/macos/Brewfile"])
|
||||
wpt_chunks(
|
||||
|
@ -619,11 +620,11 @@ def wpt_chunks(platform, make_chunk_task, build_task, total_chunks, processes,
|
|||
if this_chunk == 0:
|
||||
if run_webgpu:
|
||||
webgpu_script = """
|
||||
time ./mach test-wpt _webgpu --release --processes $PROCESSES \
|
||||
time python3 ./mach test-wpt _webgpu --release --processes $PROCESSES \
|
||||
--headless --log-raw test-webgpu.log --always-succeed \
|
||||
--log-errorsummary webgpu-errorsummary.log \
|
||||
| cat
|
||||
./mach filter-intermittents \
|
||||
python3 ./mach filter-intermittents \
|
||||
webgpu-errorsummary.log \
|
||||
--log-intermittents webgpu-intermittents.log \
|
||||
--log-filteredsummary filtered-webgpu-errorsummary.log \
|
||||
|
@ -634,7 +635,7 @@ def wpt_chunks(platform, make_chunk_task, build_task, total_chunks, processes,
|
|||
webgpu_script = ""
|
||||
|
||||
task.with_script("""
|
||||
time python ./mach test-wpt --release --binary-arg=--multiprocess \
|
||||
time python3 ./mach test-wpt --release --binary-arg=--multiprocess \
|
||||
--processes $PROCESSES \
|
||||
--log-raw test-wpt-mp.log \
|
||||
--log-errorsummary wpt-mp-errorsummary.log \
|
||||
|
@ -647,30 +648,30 @@ def wpt_chunks(platform, make_chunk_task, build_task, total_chunks, processes,
|
|||
--always-succeed \
|
||||
url \
|
||||
| cat
|
||||
./mach filter-intermittents \
|
||||
python3 ./mach filter-intermittents \
|
||||
wpt-py3-errorsummary.log \
|
||||
--log-intermittents wpt-py3-intermittents.log \
|
||||
--log-filteredsummary filtered-py3-errorsummary.log \
|
||||
--tracker-api default \
|
||||
--reporter-api default
|
||||
time ./mach test-wpt --release --product=servodriver --headless \
|
||||
time python3 ./mach test-wpt --release --product=servodriver --headless \
|
||||
tests/wpt/mozilla/tests/mozilla/DOMParser.html \
|
||||
tests/wpt/mozilla/tests/css/per_glyph_font_fallback_a.html \
|
||||
tests/wpt/mozilla/tests/css/img_simple.html \
|
||||
tests/wpt/mozilla/tests/mozilla/secure.https.html \
|
||||
| cat
|
||||
time ./mach test-wpt --release --processes $PROCESSES --product=servodriver \
|
||||
time python3 ./mach test-wpt --release --processes $PROCESSES --product=servodriver \
|
||||
--headless --log-raw test-bluetooth.log \
|
||||
--log-errorsummary bluetooth-errorsummary.log \
|
||||
bluetooth \
|
||||
| cat
|
||||
time ./mach test-wpt --release --processes $PROCESSES --timeout-multiplier=4 \
|
||||
time python3 ./mach test-wpt --release --processes $PROCESSES --timeout-multiplier=4 \
|
||||
--headless --log-raw test-wdspec.log \
|
||||
--log-servojson wdspec-jsonsummary.log \
|
||||
--always-succeed \
|
||||
webdriver \
|
||||
| cat
|
||||
./mach filter-intermittents \
|
||||
python3 ./mach filter-intermittents \
|
||||
wdspec-jsonsummary.log \
|
||||
--log-intermittents intermittents.log \
|
||||
--log-filteredsummary filtered-wdspec-errorsummary.log \
|
||||
|
@ -680,7 +681,7 @@ def wpt_chunks(platform, make_chunk_task, build_task, total_chunks, processes,
|
|||
)
|
||||
else:
|
||||
task.with_script("""
|
||||
./mach test-wpt \
|
||||
python3 ./mach test-wpt \
|
||||
--release \
|
||||
$WPT_ARGS \
|
||||
--processes $PROCESSES \
|
||||
|
@ -690,7 +691,7 @@ def wpt_chunks(platform, make_chunk_task, build_task, total_chunks, processes,
|
|||
--log-servojson wpt-jsonsummary.log \
|
||||
--always-succeed \
|
||||
| cat
|
||||
./mach filter-intermittents \
|
||||
python3 ./mach filter-intermittents \
|
||||
wpt-jsonsummary.log \
|
||||
--log-intermittents intermittents.log \
|
||||
--log-filteredsummary filtered-wpt-errorsummary.log \
|
||||
|
@ -770,7 +771,7 @@ def linux_build_task(name, *, build_env=build_env):
|
|||
.with_dockerfile(dockerfile_path("build"))
|
||||
.with_env(**build_env, **unix_build_env, **linux_build_env)
|
||||
.with_repo_bundle()
|
||||
.with_script("./mach bootstrap-gstreamer")
|
||||
.with_script("python3 ./mach bootstrap-gstreamer")
|
||||
)
|
||||
return task
|
||||
|
||||
|
@ -797,12 +798,14 @@ def windows_build_task(name, package=True, arch="x86_64", rdp=False):
|
|||
**windows_build_env["all"]
|
||||
)
|
||||
.with_repo_bundle(sparse_checkout=windows_sparse_checkout)
|
||||
.with_python2()
|
||||
.with_directory_mount(
|
||||
"https://www.python.org/ftp/python/3.7.3/python-3.7.3-embed-amd64.zip",
|
||||
sha256="6de14c9223226cf0cd8c965ecb08c51d62c770171a256991b4fddc25188cfa8e",
|
||||
path="python3",
|
||||
)
|
||||
.with_python3()
|
||||
# mozjs's virtualenv expects a DLLs folder that contains dynamic libraries.
|
||||
# The embedded python distribution does not come with this.
|
||||
.with_script("""
|
||||
mkdir %HOMEDRIVE%%HOMEPATH%\\python3\\DLLs
|
||||
copy %HOMEDRIVE%%HOMEPATH%\\python3\\*.pyd %HOMEDRIVE%%HOMEPATH%\\python3\\DLLs
|
||||
copy %HOMEDRIVE%%HOMEPATH%\\python3\\*.dll %HOMEDRIVE%%HOMEPATH%\\python3\\DLLs
|
||||
""")
|
||||
.with_rustup()
|
||||
)
|
||||
if arch in hashes["non-devel"] and arch in hashes["devel"]:
|
||||
|
@ -844,7 +847,7 @@ def macos_build_task(name):
|
|||
.with_max_run_time_minutes(60 * 2)
|
||||
.with_env(**build_env, **unix_build_env, **macos_build_env)
|
||||
.with_repo_bundle(alternate_object_dir="/var/cache/servo.git/objects")
|
||||
.with_python2()
|
||||
.with_python3()
|
||||
.with_rustup()
|
||||
.with_index_and_artifacts_expire_in(build_artifacts_expire_in)
|
||||
# Debugging for surprising generic-worker behaviour
|
||||
|
|
|
@ -640,6 +640,30 @@ class WindowsGenericWorkerTask(GenericWorkerTask):
|
|||
""") \
|
||||
.with_path_from_homedir("python2", "python2\\Scripts")
|
||||
|
||||
def with_python3(self):
|
||||
"""
|
||||
For Python 3, use `with_directory_mount` and the "embeddable zip file" distribution
|
||||
from python.org.
|
||||
You may need to remove `python37._pth` from the ZIP in order to work around
|
||||
<https://bugs.python.org/issue34841>.
|
||||
"""
|
||||
return self \
|
||||
.with_directory_mount(
|
||||
"https://www.python.org/ftp/python/3.7.3/python-3.7.3-embed-amd64.zip",
|
||||
sha256="6de14c9223226cf0cd8c965ecb08c51d62c770171a256991b4fddc25188cfa8e",
|
||||
path="python3",
|
||||
) \
|
||||
.with_path_from_homedir("python3", "python3\\Scripts") \
|
||||
.with_curl_script("https://bootstrap.pypa.io/get-pip.py", "get-pip.py") \
|
||||
.with_script("""
|
||||
echo import site>>%HOMEDRIVE%%HOMEPATH%%\\python3\\python37._pth
|
||||
echo import sys>%HOMEDRIVE%%HOMEPATH%%\\python3\\sitecustomize.py
|
||||
echo sys.path.insert(0, '')>>%HOMEDRIVE%%HOMEPATH%%\\python3\\sitecustomize.py
|
||||
|
||||
python get-pip.py
|
||||
python -m pip install virtualenv==20.2.1
|
||||
""")
|
||||
|
||||
|
||||
class UnixTaskMixin(Task):
|
||||
def with_repo(self, alternate_object_dir=""):
|
||||
|
|
6
mach
6
mach
|
@ -6,7 +6,7 @@
|
|||
# The beginning of this script is both valid shell and valid python,
|
||||
# such that the script starts with the shell and is reexecuted with
|
||||
# the right python.
|
||||
''':' && if [ ! -z "$MSYSTEM" ] ; then exec python "$0" "$@" ; else which python2.7 > /dev/null 2> /dev/null && exec python2.7 "$0" "$@" || exec python "$0" "$@" ; fi
|
||||
''':' && if [ ! -z "$MSYSTEM" ] ; then exec python "$0" "$@" ; else which python3 > /dev/null 2> /dev/null && exec python3 "$0" "$@" || exec python "$0" "$@" ; fi
|
||||
'''
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
@ -18,8 +18,8 @@ import sys
|
|||
# Check for the current python version as some users (especially on archlinux)
|
||||
# may not have python 2 installed and their /bin/python binary symlinked to
|
||||
# python 3.
|
||||
if sys.version_info >= (3, 0) and sys.version_info < (3, 5):
|
||||
print("mach does not support python 3 (< 3.5), please install python 2 or python 3 (>= 3.5)")
|
||||
if sys.version_info < (3, 5):
|
||||
print("mach does not support python 3 (< 3.5), please install python 3 (>= 3.5)")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ blessings == 1.6
|
|||
distro == 1.4
|
||||
mach == 1.0.0
|
||||
mozdebug == 0.2
|
||||
mozinfo == 1.1.0
|
||||
mozlog == 5.0
|
||||
setuptools == 39.0
|
||||
mozinfo == 1.2.1
|
||||
mozlog == 7.1.0
|
||||
setuptools == 50.3.2
|
||||
toml == 0.9.2
|
||||
|
||||
# For Python linting
|
||||
|
@ -30,6 +30,6 @@ boto3 == 1.4.4
|
|||
certifi
|
||||
|
||||
# For Python3 compatibility
|
||||
six == 1.12
|
||||
six == 1.15
|
||||
|
||||
-e python/tidy
|
||||
|
|
|
@ -749,7 +749,7 @@ install them, let us know by filing a bug!")
|
|||
# Shorten hash
|
||||
# NOTE: Partially verifies the hash, but it will still pass if it's, e.g., a tree
|
||||
git_sha = subprocess.check_output([
|
||||
'git', 'rev-parse', '--short', git_sha
|
||||
'git', 'rev-parse', '--short', git_sha.decode('ascii')
|
||||
])
|
||||
else:
|
||||
# This is a regular commit
|
||||
|
@ -999,7 +999,7 @@ install them, let us know by filing a bug!")
|
|||
toolchain = self.rust_toolchain()
|
||||
|
||||
status = subprocess.call(
|
||||
["rustup", "run", toolchain.encode("utf-8"), "rustc", "--version"],
|
||||
["rustup", "run", toolchain, "rustc", "--version"],
|
||||
stdout=open(os.devnull, "wb"),
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
|
|
|
@ -775,7 +775,11 @@ def setup_uwp_signing(ms_app_store, publisher):
|
|||
|
||||
def run_powershell_cmd(cmd):
|
||||
try:
|
||||
return subprocess.check_output(['powershell.exe', '-NoProfile', '-Command', cmd])
|
||||
return (
|
||||
subprocess
|
||||
.check_output(['powershell.exe', '-NoProfile', '-Command', cmd])
|
||||
.decode('utf-8')
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
print("ERROR: PowerShell command failed: ", cmd)
|
||||
exit(1)
|
||||
|
@ -841,6 +845,7 @@ def build_uwp(platforms, dev, msbuild_dir, ms_app_store):
|
|||
.replace("%%PACKAGE_PLATFORMS%%", '|'.join(platforms))
|
||||
.replace("%%CONFIGURATION%%", Configuration)
|
||||
.replace("%%SOLUTION%%", path.join(os.getcwd(), 'support', 'hololens', 'ServoApp.sln'))
|
||||
.encode('utf-8')
|
||||
)
|
||||
build_file.close()
|
||||
# Generate an appxbundle.
|
||||
|
|
|
@ -243,7 +243,8 @@ class PostBuildCommands(CommandBase):
|
|||
media_stack=None, **kwargs):
|
||||
self.ensure_bootstrapped(rustup_components=["rust-docs"])
|
||||
rustc_path = check_output(
|
||||
["rustup" + BIN_SUFFIX, "which", "--toolchain", self.rust_toolchain(), "rustc"])
|
||||
["rustup" + BIN_SUFFIX, "which", "--toolchain", self.rust_toolchain(), "rustc"]
|
||||
).decode('utf-8')
|
||||
assert path.basename(path.dirname(rustc_path)) == "bin"
|
||||
toolchain_path = path.dirname(path.dirname(rustc_path))
|
||||
rust_docs = path.join(toolchain_path, "share", "doc", "rust", "html")
|
||||
|
|
|
@ -585,7 +585,10 @@ class MachCommands(CommandBase):
|
|||
|
||||
def format(outputs, description, file=sys.stdout):
|
||||
formatted = "%s %s:\n%s" % (len(outputs), description, "\n".join(outputs))
|
||||
file.write(formatted.encode("utf-8"))
|
||||
if file == sys.stdout:
|
||||
file.write(formatted)
|
||||
else:
|
||||
file.write(formatted.encode("utf-8"))
|
||||
|
||||
if log_intermittents:
|
||||
with open(log_intermittents, "wb") as file:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[cross-origin-isolated.sub.https.html]
|
||||
[self: originAgentCluster must equal true]
|
||||
expected: FAIL
|
||||
|
||||
[child: originAgentCluster must equal true]
|
||||
expected: FAIL
|
||||
|
|
|
@ -11005,7 +11005,7 @@
|
|||
[]
|
||||
],
|
||||
"interfaces.js": [
|
||||
"7a105e791dd80bd42d80055a64746bbe5fece41e",
|
||||
"e37397aa973f5fb913e5b8097945368c2848bed8",
|
||||
[]
|
||||
],
|
||||
"nested_asap_script.js": [
|
||||
|
|
|
@ -10,18 +10,18 @@ def fail(msg):
|
|||
|
||||
|
||||
def main(request, response):
|
||||
content_type = request.headers.get('Content-Type').split("; ")
|
||||
content_type = request.headers.get(b'Content-Type').split(b"; ")
|
||||
|
||||
if len(content_type) != 2:
|
||||
return fail("content type length is incorrect")
|
||||
|
||||
if content_type[0] != 'multipart/form-data':
|
||||
if content_type[0] != b'multipart/form-data':
|
||||
return fail("content type first field is incorrect")
|
||||
|
||||
boundary = content_type[1].strip("boundary=")
|
||||
boundary = content_type[1].strip(b"boundary=")
|
||||
|
||||
body = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"file-input\"; filename=\"upload.txt\""
|
||||
body += "\r\n" + "content-type: text/plain\r\n\r\nHello\r\n--" + boundary + "--\r\n"
|
||||
body = b"--" + boundary + b"\r\nContent-Disposition: form-data; name=\"file-input\"; filename=\"upload.txt\""
|
||||
body += b"\r\n" + b"content-type: text/plain\r\n\r\nHello\r\n--" + boundary + b"--\r\n"
|
||||
|
||||
if body != request.body:
|
||||
return fail("request body doesn't match: " + body + "+++++++" + request.body)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
decoded = """\
|
||||
decoded = b"""\
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut viverra neque in massa rutrum, non rutrum nunc pellentesque. Phasellus et nulla metus. Nam aliquet felis nec iaculis eleifend. Donec pretium tellus non aliquam tristique. Mauris feugiat eu velit sed maximus. Praesent fringilla lorem vel orci maximus accumsan. Fusce vel sapien ipsum. Nulla ac lectus non arcu semper laoreet.
|
||||
|
||||
Aliquam et massa at ex elementum dictum vitae ac purus. Sed a nunc sed dui pulvinar mollis eu sed eros. Mauris vitae ullamcorper dolor. Ut sed nisl sem. Mauris pulvinar vitae orci nec tincidunt. Integer fringilla quam in lobortis vehicula. In aliquam egestas dapibus. Suspendisse est enim, maximus non massa eget, finibus finibus lorem. Phasellus a varius ante. Pellentesque tempor dignissim nunc ut malesuada.
|
||||
|
@ -24,15 +24,15 @@ Aenean tincidunt consequat augue, in bibendum nisl placerat in. Nulla non dignis
|
|||
Nulla facilisis dui odio, at scelerisque erat cursus a. Ut arcu nunc, ullamcorper vitae orci eget, sollicitudin maximus sapien. Fusce eu arcu nunc. Integer vitae eros turpis. Fusce ac elit in nisi rutrum suscipit id consectetur lacus. Suspendisse rutrum ligula auctor fringilla cursus. Sed consequat erat in nunc lacinia, et ullamcorper velit vestibulum. Mauris sed est a tellus feugiat sagittis non nec neque. Sed eu bibendum orci. Donec diam diam, viverra sed dolor non, posuere sagittis mi. Duis rhoncus, risus sit amet luctus sodales, risus arcu faucibus enim, eu cras amet.\
|
||||
"""
|
||||
|
||||
encoded = '\x1b\x99\x13 ,\x0elw\x08\x95t\xd2\xe6\xf2(\xcd\'5M\x9dg\xd7\xc9)uG\xf4P\x8c;\x92_(\xb1\x14@L\x9d$\xa2\x16\x8f\x06\xc8\x18J\xed\xac\xabd_\xfb\xbe\xcb\xab\x90]VTu\xbc\xe1\xc3\x11\x96\x81T\r\xabj\x07\xbd\xe0\xb2\xd7y\x89\x1c\x81\xfd8\x9f\x15\xcf\xf8\xf6\xe6\x84\x8d\x90Ta<\xef\xcf\xce\xcc\x95\xa4\xff;\xcaO\xe9e\x97z/\xeap\t\x0e\x17\xd9\x14\xb6\xa9V\x151\n\xd0\xe0Fh\xd8\xbd\xd2\xdcB@\xed\xfa\xbe\xea\xb1V\xa1\xe7I\xd5\xfa\x7fTV\xa0\xa4\xda\x86G>R\x1a\x84\x1fs\x1b/\x98\xd6\xfa#\xaa_\xf5\xb7-\xf8d\x99\x80\x87O\xdb\xa1\xbe\xa9\x1a\xc3\xfb\xaf!\xc4f#oa\xc4\xffY?\x8f\xf3\xfc{\xe6\x1dB\x11\xe6\xdd\xe6(\\_S \xfd\xc9\x12\x9d4\t\x1cMO\x9a0u\xfd\t\xd7z\x1d\xe4l\'y\x17\x83\xbcCb\x18\xbfs\x16\xe3\xcc\xf1\x82\x97y\xc9n\x93\xce>=\x05\xb7\x15i\x91\xc4\xe3\xceek_\xfe\xfdzQ\x18\xfa\x19/\xe7\xddfk\x15E\xb2\xf6\xf6\xddo\x05\xbeSOc\xbd\xcb\xad{Ve\x1e/\xa0Y\xac\xaf\x87Z\x0f\xc7\xf0\xd9\xda\x17\xf4\x8e%\xf5Qc\xb9[K\xd2\xe1\x86k\x14\x84k \xf8\x12\xe8,2\x7fE}RT\xd5\xcb\xe0lv\xb8~\x11\xc0Bl\x92`\xf1\xb2\xcd\xfc3\xba\xf1\xe5m\xc2mI\xc0>D\x813e\x1b\\]\xfb\xf4G\x1d\xf9,\xa6\xb8\xff@\x947I\x8d\xd1\xbc\x1c\x0c(\xde\x138\xa3\xd8\x8e`\xd6\x7f\x81 \x82\x0e\x87\xfa"\x01\xdbqzL\x8a\x7f{\xb2\xefw\x8c^\xcdS\x9c&K\x1e\x1f\xc7\xaaj\xad\x1f0\x1f\x199\x10\xaez\n\x18\x81R6v\x99j/^\xf9\xbb\x88WB\xae\x97\xc2*\xedM\x80a]\xcc\xc1\x0e{\xf8\x81\xbd,=\xdf\xe6c\x9a\xbe\x7f\nO\x8a\x99\xd1?\xfc\x88\xc4\\\x1a(\xa4\\\xf6!\x7f}\xfd\xed\xb7+\xe4\xff\xfa\xebhk\xf6\x13R@h9j\xfd\x8ev\x9b\x89l\xbe\xfe\x9d8S\x0b\xec\xb7gNk\xcc\x9a\x9fR\xed\xc5Fv/F\xc0\xef)B1u6z\xfc\xd6\x9d\x9a\x1b\x01;a\xfa$\x96\x1b\xd7\x97\xf5\x8f\x0316\xfb\xddZ\xe8;\xdf=\x80S\xed-\xf3\x13\xb5$1\x7f2CNm\xc3+KQ\x97\xafe\xf4i\x91\x8bNq=-h\x82\x9e\xed>B\xb1\xfc,\xbbU\xe1\x14\x1c\x1f\xc9\x14\xc6\xbd\xb5*\xc8\xc5\x0f\xc4l\xed\x13\\_\xf5j\xff0s\xbev\x11\xf0d\x1dl\xd8\x1f\xc0\xe5g\x98(P\x87\xbb%.\x8c\xf0~8\xdcF\x8e\xb3\xd8>\xc6\x0c\xfb\xc4_\xc3\xce\x85\xeds\x9aR\xf3\xdc\xe6\x8dI\xc7`F\x08B?U\xda\xcf\x0c\xb8r,\xa2\x07\x9b\xd3\x1c$aG\xfc\xe5\xd5\x02\x85\xe9\xca\t\x12\xf1\xf6@[C\x10\xe9:\xed\xb5T\x96\xca\x8a\xb1X\xbeaV\x15\x0cp\xd8k\xbam\xe4\xf2\x12*\x03\xebo\x14 \x17\xe6\x04\xff_\x80\x8f\x10\x85/\xe5T\x13\x15\x84o\xde\xc6\xac\x965\x0f\xa7\xa7]\xec^\xbfXd \xd8\x7fiL\xacg\xb2\xc7\xf1\xa5\xd0\x81;\xd7e\x87\x14.\x80\x01z\xe0\xd1\x9cV\xf4\x1e;\xfe\x83\x1d\x9e\xc1\xf6\xbd\xcb\x97\xe2xa]\x18\x1c\x02\xeeZ\xf4b\x08\xa0<\xde\xab3\xec\xe0K\x1b\xfe\xdaC\xe1 \xf7\xb3&?\xae\xa6u\x18\x9buaq\xcd\xefI\xc6zNO\xf1\xca:\xc5\xdfk\\\x96\xc5:\x01<pnba\'\x89N~\xda\xe25*\xd0i\xe2DZ\x90\xf4-\xc4\x99O91\xc9\xd5r9\x8f^8\xcaP \xce\xa3^\xce\x07L)\x87\x1c\xd6C\xad\x1d\x98V\xadl`\xd7\xa4\xc1\x9d"\x8c\xfa\xca\x84\xce\x16\x81A\xabRn?p\xb4\xdbC\x98\xf4\xa1z\x11\xcb\x86CJ\xb6#i\x08&T\x08\xe4\xb8\xf7\x81\x18h\x19h\xa4\xadT\xebD\x14t\x9d2\xff&O)\x17\xaa\x1a\xbb\x99\x98\x03\xc0\xc7\xda\xe0S\xdc\xfa\xb4p\x93g\x1dQ\xb5L\x1drL\xda`G\xa1\x1dGt\x9ci\xbd\x11X9ev^\x14\xa8\x9b\xd6<\x98\x8d\xcad\xd5\x92\xc8\x02\xc0\xc0\xe6M\xcb3\xac\x03\xa6WZ=\x14~\xde \xab@=#r\xb8]\x1c&\xec\xb0\x9e:_\xf2$\xe5b\xbe\x02\x03\x81yi\x1c\xc6>\x95S\x99\'\xc9\xa6o\x1a\xd7~w\xcb\xbc~\xd1XE\x056\x97\x06\ra\xa0\xd8\x1a\xcb\xd4jB\xa8\x9e\x0b\xbc\xf2\xcb3`Y"\xf4\x05\xbe\x98\xcb\xa4S\x97\x0b\xcd\x0cp\x84p\xad\xa2\x07\x8ej?\n\x96m \xdb`\x12\xd4\x11&\\\x07b\xa79\xda\xcb\xc8\x83\xed\x81\xefw\x9f\xf1oF\x0e\xab}`\xee\xb54\xef\xcc\x9f\xc1\xec\xfe\x16\x96B\xa7\x94^\xc4\x10P\xba,eb.\x08-8\t\x8a\xd3Uq\xc3S\x88Z"+J\x93\xd4\xc6\xdde\xde\x8au"l\xc6\x13(\x13\xe4\xc1\xf7c\x1d\xee\xe9)\x11xF\x16\x08"\xafK/W \xdc\xb9\xbd\xa5CY\x03Q\xf0\xe4F\xa5\x0eO\xec\xad\xb2q\x17>N-\x15\xff\xfa8\xbbs\xc4|\xcd;,\xc7\xec\'\xa3\xfa\xb9\x07\xd9Q%\xf6\x84\x10q\xe7*VQ\xa3\xbb\xc8\x89\xb7g\xe7t\xe1\xe7\xb5\xc0\x0e8\x8d\x19\xe5v\xa1\t{\x8c\x9b\x1dx#\xf9\xc5\xcb\xf4y\xb9^\x1d\xba\x06\x81\xc52\xb8p\x91\x8b\x04c,\x9a\xa7\xfa\xaa\x93V\xc5>\xe0\xe5X>H\x99\xa6X\x9b\xfa\xbe\xcd\x14\xfd\xe4\x8an\xa18\x1f\x11gc\x83\x0b\xb6RLIz[\x1e\x80\x18\xa3\x9d\xc5\xec\x87\x12\x1b\x12\xe7\xf1\x8a\xae\xb4\xea\x99\x0e2\xa2w\xe4S\xd7\xe9Pq\xfd\x9c\xd6k\xf6\xa5`\x99}\x08\xc9\x9b5\x12\xe8\x17\xe2\xcf\x9f\x9bm\xc3\xe5<\x9f5m\xa1\xa4\xb5\xf1\x87\x8d\xf5}2yte\x14V\xf6\x10\xae\xd4\xeec\xa0\xdaq@(\xd6B\xa8R\xee"v\xf3\xeef\xb7\xb1\x8a\x8cu|\x11J\xb0 \xbe\xe1\x0e\rg\xc3\x9dd\xe2\xb12\xaf\xa3T\xa9\x18\xe7\xf3\x14V\x90\x07\xfali\x91\xc8\x06\xb3\xad\xe0i@\x19"W\x19\x1b\xc9|\xca\xfb\xe1x\xa8\xe4\xd8\x19\x81u4%\xc4_\xfb\xe9\xf90fI\x0eo\x9b\x1d\x98\x13\xa9\xd5\x89\x8c\xab>\xafH\xa2\x91eVe\xea\x03\x19p\xab\xa5\xed\x06\xb9f\x80\xc60\xc0\x8b\x1c\x18\xec\xd3\xb2\xc6l\xe44TAs3\x15\xc4\xac\xac\x0c\x0baN\xcb\xb7\x17\xd9\x1a\xbeG\x88\x9b\x98R\xb0Tp\x04\xa8\x99\x86\x11\xd5_I\x07\xce\x0e\xb8\x92\'Y\xefV\xc287\xdb+\xfd\xd2D\x13\xf7\x84\xec\xd45\x19R\x16O\xa1\x119<2\xb9\xa0K\xf6G\x8e\xc6S\n\r*h\xb1\xd1p\x10\xdd\\\xa9\xd0y\x1cG\x95\xb3D\xba\xa16\xb0\xd1\x98E\x87\x08\x01l.J\xe8\xeaA\x11\xb4Yr@\x19d!\xbb\x91\x06\xf1\x8a\xc0\xcdK\xf9\xback\x14\xa8F\x99)\x9f\xe5\xaf\xce#}ITF\x131T\xab\xe0\x05*>\xbeA{>\xac\xeak\xea\x95\xf9Bw 4\xec\xac\xdc\xe8\xac\xe4\xb6v\xcd\x91\x95\x05'
|
||||
encoded = b'\x1b\x99\x13 ,\x0elw\x08\x95t\xd2\xe6\xf2(\xcd\'5M\x9dg\xd7\xc9)uG\xf4P\x8c;\x92_(\xb1\x14@L\x9d$\xa2\x16\x8f\x06\xc8\x18J\xed\xac\xabd_\xfb\xbe\xcb\xab\x90]VTu\xbc\xe1\xc3\x11\x96\x81T\r\xabj\x07\xbd\xe0\xb2\xd7y\x89\x1c\x81\xfd8\x9f\x15\xcf\xf8\xf6\xe6\x84\x8d\x90Ta<\xef\xcf\xce\xcc\x95\xa4\xff;\xcaO\xe9e\x97z/\xeap\t\x0e\x17\xd9\x14\xb6\xa9V\x151\n\xd0\xe0Fh\xd8\xbd\xd2\xdcB@\xed\xfa\xbe\xea\xb1V\xa1\xe7I\xd5\xfa\x7fTV\xa0\xa4\xda\x86G>R\x1a\x84\x1fs\x1b/\x98\xd6\xfa#\xaa_\xf5\xb7-\xf8d\x99\x80\x87O\xdb\xa1\xbe\xa9\x1a\xc3\xfb\xaf!\xc4f#oa\xc4\xffY?\x8f\xf3\xfc{\xe6\x1dB\x11\xe6\xdd\xe6(\\_S \xfd\xc9\x12\x9d4\t\x1cMO\x9a0u\xfd\t\xd7z\x1d\xe4l\'y\x17\x83\xbcCb\x18\xbfs\x16\xe3\xcc\xf1\x82\x97y\xc9n\x93\xce>=\x05\xb7\x15i\x91\xc4\xe3\xceek_\xfe\xfdzQ\x18\xfa\x19/\xe7\xddfk\x15E\xb2\xf6\xf6\xddo\x05\xbeSOc\xbd\xcb\xad{Ve\x1e/\xa0Y\xac\xaf\x87Z\x0f\xc7\xf0\xd9\xda\x17\xf4\x8e%\xf5Qc\xb9[K\xd2\xe1\x86k\x14\x84k \xf8\x12\xe8,2\x7fE}RT\xd5\xcb\xe0lv\xb8~\x11\xc0Bl\x92`\xf1\xb2\xcd\xfc3\xba\xf1\xe5m\xc2mI\xc0>D\x813e\x1b\\]\xfb\xf4G\x1d\xf9,\xa6\xb8\xff@\x947I\x8d\xd1\xbc\x1c\x0c(\xde\x138\xa3\xd8\x8e`\xd6\x7f\x81 \x82\x0e\x87\xfa"\x01\xdbqzL\x8a\x7f{\xb2\xefw\x8c^\xcdS\x9c&K\x1e\x1f\xc7\xaaj\xad\x1f0\x1f\x199\x10\xaez\n\x18\x81R6v\x99j/^\xf9\xbb\x88WB\xae\x97\xc2*\xedM\x80a]\xcc\xc1\x0e{\xf8\x81\xbd,=\xdf\xe6c\x9a\xbe\x7f\nO\x8a\x99\xd1?\xfc\x88\xc4\\\x1a(\xa4\\\xf6!\x7f}\xfd\xed\xb7+\xe4\xff\xfa\xebhk\xf6\x13R@h9j\xfd\x8ev\x9b\x89l\xbe\xfe\x9d8S\x0b\xec\xb7gNk\xcc\x9a\x9fR\xed\xc5Fv/F\xc0\xef)B1u6z\xfc\xd6\x9d\x9a\x1b\x01;a\xfa$\x96\x1b\xd7\x97\xf5\x8f\x0316\xfb\xddZ\xe8;\xdf=\x80S\xed-\xf3\x13\xb5$1\x7f2CNm\xc3+KQ\x97\xafe\xf4i\x91\x8bNq=-h\x82\x9e\xed>B\xb1\xfc,\xbbU\xe1\x14\x1c\x1f\xc9\x14\xc6\xbd\xb5*\xc8\xc5\x0f\xc4l\xed\x13\\_\xf5j\xff0s\xbev\x11\xf0d\x1dl\xd8\x1f\xc0\xe5g\x98(P\x87\xbb%.\x8c\xf0~8\xdcF\x8e\xb3\xd8>\xc6\x0c\xfb\xc4_\xc3\xce\x85\xeds\x9aR\xf3\xdc\xe6\x8dI\xc7`F\x08B?U\xda\xcf\x0c\xb8r,\xa2\x07\x9b\xd3\x1c$aG\xfc\xe5\xd5\x02\x85\xe9\xca\t\x12\xf1\xf6@[C\x10\xe9:\xed\xb5T\x96\xca\x8a\xb1X\xbeaV\x15\x0cp\xd8k\xbam\xe4\xf2\x12*\x03\xebo\x14 \x17\xe6\x04\xff_\x80\x8f\x10\x85/\xe5T\x13\x15\x84o\xde\xc6\xac\x965\x0f\xa7\xa7]\xec^\xbfXd \xd8\x7fiL\xacg\xb2\xc7\xf1\xa5\xd0\x81;\xd7e\x87\x14.\x80\x01z\xe0\xd1\x9cV\xf4\x1e;\xfe\x83\x1d\x9e\xc1\xf6\xbd\xcb\x97\xe2xa]\x18\x1c\x02\xeeZ\xf4b\x08\xa0<\xde\xab3\xec\xe0K\x1b\xfe\xdaC\xe1 \xf7\xb3&?\xae\xa6u\x18\x9buaq\xcd\xefI\xc6zNO\xf1\xca:\xc5\xdfk\\\x96\xc5:\x01<pnba\'\x89N~\xda\xe25*\xd0i\xe2DZ\x90\xf4-\xc4\x99O91\xc9\xd5r9\x8f^8\xcaP \xce\xa3^\xce\x07L)\x87\x1c\xd6C\xad\x1d\x98V\xadl`\xd7\xa4\xc1\x9d"\x8c\xfa\xca\x84\xce\x16\x81A\xabRn?p\xb4\xdbC\x98\xf4\xa1z\x11\xcb\x86CJ\xb6#i\x08&T\x08\xe4\xb8\xf7\x81\x18h\x19h\xa4\xadT\xebD\x14t\x9d2\xff&O)\x17\xaa\x1a\xbb\x99\x98\x03\xc0\xc7\xda\xe0S\xdc\xfa\xb4p\x93g\x1dQ\xb5L\x1drL\xda`G\xa1\x1dGt\x9ci\xbd\x11X9ev^\x14\xa8\x9b\xd6<\x98\x8d\xcad\xd5\x92\xc8\x02\xc0\xc0\xe6M\xcb3\xac\x03\xa6WZ=\x14~\xde \xab@=#r\xb8]\x1c&\xec\xb0\x9e:_\xf2$\xe5b\xbe\x02\x03\x81yi\x1c\xc6>\x95S\x99\'\xc9\xa6o\x1a\xd7~w\xcb\xbc~\xd1XE\x056\x97\x06\ra\xa0\xd8\x1a\xcb\xd4jB\xa8\x9e\x0b\xbc\xf2\xcb3`Y"\xf4\x05\xbe\x98\xcb\xa4S\x97\x0b\xcd\x0cp\x84p\xad\xa2\x07\x8ej?\n\x96m \xdb`\x12\xd4\x11&\\\x07b\xa79\xda\xcb\xc8\x83\xed\x81\xefw\x9f\xf1oF\x0e\xab}`\xee\xb54\xef\xcc\x9f\xc1\xec\xfe\x16\x96B\xa7\x94^\xc4\x10P\xba,eb.\x08-8\t\x8a\xd3Uq\xc3S\x88Z"+J\x93\xd4\xc6\xdde\xde\x8au"l\xc6\x13(\x13\xe4\xc1\xf7c\x1d\xee\xe9)\x11xF\x16\x08"\xafK/W \xdc\xb9\xbd\xa5CY\x03Q\xf0\xe4F\xa5\x0eO\xec\xad\xb2q\x17>N-\x15\xff\xfa8\xbbs\xc4|\xcd;,\xc7\xec\'\xa3\xfa\xb9\x07\xd9Q%\xf6\x84\x10q\xe7*VQ\xa3\xbb\xc8\x89\xb7g\xe7t\xe1\xe7\xb5\xc0\x0e8\x8d\x19\xe5v\xa1\t{\x8c\x9b\x1dx#\xf9\xc5\xcb\xf4y\xb9^\x1d\xba\x06\x81\xc52\xb8p\x91\x8b\x04c,\x9a\xa7\xfa\xaa\x93V\xc5>\xe0\xe5X>H\x99\xa6X\x9b\xfa\xbe\xcd\x14\xfd\xe4\x8an\xa18\x1f\x11gc\x83\x0b\xb6RLIz[\x1e\x80\x18\xa3\x9d\xc5\xec\x87\x12\x1b\x12\xe7\xf1\x8a\xae\xb4\xea\x99\x0e2\xa2w\xe4S\xd7\xe9Pq\xfd\x9c\xd6k\xf6\xa5`\x99}\x08\xc9\x9b5\x12\xe8\x17\xe2\xcf\x9f\x9bm\xc3\xe5<\x9f5m\xa1\xa4\xb5\xf1\x87\x8d\xf5}2yte\x14V\xf6\x10\xae\xd4\xeec\xa0\xdaq@(\xd6B\xa8R\xee"v\xf3\xeef\xb7\xb1\x8a\x8cu|\x11J\xb0 \xbe\xe1\x0e\rg\xc3\x9dd\xe2\xb12\xaf\xa3T\xa9\x18\xe7\xf3\x14V\x90\x07\xfali\x91\xc8\x06\xb3\xad\xe0i@\x19"W\x19\x1b\xc9|\xca\xfb\xe1x\xa8\xe4\xd8\x19\x81u4%\xc4_\xfb\xe9\xf90fI\x0eo\x9b\x1d\x98\x13\xa9\xd5\x89\x8c\xab>\xafH\xa2\x91eVe\xea\x03\x19p\xab\xa5\xed\x06\xb9f\x80\xc60\xc0\x8b\x1c\x18\xec\xd3\xb2\xc6l\xe44TAs3\x15\xc4\xac\xac\x0c\x0baN\xcb\xb7\x17\xd9\x1a\xbeG\x88\x9b\x98R\xb0Tp\x04\xa8\x99\x86\x11\xd5_I\x07\xce\x0e\xb8\x92\'Y\xefV\xc287\xdb+\xfd\xd2D\x13\xf7\x84\xec\xd45\x19R\x16O\xa1\x119<2\xb9\xa0K\xf6G\x8e\xc6S\n\r*h\xb1\xd1p\x10\xdd\\\xa9\xd0y\x1cG\x95\xb3D\xba\xa16\xb0\xd1\x98E\x87\x08\x01l.J\xe8\xeaA\x11\xb4Yr@\x19d!\xbb\x91\x06\xf1\x8a\xc0\xcdK\xf9\xback\x14\xa8F\x99)\x9f\xe5\xaf\xce#}ITF\x131T\xab\xe0\x05*>\xbeA{>\xac\xeak\xea\x95\xf9Bw 4\xec\xac\xdc\xe8\xac\xe4\xb6v\xcd\x91\x95\x05'
|
||||
|
||||
def main(request, response):
|
||||
if 'raw' in request.GET:
|
||||
headers = [("Content-type", "text/plain"),
|
||||
("Content-Length", len(decoded))]
|
||||
if b'raw' in request.GET:
|
||||
headers = [(b"Content-type", b"text/plain"),
|
||||
(b"Content-Length", len(decoded))]
|
||||
return headers, decoded
|
||||
|
||||
headers = [("Content-type", "text/plain"),
|
||||
("Content-Encoding", "br"),
|
||||
("Content-Length", len(encoded))]
|
||||
headers = [(b"Content-type", b"text/plain"),
|
||||
(b"Content-Encoding", b"br"),
|
||||
(b"Content-Length", len(encoded))]
|
||||
return headers, encoded
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
def main(request, response):
|
||||
headers = []
|
||||
if 'Content-Type' in request.GET:
|
||||
headers += [('Content-Type', request.GET['Content-Type'])]
|
||||
with open('./resources/ahem/AHEM____.TTF') as f:
|
||||
if b'Content-Type' in request.GET:
|
||||
headers += [(b'Content-Type', request.GET[b'Content-Type'])]
|
||||
with open('./resources/ahem/AHEM____.TTF', 'rb') as f:
|
||||
return 200, headers, f.read()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue