summaryrefslogtreecommitdiffstats
path: root/tools/python/google/gethash_timer.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/python/google/gethash_timer.py')
-rw-r--r--tools/python/google/gethash_timer.py168
1 files changed, 168 insertions, 0 deletions
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()