summaryrefslogtreecommitdiffstats
path: root/tools/python/google/httpd_utils.py
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:12:16 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:12:16 +0000
commit920c091ac3ee15079194c82ae8a7a18215f3f23c (patch)
treed28515d1e7732e2b6d077df1b4855ace3f4ac84f /tools/python/google/httpd_utils.py
parentae2c20f398933a9e86c387dcc465ec0f71065ffc (diff)
downloadchromium_src-920c091ac3ee15079194c82ae8a7a18215f3f23c.zip
chromium_src-920c091ac3ee15079194c82ae8a7a18215f3f23c.tar.gz
chromium_src-920c091ac3ee15079194c82ae8a7a18215f3f23c.tar.bz2
Add tools to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/python/google/httpd_utils.py')
-rw-r--r--tools/python/google/httpd_utils.py219
1 files changed, 219 insertions, 0 deletions
diff --git a/tools/python/google/httpd_utils.py b/tools/python/google/httpd_utils.py
new file mode 100644
index 0000000..7f76ca6
--- /dev/null
+++ b/tools/python/google/httpd_utils.py
@@ -0,0 +1,219 @@
+#!/bin/env python
+# Copyright 2008, 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:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * 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.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# 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.
+
+"""A class to help start/stop a local apache http server."""
+
+import logging
+import optparse
+import os
+import subprocess
+import sys
+import time
+import urllib
+
+import google.path_utils
+import google.platform_utils
+
+class HttpdNotStarted(Exception): pass
+
+def ApacheConfigDir(start_dir):
+ """Returns a path to the directory holding the Apache config files."""
+ return google.path_utils.FindUpward(start_dir, 'tools', 'python',
+ 'google', 'httpd_config')
+
+
+def GetCygserverPath(start_dir, apache2=False):
+ """Returns the path to the directory holding cygserver.exe file."""
+ cygserver_path = None
+ if apache2:
+ cygserver_path = google.path_utils.FindUpward(start_dir, 'third_party',
+ 'cygwin', 'usr', 'sbin')
+ return cygserver_path
+
+
+def StartServer(document_root=None, output_dir=None, apache2=False):
+ """Starts a local server on port 8000 using the basic configuration files.
+
+ Args:
+ document_root: If present, specifies the document root for the server;
+ otherwise, the filesystem's root (e.g., C:/ or /) will be used.
+ output_dir: If present, specifies where to put server logs; otherwise,
+ they'll be placed in the system's temp dir (e.g., $TEMP or /tmp).
+ apache2: boolean if true will cause this function to configure
+ for Apache 2.x as opposed to Apache 1.3.x
+
+ Returns: the ApacheHttpd object that was created
+ """
+ script_dir = google.path_utils.ScriptDir()
+ platform_util = google.platform_utils.PlatformUtility(script_dir)
+ if not output_dir:
+ output_dir = platform_util.GetTempDirectory()
+ if not document_root:
+ document_root = platform_util.GetFilesystemRoot()
+ apache_config_dir = ApacheConfigDir(script_dir)
+ if apache2:
+ httpd_conf_path = os.path.join(apache_config_dir, 'httpd2.conf')
+ else:
+ httpd_conf_path = os.path.join(apache_config_dir, 'httpd.conf')
+ mime_types_path = os.path.join(apache_config_dir, 'mime.types')
+ start_cmd = platform_util.GetStartHttpdCommand(output_dir,
+ httpd_conf_path,
+ mime_types_path,
+ document_root,
+ apache2=apache2)
+ stop_cmd = platform_util.GetStopHttpdCommand()
+ httpd = ApacheHttpd(start_cmd, stop_cmd, [8000],
+ cygserver_path=GetCygserverPath(script_dir, apache2))
+ httpd.StartServer()
+ return httpd
+
+
+def StopServers(apache2=False):
+ """Calls the platform's stop command on a newly created server, forcing it
+ to stop.
+
+ The details depend on the behavior of the platform stop command. For example,
+ it's often implemented to kill all running httpd processes, as implied by
+ the name of this function.
+
+ Args:
+ apache2: boolean if true will cause this function to configure
+ for Apache 2.x as opposed to Apache 1.3.x
+ """
+ script_dir = google.path_utils.ScriptDir()
+ platform_util = google.platform_utils.PlatformUtility(script_dir)
+ httpd = ApacheHttpd('', platform_util.GetStopHttpdCommand(), [],
+ cygserver_path=GetCygserverPath(script_dir, apache2))
+ httpd.StopServer(force=True)
+
+
+class ApacheHttpd(object):
+ def __init__(self, start_command, stop_command, port_list,
+ cygserver_path=None):
+ """Args:
+ start_command: command list to call to start the httpd
+ stop_command: command list to call to stop the httpd if one has been
+ started. May kill all httpd processes running on the machine.
+ port_list: list of ports expected to respond on the local machine when
+ the server has been successfully started.
+ cygserver_path: Path to cygserver.exe. If specified, exe will be started
+ with server as well as stopped when server is stopped.
+ """
+ self._http_server_proc = None
+ self._start_command = start_command
+ self._stop_command = stop_command
+ self._port_list = port_list
+ self._cygserver_path = cygserver_path
+
+ def StartServer(self):
+ if self._http_server_proc:
+ return
+ if self._cygserver_path:
+ cygserver_exe = os.path.join(self._cygserver_path, "cygserver.exe")
+ cygbin = google.path_utils.FindUpward(cygserver_exe, 'third_party',
+ 'cygwin', 'bin')
+ env = os.environ
+ env['PATH'] += ";" + cygbin
+ subprocess.Popen(cygserver_exe, env=env)
+ logging.info('Starting http server')
+ self._http_server_proc = subprocess.Popen(self._start_command)
+
+ # Ensure that the server is running on all the desired ports.
+ for port in self._port_list:
+ if not self._UrlIsAlive('http://127.0.0.1:%s/' % str(port)):
+ raise HttpdNotStarted('Failed to start httpd on port %s' % str(port))
+
+ def _UrlIsAlive(self, url):
+ """Checks to see if we get an http response from |url|.
+ We poll the url 5 times with a 1 second delay. If we don't
+ get a reply in that time, we give up and assume the httpd
+ didn't start properly.
+
+ Args:
+ url: The URL to check.
+ Return:
+ True if the url is alive.
+ """
+ wait_time = 5
+ while wait_time > 0:
+ try:
+ response = urllib.urlopen(url)
+ # Server is up and responding.
+ return True
+ except IOError:
+ pass
+ wait_time -= 1
+ # Wait a second and try again.
+ time.sleep(1)
+
+ return False
+
+ def StopServer(self, force=False):
+ """If we started an httpd.exe process, or if force is True, call
+ self._stop_command (passed in on init so it can be platform-dependent).
+ This will presumably kill it, and may also kill any other httpd.exe
+ processes that are running.
+ """
+ if force or self._http_server_proc:
+ logging.info('Stopping http server')
+ kill_proc = subprocess.Popen(self._stop_command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ logging.info('%s\n%s' % (kill_proc.stdout.read(),
+ kill_proc.stderr.read()))
+ self._http_server_proc = None
+ if self._cygserver_path:
+ subprocess.Popen(["taskkill.exe", "/f", "/im", "cygserver.exe"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+if '__main__' == __name__:
+ # Provide some command line params for starting/stopping the http server
+ # manually.
+ option_parser = optparse.OptionParser()
+ option_parser.add_option('-k', '--server', help='Server action (start|stop)')
+ option_parser.add_option('-r', '--root', help='Document root (optional)')
+ option_parser.add_option('-a', '--apache2', action='store_true',
+ default=False, help='Starts Apache 2 instead of Apache 1.3 (default).')
+ options, args = option_parser.parse_args()
+
+ if not options.server:
+ print ("Usage: %s -k {start|stop} [-r document_root] [--apache2]" %
+ sys.argv[0])
+ sys.exit(0)
+
+ document_root = None
+ if options.root:
+ document_root = options.root
+
+ if 'start' == options.server:
+ StartServer(document_root, apache2=options.apache2)
+ else:
+ StopServers(apache2=options.apache2)