diff --git a/dom/security/test/csp/file_report_chromescript.js b/dom/security/test/csp/file_report_chromescript.js new file mode 100644 index 000000000000..bf4f70edbbc0 --- /dev/null +++ b/dom/security/test/csp/file_report_chromescript.js @@ -0,0 +1,54 @@ +Components.utils.import("resource://gre/modules/Services.jsm"); + +const Ci = Components.interfaces; +const Cc = Components.classes; + +const reportURI = "http://mochi.test:8888/foo.sjs"; + +var openingObserver = { + observe: function(subject, topic, data) { + // subject should be an nsURI + if (subject.QueryInterface == undefined) + return; + + var message = {report: "", error: false}; + + if (topic == 'http-on-opening-request') { + var asciiSpec = subject.QueryInterface(Ci.nsIHttpChannel).URI.asciiSpec; + if (asciiSpec !== reportURI) return; + + var reportText = false; + try { + // Verify that the report was properly formatted. + // We'll parse the report text as JSON and verify that the properties + // have expected values. + var reportText = "{}"; + var uploadStream = subject.QueryInterface(Ci.nsIUploadChannel).uploadStream; + + if (uploadStream) { + // get the bytes from the request body + var binstream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); + binstream.setInputStream(uploadStream); + + var segments = []; + for (var count = uploadStream.available(); count; count = uploadStream.available()) { + var data = binstream.readBytes(count); + segments.push(data); + } + + var reportText = segments.join(""); + // rewind stream as we are supposed to - there will be an assertion later if we don't. + uploadStream.QueryInterface(Ci.nsISeekableStream).seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); + } + message.report = reportText; + } catch (e) { + message.error = e.toString(); + } + + sendAsyncMessage('opening-request-completed', message); + Services.obs.removeObserver(openingObserver, 'http-on-opening-request'); + } + } +}; + +Services.obs.addObserver(openingObserver, 'http-on-opening-request', false); diff --git a/dom/security/test/csp/mochitest.ini b/dom/security/test/csp/mochitest.ini index 5ba79dd5d612..7dd2f981d2b1 100644 --- a/dom/security/test/csp/mochitest.ini +++ b/dom/security/test/csp/mochitest.ini @@ -103,6 +103,7 @@ support-files = file_report_uri_missing_in_report_only_header.html file_report_uri_missing_in_report_only_header.html^headers^ file_report.html + file_report_chromescript.js file_redirect_content.sjs file_redirect_report.sjs file_subframe_run_js_if_allowed.html @@ -170,7 +171,6 @@ skip-if = buildapp == 'b2g' #no ssl support [test_path_matching_redirect.html] [test_report_uri_missing_in_report_only_header.html] [test_report.html] -skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observer not supported in child process (bug 1009632) [test_301_redirect.html] skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490) [test_302_redirect.html] @@ -198,6 +198,5 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet' || toolkit == 'gonk' || toolk skip-if = buildapp == 'b2g' || buildapp == 'mulet' || toolkit == 'gonk' || toolkit == 'android' [test_report_for_import.html] [test_blocked_uri_in_reports.html] -skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observer not supported in child process (bug 1009632) [test_service_worker.html] skip-if = buildapp == 'b2g' #no ssl support diff --git a/dom/security/test/csp/test_blocked_uri_in_reports.html b/dom/security/test/csp/test_blocked_uri_in_reports.html index fd71e4f0ca64..f68d8c03f23b 100644 --- a/dom/security/test/csp/test_blocked_uri_in_reports.html +++ b/dom/security/test/csp/test_blocked_uri_in_reports.html @@ -34,71 +34,32 @@ const reportURI = "http://mochi.test:8888/foo.sjs"; const policy = "script-src http://example.com; report-uri " + reportURI; const testfile = "tests/dom/security/test/csp/file_path_matching_redirect.html"; -// This is used to watch requests go out so we can see if the report is -// sent correctly -function examiner() { - SpecialPowers.addObserver(this, "http-on-opening-request", false); -} -examiner.prototype = { - observe: function(subject, topic, data) { - // subject should be an nsURI - if (!SpecialPowers.can_QI(subject)) - return; +var chromeScriptUrl = SimpleTest.getTestFileURL("file_report_chromescript.js"); +var script = SpecialPowers.loadChromeScript(chromeScriptUrl); - if (topic === "http-on-opening-request") { - var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec"); - if (asciiSpec !== reportURI) return; - - try { - // Verify that the report was properly formatted. - // We'll parse the report text as JSON and verify that the properties - // have expected values. - var reportText = "{}"; - var uploadStream = SpecialPowers.wrap(SpecialPowers.do_QueryInterface(subject, "nsIUploadChannel")).uploadStream; - - if (uploadStream) { - // get the bytes from the request body - var binstream = SpecialPowers.Cc["@mozilla.org/binaryinputstream;1"] - .createInstance(SpecialPowers.Ci.nsIBinaryInputStream); - binstream.setInputStream(uploadStream); - - var segments = []; - for (var count = uploadStream.available(); count; count = uploadStream.available()) { - var data = binstream.readBytes(count); - segments.push(data); - } - - var reportText = segments.join(""); - // rewind stream as we are supposed to - there will be an assertion later if we don't. - SpecialPowers.do_QueryInterface(uploadStream, "nsISeekableStream").seek(SpecialPowers.Ci.nsISeekableStream.NS_SEEK_SET, 0); - } - try { - var reportObj = JSON.parse(reportText); - } - catch (e) { - ok(false, "Could not parse JSON (exception: " + e + ")"); - } - var cspReport = reportObj["csp-report"]; - // blocked-uri should only be the asciiHost instead of: - // http://test1.example.com/tests/dom/security/test/csp/file_path_matching.js - is(cspReport["blocked-uri"], "http://test1.example.com", "Incorrect blocked-uri"); - } - catch (e) { - ok(false, "Could not query report (exception: " + e + ")"); - } - - // finish up - window.examiner.remove(); - SimpleTest.finish(); +script.addMessageListener('opening-request-completed', function ml(msg) { + if (msg.error) { + ok(false, "Could not query report (exception: " + msg.error + ")"); + } else { + try { + var reportObj = JSON.parse(msg.report); + } catch (e) { + ok(false, "Could not parse JSON (exception: " + e + ")"); + } + try { + var cspReport = reportObj["csp-report"]; + // blocked-uri should only be the asciiHost instead of: + // http://test1.example.com/tests/dom/security/test/csp/file_path_matching.js + is(cspReport["blocked-uri"], "http://test1.example.com", "Incorrect blocked-uri"); + } catch (e) { + ok(false, "Could not query report (exception: " + e + ")"); } - }, - - // remove the listener - remove: function() { - SpecialPowers.removeObserver(this, "http-on-opening-request"); } -} -window.examiner = new examiner(); + + script.removeMessageListener('opening-request-completed', ml); + SimpleTest.finish(); +}); + SimpleTest.waitForExplicitFinish(); function runTest() { diff --git a/dom/security/test/csp/test_report.html b/dom/security/test/csp/test_report.html index 2996d73ad863..e8cfb8778061 100644 --- a/dom/security/test/csp/test_report.html +++ b/dom/security/test/csp/test_report.html @@ -63,69 +63,30 @@ window.checkResults = function(reportObj) { is(cspReport["line-number"], 7, "Incorrect line-number"); } -// This is used to watch requests go out so we can see if the report is -// sent correctly -function examiner() { - SpecialPowers.addObserver(this, "http-on-opening-request", false); -} -examiner.prototype = { - observe: function(subject, topic, data) { - // subject should be an nsURI - if (!SpecialPowers.can_QI(subject)) - return; +var chromeScriptUrl = SimpleTest.getTestFileURL("file_report_chromescript.js"); +var script = SpecialPowers.loadChromeScript(chromeScriptUrl); - if (topic === "http-on-opening-request") { - var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec"); - if (asciiSpec !== reportURI) return; - - try { - // Verify that the report was properly formatted. - // We'll parse the report text as JSON and verify that the properties - // have expected values. - var reportText = "{}"; - var uploadStream = SpecialPowers.wrap(SpecialPowers.do_QueryInterface(subject, "nsIUploadChannel")).uploadStream; - - if (uploadStream) { - // get the bytes from the request body - var binstream = SpecialPowers.Cc["@mozilla.org/binaryinputstream;1"] - .createInstance(SpecialPowers.Ci.nsIBinaryInputStream); - binstream.setInputStream(uploadStream); - - var segments = []; - for (var count = uploadStream.available(); count; count = uploadStream.available()) { - var data = binstream.readBytes(count); - segments.push(data); - } - - var reportText = segments.join(""); - // rewind stream as we are supposed to - there will be an assertion later if we don't. - SpecialPowers.do_QueryInterface(uploadStream, "nsISeekableStream").seek(SpecialPowers.Ci.nsISeekableStream.NS_SEEK_SET, 0); - } - try { - var reportObj = JSON.parse(reportText); - } - catch (e) { - ok(false, "Could not parse JSON (exception: " + e + ")"); - } - // test for the proper values in the report object - window.checkResults(reportObj); - } - catch (e) { - ok(false, "Could not query report (exception: " + e + ")"); - } - - // finish up - window.examiner.remove(); - SimpleTest.finish(); +script.addMessageListener('opening-request-completed', function ml(msg) { + if (msg.error) { + ok(false, "Could not query report (exception: " + msg.error + ")"); + } else { + try { + var reportObj = JSON.parse(msg.report); + } catch (e) { + ok(false, "Could not parse JSON (exception: " + e + ")"); + } + try { + // test for the proper values in the report object + window.checkResults(reportObj); + } catch (e) { + ok(false, "Could not query report (exception: " + e + ")"); } - }, - - // remove the listener - remove: function() { - SpecialPowers.removeObserver(this, "http-on-opening-request"); } -} -window.examiner = new examiner(); + + script.removeMessageListener('opening-request-completed', ml); + SimpleTest.finish(); +}); + SimpleTest.waitForExplicitFinish(); // load the resource which will generate a CSP violation report