From 3d4f89b41e1bb47a7c51eb5d513595f41e1ebbc7 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Tue, 16 Sep 2014 20:56:27 +0000 Subject: [PATCH] Bug fixes to test-server Python response hook support. * correctly fake a package to hold all the response-hook modules * use StringIO correctly in the response hooks * prevent .py(c) files in test/www/ from being accessed directly * prevent test/www/__init__ from being treated as a response hook * add a test case that makes sure the existing hooks _can_ return 200 OK (issue #12439; buggy commit 4d60e94) --- test/basics/test-server.js | 28 ++++++++++++++++++++++++++++ test/run-tests.py | 25 +++++++++++++++++++------ test/www/__init__.py | 2 ++ test/www/echo.py | 2 +- test/www/status.py | 2 +- 5 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 test/basics/test-server.js create mode 100644 test/www/__init__.py diff --git a/test/basics/test-server.js b/test/basics/test-server.js new file mode 100644 index 00000000..3844abe6 --- /dev/null +++ b/test/basics/test-server.js @@ -0,0 +1,28 @@ +/* Test the test server itself. */ + +var assert = require('../assert'); +var webpage = require('webpage'); +var page = webpage.create(); + +var urlsToTest = [ + 'http://localhost:9180/hello.html', + 'http://localhost:9180/status?200', + 'http://localhost:9180/echo' +]; +var i = 0; + +page.onResourceReceived = function (response) { + assert.equal(response.status, 200); +}; + +page.onLoadFinished = function (status) { + assert.equal(status, 'success'); + i++; + if (i == urlsToTest.length) { + phantom.exit(0); + } else { + page.open(urlsToTest[i]); + } +} + +page.open(urlsToTest[i]); diff --git a/test/run-tests.py b/test/run-tests.py index cd1c8041..bf6b78ac 100755 --- a/test/run-tests.py +++ b/test/run-tests.py @@ -33,8 +33,10 @@ TESTS = [ # This should be in the standard library somewhere, but as far as I # can tell, isn't. def import_file_as_module(path): + # All Python response hooks, no matter how deep below www_path, + # are treated as direct children of the fake "test_www" package. if 'test_www' not in sys.modules: - imp.load_source('test_www', www_path + '/__init__.py', StringIO()) + imp.load_source('test_www', www_path + '/__init__.py') tr = string.maketrans('-./%', '____') modname = 'test_www.' + path.translate(tr) @@ -54,12 +56,23 @@ class FileHandler(SimpleHTTPServer.SimpleHTTPRequestHandler, object): def log_message(self, format, *args): return - # modified version allowing one to provide a .py file that will be - # interpreted to produce the response + # allow provision of a .py file that will be interpreted to + # produce the response. def send_head(self): path = self.translate_path(self.path) + + # do not allow direct references to .py(c) files, + # or indirect references to __init__.py + if (path.endswith('.py') or path.endswith('.pyc') or + path.endswith('__init__')): + self.send_error(404, 'File not found') + return None + + if os.path.exists(path): + return super(FileHandler, self).send_head() + py = path + '.py' - if not os.path.exists(path) and os.path.exists(py): + if os.path.exists(py): try: mod = import_file_as_module(py) return mod.handle_request(self) @@ -75,8 +88,8 @@ class FileHandler(SimpleHTTPServer.SimpleHTTPRequestHandler, object): self.end_headers() return StringIO.StringIO(buf) - else: - return super(FileHandler, self).send_head() + self.send_error(404, 'File not found') + return None # modified version of SimpleHTTPRequestHandler's translate_path # to resolve the URL relative to the www/ directory diff --git a/test/www/__init__.py b/test/www/__init__.py new file mode 100644 index 00000000..b2858867 --- /dev/null +++ b/test/www/__init__.py @@ -0,0 +1,2 @@ +# This file makes test/www/ into a "package" so that +# importing Python response hooks works correctly. diff --git a/test/www/echo.py b/test/www/echo.py index b4d0247b..8422cf8a 100644 --- a/test/www/echo.py +++ b/test/www/echo.py @@ -25,4 +25,4 @@ def handle_request(req): req.send_header('Content-Type', 'application/json') req.send_header('Content-Length', str(len(body))) req.end_headers() - return StringIO(body) + return StringIO.StringIO(body) diff --git a/test/www/status.py b/test/www/status.py index 898b838f..d4de0221 100644 --- a/test/www/status.py +++ b/test/www/status.py @@ -10,4 +10,4 @@ def handle_request(req): req.send_header('Content-Type', 'text/html') req.send_header('Content-Length', str(len(body))) req.end_headers() - return StringIO(body) + return StringIO.StringIO(body)