Bug 1253924 - Implement statusLine + fix & test statusCode r=kmag
authorGiorgio Maone <g.maone@informaction.com>
Sun, 06 Mar 2016 16:59:07 +0100
changeset 287005 6acd12ff78fd490ac5cdd833a305023c1516a333
parent 287004 0d9926dd10ea11482e186c39a3c6ab4d66f55093
child 287006 6f3b3cccc3624893777b430632b427a2f0c0642f
push id18032
push usercbook@mozilla.com
push dateMon, 07 Mar 2016 10:38:51 +0000
treeherderfx-team@087905ffec78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1253924
milestone47.0a1
Bug 1253924 - Implement statusLine + fix & test statusCode r=kmag MozReview-Commit-ID: BhyM10w8iGt
toolkit/components/extensions/ext-webRequest.js
toolkit/components/extensions/test/mochitest/test_ext_webrequest.html
toolkit/modules/addons/WebRequest.jsm
--- a/toolkit/components/extensions/ext-webRequest.js
+++ b/toolkit/components/extensions/ext-webRequest.js
@@ -48,17 +48,17 @@ function WebRequestEventManager(context,
 
       // Fills in tabId typically.
       let result = {};
       extensions.emit("fill-browser-data", data.browser, data2, result);
       if (result.cancel) {
         return;
       }
 
-      let optional = ["requestHeaders", "responseHeaders", "statusCode", "redirectUrl"];
+      let optional = ["requestHeaders", "responseHeaders", "statusCode", "statusLine", "redirectUrl"];
       for (let opt of optional) {
         if (opt in data) {
           data2[opt] = data[opt];
         }
       }
 
       return runSafeSync(context, callback, data2);
     };
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest.html
@@ -91,16 +91,30 @@ function compareLists(list1, list2, kind
 function backgroundScript() {
   let checkCompleted = true;
   let savedTabId = -1;
 
   function shouldRecord(url) {
     return url.startsWith(BASE) || /^data:.*\bwebRequestTest\b/.test(url);
   }
 
+  let statuses = [
+    {url: /_script_good\b/, code: 200, line: /^HTTP\/1.1 200 OK\b/i},
+    {url: /\bredirection\b/, code: 302, line: /^HTTP\/1.1 302\b/},
+    {url: /\bnonexistent_script_/, code: 404, line: /^HTTP\/1.1 404 Not Found\b/i},
+  ];
+  function checkStatus(details) {
+    for (let {url, code, line} of statuses) {
+      if (url.test(details.url)) {
+        browser.test.assertTrue(code === details.statusCode, `HTTP status code ${code} for ${details.url} (found ${details.statusCode})`);
+        browser.test.assertTrue(line.test(details.statusLine), `HTTP status line ${line} for ${details.url} (found ${details.statusLine})`);
+      }
+    }
+  }
+
   function checkType(details) {
     let expected_type = "???";
     if (details.url.indexOf("style") != -1) {
       expected_type = "stylesheet";
     } else if (details.url.indexOf("image") != -1) {
       expected_type = "image";
     } else if (details.url.indexOf("script") != -1) {
       expected_type = "script";
@@ -297,16 +311,17 @@ function backgroundScript() {
     browser.test.log(`onBeforeRedirect ${details.url} -> ${details.redirectUrl}`);
     checkRequestId(details, "redirect");
     checkResourceType(details.type);
     if (shouldRecord(details.url)) {
       recorded.beforeRedirect.push(details.url);
 
       browser.test.assertEq(details.tabId, savedTabId, "correct tab ID");
       checkType(details);
+      checkStatus(details);
 
       let id = frameIDs.get(details.url);
       browser.test.assertEq(id, details.frameId, "frame ID same in onBeforeRedirect as onBeforeRequest");
       frameIDs.set(details.redirectUrl, details.frameId);
     }
     if (details.url.indexOf("_redirect.") != -1) {
       let expectedUrl = details.url.replace("_redirect.", "_good.");
       browser.test.assertEq(details.redirectUrl, expectedUrl, "correct redirectUrl value");
@@ -339,16 +354,17 @@ function backgroundScript() {
     }
     if (checkCompleted && !completedUrls[kind].has(details.url)) {
       // We can only tell IPs for HTTP requests.
       if (/^https?:/.test(details.url)) {
         browser.test.assertEq(details.ip, "127.0.0.1", "correct ip");
       }
       completedUrls[kind].add(details.url);
     }
+    checkStatus(details);
   }
 
   function onHeadersReceived(details) {
     checkIpAndRecord("headersReceived", details);
     processHeaders("response", details);
     browser.test.log(`After processing response headers: ${details.responseHeaders.toSource()}`);
     return {responseHeaders: details.responseHeaders};
   }
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -82,16 +82,30 @@ function parseExtra(extra, allowed) {
   for (let al of allowed) {
     if (extra && extra.indexOf(al) != -1) {
       result[al] = true;
     }
   }
   return result;
 }
 
+function mergeStatus(data, channel) {
+  try {
+    data.statusCode = channel.responseStatus;
+    let statusText = channel.responseStatusText;
+    let maj = {};
+    let min = {};
+    channel.QueryInterface(Ci.nsIHttpChannelInternal).getResponseVersion(maj, min);
+    data.statusLine = `HTTP/${maj.value}.${min.value} ${data.statusCode} ${statusText}`;
+  } catch (e) {
+    // NS_ERROR_NOT_AVAILABLE might be thrown.
+    Cu.reportError(e);
+  }
+}
+
 var HttpObserverManager;
 
 var ContentPolicyManager = {
   policyData: new Map(),
   policies: new Map(),
   idMap: new Map(),
   nextId: 0,
 
@@ -399,17 +413,17 @@ HttpObserverManager = {
     let policyType = loadInfo ?
                      loadInfo.externalContentPolicyType :
                      Ci.nsIContentPolicy.TYPE_OTHER;
 
     let requestHeaderNames;
     let responseHeaderNames;
 
     let includeStatus = kind === "headersReceived" ||
-                        kind === "onBeforeRedirect" ||
+                        kind === "onRedirect" ||
                         kind === "onStart" ||
                         kind === "onStop";
 
     for (let [callback, opts] of listeners.entries()) {
       if (!this.shouldRunListener(policyType, channel.URI, opts.filter)) {
         continue;
       }
 
@@ -438,17 +452,17 @@ HttpObserverManager = {
         data.requestHeaders = this.getHeaders(channel, "visitRequestHeaders");
         requestHeaderNames = data.requestHeaders.map(h => h.name);
       }
       if (opts.responseHeaders) {
         data.responseHeaders = this.getHeaders(channel, "visitResponseHeaders");
         responseHeaderNames = data.responseHeaders.map(h => h.name);
       }
       if (includeStatus) {
-        data.statusCode = channel.responseStatus;
+        mergeStatus(data, channel);
       }
 
       let result = null;
       try {
         result = callback(data);
       } catch (e) {
         Cu.reportError(e);
       }