diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:12:16 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:12:16 +0000 |
commit | 920c091ac3ee15079194c82ae8a7a18215f3f23c (patch) | |
tree | d28515d1e7732e2b6d077df1b4855ace3f4ac84f /tools/python | |
parent | ae2c20f398933a9e86c387dcc465ec0f71065ffc (diff) | |
download | chromium_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')
-rw-r--r-- | tools/python/google/__init__.py | 1 | ||||
-rw-r--r-- | tools/python/google/gethash_timer.py | 168 | ||||
-rw-r--r-- | tools/python/google/httpd_config/httpd.conf | 734 | ||||
-rw-r--r-- | tools/python/google/httpd_config/httpd2.conf | 280 | ||||
-rw-r--r-- | tools/python/google/httpd_config/httpd2.pem | 36 | ||||
-rw-r--r-- | tools/python/google/httpd_config/mime.types | 599 | ||||
-rw-r--r-- | tools/python/google/httpd_utils.py | 219 | ||||
-rw-r--r-- | tools/python/google/logging_utils.py | 110 | ||||
-rw-r--r-- | tools/python/google/path_utils.py | 109 | ||||
-rw-r--r-- | tools/python/google/platform_utils.py | 46 | ||||
-rw-r--r-- | tools/python/google/platform_utils_win.py | 219 | ||||
-rw-r--r-- | tools/python/google/process_utils.py | 156 |
12 files changed, 2677 insertions, 0 deletions
diff --git a/tools/python/google/__init__.py b/tools/python/google/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tools/python/google/__init__.py @@ -0,0 +1 @@ + diff --git a/tools/python/google/gethash_timer.py b/tools/python/google/gethash_timer.py new file mode 100644 index 0000000..b36a5df --- /dev/null +++ b/tools/python/google/gethash_timer.py @@ -0,0 +1,168 @@ +#!/usr/bin/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. + +# Issue a series of GetHash requests to the SafeBrowsing servers and measure the +# response times. +# +# Usage: +# +# $ ./gethash_timer.py --period=600 --samples=20 --output=resp.csv +# +# --period (or -p): The amount of time (in seconds) to wait between GetHash +# requests. Using a value of more than 300 (5 minutes) to +# include the effect of DNS. +# +# --samples (or -s): The number of requests to issue. If this parameter is not +# specified, the test will run indefinitely. +# +# --output (or -o): The path to a file where the output will be written in +# CSV format: sample_number,response_code,elapsed_time_ms + +import getopt +import httplib +import sys +import time + +_GETHASH_HOST = 'safebrowsing.clients.google.com' +_GETHASH_REQUEST = '/safebrowsing/gethash?client=googleclient&appver=1.0&pver=2.1' + +# Global logging file handle. +g_file_handle = None + + +def IssueGetHash(prefix): + '''Issue one GetHash request to the safebrowsing servers. + Args: + prefix: A 4 byte value to look up on the server. + Returns: + The HTTP response code for the GetHash request. + ''' + body = '4:4\n' + prefix + h = httplib.HTTPConnection(_GETHASH_HOST) + h.putrequest('POST', _GETHASH_REQUEST) + h.putheader('content-length', str(len(body))) + h.endheaders() + h.send(body) + response_code = h.getresponse().status + h.close() + return response_code + + +def TimedGetHash(prefix): + '''Measure the amount of time it takes to receive a GetHash response. + Args: + prefix: A 4 byte value to look up on the the server. + Returns: + A tuple of HTTP resonse code and the response time (in milliseconds). + ''' + start = time.time() + response_code = IssueGetHash(prefix) + return response_code, (time.time() - start) * 1000 + + +def RunTimedGetHash(period, samples=None): + '''Runs an experiment to measure the amount of time it takes to receive + multiple responses from the GetHash servers. + + Args: + period: A floating point value that indicates (in seconds) the delay + between requests. + samples: An integer value indicating the number of requests to make. + If 'None', the test continues indefinitely. + Returns: + None. + ''' + global g_file_handle + prefix = '\x50\x61\x75\x6c' + sample_count = 1 + while True: + response_code, elapsed_time = TimedGetHash(prefix) + LogResponse(sample_count, response_code, elapsed_time) + sample_count += 1 + if samples is not None and sample_count == samples: + break + time.sleep(period) + + +def LogResponse(sample_count, response_code, elapsed_time): + '''Output the response for one GetHash query. + Args: + sample_count: The current sample number. + response_code: The HTTP response code for the GetHash request. + elapsed_time: The round-trip time (in milliseconds) for the + GetHash request. + Returns: + None. + ''' + global g_file_handle + output_list = (sample_count, response_code, elapsed_time) + print 'Request: %d, status: %d, elapsed time: %f ms' % output_list + if g_file_handle is not None: + g_file_handle.write(('%d,%d,%f' % output_list) + '\n') + g_file_handle.flush() + + +def SetupOutputFile(file_name): + '''Open a file for logging results. + Args: + file_name: A path to a file to store the output. + Returns: + None. + ''' + global g_file_handle + g_file_handle = open(file_name, 'w') + + +if __name__ == '__main__': + period = 10 + samples = None + + options, args = getopt.getopt(sys.argv[1:], + 's:p:o:', + ['samples=', 'period=', 'output=']) + for option, value in options: + if option == '-s' or option == '--samples': + samples = int(value) + elif option == '-p' or option == '--period': + period = float(value) + elif option == '-o' or option == '--output': + file_name = value + else: + print 'Bad option: %s' % option + sys.exit(1) + try: + print 'Starting Timed GetHash ----------' + SetupOutputFile(file_name) + RunTimedGetHash(period, samples) + except KeyboardInterrupt: + pass + + print 'Timed GetHash complete ----------' + g_file_handle.close() diff --git a/tools/python/google/httpd_config/httpd.conf b/tools/python/google/httpd_config/httpd.conf new file mode 100644 index 0000000..fc7a498 --- /dev/null +++ b/tools/python/google/httpd_config/httpd.conf @@ -0,0 +1,734 @@ +## +## httpd.conf -- Apache HTTP server configuration file +## + +# +# Based upon the NCSA server configuration files originally by Rob McCool. +# +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See <URL:http://httpd.apache.org/docs/> for detailed information about +# the directives. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# After this file is processed, the server will look for and process +# /private/etc/httpd/srm.conf and then /private/etc/httpd/access.conf +# unless you have overridden these with ResourceConfig and/or +# AccessConfig directives here. +# +# The configuration directives are grouped into three basic sections: +# 1. Directives that control the operation of the Apache server process as a +# whole (the 'global environment'). +# 2. Directives that define the parameters of the 'main' or 'default' server, +# which responds to requests that aren't handled by a virtual host. +# These directives also provide default values for the settings +# of all virtual hosts. +# 3. Settings for virtual hosts, which allow Web requests to be sent to +# different IP addresses or hostnames and have them handled by the +# same Apache server process. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so "logs/foo.log" +# with ServerRoot set to "/usr/local/apache" will be interpreted by the +# server as "/usr/local/apache/logs/foo.log". +# + +### Section 1: Global Environment +# +# The directives in this section affect the overall operation of Apache, +# such as the number of concurrent requests it can handle or where it +# can find its configuration files. +# + +# +# ServerType is either inetd, or standalone. Inetd mode is only supported on +# Unix platforms. +# +ServerType standalone + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the LockFile documentation +# (available at <URL:http://www.apache.org/docs/mod/core.html#lockfile>); +# you will save yourself a lot of trouble. +# +#ServerRoot "/usr" + +# +# The LockFile directive sets the path to the lockfile used when Apache +# is compiled with either USE_FCNTL_SERIALIZED_ACCEPT or +# USE_FLOCK_SERIALIZED_ACCEPT. This directive should normally be left at +# its default value. The main reason for changing it is if the logs +# directory is NFS mounted, since the lockfile MUST BE STORED ON A LOCAL +# DISK. The PID of the main server process is automatically appended to +# the filename. +# +#LockFile "/private/var/run/httpd.lock" + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# +PidFile "/tmp/WebKit/httpd.pid" + +# +# ScoreBoardFile: File used to store internal server process information. +# Not all architectures require this. But if yours does (you'll know because +# this file will be created when you run Apache) then you *must* ensure that +# no two invocations of Apache share the same scoreboard file. +# +ScoreBoardFile "/tmp/WebKit/httpd.scoreboard" + +# +# In the standard configuration, the server will process httpd.conf (this +# file, specified by the -f command line option), srm.conf, and access.conf +# in that order. The latter two files are now distributed empty, as it is +# recommended that all directives be kept in a single file for simplicity. +# The commented-out values below are the built-in defaults. You can have the +# server ignore these files altogether by using "/dev/null" (for Unix) or +# "nul" (for Win32) for the arguments to the directives. +# +ResourceConfig /dev/null +AccessConfig /dev/null + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 15 + +# +# Server-pool size regulation. Rather than making you guess how many +# server processes you need, Apache dynamically adapts to the load it +# sees --- that is, it tries to maintain enough server processes to +# handle the current load, plus a few spare servers to handle transient +# load spikes (e.g., multiple simultaneous requests from a single +# Netscape browser). +# +# It does this by periodically checking how many servers are waiting +# for a request. If there are fewer than MinSpareServers, it creates +# a new spare. If there are more than MaxSpareServers, some of the +# spares die off. The default values are probably OK for most sites. +# +MinSpareServers 1 +MaxSpareServers 5 + +# +# Number of servers to start initially --- should be a reasonable ballpark +# figure. +# +StartServers 1 + +# +# Limit on total number of servers running, i.e., limit on the number +# of clients who can simultaneously connect --- if this limit is ever +# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW. +# It is intended mainly as a brake to keep a runaway server from taking +# the system with it as it spirals down... +# +MaxClients 150 + +# +# MaxRequestsPerChild: the number of requests each child process is +# allowed to process before the child dies. The child will exit so +# as to avoid problems after prolonged use when Apache (and maybe the +# libraries it uses) leak memory or other resources. On most systems, this +# isn't really needed, but a few (such as Solaris) do have notable leaks +# in the libraries. For these platforms, set to something like 10000 +# or so; a setting of 0 means unlimited. +# +# NOTE: This value does not include keepalive requests after the initial +# request per connection. For example, if a child process handles +# an initial request and 10 subsequent "keptalive" requests, it +# would only count as 1 request towards this limit. +# +MaxRequestsPerChild 100000 + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the <VirtualHost> +# directive. +# +# Configured from the httpd command line for WebKit layout tests. +# +Listen 127.0.0.1:8000 +Listen 127.0.0.1:8080 +Listen 127.0.0.1:8081 +Listen 127.0.0.1:9000 +Listen 127.0.0.1:9080 + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Please read the file http://httpd.apache.org/docs/dso.html for more +# details about the DSO mechanism and run `httpd -l' for the list of already +# built-in (statically linked and thus always available) modules in your httpd +# binary. +# +# Note: The order in which modules are loaded is important. Don't change +# the order below without expert advice. +# +# Example: +# LoadModule foo_module lib/apache/mod_foo.dll +#LoadModule vhost_alias_module lib/apache/mod_vhost_alias.dll +#LoadModule env_module lib/apache/mod_env.dll +LoadModule config_log_module lib/apache/mod_log_config.dll +#LoadModule mime_magic_module lib/apache/mod_mime_magic.dll +LoadModule mime_module lib/apache/mod_mime.dll +LoadModule negotiation_module lib/apache/mod_negotiation.dll +#LoadModule status_module lib/apache/mod_status.dll +#LoadModule info_module lib/apache/mod_info.dll +LoadModule includes_module lib/apache/mod_include.dll +LoadModule autoindex_module lib/apache/mod_autoindex.dll +#LoadModule dir_module lib/apache/mod_dir.dll +LoadModule cgi_module lib/apache/mod_cgi.dll +LoadModule asis_module lib/apache/mod_asis.dll +LoadModule imap_module lib/apache/mod_imap.dll +LoadModule action_module lib/apache/mod_actions.dll +#LoadModule speling_module lib/apache/mod_speling.dll +#LoadModule userdir_module lib/apache/mod_userdir.dll +LoadModule alias_module lib/apache/mod_alias.dll +LoadModule rewrite_module lib/apache/mod_rewrite.dll +LoadModule access_module lib/apache/mod_access.dll +LoadModule auth_module lib/apache/mod_auth.dll +#LoadModule anon_auth_module lib/apache/mod_auth_anon.dll +#LoadModule dbm_auth_module lib/apache/mod_auth_dbm.dll +#LoadModule digest_module lib/apache/mod_digest.dll +#LoadModule proxy_module lib/apache/libproxy.dll +#LoadModule cern_meta_module lib/apache/mod_cern_meta.dll +#LoadModule expires_module lib/apache/mod_expires.dll +LoadModule headers_module lib/apache/mod_headers.dll +#LoadModule usertrack_module lib/apache/mod_usertrack.dll +#LoadModule log_forensic_module lib/apache/mod_log_forensic.dll +#LoadModule unique_id_module lib/apache/mod_unique_id.dll +#LoadModule setenvif_module lib/apache/mod_setenvif.dll +#LoadModule dav_module lib/apache/libdav.dll +#LoadModule ssl_module lib/apache/libssl.dll +#LoadModule perl_module lib/apache/libperl.dll +LoadModule php4_module lib/apache/libphp4.dll +#LoadModule hfs_apple_module lib/apache/mod_hfs_apple.dll +#LoadModule bonjour_module lib/apache/mod_bonjour.dll + +# Reconstruction of the complete module list from all available modules +# (static and shared ones) to achieve correct module execution order. +# [WHENEVER YOU CHANGE THE LOADMODULE SECTION ABOVE UPDATE THIS, TOO] +ClearModuleList +#AddModule mod_vhost_alias.c +#AddModule mod_env.c +AddModule mod_log_config.c +#AddModule mod_mime_magic.c +AddModule mod_mime.c +AddModule mod_negotiation.c +#AddModule mod_status.c +#AddModule mod_info.c +AddModule mod_include.c +AddModule mod_autoindex.c +#AddModule mod_dir.c +AddModule mod_cgi.c +AddModule mod_asis.c +AddModule mod_imap.c +AddModule mod_actions.c +#AddModule mod_speling.c +#AddModule mod_userdir.c +AddModule mod_alias.c +AddModule mod_rewrite.c +AddModule mod_access.c +AddModule mod_auth.c +#AddModule mod_auth_anon.c +#AddModule mod_auth_dbm.c +#AddModule mod_digest.c +#AddModule mod_proxy.c +#AddModule mod_cern_meta.c +#AddModule mod_expires.c +AddModule mod_headers.c +#AddModule mod_usertrack.c +#AddModule mod_log_forensic.c +#AddModule mod_unique_id.c +AddModule mod_so.c +#AddModule mod_setenvif.c +#AddModule mod_dav.c +#AddModule mod_ssl.c +#AddModule mod_perl.c +AddModule mod_php4.c +#AddModule mod_hfs_apple.c +#AddModule mod_bonjour.c + +### Section 2: 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# <VirtualHost> definition. These values also provide defaults for +# any <VirtualHost> containers you may define later in the file. +# +# All of these directives may appear inside <VirtualHost> containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerName allows you to set a host name which is sent back to clients for +# your server if it's different than the one the program would get (i.e., use +# "www" instead of the host's real name). +# +# Note: You cannot just invent host names and hope they work. The name you +# define here must be a valid DNS name for your host. If you don't understand +# this, ask your network administrator. +# If your host doesn't have a registered DNS name, enter its IP address here. +# You will have to access it by its address (e.g., http://123.45.67.89/) +# anyway, and this will make redirections work in a sensible way. +# +# 127.0.0.1 is the TCP/IP local loop-back address, often named localhost. Your +# machine always knows itself by this address. If you use Apache strictly for +# local testing and development, you may use 127.0.0.1 as the server name. +# +ServerName 127.0.0.1 + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +# Configured from the httpd command line for WebKit layout tests. +#DocumentRoot "/Library/WebServer/Documents" + +# +# Each directory to which Apache has access, can be configured with respect +# to which services and features are allowed and/or disabled in that +# directory (and its subdirectories). +# +<Directory /> +# +# This may also be "None", "All", or any combination of "Indexes", +# "Includes", "FollowSymLinks", "ExecCGI", or "MultiViews". +# +# Note that "MultiViews" must be named *explicitly* --- "Options All" +# doesn't give it to you. +# + Options Indexes FollowSymLinks MultiViews ExecCGI Includes + +# +# This controls which options the .htaccess files in directories can +# override. Can also be "All", or any combination of "Options", "FileInfo", +# "AuthConfig", and "Limit" +# + AllowOverride All + +# +# Controls who can get stuff from this server. +# + Order allow,deny + Allow from all +</Directory> + +# +# AccessFileName: The name of the file to look for in each directory +# for access control information. +# +AccessFileName .htaccess + +# +# The following lines prevent .htaccess files from being viewed by +# Web clients. Since .htaccess files often contain authorization +# information, access is disallowed for security reasons. Comment +# these lines out if you want Web visitors to see the contents of +# .htaccess files. If you change the AccessFileName directive above, +# be sure to make the corresponding changes here. +# +# Also, folks tend to use names such as .htpasswd for password +# files, so this will protect those as well. +# +<Files ~ "^\.([Hh][Tt]|[Dd][Ss]_[Ss])"> + Order allow,deny + Deny from all + Satisfy All +</Files> + +# +# Apple specific filesystem protection. +# + +<Files "rsrc"> + Order allow,deny + Deny from all + Satisfy All +</Files> + +<Directory ~ ".*\.\.namedfork"> + Order allow,deny + Deny from all + Satisfy All +</Directory> + +# +# CacheNegotiatedDocs: By default, Apache sends "Pragma: no-cache" with each +# document that was negotiated on the basis of content. This asks proxy +# servers not to cache the document. Uncommenting the following line disables +# this behavior, and proxies will be allowed to cache the documents. +# +#CacheNegotiatedDocs + +# +# UseCanonicalName: (new for 1.3) With this setting turned on, whenever +# Apache needs to construct a self-referencing URL (a URL that refers back +# to the server the response is coming from) it will use ServerName and +# Port to form a "canonical" name. With this setting off, Apache will +# use the hostname:port that the client supplied, when possible. This +# also affects SERVER_NAME and SERVER_PORT in CGI scripts. +# +UseCanonicalName On + +# +# TypesConfig describes where the mime.types file (or equivalent) is +# to be found. +# +# Configured from the httpd command line for WebKit layout tests. +# +#<IfModule mod_mime.c> +# TypesConfig /private/etc/httpd/mime.types +#</IfModule> + +# +# DefaultType is the default MIME type the server will use for a document +# if it cannot otherwise determine one, such as from filename extensions. +# If your server contains mostly text or HTML documents, "text/plain" is +# a good value. If most of your content is binary, such as applications +# or images, you may want to use "application/octet-stream" instead to +# keep browsers from trying to display binary files as though they are +# text. +# +DefaultType text/plain + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a <VirtualHost> +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a <VirtualHost> +# container, that host's errors will be logged there and not here. +# +# Configured from the httpd command line for WebKit layout tests. +#ErrorLog "/tmp/layout-test-results/error_log" + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + +# +# The following directives define some format nicknames for use with +# a CustomLog directive (see below). +# +LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%p %h %l %u %t \"%r\" %>s %b" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# +# The location and format of the access logfile (Common Logfile Format). +# If you do not define any access logfiles within a <VirtualHost> +# container, they will be logged here. Contrariwise, if you *do* +# define per-<VirtualHost> access logfiles, transactions will be +# logged therein and *not* in this file. +# +# Configured from the httpd command line for WebKit layout tests. +#CustomLog "/tmp/layout-test-results/access_log" common + +# +# If you prefer a single logfile with access, agent, and referer information +# (Combined Logfile Format) you can use the following directive. +# +#CustomLog "/tmp/layout-test-results/access_log" combined + +# +# Optionally add a line containing the server version and virtual host +# name to server-generated pages (error documents, FTP directory listings, +# mod_status and mod_info output etc., but not CGI generated documents). +# Set to "EMail" to also include a mailto: link to the ServerAdmin. +# Set to one of: On | Off | EMail +# +ServerSignature On + +# +# Aliases: Add here as many aliases as you need (with no limit). The format is +# Alias fakename realname +# +<IfModule mod_alias.c> +</IfModule> +# End of aliases. + +# +# Redirect allows you to tell clients about documents which used to exist in +# your server's namespace, but do not anymore. This allows you to tell the +# clients where to look for the relocated document. +# Format: Redirect old-URI new-URL +# + +# +# Document types. +# +<IfModule mod_mime.c> + + # + # AddLanguage allows you to specify the language of a document. You can + # then use content negotiation to give a browser a file in a language + # it can understand. + # + # Note 1: The suffix does not have to be the same as the language + # keyword --- those with documents in Polish (whose net-standard + # language code is pl) may wish to use "AddLanguage pl .po" to + # avoid the ambiguity with the common suffix for perl scripts. + # + # Note 2: The example entries below illustrate that in quite + # some cases the two character 'Language' abbreviation is not + # identical to the two character 'Country' code for its country, + # E.g. 'Danmark/dk' versus 'Danish/da'. + # + # Note 3: In the case of 'ltz' we violate the RFC by using a three char + # specifier. But there is 'work in progress' to fix this and get + # the reference data for rfc1766 cleaned up. + # + # Danish (da) - Dutch (nl) - English (en) - Estonian (ee) + # French (fr) - German (de) - Greek-Modern (el) + # Italian (it) - Korean (kr) - Norwegian (no) - Norwegian Nynorsk (nn) + # Portugese (pt) - Luxembourgeois* (ltz) + # Spanish (es) - Swedish (sv) - Catalan (ca) - Czech(cs) + # Polish (pl) - Brazilian Portuguese (pt-br) - Japanese (ja) + # Russian (ru) + # + AddLanguage da .dk + AddLanguage nl .nl + AddLanguage en .en + AddLanguage et .ee + AddLanguage fr .fr + AddLanguage de .de + AddLanguage el .el + AddLanguage he .he + AddCharset ISO-8859-8 .iso8859-8 + AddLanguage it .it + AddLanguage ja .ja + AddCharset ISO-2022-JP .jis + AddLanguage kr .kr + AddCharset ISO-2022-KR .iso-kr + AddLanguage nn .nn + AddLanguage no .no + AddLanguage pl .po + AddCharset ISO-8859-2 .iso-pl + AddLanguage pt .pt + AddLanguage pt-br .pt-br + AddLanguage ltz .lu + AddLanguage ca .ca + AddLanguage es .es + AddLanguage sv .sv + AddLanguage cs .cz .cs + AddLanguage ru .ru + AddLanguage zh-TW .zh-tw + AddCharset Big5 .Big5 .big5 + AddCharset WINDOWS-1251 .cp-1251 + AddCharset CP866 .cp866 + AddCharset ISO-8859-5 .iso-ru + AddCharset KOI8-R .koi8-r + AddCharset UCS-2 .ucs2 + AddCharset UCS-4 .ucs4 + AddCharset UTF-8 .utf8 + + # LanguagePriority allows you to give precedence to some languages + # in case of a tie during content negotiation. + # + # Just list the languages in decreasing order of preference. We have + # more or less alphabetized them here. You probably want to change this. + # + <IfModule mod_negotiation.c> + LanguagePriority en da nl et fr de el it ja kr no pl pt pt-br ru ltz ca es sv tw + </IfModule> + + # + # AddType allows you to tweak mime.types without actually editing it, or to + # make certain files to be certain types. + # + AddType application/x-tar .tgz + + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # Despite the name similarity, the following Add* directives have nothing + # to do with the FancyIndexing customization directives above. + # + AddEncoding x-compress .Z + AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + #AddType application/x-compress .Z + #AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers", + # actions unrelated to filetype. These can be either built into the server + # or added with the Action command (see below) + # + # If you want to use server side includes, or CGI outside + # ScriptAliased directories, uncomment the following lines. + # + # To use CGI scripts: + # + AddHandler cgi-script .cgi .pl + + # + # To use server-parsed HTML files + # + AddType text/html .shtml + AddHandler server-parsed .shtml + + # + # Uncomment the following line to enable Apache's send-asis HTTP file + # feature + # + AddHandler send-as-is asis + + # + # If you wish to use server-parsed imagemap files, use + # + #AddHandler imap-file map + + # + # To enable type maps, you might want to use + # + #AddHandler type-map var + +</IfModule> +# End of document types. + +# +# Action lets you define media types that will execute a script whenever +# a matching file is called. This eliminates the need for repeated URL +# pathnames for oft-used CGI file processors. +# Format: Action media/type /cgi-script/location +# Format: Action handler-name /cgi-script/location +# + +# +# MetaDir: specifies the name of the directory in which Apache can find +# meta information files. These files contain additional HTTP headers +# to include when sending the document +# +#MetaDir .web + +# +# MetaSuffix: specifies the file name suffix for the file containing the +# meta information. +# +#MetaSuffix .meta + +# +# Customizable error response (Apache style) +# these come in three flavors +# +# 1) plain text +#ErrorDocument 500 "The server made a boo boo. +# n.b. the single leading (") marks it as text, it does not get output +# +# 2) local redirects +#ErrorDocument 404 /missing.html +# to redirect to local URL /missing.html +#ErrorDocument 404 /cgi-bin/missing_handler.pl +# N.B.: You can redirect to a script or a document using server-side-includes. +# +# 3) external redirects +#ErrorDocument 402 http://some.other-server.com/subscription_info.html +# N.B.: Many of the environment variables associated with the original +# request will *not* be available to such a script. + +# +# Proxy Server directives. Uncomment the following lines to +# enable the proxy server: +# +#<IfModule mod_proxy.c> +# ProxyRequests On + +# <Directory proxy:*> +# Order deny,allow +# Deny from all +# Allow from .your-domain.com +# </Directory> + + # + # Enable/disable the handling of HTTP/1.1 "Via:" headers. + # ("Full" adds the server version; "Block" removes all outgoing Via: headers) + # Set to one of: Off | On | Full | Block + # +# ProxyVia On + + # + # To enable the cache as well, edit and uncomment the following lines: + # (no cacheing without CacheRoot) + # +# CacheRoot "/private/var/run/proxy" +# CacheSize 5 +# CacheGcInterval 4 +# CacheMaxExpire 24 +# CacheLastModifiedFactor 0.1 +# CacheDefaultExpire 1 +# NoCache a-domain.com another-domain.edu joes.garage-sale.com + +#</IfModule> +# End of proxy directives. + + +<IfModule mod_php4.c> + # If php is turned on, we repsect .php and .phps files. + AddType application/x-httpd-php .php + AddType application/x-httpd-php-source .phps + + # Since most users will want index.php to work we + # also automatically enable index.php + <IfModule mod_dir.c> + DirectoryIndex index.html index.php + </IfModule> +</IfModule> + +<IfModule mod_rewrite.c> + RewriteEngine On + RewriteCond %{REQUEST_METHOD} ^TRACE + RewriteRule .* - [F] +</IfModule> diff --git a/tools/python/google/httpd_config/httpd2.conf b/tools/python/google/httpd_config/httpd2.conf new file mode 100644 index 0000000..8c96f75 --- /dev/null +++ b/tools/python/google/httpd_config/httpd2.conf @@ -0,0 +1,280 @@ +## httpd2.conf -- Apache 2.x HTTP server configuration file + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the <VirtualHost> +# directive. +# +Listen 127.0.0.1:8000 +Listen 127.0.0.1:8080 +Listen 127.0.0.1:8081 +Listen 127.0.0.1:8443 +Listen 127.0.0.1:9000 +Listen 127.0.0.1:9080 +Listen 127.0.0.1:9443 + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Please read the file http://httpd.apache.org/docs/dso.html for more +# details about the DSO mechanism and run `httpd -l' for the list of already +# built-in (statically linked and thus always available) modules in your httpd +# binary. +# +# Note: The order in which modules are loaded is important. Don't change +# the order below without expert advice. +# +#LoadModule authn_file_module lib/apache2/mod_authn_file.so +#LoadModule authn_dbm_module lib/apache2/mod_authn_dbm.so +#LoadModule authn_anon_module lib/apache2/mod_authn_anon.so +#LoadModule authn_dbd_module lib/apache2/mod_authn_dbd.so +#LoadModule authn_default_module lib/apache2/mod_authn_default.so +LoadModule authz_host_module lib/apache2/mod_authz_host.so +#LoadModule authz_groupfile_module lib/apache2/mod_authz_groupfile.so +#LoadModule authz_user_module lib/apache2/mod_authz_user.so +#LoadModule authz_dbm_module lib/apache2/mod_authz_dbm.so +#LoadModule authz_owner_module lib/apache2/mod_authz_owner.so +#LoadModule authz_default_module lib/apache2/mod_authz_default.so +#LoadModule auth_basic_module lib/apache2/mod_auth_basic.so +#LoadModule auth_digest_module lib/apache2/mod_auth_digest.so +#LoadModule dbd_module lib/apache2/mod_dbd.so +#LoadModule dumpio_module lib/apache2/mod_dumpio.so +#LoadModule ext_filter_module lib/apache2/mod_ext_filter.so +LoadModule include_module lib/apache2/mod_include.so +#LoadModule filter_module lib/apache2/mod_filter.so +#LoadModule deflate_module lib/apache2/mod_deflate.so +LoadModule log_config_module lib/apache2/mod_log_config.so +#LoadModule log_forensic_module lib/apache2/mod_log_forensic.so +#LoadModule logio_module lib/apache2/mod_logio.so +#LoadModule env_module lib/apache2/mod_env.so +#LoadModule mime_magic_module lib/apache2/mod_mime_magic.so +#LoadModule cern_meta_module lib/apache2/mod_cern_meta.so +#LoadModule expires_module lib/apache2/mod_expires.so +LoadModule headers_module lib/apache2/mod_headers.so +#LoadModule ident_module lib/apache2/mod_ident.so +#LoadModule usertrack_module lib/apache2/mod_usertrack.so +#LoadModule unique_id_module lib/apache2/mod_unique_id.so +#LoadModule setenvif_module lib/apache2/mod_setenvif.so +#LoadModule version_module lib/apache2/mod_version.so +#LoadModule proxy_module lib/apache2/mod_proxy.so +#LoadModule proxy_connect_module lib/apache2/mod_proxy_connect.so +#LoadModule proxy_ftp_module lib/apache2/mod_proxy_ftp.so +#LoadModule proxy_http_module lib/apache2/mod_proxy_http.so +#LoadModule proxy_ajp_module lib/apache2/mod_proxy_ajp.so +#LoadModule proxy_balancer_module lib/apache2/mod_proxy_balancer.so +LoadModule ssl_module lib/apache2/mod_ssl.so +LoadModule mime_module lib/apache2/mod_mime.so +#LoadModule dav_module lib/apache2/mod_dav.so +#LoadModule status_module lib/apache2/mod_status.so +LoadModule autoindex_module lib/apache2/mod_autoindex.so +LoadModule asis_module lib/apache2/mod_asis.so +#LoadModule info_module lib/apache2/mod_info.so +LoadModule cgi_module lib/apache2/mod_cgi.so +#LoadModule dav_fs_module lib/apache2/mod_dav_fs.so +#LoadModule vhost_alias_module lib/apache2/mod_vhost_alias.so +LoadModule negotiation_module lib/apache2/mod_negotiation.so +#LoadModule dir_module lib/apache2/mod_dir.so +LoadModule imagemap_module lib/apache2/mod_imagemap.so +LoadModule actions_module lib/apache2/mod_actions.so +#LoadModule speling_module lib/apache2/mod_speling.so +#LoadModule userdir_module lib/apache2/mod_userdir.so +LoadModule alias_module lib/apache2/mod_alias.so +LoadModule rewrite_module lib/apache2/mod_rewrite.so +LoadModule php5_module lib/apache2/cygphp5.so + +#LoadModule imap_module lib/apache/mod_imap.dll +#LoadModule access_module lib/apache/mod_access.dll +#LoadModule auth_module lib/apache/mod_auth.dll + + +# +# Each directory to which Apache has access, can be configured with respect +# to which services and features are allowed and/or disabled in that +# directory (and its subdirectories). +# +<Directory /> + Options Indexes FollowSymLinks MultiViews ExecCGI Includes + AllowOverride All + Order allow,deny + Allow from all +</Directory> + + +# +# Apple specific filesystem protection. +# +<Files "rsrc"> + Order allow,deny + Deny from all + Satisfy All +</Files> +<Directory ~ ".*\.\.namedfork"> + Order allow,deny + Deny from all + Satisfy All +</Directory> + + +# +# UseCanonicalName: (new for 1.3) With this setting turned on, whenever +# Apache needs to construct a self-referencing URL (a URL that refers back +# to the server the response is coming from) it will use ServerName and +# Port to form a "canonical" name. With this setting off, Apache will +# use the hostname:port that the client supplied, when possible. This +# also affects SERVER_NAME and SERVER_PORT in CGI scripts. +# +UseCanonicalName On + + +# +# The following directives define some format nicknames for use with +# a CustomLog directive (see below). +# +LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %b" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + + +# +# Optionally add a line containing the server version and virtual host +# name to server-generated pages (error documents, FTP directory listings, +# mod_status and mod_info output etc., but not CGI generated documents). +# Set to "EMail" to also include a mailto: link to the ServerAdmin. +# Set to one of: On | Off | EMail +# +ServerSignature On + + +# +# Document types. +# +<IfModule mime_module> + + # + # AddLanguage allows you to specify the language of a document. You can + # then use content negotiation to give a browser a file in a language + # it can understand. + # + # Note 1: The suffix does not have to be the same as the language + # keyword --- those with documents in Polish (whose net-standard + # language code is pl) may wish to use "AddLanguage pl .po" to + # avoid the ambiguity with the common suffix for perl scripts. + # + # Note 2: The example entries below illustrate that in quite + # some cases the two character 'Language' abbreviation is not + # identical to the two character 'Country' code for its country, + # E.g. 'Danmark/dk' versus 'Danish/da'. + # + # Note 3: In the case of 'ltz' we violate the RFC by using a three char + # specifier. But there is 'work in progress' to fix this and get + # the reference data for rfc1766 cleaned up. + # + # Danish (da) - Dutch (nl) - English (en) - Estonian (ee) + # French (fr) - German (de) - Greek-Modern (el) + # Italian (it) - Korean (kr) - Norwegian (no) - Norwegian Nynorsk (nn) + # Portugese (pt) - Luxembourgeois* (ltz) + # Spanish (es) - Swedish (sv) - Catalan (ca) - Czech(cs) + # Polish (pl) - Brazilian Portuguese (pt-br) - Japanese (ja) + # Russian (ru) + # + AddLanguage da .dk + AddLanguage nl .nl + AddLanguage en .en + AddLanguage et .ee + AddLanguage fr .fr + AddLanguage de .de + AddLanguage el .el + AddLanguage he .he + AddCharset ISO-8859-8 .iso8859-8 + AddLanguage it .it + AddLanguage ja .ja + AddCharset ISO-2022-JP .jis + AddLanguage kr .kr + AddCharset ISO-2022-KR .iso-kr + AddLanguage nn .nn + AddLanguage no .no + AddLanguage pl .po + AddCharset ISO-8859-2 .iso-pl + AddLanguage pt .pt + AddLanguage pt-br .pt-br + AddLanguage ltz .lu + AddLanguage ca .ca + AddLanguage es .es + AddLanguage sv .sv + AddLanguage cs .cz .cs + AddLanguage ru .ru + AddLanguage zh-TW .zh-tw + AddCharset Big5 .Big5 .big5 + AddCharset WINDOWS-1251 .cp-1251 + AddCharset CP866 .cp866 + AddCharset ISO-8859-5 .iso-ru + AddCharset KOI8-R .koi8-r + AddCharset UCS-2 .ucs2 + AddCharset UCS-4 .ucs4 + AddCharset UTF-8 .utf8 + + # LanguagePriority allows you to give precedence to some languages + # in case of a tie during content negotiation. + # + # Just list the languages in decreasing order of preference. We have + # more or less alphabetized them here. You probably want to change this. + # + <IfModule negotiation_module> + LanguagePriority en da nl et fr de el it ja kr no pl pt pt-br ru ltz ca es sv tw + </IfModule> + + # + # AddType allows you to tweak mime.types without actually editing it, or to + # make certain files to be certain types. + # + AddType application/x-tar .tgz + + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # Despite the name similarity, the following Add* directives have nothing + # to do with the FancyIndexing customization directives above. + # + AddEncoding x-compress .Z + AddEncoding x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers", + # actions unrelated to filetype. These can be either built into the server + # or added with the Action command (see below) + # + # If you want to use server side includes, or CGI outside + # ScriptAliased directories, uncomment the following lines. + # + # To use CGI scripts: + # + AddHandler cgi-script .cgi .pl + + # + # To use server-parsed HTML files + # + AddType text/html .shtml + AddHandler server-parsed .shtml + + # + # Uncomment the following line to enable Apache's send-asis HTTP file + # feature + # + AddHandler send-as-is asis +</IfModule> + + +<IfModule php5_module> + AddType application/x-httpd-php .php + AddType application/x-httpd-php-source .phps +</IfModule> + +<IfModule rewrite_module> + RewriteEngine On + RewriteCond %{REQUEST_METHOD} ^TRACE + RewriteRule .* - [F] +</IfModule> diff --git a/tools/python/google/httpd_config/httpd2.pem b/tools/python/google/httpd_config/httpd2.pem new file mode 100644 index 0000000..1ad5794 --- /dev/null +++ b/tools/python/google/httpd_config/httpd2.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE-----
+MIIDazCCAtSgAwIBAgIBEDANBgkqhkiG9w0BAQUFADByMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIG
+A1UEChMLR29vZ2xlIEluYy4xIDAeBgNVBAMTF2F0dGljdXMuY29ycC5nb29nbGUu
+Y29tMB4XDTA2MDEwMTAwMDAwMFoXDTIwMDEwMTAwMDAwMFowTDELMAkGA1UEBhMC
+VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAoTC0dvb2dsZSBJbmMuMRIw
+EAYDVQQDEwkxMjcuMC4wLjEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK0I
+45wdTT2/fui9FfNOR17idQF0L/kpn88D1OzF0w0h3TMBN8szpOxAQYT2MTuB17Dt
+ttMiwzLuoByP7KipmeKy63GFlV7dHS2XEirzP23c/RxZ/7W9UQ/VmgSvXjNzIXyu
+t+Ylfeg6VfFANsPQmov3SIO1Zh3NQRS/d+M5ig7lAgMBAAGjggE1MIIBMTAJBgNV
+HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZp
+Y2F0ZTAdBgNVHQ4EFgQU6n4XBAZRnkrXMlko23vCClLlztEwgY4GA1UdIwSBhjCB
+g6F2pHQwcjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNV
+BAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC0dvb2dsZSBJbmMuMSAwHgYDVQQD
+ExdhdHRpY3VzLmNvcnAuZ29vZ2xlLmNvbYIJAKGvvYc2FdhzMEYGA1UdHwQ/MD0w
+O6A5oDeGNWh0dHA6Ly9jaHJvbWV0d3MuY29ycC5nb29nbGUuY29tOjgwODAvY3Js
+L2F0dGljdXMuY3JsMA0GCSqGSIb3DQEBBQUAA4GBAHt8Zxf4D86QBuWkP2STN4Pg
+aLzut1eaY0u5DOxr3fqrwbaDlPJrJJqQJmMPwUItVMjw+zWO/CmoBY7vsJMcX/57
++kIHoQ+XCQJdOnM7qa3Hslt4bLRx+d0zQqt6/+gBNrz5F36njgansvxjnnacbApv
+uNQFNT5wCAqRadGn4d63
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCtCOOcHU09v37ovRXzTkde4nUBdC/5KZ/PA9TsxdMNId0zATfL
+M6TsQEGE9jE7gdew7bbTIsMy7qAcj+yoqZnisutxhZVe3R0tlxIq8z9t3P0cWf+1
+vVEP1ZoEr14zcyF8rrfmJX3oOlXxQDbD0JqL90iDtWYdzUEUv3fjOYoO5QIDAQAB
+AoGALSNMfMUICTuTF5N7zmR1KcNZUm/Es/KvxYjyWnGghKR4131R2Kg4NYjtjonK
+fgN5CKZ6Msm2seqdydWhnr3fbl3KhPF7nTdFUR6OM4eUuUH3nV1DS1w9AW0Z/4nB
+3OipLkxvTtRomfEUoZdE3I4+2T9iBdfPGduZ3CNR1H9EL2ECQQDfyT3dOVg5Zr7Q
+gZ8rQhyxtA+OhWvqU9F5Ahii002fIMj//rMIowvGesW2rfMwYs/oFF36l2vXOhvh
+whL+hmJ/AkEAxfFnlp8hT3WeRqJ74b3QSkyItWz7XbSQRPFWurPEfNI8wz57Svvy
+8tv396X8yImPwxXhihjSn9bwSHoon0WUmwJBAMt2S1HUblsaCEjIYS/SVwZWIILC
+2Z/d/yiW+FEp7nvMMhNVve8PVohpXVM/CkkmvcJSqjNI8ppnUaxLaDuTcP8CQQCn
+40L7K+ky3g3q1zG/nCEog5WIW/Ev31BmSVRIcuT7Ac5rw3kLdnrvpcbCE9U9uf9n
+dg2f9cHftIyEzKfbv0Z1AkAlX4x7De9edylrZ14IA9BbEe0ztsCik3UGXYriYfwY
+Z9h+uyhqNJT+SaWjb1QcBQ8jbYC0d2zxQSMuf8NxYrd2
+-----END RSA PRIVATE KEY-----
diff --git a/tools/python/google/httpd_config/mime.types b/tools/python/google/httpd_config/mime.types new file mode 100644 index 0000000..6735f1b --- /dev/null +++ b/tools/python/google/httpd_config/mime.types @@ -0,0 +1,599 @@ +# This is a comment. I love comments. + +# This file controls what Internet media types are sent to the client for +# given file extension(s). Sending the correct media type to the client +# is important so they know how to handle the content of the file. +# Extra types can either be added here or by using an AddType directive +# in your config files. For more information about Internet media types, +# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type +# registry is at <http://www.iana.org/assignments/media-types/>. + +# MIME type Extensions +application/activemessage +application/andrew-inset ez +application/applefile +application/atom+xml atom +application/atomicmail +application/batch-smtp +application/beep+xml +application/cals-1840 +application/cnrp+xml +application/commonground +application/cpl+xml +application/cybercash +application/dca-rft +application/dec-dx +application/dvcs +application/edi-consent +application/edifact +application/edi-x12 +application/eshop +application/font-tdpfr +application/http +application/hyperstudio +application/iges +application/index +application/index.cmd +application/index.obj +application/index.response +application/index.vnd +application/iotp +application/ipp +application/isup +application/mac-binhex40 hqx +application/mac-compactpro cpt +application/macwriteii +application/marc +application/mathematica +application/mathml+xml mathml +application/msword doc +application/news-message-id +application/news-transmission +application/ocsp-request +application/ocsp-response +application/octet-stream bin dms lha lzh exe class so dll dmg +application/oda oda +application/ogg ogg +application/parityfec +application/pdf pdf +application/pgp-encrypted +application/pgp-keys +application/pgp-signature +application/pkcs10 +application/pkcs7-mime +application/pkcs7-signature +application/pkix-cert +application/pkix-crl +application/pkixcmp +application/postscript ai eps ps +application/prs.alvestrand.titrax-sheet +application/prs.cww +application/prs.nprend +application/prs.plucker +application/qsig +application/rdf+xml rdf +application/reginfo+xml +application/remote-printing +application/riscos +application/rtf +application/sdp +application/set-payment +application/set-payment-initiation +application/set-registration +application/set-registration-initiation +application/sgml +application/sgml-open-catalog +application/sieve +application/slate +application/smil smi smil +application/srgs gram +application/srgs+xml grxml +application/timestamp-query +application/timestamp-reply +application/tve-trigger +application/vemmi +application/vnd.3gpp.pic-bw-large +application/vnd.3gpp.pic-bw-small +application/vnd.3gpp.pic-bw-var +application/vnd.3gpp.sms +application/vnd.3m.post-it-notes +application/vnd.accpac.simply.aso +application/vnd.accpac.simply.imp +application/vnd.acucobol +application/vnd.acucorp +application/vnd.adobe.xfdf +application/vnd.aether.imp +application/vnd.amiga.ami +application/vnd.anser-web-certificate-issue-initiation +application/vnd.anser-web-funds-transfer-initiation +application/vnd.audiograph +application/vnd.blueice.multipass +application/vnd.bmi +application/vnd.businessobjects +application/vnd.canon-cpdl +application/vnd.canon-lips +application/vnd.cinderella +application/vnd.claymore +application/vnd.commerce-battelle +application/vnd.commonspace +application/vnd.contact.cmsg +application/vnd.cosmocaller +application/vnd.criticaltools.wbs+xml +application/vnd.ctc-posml +application/vnd.cups-postscript +application/vnd.cups-raster +application/vnd.cups-raw +application/vnd.curl +application/vnd.cybank +application/vnd.data-vision.rdz +application/vnd.dna +application/vnd.dpgraph +application/vnd.dreamfactory +application/vnd.dxr +application/vnd.ecdis-update +application/vnd.ecowin.chart +application/vnd.ecowin.filerequest +application/vnd.ecowin.fileupdate +application/vnd.ecowin.series +application/vnd.ecowin.seriesrequest +application/vnd.ecowin.seriesupdate +application/vnd.enliven +application/vnd.epson.esf +application/vnd.epson.msf +application/vnd.epson.quickanime +application/vnd.epson.salt +application/vnd.epson.ssf +application/vnd.ericsson.quickcall +application/vnd.eudora.data +application/vnd.fdf +application/vnd.ffsns +application/vnd.fints +application/vnd.flographit +application/vnd.framemaker +application/vnd.fsc.weblaunch +application/vnd.fujitsu.oasys +application/vnd.fujitsu.oasys2 +application/vnd.fujitsu.oasys3 +application/vnd.fujitsu.oasysgp +application/vnd.fujitsu.oasysprs +application/vnd.fujixerox.ddd +application/vnd.fujixerox.docuworks +application/vnd.fujixerox.docuworks.binder +application/vnd.fut-misnet +application/vnd.grafeq +application/vnd.groove-account +application/vnd.groove-help +application/vnd.groove-identity-message +application/vnd.groove-injector +application/vnd.groove-tool-message +application/vnd.groove-tool-template +application/vnd.groove-vcard +application/vnd.hbci +application/vnd.hhe.lesson-player +application/vnd.hp-hpgl +application/vnd.hp-hpid +application/vnd.hp-hps +application/vnd.hp-pcl +application/vnd.hp-pclxl +application/vnd.httphone +application/vnd.hzn-3d-crossword +application/vnd.ibm.afplinedata +application/vnd.ibm.electronic-media +application/vnd.ibm.minipay +application/vnd.ibm.modcap +application/vnd.ibm.rights-management +application/vnd.ibm.secure-container +application/vnd.informix-visionary +application/vnd.intercon.formnet +application/vnd.intertrust.digibox +application/vnd.intertrust.nncp +application/vnd.intu.qbo +application/vnd.intu.qfx +application/vnd.irepository.package+xml +application/vnd.is-xpr +application/vnd.japannet-directory-service +application/vnd.japannet-jpnstore-wakeup +application/vnd.japannet-payment-wakeup +application/vnd.japannet-registration +application/vnd.japannet-registration-wakeup +application/vnd.japannet-setstore-wakeup +application/vnd.japannet-verification +application/vnd.japannet-verification-wakeup +application/vnd.jisp +application/vnd.kde.karbon +application/vnd.kde.kchart +application/vnd.kde.kformula +application/vnd.kde.kivio +application/vnd.kde.kontour +application/vnd.kde.kpresenter +application/vnd.kde.kspread +application/vnd.kde.kword +application/vnd.kenameaapp +application/vnd.koan +application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop +application/vnd.llamagraphics.life-balance.exchange+xml +application/vnd.lotus-1-2-3 +application/vnd.lotus-approach +application/vnd.lotus-freelance +application/vnd.lotus-notes +application/vnd.lotus-organizer +application/vnd.lotus-screencam +application/vnd.lotus-wordpro +application/vnd.mcd +application/vnd.mediastation.cdkey +application/vnd.meridian-slingshot +application/vnd.micrografx.flo +application/vnd.micrografx.igx +application/vnd.mif mif +application/vnd.minisoft-hp3000-save +application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf +application/vnd.mobius.dis +application/vnd.mobius.mbk +application/vnd.mobius.mqy +application/vnd.mobius.msl +application/vnd.mobius.plc +application/vnd.mobius.txf +application/vnd.mophun.application +application/vnd.mophun.certificate +application/vnd.motorola.flexsuite +application/vnd.motorola.flexsuite.adsi +application/vnd.motorola.flexsuite.fis +application/vnd.motorola.flexsuite.gotap +application/vnd.motorola.flexsuite.kmr +application/vnd.motorola.flexsuite.ttc +application/vnd.motorola.flexsuite.wem +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry +application/vnd.ms-asf +application/vnd.ms-excel xls +application/vnd.ms-lrm +application/vnd.ms-powerpoint ppt +application/vnd.ms-project +application/vnd.ms-tnef +application/vnd.ms-works +application/vnd.ms-wpl +application/vnd.mseq +application/vnd.msign +application/vnd.music-niff +application/vnd.musician +application/vnd.netfpx +application/vnd.noblenet-directory +application/vnd.noblenet-sealer +application/vnd.noblenet-web +application/vnd.novadigm.edm +application/vnd.novadigm.edx +application/vnd.novadigm.ext +application/vnd.obn +application/vnd.osa.netdeploy +application/vnd.palm +application/vnd.pg.format +application/vnd.pg.osasli +application/vnd.powerbuilder6 +application/vnd.powerbuilder6-s +application/vnd.powerbuilder7 +application/vnd.powerbuilder7-s +application/vnd.powerbuilder75 +application/vnd.powerbuilder75-s +application/vnd.previewsystems.box +application/vnd.publishare-delta-tree +application/vnd.pvi.ptid1 +application/vnd.pwg-multiplexed +application/vnd.pwg-xhtml-print+xml +application/vnd.quark.quarkxpress +application/vnd.rapid +application/vnd.rn-realmedia rm +application/vnd.s3sms +application/vnd.sealed.net +application/vnd.seemail +application/vnd.shana.informed.formdata +application/vnd.shana.informed.formtemplate +application/vnd.shana.informed.interchange +application/vnd.shana.informed.package +application/vnd.smaf +application/vnd.sss-cod +application/vnd.sss-dtf +application/vnd.sss-ntf +application/vnd.street-stream +application/vnd.svd +application/vnd.swiftview-ics +application/vnd.triscape.mxs +application/vnd.trueapp +application/vnd.truedoc +application/vnd.ufdl +application/vnd.uplanet.alert +application/vnd.uplanet.alert-wbxml +application/vnd.uplanet.bearer-choice +application/vnd.uplanet.bearer-choice-wbxml +application/vnd.uplanet.cacheop +application/vnd.uplanet.cacheop-wbxml +application/vnd.uplanet.channel +application/vnd.uplanet.channel-wbxml +application/vnd.uplanet.list +application/vnd.uplanet.list-wbxml +application/vnd.uplanet.listcmd +application/vnd.uplanet.listcmd-wbxml +application/vnd.uplanet.signal +application/vnd.vcx +application/vnd.vectorworks +application/vnd.vidsoft.vidconference +application/vnd.visio +application/vnd.visionary +application/vnd.vividence.scriptfile +application/vnd.vsf +application/vnd.wap.sic +application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo +application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf +application/vnd.wv.csp+wbxml +application/vnd.xara +application/vnd.xfdl +application/vnd.yamaha.hv-dic +application/vnd.yamaha.hv-script +application/vnd.yamaha.hv-voice +application/vnd.yellowriver-custom-menu +application/voicexml+xml vxml +application/watcherinfo+xml +application/whoispp-query +application/whoispp-response +application/wita +application/wordperfect5.1 +application/x-bcpio bcpio +application/x-cdlink vcd +application/x-chess-pgn pgn +application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-director dcr dir dxr +application/x-dvi dvi +application/x-futuresplash spl +application/x-gtar gtar +application/x-gzip +application/x-hdf hdf +application/x-javascript js +application/x-java-jnlp-file jnlp +application/x-koan skp skd skt skm +application/x-latex latex +application/x-netcdf nc cdf +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-stuffit sit +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-texinfo texinfo texi +application/x-troff t tr roff +application/x-troff-man man +application/x-troff-me me +application/x-troff-ms ms +application/x-ustar ustar +application/x-wais-source src +application/x400-bp +application/xhtml+xml xhtml xht +application/xslt+xml xslt +application/xml xml xsl +application/xml-dtd dtd +application/xml-external-parsed-entity +application/zip zip +audio/32kadpcm +audio/amr +audio/amr-wb +audio/basic au snd +audio/cn +audio/dat12 +audio/dsr-es201108 +audio/dvi4 +audio/evrc +audio/evrc0 +audio/g722 +audio/g.722.1 +audio/g723 +audio/g726-16 +audio/g726-24 +audio/g726-32 +audio/g726-40 +audio/g728 +audio/g729 +audio/g729D +audio/g729E +audio/gsm +audio/gsm-efr +audio/l8 +audio/l16 +audio/l20 +audio/l24 +audio/lpc +audio/midi mid midi kar +audio/mpa +audio/mpa-robust +audio/mp4a-latm m4a m4p +audio/mpeg mpga mp2 mp3 +audio/parityfec +audio/pcma +audio/pcmu +audio/prs.sid +audio/qcelp +audio/red +audio/smv +audio/smv0 +audio/telephone-event +audio/tone +audio/vdvi +audio/vnd.3gpp.iufp +audio/vnd.cisco.nse +audio/vnd.cns.anp1 +audio/vnd.cns.inf1 +audio/vnd.digital-winds +audio/vnd.everad.plj +audio/vnd.lucent.voice +audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 +audio/vnd.nuera.ecelp7470 +audio/vnd.nuera.ecelp9600 +audio/vnd.octel.sbc +audio/vnd.qcelp +audio/vnd.rhetorex.32kadpcm +audio/vnd.vmx.cvsd +audio/x-aiff aif aiff aifc +audio/x-alaw-basic +audio/x-mpegurl m3u +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin +audio/x-wav wav +chemical/x-pdb pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +image/g3fax +image/gif gif +image/ief ief +image/jpeg jpeg jpg jpe +image/jp2 jp2 +image/naplps +image/pict pict pic pct +image/png png +image/prs.btif +image/prs.pti +image/svg+xml svg +image/t38 +image/tiff tiff tif +image/tiff-fx +image/vnd.cns.inf2 +image/vnd.djvu djvu djv +image/vnd.dwg +image/vnd.dxf +image/vnd.fastbidsheet +image/vnd.fpx +image/vnd.fst +image/vnd.fujixerox.edmics-mmr +image/vnd.fujixerox.edmics-rlc +image/vnd.globalgraphics.pgb +image/vnd.mix +image/vnd.ms-modi +image/vnd.net-fpx +image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff +image/x-cmu-raster ras +image/x-macpaint pntg pnt mac +image/x-icon ico +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-quicktime qtif qti +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +message/delivery-status +message/disposition-notification +message/external-body +message/http +message/news +message/partial +message/rfc822 +message/s-http +message/sip +message/sipfrag +model/iges igs iges +model/mesh msh mesh silo +model/vnd.dwf +model/vnd.flatland.3dml +model/vnd.gdl +model/vnd.gs-gdl +model/vnd.gtw +model/vnd.mts +model/vnd.parasolid.transmit.binary +model/vnd.parasolid.transmit.text +model/vnd.vtu +model/vrml wrl vrml +multipart/alternative +multipart/appledouble +multipart/byteranges +multipart/digest +multipart/encrypted +multipart/form-data +multipart/header-set +multipart/mixed +multipart/parallel +multipart/related +multipart/report +multipart/signed +multipart/voice-message +text/calendar ics ifb +text/css css +text/directory +text/enriched +text/html html htm +text/parityfec +text/plain asc txt +text/prs.lines.tag +text/rfc822-headers +text/richtext rtx +text/rtf rtf +text/sgml sgml sgm +text/t140 +text/tab-separated-values tsv +text/uri-list +text/vnd.abc +text/vnd.curl +text/vnd.dmclientscript +text/vnd.fly +text/vnd.fmi.flexstor +text/vnd.in3d.3dml +text/vnd.in3d.spot +text/vnd.iptc.nitf +text/vnd.iptc.newsml +text/vnd.latex-z +text/vnd.motorola.reflex +text/vnd.ms-mediapackage +text/vnd.net2phone.commcenter.command +text/vnd.sun.j2me.app-descriptor +text/vnd.wap.si +text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-setext etx +text/xml +text/xml-external-parsed-entity +video/bmpeg +video/bt656 +video/celb +video/dv +video/h261 +video/h263 +video/h263-1998 +video/h263-2000 +video/jpeg +video/mp1s +video/mp2p +video/mp2t +video/mp4 mp4 +video/mp4v-es +video/mpv +video/mpeg mpeg mpg mpe +video/nv +video/parityfec +video/pointer +video/quicktime qt mov +video/smpte292m +video/vnd.fvt +video/vnd.motorola.video +video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.nokia.interleaved-multimedia +video/vnd.objectvideo +video/vnd.vivo +video/x-dv dv dif +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice 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) diff --git a/tools/python/google/logging_utils.py b/tools/python/google/logging_utils.py new file mode 100644 index 0000000..cf9f3fa --- /dev/null +++ b/tools/python/google/logging_utils.py @@ -0,0 +1,110 @@ +#!/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. + +# logging_utils.py + +''' Utility functions and objects for logging. +''' + +import logging +import sys + +class StdoutStderrHandler(logging.Handler): + ''' Subclass of logging.Handler which outputs to either stdout or stderr + based on a threshold level. + ''' + + def __init__(self, threshold=logging.WARNING, err=sys.stderr, out=sys.stdout): + ''' Args: + threshold: below this logging level messages are sent to stdout, + otherwise they are sent to stderr + err: a stream object that error messages are sent to, defaults to + sys.stderr + out: a stream object that non-error messages are sent to, defaults to + sys.stdout + ''' + logging.Handler.__init__(self) + self._err = logging.StreamHandler(err) + self._out = logging.StreamHandler(out) + self._threshold = threshold + self._last_was_err = False + + def setLevel(self, lvl): + logging.Handler.setLevel(self, lvl) + self._err.setLevel(lvl) + self._out.setLevel(lvl) + + def setFormatter(self, formatter): + logging.Handler.setFormatter(self, formatter) + self._err.setFormatter(formatter) + self._out.setFormatter(formatter) + + def emit(self, record): + if record.levelno < self._threshold: + self._out.emit(record) + self._last_was_err = False + else: + self._err.emit(record) + self._last_was_err = False + + def flush(self): + # preserve order on the flushing, the stalest stream gets flushed first + if self._last_was_err: + self._out.flush() + self._err.flush() + else: + self._err.flush() + self._out.flush() + + +FORMAT = "%(asctime)s %(filename)s [%(levelname)s] %(message)s" +DATEFMT = "%H:%M:%S" + +def config_root(level=logging.INFO, threshold=logging.WARNING, format=FORMAT, + datefmt=DATEFMT): + ''' Configure the root logger to use a StdoutStderrHandler and some default + formatting. + Args: + level: messages below this level are ignored + threshold: below this logging level messages are sent to stdout, + otherwise they are sent to stderr + format: format for log messages, see logger.Format + datefmt: format for date in log messages + + ''' + # to set the handler of the root logging object, we need to do setup + # manually rather than using basicConfig + root = logging.getLogger() + root.setLevel(level) + formatter = logging.Formatter(format, datefmt) + handler = StdoutStderrHandler(threshold=threshold) + handler.setLevel(level) + handler.setFormatter(formatter) + root.addHandler(handler) diff --git a/tools/python/google/path_utils.py b/tools/python/google/path_utils.py new file mode 100644 index 0000000..0585614 --- /dev/null +++ b/tools/python/google/path_utils.py @@ -0,0 +1,109 @@ +# 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. + +"""Some utility methods for getting and manipulating paths.""" + +# TODO(pamg): Have the buildbot use these, too. + + +import errno +import os +import sys + +class PathNotFound(Exception): pass + +def ScriptDir(): + """Get the full path to the directory containing the current script.""" + script_filename = os.path.abspath(sys.argv[0]) + return os.path.dirname(script_filename) + +def FindAncestor(start_dir, ancestor): + """Finds an ancestor dir in a path. + + For example, FindAncestor('c:\foo\bar\baz', 'bar') would return + 'c:\foo\bar'. Unlike FindUpward*, this only looks at direct path ancestors. + """ + start_dir = os.path.abspath(start_dir) + path = start_dir + while True: + (parent, tail) = os.path.split(path) + if tail == ancestor: + return path + if not tail: + break + path = parent + raise PathNotFound("Unable to find ancestor %s in %s" % (ancestor, start_dir)) + +def FindUpwardParent(start_dir, *desired_list): + """Finds the desired object's parent, searching upward from the start_dir. + + Searches start_dir and all its parents looking for the desired directory + or file, which may be given in one or more path components. Returns the + first directory in which the top desired path component was found, or raises + PathNotFound if it wasn't. + """ + desired_path = os.path.join(*desired_list) + last_dir = '' + cur_dir = start_dir + found_path = os.path.join(cur_dir, desired_path) + while not os.path.exists(found_path): + last_dir = cur_dir + cur_dir = os.path.dirname(cur_dir) + if last_dir == cur_dir: + raise PathNotFound('Unable to find %s above %s' % + (desired_path, start_dir)) + found_path = os.path.join(cur_dir, desired_path) + # Strip the entire original desired path from the end of the one found + # and remove a trailing path separator, if present. + found_path = found_path[:len(found_path) - len(desired_path)] + if found_path.endswith(os.sep): + found_path = found_path[:len(found_path) - 1] + return found_path + + +def FindUpward(start_dir, *desired_list): + """Returns a path to the desired directory or file, searching upward. + + Searches start_dir and all its parents looking for the desired directory + or file, which may be given in one or more path components. Returns the full + path to the desired object, or raises PathNotFound if it wasn't found. + """ + parent = FindUpwardParent(start_dir, *desired_list) + return os.path.join(parent, *desired_list) + + +def MaybeMakeDirectory(*path): + """Creates an entire path, if it doesn't already exist.""" + file_path = os.path.join(*path) + try: + os.makedirs(file_path) + except OSError, e: + # errno.EEXIST is "File exists". If we see another error, re-raise. + if e.errno != errno.EEXIST: + raise diff --git a/tools/python/google/platform_utils.py b/tools/python/google/platform_utils.py new file mode 100644 index 0000000..1fcb182 --- /dev/null +++ b/tools/python/google/platform_utils.py @@ -0,0 +1,46 @@ +#!/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. + +"""Platform-specific utilities and pseudo-constants + +Any functions whose implementations or values differ from one platform to +another should be defined in their respective platform_utils_<platform>.py +modules. The appropriate one of those will be imported into this module to +provide callers with a common, platform-independent interface. +""" + +import sys + +# We may not support the version of Python that a user has installed (Cygwin +# especially has had problems), but we'll allow the platform utils to be +# included in any case so we don't get an import error. +if sys.platform in ('cygwin', 'win32'): + from platform_utils_win import * + diff --git a/tools/python/google/platform_utils_win.py b/tools/python/google/platform_utils_win.py new file mode 100644 index 0000000..df72e3d --- /dev/null +++ b/tools/python/google/platform_utils_win.py @@ -0,0 +1,219 @@ +# 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. +"""Platform-specific utility methods shared by several scripts.""" + +import os +import re +import subprocess +import sys + +import google.path_utils + +# Cache a single cygpath process for use throughout, even across instances of +# the PlatformUtility class. +_cygpath_proc = None + +class PlatformUtility(object): + def __init__(self, base_dir): + """Args: + base_dir: a directory above which third_party/cygwin can be found, + used to locate the cygpath executable for path conversions. + """ + self._cygwin_root = None + self._base_dir = base_dir + + def _CygwinRoot(self): + """Returns the full path to third_party/cygwin/.""" + if not self._cygwin_root: + self._cygwin_root = google.path_utils.FindUpward(self._base_dir, + 'third_party', 'cygwin') + return self._cygwin_root + + def _PathToExecutable(self, executable): + """Returns the full path to an executable in Cygwin's bin dir.""" + return os.path.join(self._CygwinRoot(), 'bin', executable) + + def GetAbsolutePath(self, path, force=False): + """Returns an absolute windows path. If platform is cygwin, converts it to + windows style using cygpath. + + For performance reasons, we use a single cygpath process, shared among all + instances of this class. Otherwise Python can run out of file handles. + """ + if not force and sys.platform != "cygwin": + return os.path.abspath(path) + global _cygpath_proc + if not _cygpath_proc: + cygpath_command = [self._PathToExecutable("cygpath.exe"), + "-a", "-m", "-f", "-"] + _cygpath_proc = subprocess.Popen(cygpath_command, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + _cygpath_proc.stdin.write(path + "\n") + return _cygpath_proc.stdout.readline().rstrip() + + def GetFilesystemRoot(self): + """Returns the root directory of the file system.""" + return os.environ['SYSTEMDRIVE'] + '\\' + + def GetTempDirectory(self): + """Returns the file system's base temp directory, or the filesystem root + if the standard temp directory can't be determined. + + Note that this does not use a random subdirectory, so it's not + intrinsically secure. If you need a secure subdir, use the tempfile + package. + """ + return os.environ.get('TEMP', self.GetFilesystemRoot()) + + def FilenameToUri(self, path, use_http=False, use_ssl=False, port=8000): + """Convert a Windows style path to a URI. + + Args: + path: For an http URI, the path relative to the httpd server's + DocumentRoot; for a file URI, the full path to the file. + use_http: if True, returns a URI of the form http://127.0.0.1:8000/. + If False, returns a file:/// URI. + use_ssl: if True, returns HTTPS URL (https://127.0.0.1:8000/). + This parameter is ignored if use_http=False. + port: The port number to append when returning an HTTP URI + """ + if use_http: + protocol = 'http' + if use_ssl: + protocol = 'https' + path = path.replace("\\", "/") + return "%s://127.0.0.1:%s/%s" % (protocol, str(port), path) + return "file:///" + self.GetAbsolutePath(path) + + def GetStartHttpdCommand(self, output_dir, + httpd_conf_path, mime_types_path, + document_root=None, apache2=False): + """Prepares the config file and output directory to start an httpd server. + Returns a list of strings containing the server's command line+args. + + Args: + output_dir: the path to the server's output directory, for log files. + It will be created if necessary. + httpd_conf_path: full path to the httpd.conf file to be used. + mime_types_path: full path to the mime.types file to be used. + document_root: full path to the DocumentRoot. If None, the DocumentRoot + from the httpd.conf file will be used. Note that the httpd.conf + file alongside this script does not specify any DocumentRoot, so if + you're using that one, be sure to specify a document_root here. + apache2: boolean if true will cause this function to return start + command for Apache 2.x as opposed to Apache 1.3.x + """ + + if document_root: + document_root = GetCygwinPath(document_root) + exe_name = "httpd" + cert_file = "" + if apache2: + exe_name = "httpd2" + cert_file = google.path_utils.FindUpward(self._base_dir, 'tools', + 'python', 'google', + 'httpd_config', 'httpd2.pem') + httpd_vars = { + "httpd_executable_path": GetCygwinPath( + os.path.join(self._CygwinRoot(), "usr", "sbin", exe_name)), + "httpd_conf_path": GetCygwinPath(httpd_conf_path), + "ssl_certificate_file": GetCygwinPath(cert_file), + "document_root" : document_root, + "server_root": GetCygwinPath(os.path.join(self._CygwinRoot(), "usr")), + "mime_types_path": GetCygwinPath(mime_types_path), + "output_dir": GetCygwinPath(output_dir), + "bindir": GetCygwinPath(os.path.join(self._CygwinRoot(), "bin")), + "user": os.environ.get("USERNAME", os.environ.get("USER", "")), + } + if not httpd_vars["user"]: + # Failed to get the username from the environment; use whoami.exe + # instead. + proc = subprocess.Popen(self._PathToExecutable("whoami.exe"), + stdout=subprocess.PIPE) + httpd_vars["user"] = proc.stdout.read().strip() + + if not httpd_vars["user"]: + raise Exception("Failed to get username.") + + google.path_utils.MaybeMakeDirectory(output_dir) + + # We have to wrap the command in bash because the cygwin environment + # is required for httpd to run. + # -C: process directive before reading config files + # -c: process directive after reading config files + # Apache wouldn't run CGIs with permissions==700 unless we add + # -c User "<username>" + bash = self._PathToExecutable("bash.exe") + httpd_cmd_string = ( + ' PATH=%(bindir)s %(httpd_executable_path)s' + ' -f %(httpd_conf_path)s' + ' -c \'TypesConfig "%(mime_types_path)s"\'' + ' -c \'CustomLog "%(output_dir)s/access_log.txt" common\'' + ' -c \'ErrorLog "%(output_dir)s/error_log.txt"\'' + ' -c \'PidFile "%(output_dir)s/httpd.pid"\'' + ' -C \'User "%(user)s"\'' + ' -C \'ServerRoot "%(server_root)s"\'' + ) + if apache2: + httpd_cmd_string = ('export CYGWIN=server;' + httpd_cmd_string + + ' -c \'SSLCertificateFile "%(ssl_certificate_file)s"\'') + if document_root: + httpd_cmd_string += ' -C \'DocumentRoot "%(document_root)s"\'' + + httpd_cmd = [bash, "-c", httpd_cmd_string % httpd_vars] + return httpd_cmd + + def GetStopHttpdCommand(self): + """Returns a list of strings that contains the command line+args needed to + stop the http server used in the http tests. + """ + # Force kill (/f) *all* httpd processes. This has the side effect of + # killing httpd processes that we didn't start. + return ["taskkill.exe", "/f", "/im", "httpd*"] + +########################################################################### +# This method is specific to windows, expected to be used only by *_win.py +# files. + +def GetCygwinPath(path): + """Convert a Windows path to a cygwin path. + + The cygpath utility insists on converting paths that it thinks are Cygwin + root paths to what it thinks the correct roots are. So paths such as + "C:\b\slave\webkit-release-kjs\build\third_party\cygwin\bin" are converted to + plain "/usr/bin". To avoid this, we do the conversion manually. + + The path is expected to be an absolute path, on any drive. + """ + drive_regexp = re.compile(r'([a-z]):[/\\]', re.IGNORECASE) + def LowerDrive(matchobj): + return '/cygdrive/%s/' % matchobj.group(1).lower() + path = drive_regexp.sub(LowerDrive, path) + return path.replace('\\', '/') diff --git a/tools/python/google/process_utils.py b/tools/python/google/process_utils.py new file mode 100644 index 0000000..966fdf6 --- /dev/null +++ b/tools/python/google/process_utils.py @@ -0,0 +1,156 @@ +# 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. +"""Shared process-related utility functions.""" + +import errno +import os +import subprocess +import sys + +class CommandNotFound(Exception): pass + + +TASKKILL = os.path.join(os.environ['WINDIR'], 'system32', 'taskkill.exe') +TASKKILL_PROCESS_NOT_FOUND_ERR = 128 +# On windows 2000 there is no taskkill.exe, we need to have pskill somewhere +# in the path. +PSKILL = 'pskill.exe' +PSKILL_PROCESS_NOT_FOUND_ERR = -1 + +def KillAll(executables): + """Tries to kill all copies of each process in the processes list. Returns + an error if any running processes couldn't be killed. + """ + result = 0 + if os.path.exists(TASKKILL): + command = [TASKKILL, '/f', '/im'] + process_not_found_err = TASKKILL_PROCESS_NOT_FOUND_ERR + else: + command = [PSKILL, '/t'] + process_not_found_err = PSKILL_PROCESS_NOT_FOUND_ERR + + for name in executables: + new_error = RunCommand(command + [name]) + # Ignore "process not found" error. + if new_error != 0 and new_error != process_not_found_err: + result = new_error + return result + +def RunCommandFull(command, verbose=True, collect_output=False, + print_output=True): + """Runs the command list. + + Prints the given command (which should be a list of one or more strings). + If specified, prints its stderr (and optionally stdout) to stdout, + line-buffered, converting line endings to CRLF (see note below). If + specified, collects the output as a list of lines and returns it. Waits + for the command to terminate and returns its status. + + Args: + command: the full command to run, as a list of one or more strings + verbose: if True, combines all output (stdout and stderr) into stdout. + Otherwise, prints only the command's stderr to stdout. + collect_output: if True, collects the output of the command as a list of + lines and returns it + print_output: if True, prints the output of the command + + Returns: + A tuple consisting of the process's exit status and output. If + collect_output is False, the output will be []. + + Raises: + CommandNotFound if the command executable could not be found. + """ + print '\n' + subprocess.list2cmdline(command).replace('\\', '/') + '\n', ### + + if verbose: + out = subprocess.PIPE + err = subprocess.STDOUT + else: + out = file(os.devnull, 'w') + err = subprocess.PIPE + try: + proc = subprocess.Popen(command, stdout=out, stderr=err, bufsize=1) + except OSError, e: + if e.errno == errno.ENOENT: + raise CommandNotFound('Unable to find "%s"' % command[0]) + raise + + output = [] + + if verbose: + read_from = proc.stdout + else: + read_from = proc.stderr + line = read_from.readline() + while line: + line = line.rstrip() + + if collect_output: + output.append(line) + + if print_output: + # Windows Python converts \n to \r\n automatically whenever it + # encounters it written to a text file (including stdout). The only + # way around it is to write to a binary file, which isn't feasible for + # stdout. So we end up with \r\n here even though we explicitly write + # \n. (We could write \r instead, which doesn't get converted to \r\n, + # but that's probably more troublesome for people trying to read the + # files.) + print line + '\n', + + # Python on windows writes the buffer only when it reaches 4k. This is + # not fast enough for all purposes. + sys.stdout.flush() + line = read_from.readline() + + if not verbose: + out.close() + return (proc.returncode, output) + +def RunCommand(command, verbose=True): + """Runs the command list, printing its output and returning its exit status. + + Prints the given command (which should be a list of one or more strings), + then runs it and prints its stderr (and optionally stdout) to stdout, + line-buffered, converting line endings to CRLF. Waits for the command to + terminate and returns its status. + + Args: + command: the full command to run, as a list of one or more strings + verbose: if True, combines all output (stdout and stderr) into stdout. + Otherwise, prints only the command's stderr to stdout. + + Returns: + The process's exit status. + + Raises: + CommandNotFound if the command executable could not be found. + """ + return RunCommandFull(command, verbose)[0] |