Bug 1260403 - Support brotli encoding in Developer Tools Netmonitor. r=ochameau

--HG--
extra : amend_source : af322134547025af7b135b6603fe697eff49bdf0
This commit is contained in:
Tooru Fujisawa 2016-11-08 04:18:04 +09:00
Родитель 8ad312e3e3
Коммит 8d3733057e
9 изменённых файлов: 95 добавлений и 30 удалений

Просмотреть файл

@ -7,10 +7,16 @@
* Tests if different response content types are handled correctly.
*/
add_task(function* () {
function* content_type_test(isHTTPS) {
let { L10N } = require("devtools/client/netmonitor/l10n");
let { tab, monitor } = yield initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL);
let pageURL = isHTTPS ? HTTPS_CONTENT_TYPE_WITHOUT_CACHE_URL
: CONTENT_TYPE_WITHOUT_CACHE_URL;
let imageURL = isHTTPS ? HTTPS_TEST_IMAGE
: TEST_IMAGE;
let sjsURL = isHTTPS ? HTTPS_CONTENT_TYPE_SJS
: CONTENT_TYPE_SJS;
let { tab, monitor } = yield initNetMonitor(pageURL);
info("Starting test... ");
let { document, Editor, NetMonitorView } = monitor.panelWin;
@ -18,77 +24,95 @@ add_task(function* () {
RequestsMenu.lazyUpdate = false;
let wait = waitForNetworkEvents(monitor, 7);
let wait = waitForNetworkEvents(monitor, 8);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
let okStatus = isHTTPS ? "Connected" : "OK";
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
"GET", CONTENT_TYPE_SJS + "?fmt=xml", {
"GET", sjsURL + "?fmt=xml", {
status: 200,
statusText: "OK",
statusText: okStatus,
type: "xml",
fullMimeType: "text/xml; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 42),
time: true
});
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(1),
"GET", CONTENT_TYPE_SJS + "?fmt=css", {
"GET", sjsURL + "?fmt=css", {
status: 200,
statusText: "OK",
statusText: okStatus,
type: "css",
fullMimeType: "text/css; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 34),
time: true
});
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(2),
"GET", CONTENT_TYPE_SJS + "?fmt=js", {
"GET", sjsURL + "?fmt=js", {
status: 200,
statusText: "OK",
statusText: okStatus,
type: "js",
fullMimeType: "application/javascript; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 34),
time: true
});
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(3),
"GET", CONTENT_TYPE_SJS + "?fmt=json", {
"GET", sjsURL + "?fmt=json", {
status: 200,
statusText: "OK",
statusText: okStatus,
type: "json",
fullMimeType: "application/json; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 29),
time: true
});
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(4),
"GET", CONTENT_TYPE_SJS + "?fmt=bogus", {
status: 404,
statusText: "Not Found",
type: "html",
fullMimeType: "text/html; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 24),
time: true
});
if (!isHTTPS) {
// 404 doesn't work on HTTPS test harness.
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(4),
"GET", sjsURL + "?fmt=bogus", {
status: 404,
statusText: "Not Found",
type: "html",
fullMimeType: "text/html; charset=utf-8",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 24),
time: true
});
}
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(5),
"GET", TEST_IMAGE, {
"GET", imageURL, {
fuzzyUrl: true,
status: 200,
statusText: "OK",
statusText: okStatus,
type: "png",
fullMimeType: "image/png",
size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 580),
time: true
});
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(6),
"GET", CONTENT_TYPE_SJS + "?fmt=gzip", {
"GET", sjsURL + "?fmt=gzip", {
status: 200,
statusText: "OK",
statusText: okStatus,
type: "plain",
fullMimeType: "text/plain",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 73),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 10.73),
time: true
});
if (isHTTPS) {
// Brotli is enabled only on HTTPS.
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(6),
"GET", sjsURL + "?fmt=gzip", {
status: 200,
statusText: okStatus,
type: "plain",
fullMimeType: "text/plain",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 73),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 10.73),
time: true
});
}
let onEvent = waitForResponseBodyDisplayed();
EventUtils.sendMouseEvent({ type: "mousedown" },
@ -116,6 +140,11 @@ add_task(function* () {
yield selectIndexAndWaitForTabUpdated(6);
yield testResponseTab("gzip");
if (isHTTPS) {
yield selectIndexAndWaitForTabUpdated(7);
yield testResponseTab("br");
}
yield teardown(monitor);
function* testResponseTab(type) {
@ -240,6 +269,17 @@ add_task(function* () {
"The mode active in the source editor is incorrect for the gzip request.");
break;
}
case "br": {
checkVisibility("textarea");
let expected = "X".repeat(64);
let editor = yield NetMonitorView.editor("#response-content-textarea");
is(editor.getText(), expected,
"The text shown in the source editor is incorrect for the brotli request.");
is(editor.getMode(), Editor.modes.text,
"The mode active in the source editor is incorrect for the brotli request.");
break;
}
}
}
@ -252,4 +292,12 @@ add_task(function* () {
function waitForResponseBodyDisplayed() {
return monitor.panelWin.once(monitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED);
}
}
add_task(function* () {
yield* content_type_test(false);
});
add_task(function* () {
yield* content_type_test(true);
});

Просмотреть файл

@ -16,7 +16,7 @@ add_task(function* () {
RequestsMenu.lazyUpdate = false;
let wait = waitForNetworkEvents(monitor, 7);
let wait = waitForNetworkEvents(monitor, 8);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});

Просмотреть файл

@ -18,7 +18,7 @@ add_task(function* () {
RequestsMenu.lazyUpdate = false;
let wait = waitForNetworkEvents(monitor, 7);
let wait = waitForNetworkEvents(monitor, 8);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});

Просмотреть файл

@ -44,7 +44,7 @@ add_task(function* () {
function waitForEvents() {
return promise.all([
waitForNetworkEvents(monitor, 7),
waitForNetworkEvents(monitor, 8),
monitor.panelWin.once(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED)
]);
}

Просмотреть файл

@ -15,7 +15,7 @@ add_task(function* test() {
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = true;
let onEvents = waitForNetworkEvents(monitor, 7);
let onEvents = waitForNetworkEvents(monitor, 8);
let onThumbnail = monitor.panelWin.once(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
yield performRequests();

Просмотреть файл

@ -13,12 +13,14 @@ var NetworkHelper = require("devtools/shared/webconsole/network-helper");
var { Toolbox } = require("devtools/client/framework/toolbox");
const EXAMPLE_URL = "http://example.com/browser/devtools/client/netmonitor/test/";
const HTTPS_EXAMPLE_URL = "https://example.com/browser/devtools/client/netmonitor/test/";
const API_CALLS_URL = EXAMPLE_URL + "html_api-calls-test-page.html";
const SIMPLE_URL = EXAMPLE_URL + "html_simple-test-page.html";
const NAVIGATE_URL = EXAMPLE_URL + "html_navigate-test-page.html";
const CONTENT_TYPE_URL = EXAMPLE_URL + "html_content-type-test-page.html";
const CONTENT_TYPE_WITHOUT_CACHE_URL = EXAMPLE_URL + "html_content-type-without-cache-test-page.html";
const HTTPS_CONTENT_TYPE_WITHOUT_CACHE_URL = HTTPS_EXAMPLE_URL + "html_content-type-without-cache-test-page.html";
const CYRILLIC_URL = EXAMPLE_URL + "html_cyrillic-test-page.html";
const STATUS_CODES_URL = EXAMPLE_URL + "html_status-codes-test-page.html";
const POST_DATA_URL = EXAMPLE_URL + "html_post-data-test-page.html";
@ -44,6 +46,7 @@ const CORS_URL = EXAMPLE_URL + "html_cors-test-page.html";
const SIMPLE_SJS = EXAMPLE_URL + "sjs_simple-test-server.sjs";
const CONTENT_TYPE_SJS = EXAMPLE_URL + "sjs_content-type-test-server.sjs";
const HTTPS_CONTENT_TYPE_SJS = HTTPS_EXAMPLE_URL + "sjs_content-type-test-server.sjs";
const STATUS_CODES_SJS = EXAMPLE_URL + "sjs_status-codes-test-server.sjs";
const SORTING_SJS = EXAMPLE_URL + "sjs_sorting-test-server.sjs";
const HTTPS_REDIRECT_SJS = EXAMPLE_URL + "sjs_https-redirect-test-server.sjs";
@ -54,6 +57,7 @@ const HSTS_BASE_URL = EXAMPLE_URL;
const HSTS_PAGE_URL = CUSTOM_GET_URL;
const TEST_IMAGE = EXAMPLE_URL + "test-image.png";
const HTTPS_TEST_IMAGE = HTTPS_EXAMPLE_URL + "test-image.png";
const TEST_IMAGE_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
const FRAME_SCRIPT_UTILS_URL = "chrome://devtools/content/shared/frame-script-utils.js";

Просмотреть файл

@ -35,7 +35,9 @@
get("sjs_content-type-test-server.sjs?fmt=bogus", function() {
get("test-image.png?v=" + Math.random(), function() {
get("sjs_content-type-test-server.sjs?fmt=gzip", function() {
// Done.
get("sjs_content-type-test-server.sjs?fmt=br", function() {
// Done.
});
});
});
});

Просмотреть файл

@ -232,6 +232,17 @@ function handleRequest(request, response) {
doubleGzipCompressString(data, observer);
break;
}
case "br": {
response.setStatusLine(request.httpVersion, status, "Connected");
response.setHeader("Content-Type", "text/plain", false);
response.setHeader("Content-Encoding", "br", false);
setCacheHeaders();
response.setHeader("Content-Length", "10", false);
// Use static data since we cannot encode brotli.
response.write("\x1b\x3f\x00\x00\x24\xb0\xe2\x99\x80\x12");
response.finish();
break;
}
case "hls-m3u8": {
response.setStatusLine(request.httpVersion, status, "OK");
response.setHeader("Content-Type", "application/x-mpegurl", false);

Просмотреть файл

@ -446,7 +446,7 @@ NetworkResponseListener.prototype = {
.getService(Ci.nsIStreamConverterService);
let encodings = encodingHeader.split(/\s*\t*,\s*\t*/);
let nextListener = this;
let acceptedEncodings = ["gzip", "deflate", "x-gzip", "x-deflate"];
let acceptedEncodings = ["gzip", "deflate", "br", "x-gzip", "x-deflate"];
for (let i in encodings) {
// There can be multiple conversions applied
let enc = encodings[i].toLowerCase();