mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-13 03:24:26 +00:00
Bug 463254 - httpd.js fails on mac when running test_CrossSiteXHR.html. The problem was that exceptions were causing files not to be closed on OS X, and we were hitting the open-file limit; add some try-finally magic to close in a failsafe manner. r=honzab
This commit is contained in:
parent
159005ad48
commit
6ed4048793
@ -40,12 +40,6 @@ window.addEventListener("message", function(e) {
|
||||
gen = runTest();
|
||||
|
||||
function runTest() {
|
||||
if (navigator.platform == "MacIntel") {
|
||||
todo(false, "httpd.js fails on Mac");
|
||||
SimpleTest.finish();
|
||||
yield;
|
||||
}
|
||||
|
||||
var loader = document.getElementById('loader');
|
||||
var loaderWindow = loader.contentWindow;
|
||||
loader.onload = function () { gen.next() };
|
||||
|
@ -1805,11 +1805,11 @@ function maybeAddHeaders(file, metadata, response)
|
||||
var fis = new FileInputStream(headerFile, PR_RDONLY, 0444,
|
||||
Ci.nsIFileInputStream.CLOSE_ON_EOF);
|
||||
|
||||
var lis = new ConverterInputStream(fis, "UTF-8", 1024, 0x0);
|
||||
lis.QueryInterface(Ci.nsIUnicharLineInputStream);
|
||||
|
||||
try
|
||||
{
|
||||
var lis = new ConverterInputStream(fis, "UTF-8", 1024, 0x0);
|
||||
lis.QueryInterface(Ci.nsIUnicharLineInputStream);
|
||||
|
||||
var line = {value: ""};
|
||||
var more = lis.readLine(line);
|
||||
|
||||
@ -1861,6 +1861,10 @@ function maybeAddHeaders(file, metadata, response)
|
||||
dumpn("WARNING: error in headers for " + metadata.path + ": " + e);
|
||||
throw HTTP_500;
|
||||
}
|
||||
finally
|
||||
{
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2338,20 +2342,45 @@ ServerHandler.prototype =
|
||||
var type = this._getTypeFromFile(file);
|
||||
if (type == SJS_TYPE)
|
||||
{
|
||||
var fis = new FileInputStream(file, PR_RDONLY, 0444,
|
||||
Ci.nsIFileInputStream.CLOSE_ON_EOF);
|
||||
|
||||
try
|
||||
{
|
||||
var fis = new FileInputStream(file, PR_RDONLY, 0444,
|
||||
Ci.nsIFileInputStream.CLOSE_ON_EOF);
|
||||
var sis = new ScriptableInputStream(fis);
|
||||
var s = Cu.Sandbox(gGlobalObject);
|
||||
s.importFunction(dump, "dump");
|
||||
Cu.evalInSandbox(sis.read(file.fileSize), s);
|
||||
s.handleRequest(metadata, response);
|
||||
|
||||
try
|
||||
{
|
||||
// Alas, the line number in errors dumped to console when calling the
|
||||
// request handler is simply an offset from where we load the SJS file.
|
||||
// Work around this in a reasonably non-fragile way by dynamically
|
||||
// getting the line number where we evaluate the SJS file. Don't
|
||||
// separate these two lines!
|
||||
var line = new Error().lineNumber;
|
||||
Cu.evalInSandbox(sis.read(file.fileSize), s);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
dumpn("*** syntax error in SJS at " + file.path + ": " + e);
|
||||
throw HTTP_500;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
s.handleRequest(metadata, response);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
dumpn("*** error running SJS at " + file.path + ": " +
|
||||
e + " on line " + (e.lineNumber - line));
|
||||
throw HTTP_500;
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
finally
|
||||
{
|
||||
dump("*** error running SJS: " + e + " on line " + (e.lineNumber-2192) + "\n");
|
||||
throw HTTP_500;
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2368,21 +2397,28 @@ ServerHandler.prototype =
|
||||
|
||||
var fis = new FileInputStream(file, PR_RDONLY, 0444,
|
||||
Ci.nsIFileInputStream.CLOSE_ON_EOF);
|
||||
offset = offset || 0;
|
||||
count = count || file.fileSize;
|
||||
|
||||
NS_ASSERT(offset == 0 || offset < file.fileSize, "bad offset");
|
||||
NS_ASSERT(count >= 0, "bad count");
|
||||
|
||||
if (offset != 0)
|
||||
try
|
||||
{
|
||||
// Read and discard data up to offset so the data sent to
|
||||
// the client matches the requested range request.
|
||||
var sis = new ScriptableInputStream(fis);
|
||||
sis.read(offset);
|
||||
offset = offset || 0;
|
||||
count = count || file.fileSize;
|
||||
|
||||
NS_ASSERT(offset == 0 || offset < file.fileSize, "bad offset");
|
||||
NS_ASSERT(count >= 0, "bad count");
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
// Read and discard data up to offset so the data sent to
|
||||
// the client matches the requested range request.
|
||||
var sis = new ScriptableInputStream(fis);
|
||||
sis.read(offset);
|
||||
}
|
||||
response.bodyOutputStream.writeFrom(fis, count);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fis.close();
|
||||
}
|
||||
response.bodyOutputStream.writeFrom(fis, count);
|
||||
fis.close();
|
||||
|
||||
maybeAddHeaders(file, metadata, response);
|
||||
}
|
||||
|
6
netwerk/test/httpserver/test/data/sjs/thrower.sjs
Normal file
6
netwerk/test/httpserver/test/data/sjs/thrower.sjs
Normal file
@ -0,0 +1,6 @@
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
if (request.queryString == "throw")
|
||||
undefined[5];
|
||||
response.setHeader("X-Test-Status", "PASS", false);
|
||||
}
|
@ -249,11 +249,26 @@ function runHttpTests(testArray, done)
|
||||
{
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
testArray[testIndex].onStopRequest(ch, cx, status, this._data);
|
||||
|
||||
performNextTest();
|
||||
do_test_finished();
|
||||
// NB: The onStopRequest callback must run before performNextTest here,
|
||||
// because the latter runs the next test's initChannel callback, and
|
||||
// we want one test to be sequentially processed before the next
|
||||
// one.
|
||||
try
|
||||
{
|
||||
testArray[testIndex].onStopRequest(ch, cx, status, this._data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
performNextTest();
|
||||
}
|
||||
finally
|
||||
{
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
},
|
||||
QueryInterface: function(aIID)
|
||||
{
|
||||
|
103
netwerk/test/httpserver/test/test_sjs_throwing_exceptions.js
Normal file
103
netwerk/test/httpserver/test/test_sjs_throwing_exceptions.js
Normal file
@ -0,0 +1,103 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is httpd.js code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Walden <jwalden+code@mit.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Tests that running an SJS a whole lot of times doesn't have any ill effects
|
||||
* (like exceeding open-file limits due to not closing the SJS file each time,
|
||||
* then preventing any file from being opened).
|
||||
*/
|
||||
|
||||
const PORT = 4444;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
var srv = createServer();
|
||||
var sjsDir = do_get_file("netwerk/test/httpserver/test/data/sjs/");
|
||||
srv.registerDirectory("/", sjsDir);
|
||||
srv.registerContentType("sjs", "sjs");
|
||||
srv.start(PORT);
|
||||
|
||||
function done()
|
||||
{
|
||||
srv.stop();
|
||||
do_check_eq(gStartCount, TEST_RUNS);
|
||||
do_check_true(lastPassed);
|
||||
}
|
||||
|
||||
runHttpTests(tests, done);
|
||||
}
|
||||
|
||||
/***************
|
||||
* BEGIN TESTS *
|
||||
***************/
|
||||
|
||||
var gStartCount = 0;
|
||||
var lastPassed = false;
|
||||
|
||||
// This hits the open-file limit for me on OS X; your mileage may vary.
|
||||
const TEST_RUNS = 250;
|
||||
|
||||
var test = new Test("http://localhost:4444/thrower.sjs?throw",
|
||||
null, start_thrower);
|
||||
|
||||
var tests = new Array(TEST_RUNS + 1);
|
||||
for (var i = 0; i < TEST_RUNS; i++)
|
||||
tests[i] = test;
|
||||
|
||||
// ...and don't forget to stop!
|
||||
tests[TEST_RUNS] = new Test("http://localhost:4444/thrower.sjs",
|
||||
null, start_last);
|
||||
|
||||
function start_thrower(ch, cx)
|
||||
{
|
||||
do_check_eq(ch.responseStatus, 500);
|
||||
do_check_false(ch.requestSucceeded);
|
||||
|
||||
gStartCount++;
|
||||
}
|
||||
|
||||
function start_last(ch, cx)
|
||||
{
|
||||
do_check_eq(ch.responseStatus, 200);
|
||||
do_check_true(ch.requestSucceeded);
|
||||
|
||||
do_check_eq(ch.getResponseHeader("X-Test-Status"), "PASS");
|
||||
|
||||
lastPassed = true;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user