Bug 589089 - NetworkPanel: Show hint if response content-type can't be displayed, r=sdwilsh, a=blocking2.0

This commit is contained in:
Rob Campbell 2010-10-04 18:51:00 -03:00
parent 2fed945ba6
commit e5a3d3f04b
5 changed files with 260 additions and 30 deletions

View File

@ -63,6 +63,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "sss",
"@mozilla.org/content/style-sheet-service;1",
"nsIStyleSheetService");
XPCOMUtils.defineLazyServiceGetter(this, "mimeService",
"@mozilla.org/mime;1",
"nsIMIMEService");
XPCOMUtils.defineLazyGetter(this, "NetUtil", function () {
var obj = {};
Cu.import("resource://gre/modules/NetUtil.jsm", obj);
@ -538,6 +542,76 @@ var NetworkHelper =
aCallback(NetworkHelper.readAndConvertFromStream(aInputStream,
contentCharset));
});
},
// This is a list of all the mime category maps jviereck could find in the
// firebug code base.
mimeCategoryMap: {
"text/plain": "txt",
"text/html": "html",
"text/xml": "xml",
"text/xsl": "txt",
"text/xul": "txt",
"text/css": "css",
"text/sgml": "txt",
"text/rtf": "txt",
"text/x-setext": "txt",
"text/richtext": "txt",
"text/javascript": "js",
"text/jscript": "txt",
"text/tab-separated-values": "txt",
"text/rdf": "txt",
"text/xif": "txt",
"text/ecmascript": "js",
"text/vnd.curl": "txt",
"text/x-json": "json",
"text/x-js": "txt",
"text/js": "txt",
"text/vbscript": "txt",
"view-source": "txt",
"view-fragment": "txt",
"application/xml": "xml",
"application/xhtml+xml": "xml",
"application/atom+xml": "xml",
"application/rss+xml": "xml",
"application/vnd.mozilla.maybe.feed": "xml",
"application/vnd.mozilla.xul+xml": "xml",
"application/javascript": "js",
"application/x-javascript": "js",
"application/x-httpd-php": "txt",
"application/rdf+xml": "xml",
"application/ecmascript": "js",
"application/http-index-format": "txt",
"application/json": "json",
"application/x-js": "txt",
"multipart/mixed": "txt",
"multipart/x-mixed-replace": "txt",
"image/svg+xml": "svg",
"application/octet-stream": "bin",
"image/jpeg": "image",
"image/jpg": "image",
"image/gif": "image",
"image/png": "image",
"image/bmp": "image",
"application/x-shockwave-flash": "flash",
"video/x-flv": "flash",
"audio/mpeg3": "media",
"audio/x-mpeg-3": "media",
"video/mpeg": "media",
"video/x-mpeg": "media",
"audio/ogg": "media",
"application/ogg": "media",
"application/x-ogg": "media",
"application/x-midi": "media",
"audio/midi": "media",
"audio/x-mid": "media",
"audio/x-midi": "media",
"music/crescendo": "media",
"audio/wav": "media",
"audio/x-wav": "media",
"text/json": "json",
"application/x-json": "json",
"application/json-rpc": "json"
}
}
@ -688,6 +762,43 @@ NetworkPanel.prototype =
return HUDService.getFormatStr("NetworkPanel." + aName, aArray);
},
/**
* Returns the content type of the response body. This is based on the
* response.header["Content-Type"] info. If this value is not available, then
* the content type is tried to be estimated by the url file ending.
*
* @returns string or null
* Content type or null if no content type could be figured out.
*/
get _contentType()
{
let response = this.httpActivity.response;
let contentTypeValue = null;
if (response.header && response.header["Content-Type"]) {
let types = response.header["Content-Type"].split(/,|;/);
for (let i = 0; i < types.length; i++) {
let type = NetworkHelper.mimeCategoryMap[types[i]];
if (type) {
return types[i];
}
}
}
// Try to get the content type from the request file extension.
let uri = NetUtil.newURI(this.httpActivity.url);
let mimeType = null;
if ((uri instanceof Ci.nsIURL) && uri.fileExtension) {
try {
mimeType = mimeService.getTypeFromExtension(uri.fileExtension);
} catch(e) {
// Added to prevent failures on OS X 64. No Flash?
Cu.reportError(e);
}
}
return mimeType;
},
/**
*
* @returns boolean
@ -695,18 +806,34 @@ NetworkPanel.prototype =
*/
get _responseIsImage()
{
let response = this.httpActivity.response;
if (!response || !response.header || !response.header["Content-Type"]) {
let request = this.httpActivity.request;
if (request.header["Accept"] &&
request.header["Accept"].indexOf("image/") != -1) {
return true;
}
else {
return false;
}
return NetworkHelper.mimeCategoryMap[this._contentType] == "image";
},
/**
*
* @returns boolean
* True if the response body contains text, false otherwise.
*/
get _isResponseBodyTextData()
{
let contentType = this._contentType;
if (contentType.indexOf("text/") == 0) {
return true;
}
switch (NetworkHelper.mimeCategoryMap[contentType]) {
case "txt":
case "js":
case "json":
case "css":
case "html":
case "svg":
case "xml":
return true;
default:
return false;
}
return response.header["Content-Type"].indexOf("image/") != -1;
},
/**
@ -988,6 +1115,26 @@ NetworkPanel.prototype =
aCachedContent || response.body);
},
/**
* Displays the `Unknown Content-Type hint` and sets the duration between the
* receiving of the response header on the NetworkPanel.
*
* @returns void
*/
_displayResponseBodyUnknownType: function NP_displayResponseBodyUnknownType()
{
let timing = this.httpActivity.timing;
this._displayNode("responseBodyUnknownType");
let deltaDuration =
Math.round((timing.RESPONSE_COMPLETE - timing.RESPONSE_HEADER) / 1000);
this._appendTextNode("responseBodyUnknownTypeInfo",
this._format("durationMS", [deltaDuration]));
this._appendTextNode("responseBodyUnknownTypeContent",
this._format("responseBodyUnableToDisplay.content", [this._contentType]));
},
/**
* Displays the `no response body` section and sets the the duration between
* the receiving of the response header and the end of the request.
@ -1075,6 +1222,10 @@ NetworkPanel.prototype =
this._displayResponseImage();
this._callIsDone();
}
else if (!this._isResponseBodyTextData) {
this._displayResponseBodyUnknownType();
this._callIsDone();
}
else if (response.body) {
this._displayResponseBody();
this._callIsDone();

View File

@ -109,6 +109,13 @@
<span id="responseNoBodyInfo" class="info">&Delta;</span>
</h1>
</div>
<div id="responseBodyUnknownType" style="display:none">
<h1>
&networkPanel.responseBodyUnknownType;
<span id="responseBodyUnknownTypeInfo" class="info">&Delta;</span>
</h1>
<div class="property-header" id="responseBodyUnknownTypeContent"></div>
</div>
<div id="responseImage" style="display:none">
<h1>
&networkPanel.responseImage;

View File

@ -691,7 +691,8 @@ function testNetworkPanel()
httpActivity.timing.RESPONSE_HEADER = 1000;
httpActivity.response.status = "999 earthquake win";
httpActivity.response.header = {
leaveHouses: "true"
leaveHouses: "true",
"Content-Type": "text/html"
}
networkPanel.update();
checkIsVisible(networkPanel, {
@ -915,26 +916,85 @@ function testNetworkPanel()
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.isDoneCallback = function NP_doneCallback() {
networkPanel.isDoneCallback = null;
checkIsVisible(networkPanel, {
requestBody: false,
requestFormData: true,
requestCookie: true,
responseContainer: true,
responseBody: false,
responseBodyCached: true,
responseNoBody: false,
responseImage: false,
responseImageCached: false
});
checkNodeContent(networkPanel, "responseBodyCachedContent", "<body>\u00fc\u00f6\u00E4</body>");
networkPanel.panel.hidePopup();
// Run the next test.
testErrorOnPageReload();
testDriver.next();
}
yield;
checkIsVisible(networkPanel, {
requestBody: false,
requestFormData: true,
requestCookie: true,
responseContainer: true,
responseBody: false,
responseBodyCached: true,
responseNoBody: false,
responseImage: false,
responseImageCached: false
});
checkNodeContent(networkPanel, "responseBodyCachedContent", "<body>\u00fc\u00f6\u00E4</body>");
networkPanel.panel.hidePopup();
// Test a response with a content type that can't be displayed in the
// NetworkPanel.
httpActivity.response.header["Content-Type"] = "application/x-shockwave-flash";
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.isDoneCallback = function NP_doneCallback() {
networkPanel.isDoneCallback = null;
testDriver.next();
}
yield;
checkIsVisible(networkPanel, {
requestBody: false,
requestFormData: true,
requestCookie: true,
responseContainer: true,
responseBody: false,
responseBodyCached: false,
responseBodyUnknownType: true,
responseNoBody: false,
responseImage: false,
responseImageCached: false
});
let responseString = HUDService.getFormatStr("NetworkPanel.responseBodyUnableToDisplay.content", ["application/x-shockwave-flash"]);
checkNodeContent(networkPanel, "responseBodyUnknownTypeContent", responseString);
networkPanel.panel.hidePopup();
// Test if the NetworkPanel figures out the content type based on an URL as
// well.
delete httpActivity.response.header["Content-Type"];
httpActivity.url = "http://www.test.com/someCrazyFile.swf?done=right&ending=txt"
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
networkPanel.isDoneCallback = function NP_doneCallback() {
networkPanel.isDoneCallback = null;
testDriver.next();
}
yield;
checkIsVisible(networkPanel, {
requestBody: false,
requestFormData: true,
requestCookie: true,
responseContainer: true,
responseBody: false,
responseBodyCached: false,
responseBodyUnknownType: true,
responseNoBody: false,
responseImage: false,
responseImageCached: false
});
checkNodeContent(networkPanel, "responseBodyUnknownTypeContent", responseString);
networkPanel.panel.hidePopup();
// Run the next test.
testErrorOnPageReload();
};
testDriver = testGen();

View File

@ -109,4 +109,15 @@ NetworkPanel.durationMS=%Sms
# The third %S is replaced by the duration between the response header and the
# response body event.
NetworkPanel.imageSizeDeltaDurationMS=%Sx%Spx, Δ%Sms
# LOCALIZATION NOTE (NetworkPanel.responseBodyUnableToDisplay.content):
#
# This string is displayed within the response body section of the NetworkPanel
# if the content type of the network request can't be displayed in the
# NetworkPanel. E.g. any kind of text is easy to display, but some audio or
# flash data received from the server can't be displayed.
#
# The %S is replaced by the content type, that can't be displayed, examples are
# o application/x-shockwave-flash
# o music/crescendo
NetworkPanel.responseBodyUnableToDisplay.content=Unable to display responses of type "%S"
ConsoleAPIDisabled=The Web Console logging API (console.log, console.info, console.warn, console.error) has been disabled by a script on this page.

View File

@ -10,6 +10,7 @@
<!ENTITY networkPanel.responseHeaders "Response Headers">
<!ENTITY networkPanel.responseBody "Response Body">
<!ENTITY networkPanel.responseBodyCached "Cached Data">
<!ENTITY networkPanel.responseBodyUnknownType "Unknown Content Type">
<!ENTITY networkPanel.responseNoBody "No Response Body">
<!ENTITY networkPanel.responseImage "Received Image">
<!ENTITY networkPanel.responseImageCached "Cached Image">