michael@0: /* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=8 sts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: Cu.import("resource://testing-common/httpd.js"); michael@0: michael@0: var baseURL; michael@0: const kResponseTimeoutPref = "network.http.response.timeout"; michael@0: const kResponseTimeout = 1; michael@0: const kShortLivedKeepalivePref = michael@0: "network.http.tcp_keepalive.short_lived_connections"; michael@0: const kLongLivedKeepalivePref = michael@0: "network.http.tcp_keepalive.long_lived_connections"; michael@0: michael@0: const prefService = Cc["@mozilla.org/preferences-service;1"] michael@0: .getService(Ci.nsIPrefBranch); michael@0: michael@0: var server = new HttpServer(); michael@0: michael@0: function TimeoutListener(expectResponse) { michael@0: this.expectResponse = expectResponse; michael@0: } michael@0: michael@0: TimeoutListener.prototype = { michael@0: onStartRequest: function (request, ctx) { michael@0: }, michael@0: michael@0: onDataAvailable: function (request, ctx, stream) { michael@0: }, michael@0: michael@0: onStopRequest: function (request, ctx, status) { michael@0: if (this.expectResponse) { michael@0: do_check_eq(status, Cr.NS_OK); michael@0: } else { michael@0: do_check_eq(status, Cr.NS_ERROR_NET_TIMEOUT); michael@0: } michael@0: michael@0: run_next_test(); michael@0: }, michael@0: }; michael@0: michael@0: function serverStopListener() { michael@0: do_test_finished(); michael@0: } michael@0: michael@0: function testTimeout(timeoutEnabled, expectResponse) { michael@0: // Set timeout pref. michael@0: if (timeoutEnabled) { michael@0: prefService.setIntPref(kResponseTimeoutPref, kResponseTimeout); michael@0: } else { michael@0: prefService.setIntPref(kResponseTimeoutPref, 0); michael@0: } michael@0: michael@0: var ios = Cc["@mozilla.org/network/io-service;1"] michael@0: .getService(Ci.nsIIOService); michael@0: var chan = ios.newChannel(baseURL, null, null) michael@0: .QueryInterface(Ci.nsIHttpChannel); michael@0: var listener = new TimeoutListener(expectResponse); michael@0: chan.asyncOpen(listener, null); michael@0: } michael@0: michael@0: function testTimeoutEnabled() { michael@0: // Set a timeout value; expect a timeout and no response. michael@0: testTimeout(true, false); michael@0: } michael@0: michael@0: function testTimeoutDisabled() { michael@0: // Set a timeout value of 0; expect a response. michael@0: testTimeout(false, true); michael@0: } michael@0: michael@0: function testTimeoutDisabledByShortLivedKeepalives() { michael@0: // Enable TCP Keepalives for short lived HTTP connections. michael@0: prefService.setBoolPref(kShortLivedKeepalivePref, true); michael@0: prefService.setBoolPref(kLongLivedKeepalivePref, false); michael@0: michael@0: // Try to set a timeout value, but expect a response without timeout. michael@0: testTimeout(true, true); michael@0: } michael@0: michael@0: function testTimeoutDisabledByLongLivedKeepalives() { michael@0: // Enable TCP Keepalives for long lived HTTP connections. michael@0: prefService.setBoolPref(kShortLivedKeepalivePref, false); michael@0: prefService.setBoolPref(kLongLivedKeepalivePref, true); michael@0: michael@0: // Try to set a timeout value, but expect a response without timeout. michael@0: testTimeout(true, true); michael@0: } michael@0: michael@0: function testTimeoutDisabledByBothKeepalives() { michael@0: // Enable TCP Keepalives for short and long lived HTTP connections. michael@0: prefService.setBoolPref(kShortLivedKeepalivePref, true); michael@0: prefService.setBoolPref(kLongLivedKeepalivePref, true); michael@0: michael@0: // Try to set a timeout value, but expect a response without timeout. michael@0: testTimeout(true, true); michael@0: } michael@0: michael@0: function setup_tests() { michael@0: // Start tests with timeout enabled, i.e. disable TCP keepalives for HTTP. michael@0: // Reset pref in cleanup. michael@0: if (prefService.getBoolPref(kShortLivedKeepalivePref)) { michael@0: prefService.setBoolPref(kShortLivedKeepalivePref, false); michael@0: do_register_cleanup(function() { michael@0: prefService.setBoolPref(kShortLivedKeepalivePref, true); michael@0: }); michael@0: } michael@0: if (prefService.getBoolPref(kLongLivedKeepalivePref)) { michael@0: prefService.setBoolPref(kLongLivedKeepalivePref, false); michael@0: do_register_cleanup(function() { michael@0: prefService.setBoolPref(kLongLivedKeepalivePref, true); michael@0: }); michael@0: } michael@0: michael@0: var tests = [ michael@0: // Enable with a timeout value >0; michael@0: testTimeoutEnabled, michael@0: // Disable with a timeout value of 0; michael@0: testTimeoutDisabled, michael@0: // Disable by enabling TCP keepalive for short-lived HTTP connections. michael@0: testTimeoutDisabledByShortLivedKeepalives, michael@0: // Disable by enabling TCP keepalive for long-lived HTTP connections. michael@0: testTimeoutDisabledByLongLivedKeepalives, michael@0: // Disable by enabling TCP keepalive for both HTTP connection types. michael@0: testTimeoutDisabledByBothKeepalives michael@0: ]; michael@0: michael@0: for (var i=0; i < tests.length; i++) { michael@0: add_test(tests[i]); michael@0: } michael@0: } michael@0: michael@0: function setup_http_server() { michael@0: // Start server; will be stopped at test cleanup time. michael@0: server.start(-1); michael@0: baseURL = "http://localhost:" + server.identity.primaryPort + "/"; michael@0: do_print("Using baseURL: " + baseURL); michael@0: server.registerPathHandler('/', function(metadata, response) { michael@0: // Wait until the timeout should have passed, then respond. michael@0: response.processAsync(); michael@0: michael@0: do_timeout((kResponseTimeout+1)*1000 /* ms */, function() { michael@0: response.setStatusLine(metadata.httpVersion, 200, "OK"); michael@0: response.write("Hello world"); michael@0: response.finish(); michael@0: }); michael@0: }); michael@0: do_register_cleanup(function() { michael@0: server.stop(serverStopListener); michael@0: }); michael@0: } michael@0: michael@0: function run_test() { michael@0: setup_http_server(); michael@0: michael@0: setup_tests(); michael@0: michael@0: run_next_test(); michael@0: }