| Index: third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/wptserve/wptserve/handlers.py
|
| diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/wptserve/wptserve/handlers.py b/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/wptserve/wptserve/handlers.py
|
| index f22ddd59d710386143f818ba80bcb3bb8c55d98a..c40321dfeabb4d97ce134137a76fb928285e5c9f 100644
|
| --- a/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/wptserve/wptserve/handlers.py
|
| +++ b/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/wptserve/wptserve/handlers.py
|
| @@ -5,12 +5,12 @@ import traceback
|
| import urllib
|
| import urlparse
|
|
|
| -from constants import content_types
|
| -from pipes import Pipeline, template
|
| -from ranges import RangeParser
|
| -from request import Authentication
|
| -from response import MultipartContent
|
| -from utils import HTTPException
|
| +from .constants import content_types
|
| +from .pipes import Pipeline, template
|
| +from .ranges import RangeParser
|
| +from .request import Authentication
|
| +from .response import MultipartContent
|
| +from .utils import HTTPException
|
|
|
| __all__ = ["file_handler", "python_script_handler",
|
| "FunctionHandler", "handler", "json_handler",
|
| @@ -30,7 +30,7 @@ def filesystem_path(base_path, request, url_base="/"):
|
| if base_path is None:
|
| base_path = request.doc_root
|
|
|
| - path = request.url_parts.path
|
| + path = urllib.unquote(request.url_parts.path)
|
|
|
| if path.startswith(url_base):
|
| path = path[len(url_base):]
|
| @@ -51,8 +51,13 @@ class DirectoryHandler(object):
|
| self.base_path = base_path
|
| self.url_base = url_base
|
|
|
| + def __repr__(self):
|
| + return "<%s base_path:%s url_base:%s>" % (self.__class__.__name__, self.base_path, self.url_base)
|
| +
|
| def __call__(self, request, response):
|
| - if not request.url_parts.path.endswith("/"):
|
| + url_path = request.url_parts.path
|
| +
|
| + if not url_path.endswith("/"):
|
| raise HTTPException(404)
|
|
|
| path = filesystem_path(self.base_path, request, self.url_base)
|
| @@ -66,23 +71,22 @@ class DirectoryHandler(object):
|
| <h1>Directory listing for %(path)s</h1>
|
| <ul>
|
| %(items)s
|
| -</li>
|
| -""" % {"path": cgi.escape(request.url_parts.path),
|
| - "items": "\n".join(self.list_items(request, path))}
|
| +</ul>
|
| +""" % {"path": cgi.escape(url_path),
|
| + "items": "\n".join(self.list_items(url_path, path))} # flake8: noqa
|
| +
|
| + def list_items(self, base_path, path):
|
| + assert base_path.endswith("/")
|
|
|
| - def list_items(self, request, path):
|
| # TODO: this won't actually list all routes, only the
|
| # ones that correspond to a real filesystem path. It's
|
| # not possible to list every route that will match
|
| # something, but it should be possible to at least list the
|
| # statically defined ones
|
| - base_path = request.url_parts.path
|
|
|
| - if not base_path.endswith("/"):
|
| - base_path += "/"
|
| if base_path != "/":
|
| link = urlparse.urljoin(base_path, "..")
|
| - yield ("""<li class="dir"><a href="%(link)s">%(name)s</a>""" %
|
| + yield ("""<li class="dir"><a href="%(link)s">%(name)s</a></li>""" %
|
| {"link": link, "name": ".."})
|
| for item in sorted(os.listdir(path)):
|
| link = cgi.escape(urllib.quote(item))
|
| @@ -91,18 +95,18 @@ class DirectoryHandler(object):
|
| class_ = "dir"
|
| else:
|
| class_ = "file"
|
| - yield ("""<li class="%(class)s"><a href="%(link)s">%(name)s</a>""" %
|
| + yield ("""<li class="%(class)s"><a href="%(link)s">%(name)s</a></li>""" %
|
| {"link": link, "name": cgi.escape(item), "class": class_})
|
|
|
|
|
| -directory_handler = DirectoryHandler()
|
| -
|
| -
|
| class FileHandler(object):
|
| def __init__(self, base_path=None, url_base="/"):
|
| self.base_path = base_path
|
| self.url_base = url_base
|
| - self.directory_handler = DirectoryHandler(self.base_path)
|
| + self.directory_handler = DirectoryHandler(self.base_path, self.url_base)
|
| +
|
| + def __repr__(self):
|
| + return "<%s base_path:%s url_base:%s>" % (self.__class__.__name__, self.base_path, self.url_base)
|
|
|
| def __call__(self, request, response):
|
| path = filesystem_path(self.base_path, request, self.url_base)
|
| @@ -130,7 +134,10 @@ class FileHandler(object):
|
| if "pipe" in query:
|
| pipeline = Pipeline(query["pipe"][-1])
|
| elif os.path.splitext(path)[0].endswith(".sub"):
|
| - pipeline = Pipeline("sub")
|
| + ml_extensions = {".html", ".htm", ".xht", ".xhtml", ".xml", ".svg"}
|
| + escape_type = "html" if os.path.splitext(path)[1] in ml_extensions else "none"
|
| + pipeline = Pipeline("sub(%s)" % escape_type)
|
| +
|
| if pipeline is not None:
|
| response = pipeline(request, response)
|
|
|
| @@ -140,9 +147,12 @@ class FileHandler(object):
|
| raise HTTPException(404)
|
|
|
| def get_headers(self, request, path):
|
| - rv = self.default_headers(path)
|
| - rv.extend(self.load_headers(request, os.path.join(os.path.split(path)[0], "__dir__")))
|
| - rv.extend(self.load_headers(request, path))
|
| + rv = (self.load_headers(request, os.path.join(os.path.split(path)[0], "__dir__")) +
|
| + self.load_headers(request, path))
|
| +
|
| + if not any(key.lower() == "content-type" for (key, _) in rv):
|
| + rv.insert(0, ("Content-Type", guess_content_type(path)))
|
| +
|
| return rv
|
|
|
| def load_headers(self, request, path):
|
| @@ -160,15 +170,17 @@ class FileHandler(object):
|
| return []
|
| else:
|
| if use_sub:
|
| - data = template(request, data)
|
| + data = template(request, data, escape_type="none")
|
| return [tuple(item.strip() for item in line.split(":", 1))
|
| for line in data.splitlines() if line]
|
|
|
| def get_data(self, response, path, byte_ranges):
|
| - with open(path, 'rb') as f:
|
| - if byte_ranges is None:
|
| - return f.read()
|
| - else:
|
| + """Return either the handle to a file, or a string containing
|
| + the content of a chunk of the file, if we have a range request."""
|
| + if byte_ranges is None:
|
| + return open(path, 'rb')
|
| + else:
|
| + with open(path, 'rb') as f:
|
| response.status = 206
|
| if len(byte_ranges) > 1:
|
| parts_content_type, content = self.set_response_multipart(response,
|
| @@ -197,9 +209,6 @@ class FileHandler(object):
|
| f.seek(byte_range.lower)
|
| return f.read(byte_range.upper - byte_range.lower)
|
|
|
| - def default_headers(self, path):
|
| - return [("Content-Type", guess_content_type(path))]
|
| -
|
|
|
| file_handler = FileHandler()
|
|
|
| @@ -209,6 +218,9 @@ class PythonScriptHandler(object):
|
| self.base_path = base_path
|
| self.url_base = url_base
|
|
|
| + def __repr__(self):
|
| + return "<%s base_path:%s url_base:%s>" % (self.__class__.__name__, self.base_path, self.url_base)
|
| +
|
| def __call__(self, request, response):
|
| path = filesystem_path(self.base_path, request, self.url_base)
|
|
|
| @@ -330,3 +342,29 @@ class ErrorHandler(object):
|
|
|
| def __call__(self, request, response):
|
| response.set_error(self.status)
|
| +
|
| +
|
| +class StaticHandler(object):
|
| + def __init__(self, path, format_args, content_type, **headers):
|
| + """Hander that reads a file from a path and substitutes some fixed data
|
| +
|
| + :param path: Path to the template file to use
|
| + :param format_args: Dictionary of values to substitute into the template file
|
| + :param content_type: Content type header to server the response with
|
| + :param headers: List of headers to send with responses"""
|
| +
|
| + with open(path) as f:
|
| + self.data = f.read() % format_args
|
| +
|
| + self.resp_headers = [("Content-Type", content_type)]
|
| + for k, v in headers.iteritems():
|
| + resp_headers.append((k.replace("_", "-"), v))
|
| +
|
| + self.handler = handler(self.handle_request)
|
| +
|
| + def handle_request(self, request, response):
|
| + return self.resp_headers, self.data
|
| +
|
| + def __call__(self, request, response):
|
| + rv = self.handler(request, response)
|
| + return rv
|
|
|