Reviewed by Pavel Feldman.
Web Inspector: Enable raw HTTP headers support
https://bugs.webkit.org/show_bug.cgi?id=58259
Added raw headers text support to inspector.
* English.lproj/localizedStrings.js:
* inspector/Inspector.json:
* inspector/InspectorResourceAgent.cpp:
(WebCore::buildObjectForResourceResponse):
* inspector/front-end/NetworkManager.js:
(WebInspector.NetworkDispatcher.prototype._updateResourceWithResponse):
* inspector/front-end/Resource.js:
(WebInspector.Resource):
(WebInspector.Resource.prototype.get transferSize):
(WebInspector.Resource.prototype.set requestHeaders):
(WebInspector.Resource.prototype.get rawRequestHeadersText):
(WebInspector.Resource.prototype.set rawRequestHeadersText):
(WebInspector.Resource.prototype.get requestHeadersSize):
(WebInspector.Resource.prototype.set responseHeaders):
(WebInspector.Resource.prototype.get rawResponseHeadersText):
(WebInspector.Resource.prototype.set rawResponseHeadersText):
(WebInspector.Resource.prototype.get responseHeadersSize):
(WebInspector.Resource.prototype._headersSize):
* inspector/front-end/ResourceHeadersView.js:
(WebInspector.ResourceHeadersView):
(WebInspector.ResourceHeadersView.prototype._refreshParms):
(WebInspector.ResourceHeadersView.prototype._refreshRequestHeaders):
(WebInspector.ResourceHeadersView.prototype._refreshResponseHeaders):
(WebInspector.ResourceHeadersView.prototype._refreshHeadersTitle):
(WebInspector.ResourceHeadersView.prototype._refreshHeaders):
(WebInspector.ResourceHeadersView.prototype._refreshRawHeadersText):
(WebInspector.ResourceHeadersView.prototype._toggleRawRequestHeadersText):
(WebInspector.ResourceHeadersView.prototype._toggleRawResponseHeadersText):
(WebInspector.ResourceHeadersView.prototype._createToggleButton):
(WebInspector.ResourceHeadersView.prototype._createHeadersToggleButton):
* inspector/front-end/networkPanel.css:
(.resource-headers-view .outline-disclosure li .header-toggle):
(.resource-headers-view .outline-disclosure li.expanded .header-toggle):
(.resource-headers-view .outline-disclosure li .header-toggle:hover):
(.resource-headers-view .outline-disclosure li.raw-headers-text):
* platform/network/ResourceLoadInfo.h:
2011-04-14 Vsevolod Vlasov <vsevik@chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: Enable raw HTTP headers support
https://bugs.webkit.org/show_bug.cgi?id=58259
Added raw headers text support to inspector.
* public/WebHTTPLoadInfo.h:
* src/WebHTTPLoadInfo.cpp:
(WebKit::WebHTTPLoadInfo::rawRequestHeadersText):
(WebKit::WebHTTPLoadInfo::setRawRequestHeadersText):
(WebKit::WebHTTPLoadInfo::rawResponseHeadersText):
(WebKit::WebHTTPLoadInfo::setRawResponseHeadersText):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@83950
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2011-04-14 Vsevolod Vlasov <vsevik@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: Enable raw HTTP headers support
+ https://bugs.webkit.org/show_bug.cgi?id=58259
+
+ Added raw headers text support to inspector.
+
+ * English.lproj/localizedStrings.js:
+ * inspector/Inspector.json:
+ * inspector/InspectorResourceAgent.cpp:
+ (WebCore::buildObjectForResourceResponse):
+ * inspector/front-end/NetworkManager.js:
+ (WebInspector.NetworkDispatcher.prototype._updateResourceWithResponse):
+ * inspector/front-end/Resource.js:
+ (WebInspector.Resource):
+ (WebInspector.Resource.prototype.get transferSize):
+ (WebInspector.Resource.prototype.set requestHeaders):
+ (WebInspector.Resource.prototype.get rawRequestHeadersText):
+ (WebInspector.Resource.prototype.set rawRequestHeadersText):
+ (WebInspector.Resource.prototype.get requestHeadersSize):
+ (WebInspector.Resource.prototype.set responseHeaders):
+ (WebInspector.Resource.prototype.get rawResponseHeadersText):
+ (WebInspector.Resource.prototype.set rawResponseHeadersText):
+ (WebInspector.Resource.prototype.get responseHeadersSize):
+ (WebInspector.Resource.prototype._headersSize):
+ * inspector/front-end/ResourceHeadersView.js:
+ (WebInspector.ResourceHeadersView):
+ (WebInspector.ResourceHeadersView.prototype._refreshParms):
+ (WebInspector.ResourceHeadersView.prototype._refreshRequestHeaders):
+ (WebInspector.ResourceHeadersView.prototype._refreshResponseHeaders):
+ (WebInspector.ResourceHeadersView.prototype._refreshHeadersTitle):
+ (WebInspector.ResourceHeadersView.prototype._refreshHeaders):
+ (WebInspector.ResourceHeadersView.prototype._refreshRawHeadersText):
+ (WebInspector.ResourceHeadersView.prototype._toggleRawRequestHeadersText):
+ (WebInspector.ResourceHeadersView.prototype._toggleRawResponseHeadersText):
+ (WebInspector.ResourceHeadersView.prototype._createToggleButton):
+ (WebInspector.ResourceHeadersView.prototype._createHeadersToggleButton):
+ * inspector/front-end/networkPanel.css:
+ (.resource-headers-view .outline-disclosure li .header-toggle):
+ (.resource-headers-view .outline-disclosure li.expanded .header-toggle):
+ (.resource-headers-view .outline-disclosure li .header-toggle:hover):
+ (.resource-headers-view .outline-disclosure li.raw-headers-text):
+ * platform/network/ResourceLoadInfo.h:
+
2011-04-14 Justin Novosad <junov@chromium.org>
Reviewed by Kenneth Russell.
{ "name": "status", "type": "number", "description": "HTTP response status code." },
{ "name": "statusText", "type": "string", "description": "HTTP response status text." },
{ "name": "headers", "type": "object", "description": "HTTP response headers." },
+ { "name": "rawHeadersText", "type": "string", "optional": true, "description": "Raw HTTP response headers text." },
{ "name": "mimeType", "type": "string", "description": "Resource mimeType as determined by the browser." },
{ "name": "requestHeaders", "type": "object", "optional": true, "description": "Refined HTTP request headers that were actually transmitted over the network." },
+ { "name": "rawRequestHeadersText", "type": "string", "optional": true, "description": "Raw HTTP request headers text." },
{ "name": "connectionReused", "type": "boolean", "description": "Specifies whether physical connection was actually reused for this request." },
{ "name": "connectionID", "type": "number", "description": "Physical connection id that was actually used for this request." },
{ "name": "fromDiskCache", "type": "boolean", "optional": true, "description": "Specifies that the resource was loaded from the disk cache." },
RefPtr<InspectorObject> responseObject = InspectorObject::create();
responseObject->setNumber("status", response.resourceLoadInfo() ? response.resourceLoadInfo()->httpStatusCode : response.httpStatusCode());
responseObject->setString("statusText", response.resourceLoadInfo() ? response.resourceLoadInfo()->httpStatusText : response.httpStatusText());
- responseObject->setObject("headers", buildObjectForHeaders(response.resourceLoadInfo() ? response.resourceLoadInfo()->responseHeaders : response.httpHeaderFields()));
responseObject->setString("mimeType", response.mimeType());
responseObject->setBoolean("connectionReused", response.connectionReused());
if (response.resourceLoadTiming())
responseObject->setObject("timing", buildObjectForTiming(*response.resourceLoadTiming()));
- if (response.resourceLoadInfo())
+ if (response.resourceLoadInfo()) {
+ responseObject->setObject("headers", buildObjectForHeaders(response.resourceLoadInfo()->responseHeaders));
+ if (!response.resourceLoadInfo()->rawResponseHeadersText.isEmpty())
+ responseObject->setString("rawHeadersText", response.resourceLoadInfo()->rawResponseHeadersText);
+
responseObject->setObject("requestHeaders", buildObjectForHeaders(response.resourceLoadInfo()->requestHeaders));
+ if (!response.resourceLoadInfo()->rawRequestHeadersText.isEmpty())
+ responseObject->setString("rawRequestHeadersText", response.resourceLoadInfo()->rawRequestHeadersText);
+ } else
+ responseObject->setObject("headers", buildObjectForHeaders(response.httpHeaderFields()));
return responseObject;
}
resource.statusCode = response.status;
resource.statusText = response.statusText;
resource.responseHeaders = response.headers;
- // Raw request headers can be a part of response as well.
+ if (response.rawHeadersText)
+ resource.rawResponseHeadersText = response.rawHeadersText;
if (response.requestHeaders)
resource.requestHeaders = response.requestHeaders;
+ if (response.rawRequestHeadersText)
+ resource.rawRequestHeadersText = response.rawRequestHeadersText;
resource.connectionReused = response.connectionReused;
resource.connectionID = response.connectionID;
this._endTime = -1;
this._category = WebInspector.resourceCategories.other;
this._pendingContentCallbacks = [];
- this._responseHeadersSize = 0;
}
// Keep these in sync with WebCore::InspectorResource::Type
if (this.cached)
return 0;
if (this.statusCode === 304) // Not modified
- return this._responseHeadersSize;
+ return this.responseHeadersSize;
if (this._transferSize !== undefined)
return this._transferSize;
// If we did not receive actual transfer size from network
// work for chunks with non-trivial encodings. We need a way to
// get actual transfer size from the network stack.
var bodySize = Number(this.responseHeaders["Content-Length"] || this.resourceSize);
- return this._responseHeadersSize + bodySize;
+ return this.responseHeadersSize + bodySize;
},
increaseTransferSize: function(x)
this._requestHeaders = x;
delete this._sortedRequestHeaders;
delete this._requestCookies;
+ delete this._responseHeadersSize;
this.dispatchEventToListeners("requestHeaders changed");
},
+ get rawRequestHeadersText()
+ {
+ return this._rawRequestHeadersText;
+ },
+
+ set rawRequestHeadersText(x)
+ {
+ this._rawRequestHeadersText = x;
+ delete this._responseHeadersSize;
+
+ this.dispatchEventToListeners("requestHeaders changed");
+ },
+
+ get requestHeadersSize()
+ {
+ if (typeof(this._requestHeadersSize) === "undefined") {
+ if (this._rawRequestHeadersText)
+ this._requestHeadersSize = this._rawRequestHeadersText.length;
+ else
+ this._requestHeadersSize = this._headersSize(this._requestHeaders)
+ }
+ return this._requestHeadersSize;
+ },
+
get sortedRequestHeaders()
{
if (this._sortedRequestHeaders !== undefined)
set responseHeaders(x)
{
this._responseHeaders = x;
- // FIXME: we should take actual headers size from network stack, when possible.
- this._responseHeadersSize = this._headersSize(x);
+ delete this._responseHeadersSize;
delete this._sortedResponseHeaders;
delete this._responseCookies;
this.dispatchEventToListeners("responseHeaders changed");
},
+
+ get rawResponseHeadersText()
+ {
+ return this._rawResponseHeadersText;
+ },
+
+ set rawResponseHeadersText(x)
+ {
+ this._rawResponseHeadersText = x;
+ delete this._responseHeadersSize;
+
+ this.dispatchEventToListeners("responseHeaders changed");
+ },
+
+ get responseHeadersSize()
+ {
+ if (typeof(this._responseHeadersSize) === "undefined") {
+ if (this._rawResponseHeadersText)
+ this._responseHeadersSize = this._rawResponseHeadersText.length;
+ else
+ this._responseHeadersSize = this._headersSize(this._responseHeaders)
+ }
+ return this._responseHeadersSize;
+ },
+
get sortedResponseHeaders()
{
_headersSize: function(headers)
{
+ // We should take actual headers size from network stack, when possible, but fall back to
+ // this lousy computation when no raw headers are available.
var size = 0;
for (var header in headers)
- size += header.length + headers[header].length + 3; // _typical_ overhead per herader is ": ".length + "\n".length.
+ size += header.length + headers[header].length + 4; // _typical_ overhead per header is ": ".length + "\r\n".length.
return size;
},
this._requestHeadersTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._requestHeadersTreeElement);
- this._decodeHover = WebInspector.UIString("Double-Click to toggle between URL encoded and decoded formats");
this._decodeRequestParameters = true;
+ this._showRawRequestHeadersText = false;
+ this._showRawResponseHeadersText = false;
+
this._queryStringTreeElement = new TreeElement("", null, true);
this._queryStringTreeElement.expanded = true;
this._queryStringTreeElement.selectable = false;
{
parmsTreeElement.removeChildren();
- parmsTreeElement.titleHTML = title + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", parms.length) + "</span>";
+ parmsTreeElement.listItemElement.removeChildren();
+ parmsTreeElement.listItemElement.appendChild(document.createTextNode(title));
+
+ var headerCount = document.createElement("span");
+ headerCount.addStyleClass("header-count");
+ headerCount.textContent = WebInspector.UIString(" (%d)", parms.length);
+ parmsTreeElement.listItemElement.appendChild(headerCount);
+
+ var toggleTitle = this._decodeRequestParameters ? WebInspector.UIString("view URL encoded") : WebInspector.UIString("view decoded");
+ var toggleButton = this._createToggleButton(toggleTitle);
+ toggleButton.addEventListener("click", this._toggleURLdecoding.bind(this));
+ parmsTreeElement.listItemElement.appendChild(toggleButton);
+
for (var i = 0; i < parms.length; ++i) {
var name = parms[i].name;
var parmTreeElement = new TreeElement(null, null, false);
parmTreeElement.titleHTML = title;
parmTreeElement.selectable = false;
- parmTreeElement.tooltip = this._decodeHover;
- parmTreeElement.ondblclick = this._toggleURLdecoding.bind(this);
parmsTreeElement.appendChild(parmTreeElement);
}
},
var additionalRow = null;
if (typeof this._resource.webSocketRequestKey3 !== "undefined")
additionalRow = {header: "(Key3)", value: this._resource.webSocketRequestKey3};
- this._refreshHeaders(WebInspector.UIString("Request Headers"), this._resource.sortedRequestHeaders, additionalRow, this._requestHeadersTreeElement);
+ if (this._showRawRequestHeadersText)
+ this._refreshRawHeadersText(WebInspector.UIString("Request Headers"), this._resource.rawRequestHeadersText, this._requestHeadersTreeElement);
+ else
+ this._refreshHeaders(WebInspector.UIString("Request Headers"), this._resource.sortedRequestHeaders, additionalRow, this._requestHeadersTreeElement);
+
+ if (this._resource.rawRequestHeadersText) {
+ var toggleButton = this._createHeadersToggleButton(this._showRawRequestHeadersText);
+ toggleButton.addEventListener("click", this._toggleRawRequestHeadersText.bind(this));
+ this._requestHeadersTreeElement.listItemElement.appendChild(toggleButton);
+ }
+
this._refreshFormData();
},
var additionalRow = null;
if (typeof this._resource.webSocketChallengeResponse !== "undefined")
additionalRow = {header: "(Challenge Response)", value: this._resource.webSocketChallengeResponse};
- this._refreshHeaders(WebInspector.UIString("Response Headers"), this._resource.sortedResponseHeaders, additionalRow, this._responseHeadersTreeElement);
+ if (this._showRawResponseHeadersText)
+ this._refreshRawHeadersText(WebInspector.UIString("Response Headers"), this._resource.rawResponseHeadersText, this._responseHeadersTreeElement);
+ else
+ this._refreshHeaders(WebInspector.UIString("Response Headers"), this._resource.sortedResponseHeaders, additionalRow, this._responseHeadersTreeElement);
+
+ if (this._resource.rawResponseHeadersText) {
+ var toggleButton = this._createHeadersToggleButton(this._showRawResponseHeadersText);
+ toggleButton.addEventListener("click", this._toggleRawResponseHeadersText.bind(this));
+ this._responseHeadersTreeElement.listItemElement.appendChild(toggleButton);
+ }
},
_refreshHTTPInformation: function()
}
},
+ _refreshHeadersTitle: function(title, headersTreeElement, isRawHeadersTextShown, headersLength)
+ {
+ headersTreeElement.listItemElement.removeChildren();
+ headersTreeElement.listItemElement.appendChild(document.createTextNode(title));
+
+ if (!isRawHeadersTextShown) {
+ var headerCount = document.createElement("span");
+ headerCount.addStyleClass("header-count");
+ headerCount.textContent = WebInspector.UIString(" (%d)", headersLength);
+ headersTreeElement.listItemElement.appendChild(headerCount);
+ }
+ },
+
_refreshHeaders: function(title, headers, additionalRow, headersTreeElement)
{
headersTreeElement.removeChildren();
-
+
var length = headers.length;
- headersTreeElement.titleHTML = title.escapeHTML() + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", length) + "</span>";
+ this._refreshHeadersTitle(title, headersTreeElement, false, length);
headersTreeElement.hidden = !length;
-
- var length = headers.length;
for (var i = 0; i < length; ++i) {
var title = "<div class=\"header-name\">" + headers[i].header.escapeHTML() + ":</div>";
title += "<div class=\"header-value source-code\">" + headers[i].value.escapeHTML() + "</div>"
headerTreeElement.selectable = false;
headersTreeElement.appendChild(headerTreeElement);
}
+ },
+
+ _refreshRawHeadersText: function(title, rawHeadersText, headersTreeElement)
+ {
+ headersTreeElement.removeChildren();
+
+ this._refreshHeadersTitle(title, headersTreeElement, true);
+ var headerTreeElement = new TreeElement(null, null, false);
+ headerTreeElement.selectable = false;
+ headersTreeElement.appendChild(headerTreeElement);
+ headerTreeElement.listItemElement.addStyleClass("raw-headers-text");
+
+ var rawHeadersTextElement = document.createElement("span");
+ rawHeadersTextElement.addStyleClass("header-value");
+ rawHeadersTextElement.addStyleClass("source-code");
+ rawHeadersTextElement.textContent = String(rawHeadersText).trim();
+ headerTreeElement.listItemElement.appendChild(rawHeadersTextElement);
+ },
+
+ _toggleRawRequestHeadersText: function(event)
+ {
+ this._showRawRequestHeadersText = !this._showRawRequestHeadersText;
+ this._refreshRequestHeaders();
+ },
+
+ _toggleRawResponseHeadersText: function(event)
+ {
+ this._showRawResponseHeadersText = !this._showRawResponseHeadersText;
+ this._refreshResponseHeaders();
+ },
+
+ _createToggleButton: function(title)
+ {
+ var button = document.createElement("span");
+ button.addStyleClass("header-toggle");
+ button.textContent = title;
+ return button;
+ },
+
+ _createHeadersToggleButton: function(isRawHeadersTextShown)
+ {
+ var toggleTitle = isRawHeadersTextShown ? WebInspector.UIString("view parsed") : WebInspector.UIString("view source");
+ return this._createToggleButton(toggleTitle);
}
}
display: none;
}
+.resource-headers-view .outline-disclosure li .header-toggle {
+ display: none;
+}
+
+.resource-headers-view .outline-disclosure li.expanded .header-toggle {
+ display: inline;
+ margin-left: 30px;
+ font-weight: normal;
+ color: rgb(45%, 45%, 45%);
+}
+
+.resource-headers-view .outline-disclosure li .header-toggle:hover {
+ color: rgb(20%, 20%, 45%);
+ cursor: pointer;
+}
+
.resource-headers-view .outline-disclosure .header-name {
color: rgb(33%, 33%, 33%);
display: inline-block;
margin-top: 1px;
}
+.resource-headers-view .outline-disclosure li.raw-headers-text {
+ text-indent: 0;
+ margin-left: -2px;
+}
+
.resource-headers-view .outline-disclosure .raw-form-data {
white-space: pre-wrap;
}
long long encodedDataLength;
HTTPHeaderMap requestHeaders;
HTTPHeaderMap responseHeaders;
+ String rawRequestHeadersText;
+ String rawResponseHeadersText;
};
}
Reviewed by Pavel Feldman.
+ Web Inspector: Enable raw HTTP headers support
+ https://bugs.webkit.org/show_bug.cgi?id=58259
+
+ Added raw headers text support to inspector.
+
+ * public/WebHTTPLoadInfo.h:
+ * src/WebHTTPLoadInfo.cpp:
+ (WebKit::WebHTTPLoadInfo::rawRequestHeadersText):
+ (WebKit::WebHTTPLoadInfo::setRawRequestHeadersText):
+ (WebKit::WebHTTPLoadInfo::rawResponseHeadersText):
+ (WebKit::WebHTTPLoadInfo::setRawResponseHeadersText):
+
+2011-04-14 Vsevolod Vlasov <vsevik@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
Web Inspector: ResourceResponse should have encodedDataLength field for synchronous requests transfer size
https://bugs.webkit.org/show_bug.cgi?id=58447
WEBKIT_API void addRequestHeader(const WebString& name, const WebString& value);
WEBKIT_API void addResponseHeader(const WebString& name, const WebString& value);
+ WEBKIT_API WebString rawRequestHeadersText() const;
+ WEBKIT_API void setRawRequestHeadersText(const WebString&);
+
+ WEBKIT_API WebString rawResponseHeadersText() const;
+ WEBKIT_API void setRawResponseHeadersText(const WebString&);
+
#if WEBKIT_IMPLEMENTATION
WebHTTPLoadInfo(WTF::PassRefPtr<WebCore::ResourceLoadInfo>);
operator WTF::PassRefPtr<WebCore::ResourceLoadInfo>() const;
addHeader(&m_private->responseHeaders, name, value);
}
+WebString WebHTTPLoadInfo::rawRequestHeadersText() const
+{
+ ASSERT(!m_private.isNull());
+ return m_private->rawRequestHeadersText;
+}
+
+void WebHTTPLoadInfo::setRawRequestHeadersText(const WebString& rawHeadersText)
+{
+ ASSERT(!m_private.isNull());
+ m_private->rawRequestHeadersText = rawHeadersText;
+}
+
+WebString WebHTTPLoadInfo::rawResponseHeadersText() const
+{
+ ASSERT(!m_private.isNull());
+ return m_private->rawResponseHeadersText;
+}
+
+void WebHTTPLoadInfo::setRawResponseHeadersText(const WebString& rawHeadersText)
+{
+ ASSERT(!m_private.isNull());
+ m_private->rawResponseHeadersText = rawHeadersText;
+}
+
} // namespace WebKit