| # Copyright (C) 2011 Google Inc. All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are |
| # met: |
| # |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| from __future__ import print_function |
| |
| import logging |
| import os |
| import sys |
| import urllib |
| |
| if sys.version_info > (3, 0): |
| from http.server import HTTPServer |
| from socketserver import ThreadingMixIn |
| else: |
| from BaseHTTPServer import HTTPServer |
| from SocketServer import ThreadingMixIn |
| |
| from webkitpy.tool.servers.reflectionhandler import ReflectionHandler |
| |
| |
| _log = logging.getLogger(__name__) |
| |
| |
| class GardeningHTTPServer(ThreadingMixIn, HTTPServer): |
| def __init__(self, httpd_port, config): |
| server_name = '' |
| self.tool = config['tool'] |
| self.options = config['options'] |
| BaseHTTPServer.HTTPServer.__init__(self, (server_name, httpd_port), GardeningHTTPRequestHandler) |
| |
| def url(self, args=None): |
| # We can't use urllib.encode() here because that encodes spaces as plus signs and the buildbots don't decode those properly. |
| arg_string = ('?' + '&'.join("%s=%s" % (key, urllib.quote(value)) for (key, value) in args.items())) if args else '' |
| return 'http://localhost:8127/garden-o-matic.html' + arg_string |
| |
| |
| class GardeningHTTPRequestHandler(ReflectionHandler): |
| STATIC_FILE_NAMES = frozenset() |
| |
| STATIC_FILE_EXTENSIONS = ('.js', '.css', '.html', '.gif', '.png', '.ico') |
| |
| STATIC_FILE_DIRECTORY = os.path.join( |
| os.path.dirname(__file__), |
| '..', |
| '..', |
| '..', |
| '..', |
| 'CISupport', |
| 'build-webkit-org', |
| 'public_html', |
| 'TestFailures') |
| |
| allow_cross_origin_requests = True |
| debug_output = '' |
| |
| def ping(self): |
| self._serve_text('pong') |
| |
| def _run_webkit_patch(self, command, input_string): |
| PIPE = self.server.tool.executive.PIPE |
| process = self.server.tool.executive.popen([self.server.tool.path()] + command, cwd=self.server.tool.scm().checkout_root, stdin=PIPE, stdout=PIPE, stderr=PIPE) |
| process.stdin.write(input_string) |
| output, error = process.communicate() |
| return (process.returncode, output, error) |
| |
| def rebaselineall(self): |
| command = ['rebaseline-json'] |
| if self.server.options.move_overwritten_baselines: |
| command.append('--move-overwritten-baselines') |
| if self.server.options.results_directory: |
| command.extend(['--results-directory', self.server.options.results_directory]) |
| if not self.server.options.optimize: |
| command.append('--no-optimize') |
| if self.server.options.verbose: |
| command.append('--verbose') |
| json_input = self.read_entity_body() |
| |
| _log.debug("calling %s, input='%s'", command, json_input) |
| return_code, output, error = self._run_webkit_patch(command, json_input) |
| print(error, file=sys.stderr) |
| if return_code: |
| _log.error("rebaseline-json failed: %d, output='%s'" % (return_code, output)) |
| else: |
| _log.debug("rebaseline-json succeeded") |
| |
| # FIXME: propagate error and/or log messages back to the UI. |
| self._serve_text('success') |
| |
| def localresult(self): |
| path = self.query['path'][0] |
| filesystem = self.server.tool.filesystem |
| |
| # Ensure that we're only serving files from inside the results directory. |
| if not filesystem.isabs(path) and self.server.options.results_directory: |
| fullpath = filesystem.abspath(filesystem.join(self.server.options.results_directory, path)) |
| if fullpath.startswith(filesystem.abspath(self.server.options.results_directory)): |
| self._serve_file(fullpath, headers_only=(self.command == 'HEAD')) |
| return |
| |
| self.send_response(403) |