diff --git a/devtools/client/locales/en-US/netmonitor.properties b/devtools/client/locales/en-US/netmonitor.properties index e6f6b57dc43a..be383ab43a5b 100644 --- a/devtools/client/locales/en-US/netmonitor.properties +++ b/devtools/client/locales/en-US/netmonitor.properties @@ -501,6 +501,10 @@ netmonitor.toolbar.cookies=Cookies # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie netmonitor.toolbar.setCookies=Set-Cookies +# LOCALIZATION NOTE (netmonitor.toolbar.cookies): This is the label displayed +# in the network table toolbar, above the "scheme" column. +netmonitor.toolbar.scheme=Scheme + # LOCALIZATION NOTE (netmonitor.toolbar.transferred): This is the label displayed # in the network table toolbar, above the "transferred" column, which is the # compressed / encoded size. diff --git a/devtools/client/netmonitor/index.js b/devtools/client/netmonitor/index.js index 76ab15e861ea..ff590e3eb469 100644 --- a/devtools/client/netmonitor/index.js +++ b/devtools/client/netmonitor/index.js @@ -24,7 +24,7 @@ EventEmitter.decorate(window); pref("devtools.netmonitor.enabled", true); pref("devtools.netmonitor.filters", "[\"all\"]"); pref("devtools.netmonitor.hiddenColumns", - "[\"cookies\",\"protocol\",\"remoteip\",\"setCookies\"]"); + "[\"cookies\",\"protocol\",\"remoteip\",\"scheme\",\"setCookies\"]"); pref("devtools.netmonitor.panes-network-details-width", 550); pref("devtools.netmonitor.panes-network-details-height", 450); pref("devtools.netmonitor.har.defaultLogDir", ""); diff --git a/devtools/client/netmonitor/src/assets/styles/netmonitor.css b/devtools/client/netmonitor/src/assets/styles/netmonitor.css index 819d89413ae5..ba7c1758dd7d 100644 --- a/devtools/client/netmonitor/src/assets/styles/netmonitor.css +++ b/devtools/client/netmonitor/src/assets/styles/netmonitor.css @@ -447,6 +447,12 @@ body, width: 8%; } +/* Scheme column */ + +.requests-list-scheme { + width: 8%; +} + /* Domain column */ .requests-list-domain { diff --git a/devtools/client/netmonitor/src/components/moz.build b/devtools/client/netmonitor/src/components/moz.build index 6fc25c090217..650a760b6dbc 100644 --- a/devtools/client/netmonitor/src/components/moz.build +++ b/devtools/client/netmonitor/src/components/moz.build @@ -20,6 +20,7 @@ DevToolsModules( 'request-list-column-method.js', 'request-list-column-protocol.js', 'request-list-column-remote-ip.js', + 'request-list-column-scheme.js', 'request-list-column-set-cookies.js', 'request-list-column-status.js', 'request-list-column-transferred-size.js', diff --git a/devtools/client/netmonitor/src/components/request-list-column-scheme.js b/devtools/client/netmonitor/src/components/request-list-column-scheme.js new file mode 100644 index 000000000000..8765d6c4ee43 --- /dev/null +++ b/devtools/client/netmonitor/src/components/request-list-column-scheme.js @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { + createClass, + DOM, + PropTypes, +} = require("devtools/client/shared/vendor/react"); + +const { div } = DOM; + +const RequestListColumnScheme = createClass({ + displayName: "RequestListColumnScheme", + + propTypes: { + item: PropTypes.object.isRequired, + }, + + shouldComponentUpdate(nextProps) { + return this.props.item.urlDetails.scheme !== nextProps.item.urlDetails.scheme; + }, + + render() { + const { urlDetails } = this.props.item; + return ( + div({ + className: "requests-list-column requests-list-scheme", + title: urlDetails.scheme + }, + urlDetails.scheme + ) + ); + } +}); + +module.exports = RequestListColumnScheme; diff --git a/devtools/client/netmonitor/src/components/request-list-item.js b/devtools/client/netmonitor/src/components/request-list-item.js index 98877b52cabc..0d9058dd6ff4 100644 --- a/devtools/client/netmonitor/src/components/request-list-item.js +++ b/devtools/client/netmonitor/src/components/request-list-item.js @@ -22,6 +22,7 @@ const RequestListColumnFile = createFactory(require("./request-list-column-file" const RequestListColumnMethod = createFactory(require("./request-list-column-method")); const RequestListColumnProtocol = createFactory(require("./request-list-column-protocol")); const RequestListColumnRemoteIP = createFactory(require("./request-list-column-remote-ip")); +const RequestListColumnScheme = createFactory(require("./request-list-column-scheme")); const RequestListColumnSetCookies = createFactory(require("./request-list-column-set-cookies")); const RequestListColumnStatus = createFactory(require("./request-list-column-status")); const RequestListColumnTransferredSize = createFactory(require("./request-list-column-transferred-size")); @@ -135,6 +136,7 @@ const RequestListItem = createClass({ columns.get("method") && RequestListColumnMethod({ item }), columns.get("file") && RequestListColumnFile({ item }), columns.get("protocol") && RequestListColumnProtocol({ item }), + columns.get("scheme") && RequestListColumnScheme({ item }), columns.get("domain") && RequestListColumnDomain({ item, onSecurityIconClick }), columns.get("remoteip") && RequestListColumnRemoteIP({ item }), columns.get("cause") && RequestListColumnCause({ item, onCauseBadgeClick }), diff --git a/devtools/client/netmonitor/src/constants.js b/devtools/client/netmonitor/src/constants.js index e3620f5a636e..f19ccce14342 100644 --- a/devtools/client/netmonitor/src/constants.js +++ b/devtools/client/netmonitor/src/constants.js @@ -117,6 +117,10 @@ const HEADERS = [ name: "protocol", canFilter: true, }, + { + name: "scheme", + canFilter: true, + }, { name: "domain", canFilter: true, diff --git a/devtools/client/netmonitor/src/reducers/ui.js b/devtools/client/netmonitor/src/reducers/ui.js index 69c2d90ceff7..eb5c4867a7fe 100644 --- a/devtools/client/netmonitor/src/reducers/ui.js +++ b/devtools/client/netmonitor/src/reducers/ui.js @@ -23,6 +23,7 @@ const Columns = I.Record({ method: true, file: true, protocol: false, + scheme: false, domain: true, remoteip: false, cause: true, diff --git a/devtools/client/netmonitor/src/utils/filter-text-utils.js b/devtools/client/netmonitor/src/utils/filter-text-utils.js index 4273d2a22640..771979e2ff3a 100644 --- a/devtools/client/netmonitor/src/utils/filter-text-utils.js +++ b/devtools/client/netmonitor/src/utils/filter-text-utils.js @@ -38,7 +38,6 @@ const HEADER_FILTERS = HEADERS const FILTER_FLAGS = [ ...HEADER_FILTERS, - "scheme", "set-cookie-domain", "set-cookie-name", "set-cookie-value", @@ -182,8 +181,7 @@ function isFlagFilterMatch(item, { type, value, negative }) { } break; case "scheme": - let scheme = new URL(item.url).protocol.replace(":", "").toLowerCase(); - match = scheme === value; + match = item.urlDetails.scheme === value; break; case "regexp": try { diff --git a/devtools/client/netmonitor/src/utils/request-utils.js b/devtools/client/netmonitor/src/utils/request-utils.js index 1b7591216d98..e2bf2e823586 100644 --- a/devtools/client/netmonitor/src/utils/request-utils.js +++ b/devtools/client/netmonitor/src/utils/request-utils.js @@ -176,6 +176,17 @@ function getUrlHost(url) { return decodeUnicodeUrl((new URL(url)).host); } +/** + * Helpers for getting the shceme portion of a url. + * For example helper returns "http" from http://domain.com/path/basename + * + * @param {string} url - url string + * @return {string} string scheme of a url + */ +function getUrlScheme(url) { + return (new URL(url)).protocol.replace(":", "").toLowerCase(); +} + /** * Extract several details fields from a URL at once. */ @@ -184,6 +195,7 @@ function getUrlDetails(url) { let host = getUrlHost(url); let hostname = getUrlHostName(url); let unicodeUrl = decodeUnicodeUrl(url); + let scheme = getUrlScheme(url); // Mark local hosts specially, where "local" is as defined in the W3C // spec for secure contexts. @@ -202,6 +214,7 @@ function getUrlDetails(url) { return { baseNameWithQuery, host, + scheme, unicodeUrl, isLocal }; @@ -296,11 +309,12 @@ module.exports = { decodeUnicodeUrl, getAbbreviatedMimeType, getUrlBaseName, - getUrlQuery, getUrlBaseNameWithQuery, - getUrlHostName, - getUrlHost, getUrlDetails, + getUrlHost, + getUrlHostName, + getUrlQuery, + getUrlScheme, parseQueryString, parseFormData, propertiesEqual, diff --git a/devtools/client/netmonitor/src/utils/sort-predicates.js b/devtools/client/netmonitor/src/utils/sort-predicates.js index 3fe3b5d4d82f..e614c2ecae75 100644 --- a/devtools/client/netmonitor/src/utils/sort-predicates.js +++ b/devtools/client/netmonitor/src/utils/sort-predicates.js @@ -56,6 +56,11 @@ function protocol(first, second) { return result || waterfall(first, second); } +function scheme(first, second) { + const result = compareValues(first.urlDetails.scheme, second.urlDetails.scheme); + return result || waterfall(first, second); +} + function domain(first, second) { const firstDomain = first.urlDetails.host.toLowerCase(); const secondDomain = second.urlDetails.host.toLowerCase(); @@ -119,6 +124,7 @@ exports.Sorters = { method, file, protocol, + scheme, cookies, setCookies, domain, diff --git a/devtools/client/netmonitor/test/head.js b/devtools/client/netmonitor/test/head.js index 62e48acb83e9..560e69a21658 100644 --- a/devtools/client/netmonitor/test/head.js +++ b/devtools/client/netmonitor/test/head.js @@ -20,8 +20,9 @@ const { const { decodeUnicodeUrl, getUrlBaseName, - getUrlQuery, getUrlHost, + getUrlQuery, + getUrlScheme, } = require("devtools/client/netmonitor/src/utils/request-utils"); /* eslint-disable no-unused-vars, max-len */ @@ -380,6 +381,7 @@ function verifyRequestItemTarget(document, requestList, requestItem, method, let name = getUrlBaseName(url); let query = getUrlQuery(url); let host = getUrlHost(url); + let scheme = getUrlScheme(url); let { httpVersion = "", remoteAddress, remotePort } = requestItem; let formattedIPPort = getFormattedIPAndPort(remoteAddress, remotePort); let remoteIP = remoteAddress ? `${formattedIPPort}` : "unknown"; @@ -427,6 +429,12 @@ function verifyRequestItemTarget(document, requestList, requestItem, method, is(target.querySelector(".requests-list-remoteip").getAttribute("title"), remoteIP, "The tooltip remote IP is correct."); + is(target.querySelector(".requests-list-scheme").textContent, + scheme, "The displayed scheme is correct."); + + is(target.querySelector(".requests-list-scheme").getAttribute("title"), + scheme, "The tooltip scheme is correct."); + if (status !== undefined) { let value = target.querySelector(".requests-list-status-icon") .getAttribute("data-code"); diff --git a/devtools/client/preferences/devtools.js b/devtools/client/preferences/devtools.js index 574dd962ce40..15e241e67de3 100644 --- a/devtools/client/preferences/devtools.js +++ b/devtools/client/preferences/devtools.js @@ -150,7 +150,8 @@ pref("devtools.netmonitor.enabled", true); pref("devtools.netmonitor.panes-network-details-width", 550); pref("devtools.netmonitor.panes-network-details-height", 450); pref("devtools.netmonitor.filters", "[\"all\"]"); -pref("devtools.netmonitor.hiddenColumns", "[\"cookies\",\"protocol\",\"remoteip\",\"setCookies\"]"); +pref("devtools.netmonitor.hiddenColumns", + "[\"cookies\",\"protocol\",\"remoteip\",\"scheme\",\"setCookies\"]"); // The default Network monitor HAR export setting pref("devtools.netmonitor.har.defaultLogDir", "");