[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
commit-queue at webkit.org
commit-queue at webkit.org
Wed Dec 22 13:23:58 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 44ca3efdb64c65d57aba2a6448d3804c77370b50
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Sep 14 06:27:38 2010 +0000
2010-09-13 Yuta Kitamura <yutak at chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: WebSocket in Resources tab
https://bugs.webkit.org/show_bug.cgi?id=40768
* inspector/extensions-api-expected.txt: Added a new resource type.
2010-09-13 Yuta Kitamura <yutak at chromium.org>
Reviewed by Pavel Feldman.
Add WebSocket resource type to Web Inspector.
When a new WebSocket connection is established, a line for that connection
will appear in Web Inspector's Resources tab. If the resource name is
clicked, the details of handshake request and response will be shown.
Web Inspector: WebSocket in Resources tab
https://bugs.webkit.org/show_bug.cgi?id=40768
* inspector/InspectorController.cpp:
(WebCore::InspectorController::addResource): WebSocket resource does not
have an associated loader, thus frame might be null. Need to check it.
(WebCore::InspectorController::removeResource): Ditto.
(WebCore::InspectorController::didCreateWebSocket):
(WebCore::InspectorController::willSendWebSocketHandshakeRequest):
(WebCore::InspectorController::didReceiveWebSocketHandshakeResponse):
(WebCore::InspectorController::didCloseWebSocket):
* inspector/InspectorController.h:
* inspector/InspectorResource.cpp: Add null checks of m_loader and m_frame,
because WebSocket does not have a loader and we need to allow null for
these variables.
(WebCore::createReadableStringFromBinary):
(WebCore::InspectorResource::InspectorResource):
(WebCore::InspectorResource::create): Factory function of
regular (non-WebSocket) resources.
(WebCore::InspectorResource::createWebSocket): Factory function of
WebSocket resources.
(WebCore::InspectorResource::updateWebSocketRequest):
(WebCore::InspectorResource::updateWebSocketResponse):
(WebCore::InspectorResource::updateScriptObject): m_frame->document() becomes
available when Frame::setDocument() is called. We cannot obtain documentURL
during the constructor or updateRequest() function, because m_frame->document()
is not available yet at that point and documentURL will contain a wrong URL.
As far as I know, updateScriptObject() is the only place where we can safely
obtain documentURL.
(WebCore::InspectorResource::cachedResource):
(WebCore::InspectorResource::type):
(WebCore::InspectorResource::resourceData):
* inspector/InspectorResource.h:
(WebCore::InspectorResource::):
(WebCore::InspectorResource::markWebSocket):
* inspector/front-end/Resource.js:
(WebInspector.Resource.Type.toString):
(WebInspector.Resource.prototype.set type):
(WebInspector.Resource.prototype._mimeTypeIsConsistentWithType):
* inspector/front-end/ResourceView.js:
(WebInspector.ResourceView.prototype._refreshRequestHeaders):
(WebInspector.ResourceView.prototype._refreshResponseHeaders):
(WebInspector.ResourceView.prototype._refreshHeaders):
* inspector/front-end/inspector.css:
(.resources-category-websockets, .resources-category-other):
(.resources-category-websockets .resources-graph-bar):
(.resources-category-websockets.resource-cached .resources-graph-bar):
* inspector/front-end/inspector.js:
(WebInspector.loaded):
(WebInspector.updateResource):
* websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::WebSocketChannel):
(WebCore::WebSocketChannel::disconnect):
(WebCore::WebSocketChannel::didOpen):
(WebCore::WebSocketChannel::didClose):
(WebCore::WebSocketChannel::processBuffer):
(WebCore::WebSocketChannel::identifier):
* websockets/WebSocketChannel.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67447 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 8cc2f12..54e0cad 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,12 @@
+2010-09-13 Yuta Kitamura <yutak at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: WebSocket in Resources tab
+ https://bugs.webkit.org/show_bug.cgi?id=40768
+
+ * inspector/extensions-api-expected.txt: Added a new resource type.
+
2010-09-13 Ryosuke Niwa <rniwa at webkit.org>
Reviewed by Darin Adler.
diff --git a/LayoutTests/inspector/extensions-api-expected.txt b/LayoutTests/inspector/extensions-api-expected.txt
index 3e66ab6..95d3a26 100644
--- a/LayoutTests/inspector/extensions-api-expected.txt
+++ b/LayoutTests/inspector/extensions-api-expected.txt
@@ -54,6 +54,7 @@ RUNNING TEST: extension_testAPI
Script : "script"
XHR : "XHR"
Media : "media"
+ WebSocket : "WebSocket"
Other : "other"
}
getAll : <function>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 48afca0..c03ca8d 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,72 @@
+2010-09-13 Yuta Kitamura <yutak at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Add WebSocket resource type to Web Inspector.
+
+ When a new WebSocket connection is established, a line for that connection
+ will appear in Web Inspector's Resources tab. If the resource name is
+ clicked, the details of handshake request and response will be shown.
+
+ Web Inspector: WebSocket in Resources tab
+ https://bugs.webkit.org/show_bug.cgi?id=40768
+
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::addResource): WebSocket resource does not
+ have an associated loader, thus frame might be null. Need to check it.
+ (WebCore::InspectorController::removeResource): Ditto.
+ (WebCore::InspectorController::didCreateWebSocket):
+ (WebCore::InspectorController::willSendWebSocketHandshakeRequest):
+ (WebCore::InspectorController::didReceiveWebSocketHandshakeResponse):
+ (WebCore::InspectorController::didCloseWebSocket):
+ * inspector/InspectorController.h:
+ * inspector/InspectorResource.cpp: Add null checks of m_loader and m_frame,
+ because WebSocket does not have a loader and we need to allow null for
+ these variables.
+ (WebCore::createReadableStringFromBinary):
+ (WebCore::InspectorResource::InspectorResource):
+ (WebCore::InspectorResource::create): Factory function of
+ regular (non-WebSocket) resources.
+ (WebCore::InspectorResource::createWebSocket): Factory function of
+ WebSocket resources.
+ (WebCore::InspectorResource::updateWebSocketRequest):
+ (WebCore::InspectorResource::updateWebSocketResponse):
+ (WebCore::InspectorResource::updateScriptObject): m_frame->document() becomes
+ available when Frame::setDocument() is called. We cannot obtain documentURL
+ during the constructor or updateRequest() function, because m_frame->document()
+ is not available yet at that point and documentURL will contain a wrong URL.
+ As far as I know, updateScriptObject() is the only place where we can safely
+ obtain documentURL.
+ (WebCore::InspectorResource::cachedResource):
+ (WebCore::InspectorResource::type):
+ (WebCore::InspectorResource::resourceData):
+ * inspector/InspectorResource.h:
+ (WebCore::InspectorResource::):
+ (WebCore::InspectorResource::markWebSocket):
+ * inspector/front-end/Resource.js:
+ (WebInspector.Resource.Type.toString):
+ (WebInspector.Resource.prototype.set type):
+ (WebInspector.Resource.prototype._mimeTypeIsConsistentWithType):
+ * inspector/front-end/ResourceView.js:
+ (WebInspector.ResourceView.prototype._refreshRequestHeaders):
+ (WebInspector.ResourceView.prototype._refreshResponseHeaders):
+ (WebInspector.ResourceView.prototype._refreshHeaders):
+ * inspector/front-end/inspector.css:
+ (.resources-category-websockets, .resources-category-other):
+ (.resources-category-websockets .resources-graph-bar):
+ (.resources-category-websockets.resource-cached .resources-graph-bar):
+ * inspector/front-end/inspector.js:
+ (WebInspector.loaded):
+ (WebInspector.updateResource):
+ * websockets/WebSocketChannel.cpp:
+ (WebCore::WebSocketChannel::WebSocketChannel):
+ (WebCore::WebSocketChannel::disconnect):
+ (WebCore::WebSocketChannel::didOpen):
+ (WebCore::WebSocketChannel::didClose):
+ (WebCore::WebSocketChannel::processBuffer):
+ (WebCore::WebSocketChannel::identifier):
+ * websockets/WebSocketChannel.h:
+
2010-09-13 W. James MacLean <wjmaclean at google.com>
Reviewed by Darin Fisher.
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index 8695758..90ef344 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -800,6 +800,8 @@ void InspectorController::addResource(InspectorResource* resource)
m_knownResources.add(resource->requestURL());
Frame* frame = resource->frame();
+ if (!frame)
+ return;
ResourcesMap* resourceMap = m_frameResources.get(frame);
if (resourceMap)
resourceMap->set(resource->identifier(), resource);
@@ -818,6 +820,8 @@ void InspectorController::removeResource(InspectorResource* resource)
m_knownResources.remove(requestURL);
Frame* frame = resource->frame();
+ if (!frame)
+ return;
ResourcesMap* resourceMap = m_frameResources.get(frame);
if (!resourceMap) {
ASSERT_NOT_REACHED();
@@ -1444,6 +1448,56 @@ InspectorDOMStorageResource* InspectorController::getDOMStorageResourceForId(lon
}
#endif
+#if ENABLE(WEB_SOCKETS)
+void InspectorController::didCreateWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL)
+{
+ if (!enabled())
+ return;
+ ASSERT(m_inspectedPage);
+
+ RefPtr<InspectorResource> resource = InspectorResource::createWebSocket(identifier, requestURL, documentURL);
+ addResource(resource.get());
+
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
+}
+
+void InspectorController::willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest& request)
+{
+ RefPtr<InspectorResource> resource = getTrackedResource(identifier);
+ if (!resource)
+ return;
+ resource->startTiming();
+ resource->updateWebSocketRequest(request);
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
+}
+
+void InspectorController::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse& response)
+{
+ RefPtr<InspectorResource> resource = getTrackedResource(identifier);
+ if (!resource)
+ return;
+ // Calling resource->markResponseReceivedTime() here makes resources bar chart confusing, because
+ // we cannot apply the "latency + download" model of regular resources to WebSocket connections.
+ // FIXME: Design a new UI for bar charts of WebSocket resources, and record timing here.
+ resource->updateWebSocketResponse(response);
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
+}
+
+void InspectorController::didCloseWebSocket(unsigned long identifier)
+{
+ RefPtr<InspectorResource> resource = getTrackedResource(identifier);
+ if (!resource)
+ return;
+
+ resource->endTiming();
+ if (m_frontend)
+ resource->updateScriptObject(m_frontend.get());
+}
+#endif // ENABLE(WEB_SOCKETS)
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
void InspectorController::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL)
{
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index 40099c6..079cf55 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -89,6 +89,11 @@ class StorageArea;
class InspectorApplicationCacheAgent;
#endif
+#if ENABLE(WEB_SOCKETS)
+class WebSocketHandshakeRequest;
+class WebSocketHandshakeResponse;
+#endif
+
class InspectorController : public Noncopyable {
public:
typedef HashMap<unsigned long, RefPtr<InspectorResource> > ResourcesMap;
@@ -209,6 +214,12 @@ public:
void setDOMStorageItem(long storageId, const String& key, const String& value, bool* success);
void removeDOMStorageItem(long storageId, const String& key, bool* success);
#endif
+#if ENABLE(WEB_SOCKETS)
+ void didCreateWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL);
+ void willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest&);
+ void didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse&);
+ void didCloseWebSocket(unsigned long identifier);
+#endif
const ResourcesMap& resources() const { return m_resources; }
InspectorResource* resourceForURL(const String& url);
diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp
index be77827..0a4784d 100644
--- a/WebCore/inspector/InspectorResource.cpp
+++ b/WebCore/inspector/InspectorResource.cpp
@@ -43,14 +43,37 @@
#include "ResourceLoadTiming.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
+#include "StringBuffer.h"
#include "TextEncoding.h"
+#include "WebSocketHandshakeRequest.h"
+#include "WebSocketHandshakeResponse.h"
+
+#include <wtf/Assertions.h>
namespace WebCore {
+// Create human-readable binary representation, like "01:23:45:67:89:AB:CD:EF".
+static String createReadableStringFromBinary(const unsigned char* value, size_t length)
+{
+ ASSERT(length > 0);
+ static const char hexDigits[17] = "0123456789ABCDEF";
+ size_t bufferSize = length * 3 - 1;
+ StringBuffer buffer(bufferSize);
+ size_t index = 0;
+ for (size_t i = 0; i < length; ++i) {
+ if (i > 0)
+ buffer[index++] = ':';
+ buffer[index++] = hexDigits[value[i] >> 4];
+ buffer[index++] = hexDigits[value[i] & 0xF];
+ }
+ ASSERT(index == bufferSize);
+ return String::adopt(buffer);
+}
+
InspectorResource::InspectorResource(unsigned long identifier, DocumentLoader* loader, const KURL& requestURL)
: m_identifier(identifier)
, m_loader(loader)
- , m_frame(loader->frame())
+ , m_frame(loader ? loader->frame() : 0)
, m_requestURL(requestURL)
, m_expectedContentLength(0)
, m_cached(false)
@@ -66,6 +89,9 @@ InspectorResource::InspectorResource(unsigned long identifier, DocumentLoader* l
, m_connectionID(0)
, m_connectionReused(false)
, m_isMainResource(false)
+#if ENABLE(WEB_SOCKETS)
+ , m_isWebSocket(false)
+#endif
{
}
@@ -88,6 +114,12 @@ PassRefPtr<InspectorResource> InspectorResource::appendRedirect(unsigned long id
return redirect;
}
+PassRefPtr<InspectorResource> InspectorResource::create(unsigned long identifier, DocumentLoader* loader, const KURL& requestURL)
+{
+ ASSERT(loader);
+ return adoptRef(new InspectorResource(identifier, loader, requestURL));
+}
+
PassRefPtr<InspectorResource> InspectorResource::createCached(unsigned long identifier, DocumentLoader* loader, const CachedResource* cachedResource)
{
PassRefPtr<InspectorResource> resource = create(identifier, loader, KURL(ParsedURLString, cachedResource->url()));
@@ -107,6 +139,16 @@ PassRefPtr<InspectorResource> InspectorResource::createCached(unsigned long iden
return resource;
}
+#if ENABLE(WEB_SOCKETS)
+PassRefPtr<InspectorResource> InspectorResource::createWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL)
+{
+ RefPtr<InspectorResource> resource = adoptRef(new InspectorResource(identifier, 0, requestURL));
+ resource->markWebSocket();
+ resource->m_documentURL = documentURL;
+ return resource.release();
+}
+#endif
+
void InspectorResource::updateRequest(const ResourceRequest& request)
{
m_requestHeaderFields = request.httpHeaderFields();
@@ -146,6 +188,27 @@ void InspectorResource::updateResponse(const ResourceResponse& response)
m_changes.set(TypeChange);
}
+#if ENABLE(WEB_SOCKETS)
+void InspectorResource::updateWebSocketRequest(const WebSocketHandshakeRequest& request)
+{
+ m_requestHeaderFields = request.headerFields();
+ m_requestMethod = "GET"; // Currently we always use "GET" to request handshake.
+ m_webSocketRequestKey3.set(new WebSocketHandshakeRequest::Key3(request.key3()));
+ m_changes.set(RequestChange);
+ m_changes.set(TypeChange);
+}
+
+void InspectorResource::updateWebSocketResponse(const WebSocketHandshakeResponse& response)
+{
+ m_responseStatusCode = response.statusCode();
+ m_responseStatusText = response.statusText();
+ m_responseHeaderFields = response.headerFields();
+ m_webSocketChallengeResponse.set(new WebSocketHandshakeResponse::ChallengeResponse(response.challengeResponse()));
+ m_changes.set(ResponseChange);
+ m_changes.set(TypeChange);
+}
+#endif // ENABLE(WEB_SOCKETS)
+
static PassRefPtr<InspectorObject> buildHeadersObject(const HTTPHeaderMap& headers)
{
RefPtr<InspectorObject> object = InspectorObject::create();
@@ -183,8 +246,10 @@ void InspectorResource::updateScriptObject(InspectorFrontend* frontend)
RefPtr<InspectorObject> jsonObject = InspectorObject::create();
jsonObject->setNumber("id", m_identifier);
if (m_changes.hasChange(RequestChange)) {
+ if (m_frame)
+ m_documentURL = m_frame->document()->url();
jsonObject->setString("url", m_requestURL.string());
- jsonObject->setString("documentURL", m_frame->document()->url().string());
+ jsonObject->setString("documentURL", m_documentURL.string());
jsonObject->setString("host", m_requestURL.host());
jsonObject->setString("path", m_requestURL.path());
jsonObject->setString("lastPathComponent", m_requestURL.lastPathComponent());
@@ -194,6 +259,10 @@ void InspectorResource::updateScriptObject(InspectorFrontend* frontend)
jsonObject->setString("requestMethod", m_requestMethod);
jsonObject->setString("requestFormData", m_requestFormData);
jsonObject->setBoolean("didRequestChange", true);
+#if ENABLE(WEB_SOCKETS)
+ if (m_webSocketRequestKey3)
+ jsonObject->setString("webSocketRequestKey3", createReadableStringFromBinary(m_webSocketRequestKey3->value, sizeof(m_webSocketRequestKey3->value)));
+#endif
}
if (m_changes.hasChange(ResponseChange)) {
@@ -209,6 +278,10 @@ void InspectorResource::updateScriptObject(InspectorFrontend* frontend)
jsonObject->setBoolean("cached", m_cached);
if (m_loadTiming && !m_cached)
jsonObject->setObject("timing", buildObjectForTiming(m_loadTiming.get()));
+#if ENABLE(WEB_SOCKETS)
+ if (m_webSocketChallengeResponse)
+ jsonObject->setString("webSocketChallengeResponse", createReadableStringFromBinary(m_webSocketChallengeResponse->value, sizeof(m_webSocketChallengeResponse->value)));
+#endif
jsonObject->setBoolean("didResponseChange", true);
}
@@ -267,6 +340,8 @@ CachedResource* InspectorResource::cachedResource() const
// Try hard to find a corresponding CachedResource. During preloading, CachedResourceLoader may not have the resource in document resources set yet,
// but Inspector will already try to fetch data that is only available via CachedResource (and it won't update once the resource is added,
// because m_changes will not have the appropriate bits set).
+ if (!m_frame)
+ return 0;
const String& url = m_requestURL.string();
CachedResource* cachedResource = m_frame->document()->cachedResourceLoader()->cachedResource(url);
if (!cachedResource)
@@ -303,6 +378,12 @@ InspectorResource::Type InspectorResource::type() const
if (!m_overrideContent.isNull())
return m_overrideContentType;
+#if ENABLE(WEB_SOCKETS)
+ if (m_isWebSocket)
+ return WebSocket;
+#endif
+
+ ASSERT(m_loader);
if (equalIgnoringFragmentIdentifier(m_requestURL, m_loader->requestURL())) {
InspectorResource::Type resourceType = cachedResourceType();
if (resourceType == Other)
@@ -342,7 +423,7 @@ String InspectorResource::sourceString() const
PassRefPtr<SharedBuffer> InspectorResource::resourceData(String* textEncodingName) const
{
- if (equalIgnoringFragmentIdentifier(m_requestURL, m_loader->requestURL())) {
+ if (m_loader && equalIgnoringFragmentIdentifier(m_requestURL, m_loader->requestURL())) {
*textEncodingName = m_frame->document()->inputEncoding();
return m_loader->mainResourceData();
}
diff --git a/WebCore/inspector/InspectorResource.h b/WebCore/inspector/InspectorResource.h
index 4004142..3fd5a69 100644
--- a/WebCore/inspector/InspectorResource.h
+++ b/WebCore/inspector/InspectorResource.h
@@ -34,6 +34,8 @@
#include "HTTPHeaderMap.h"
#include "KURL.h"
#include "ScriptString.h"
+#include "WebSocketHandshakeRequest.h"
+#include "WebSocketHandshakeResponse.h"
#include <wtf/CurrentTime.h>
#include <wtf/OwnPtr.h>
@@ -51,6 +53,11 @@ namespace WebCore {
class ResourceRequest;
class ResourceResponse;
+#if ENABLE(WEB_SOCKETS)
+ class WebSocketHandshakeRequest;
+ class WebSocketHandshakeResponse;
+#endif
+
class InspectorResource : public RefCounted<InspectorResource> {
public:
@@ -63,16 +70,19 @@ namespace WebCore {
Script,
XHR,
Media,
+ WebSocket,
Other
};
- static PassRefPtr<InspectorResource> create(unsigned long identifier, DocumentLoader* loader, const KURL& requestURL)
- {
- return adoptRef(new InspectorResource(identifier, loader, requestURL));
- }
+ static PassRefPtr<InspectorResource> create(unsigned long identifier, DocumentLoader* loader, const KURL& requestURL);
static PassRefPtr<InspectorResource> createCached(unsigned long identifier, DocumentLoader*, const CachedResource*);
+#if ENABLE(WEB_SOCKETS)
+ // WebSocket resource doesn't have its loader. For WebSocket resources, m_loader and m_frame will become null.
+ static PassRefPtr<InspectorResource> createWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL);
+#endif
+
~InspectorResource();
PassRefPtr<InspectorResource> appendRedirect(unsigned long identifier, const KURL& redirectURL);
@@ -82,6 +92,11 @@ namespace WebCore {
void updateRequest(const ResourceRequest&);
void updateResponse(const ResourceResponse&);
+#if ENABLE(WEB_SOCKETS)
+ void updateWebSocketRequest(const WebSocketHandshakeRequest&);
+ void updateWebSocketResponse(const WebSocketHandshakeResponse&);
+#endif
+
void setOverrideContent(const ScriptString& data, Type);
String sourceString() const;
@@ -149,10 +164,15 @@ namespace WebCore {
Type cachedResourceType() const;
CachedResource* cachedResource() const;
+#if ENABLE(WEB_SOCKETS)
+ void markWebSocket() { m_isWebSocket = true; }
+#endif
+
unsigned long m_identifier;
RefPtr<DocumentLoader> m_loader;
RefPtr<Frame> m_frame;
KURL m_requestURL;
+ KURL m_documentURL;
HTTPHeaderMap m_requestHeaderFields;
HTTPHeaderMap m_responseHeaderFields;
String m_mimeType;
@@ -179,6 +199,15 @@ namespace WebCore {
String m_requestMethod;
String m_requestFormData;
Vector<RefPtr<InspectorResource> > m_redirects;
+
+#if ENABLE(WEB_SOCKETS)
+ bool m_isWebSocket;
+
+ // The following fields are not used for resources other than WebSocket.
+ // We allocate them dynamically to reduce memory consumption for regular resources.
+ OwnPtr<WebSocketHandshakeRequest::Key3> m_webSocketRequestKey3;
+ OwnPtr<WebSocketHandshakeResponse::ChallengeResponse> m_webSocketChallengeResponse;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js
index de87047..ea9052d 100644
--- a/WebCore/inspector/front-end/Resource.js
+++ b/WebCore/inspector/front-end/Resource.js
@@ -45,7 +45,8 @@ WebInspector.Resource.Type = {
Script: 4,
XHR: 5,
Media: 6,
- Other: 7,
+ WebSocket: 7,
+ Other: 8,
isTextType: function(type)
{
@@ -76,6 +77,8 @@ WebInspector.Resource.Type = {
return "XHR";
case this.Media:
return "media";
+ case this.WebSocket:
+ return "WebSocket";
case this.Other:
default:
return "other";
@@ -372,6 +375,9 @@ WebInspector.Resource.prototype = {
case WebInspector.Resource.Type.XHR:
this.category = WebInspector.resourceCategories.xhr;
break;
+ case WebInspector.Resource.Type.WebSocket:
+ this.category = WebInspector.resourceCategories.websocket;
+ break;
case WebInspector.Resource.Type.Other:
default:
this.category = WebInspector.resourceCategories.other;
@@ -584,7 +590,8 @@ WebInspector.Resource.prototype = {
if (typeof this.type === "undefined"
|| this.type === WebInspector.Resource.Type.Other
- || this.type === WebInspector.Resource.Type.XHR)
+ || this.type === WebInspector.Resource.Type.XHR
+ || this.type === WebInspector.Resource.Type.WebSocket)
return true;
if (this.mimeType in WebInspector.MIMETypes)
diff --git a/WebCore/inspector/front-end/ResourceView.js b/WebCore/inspector/front-end/ResourceView.js
index 7ce09b6..1c2574f 100644
--- a/WebCore/inspector/front-end/ResourceView.js
+++ b/WebCore/inspector/front-end/ResourceView.js
@@ -279,13 +279,19 @@ WebInspector.ResourceView.prototype = {
_refreshRequestHeaders: function()
{
- this._refreshHeaders(WebInspector.UIString("Request Headers"), this.resource.sortedRequestHeaders, this.requestHeadersTreeElement);
+ 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);
this._refreshFormData();
},
_refreshResponseHeaders: function()
{
- this._refreshHeaders(WebInspector.UIString("Response Headers"), this.resource.sortedResponseHeaders, this.responseHeadersTreeElement);
+ 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);
},
_refreshHTTPInformation: function()
@@ -316,7 +322,7 @@ WebInspector.ResourceView.prototype = {
}
},
- _refreshHeaders: function(title, headers, headersTreeElement)
+ _refreshHeaders: function(title, headers, additionalRow, headersTreeElement)
{
headersTreeElement.removeChildren();
@@ -333,6 +339,15 @@ WebInspector.ResourceView.prototype = {
headerTreeElement.selectable = false;
headersTreeElement.appendChild(headerTreeElement);
}
+
+ if (additionalRow) {
+ var title = "<div class=\"header-name\">" + additionalRow.header.escapeHTML() + ":</div>";
+ title += "<div class=\"header-value source-code\">" + additionalRow.value.escapeHTML() + "</div>"
+
+ var headerTreeElement = new TreeElement(title, null, false);
+ headerTreeElement.selectable = false;
+ headersTreeElement.appendChild(headerTreeElement);
+ }
}
}
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 4319816..2823418 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -2835,7 +2835,8 @@ button.enable-toggle-status-bar-item.toggled-on .glyph {
}
.resources-category-documents, .resources-category-stylesheets, .resources-category-images,
-.resources-category-scripts, .resources-category-xhr, .resources-category-fonts, .resources-category-other {
+.resources-category-scripts, .resources-category-xhr, .resources-category-fonts,
+.resources-category-websockets, .resources-category-other {
display: none;
}
@@ -2845,6 +2846,7 @@ button.enable-toggle-status-bar-item.toggled-on .glyph {
.filter-all .resources-category-scripts, .filter-scripts .resources-category-scripts,
.filter-all .resources-category-xhr, .filter-xhr .resources-category-xhr,
.filter-all .resources-category-fonts, .filter-fonts .resources-category-fonts,
+.filter-all .resources-category-websockets, .filter-websockets .resources-category-websockets,
.filter-all .resources-category-other, .filter-other .resources-category-other,
.resource-sidebar-tree-item.selected {
display: list-item;
@@ -2920,6 +2922,15 @@ button.enable-toggle-status-bar-item.toggled-on .glyph {
-webkit-border-image: url(Images/timelineHollowPillYellow.png) 6 7 6 7;
}
+/* FIXME: Create bar images for WebSocket. */
+.resources-category-websockets .resources-graph-bar {
+ -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+}
+
+.resources-category-websockets.resource-cached .resources-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+}
+
#resource-views {
position: absolute;
top: 23px;
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 4c38a5a..cb5c83c 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -517,6 +517,7 @@ WebInspector.doLoadedDone = function()
scripts: new WebInspector.ResourceCategory("scripts", WebInspector.UIString("Scripts"), "rgb(255,121,0)"),
xhr: new WebInspector.ResourceCategory("xhr", WebInspector.UIString("XHR"), "rgb(231,231,10)"),
fonts: new WebInspector.ResourceCategory("fonts", WebInspector.UIString("Fonts"), "rgb(255,82,62)"),
+ websocket: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSocket"), "rgb(186,186,186)"), // FIXME: Decide the color.
other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)")
};
@@ -1233,6 +1234,8 @@ WebInspector.updateResource = function(payload)
resource.requestMethod = payload.requestMethod;
resource.requestFormData = payload.requestFormData;
resource.documentURL = payload.documentURL;
+ if (typeof payload.webSocketRequestKey3 !== "undefined")
+ resource.webSocketRequestKey3 = payload.webSocketRequestKey3;
if (resource.mainResource)
this.mainResource = resource;
@@ -1257,6 +1260,8 @@ WebInspector.updateResource = function(payload)
resource.connectionReused = payload.connectionReused;
resource.timing = payload.timing;
resource.cached = payload.cached;
+ if (typeof payload.webSocketChallengeResponse !== "undefined")
+ resource.webSocketChallengeResponse = payload.webSocketChallengeResponse;
}
if (payload.didTypeChange) {
diff --git a/WebCore/websockets/WebSocketChannel.cpp b/WebCore/websockets/WebSocketChannel.cpp
index a09224d..5ce1cc3 100644
--- a/WebCore/websockets/WebSocketChannel.cpp
+++ b/WebCore/websockets/WebSocketChannel.cpp
@@ -36,8 +36,11 @@
#include "CookieJar.h"
#include "Document.h"
+#include "InspectorController.h"
#include "Logging.h"
+#include "Page.h"
#include "PlatformString.h"
+#include "ProgressTracker.h"
#include "ScriptExecutionContext.h"
#include "SocketStreamError.h"
#include "SocketStreamHandle.h"
@@ -63,7 +66,14 @@ WebSocketChannel::WebSocketChannel(ScriptExecutionContext* context, WebSocketCha
, m_closed(false)
, m_shouldDiscardReceivedData(false)
, m_unhandledBufferedAmount(0)
+#if ENABLE(INSPECTOR)
+ , m_identifier(0)
+#endif
{
+#if ENABLE(INSPECTOR)
+ if (InspectorController* controller = m_context->inspectorController())
+ controller->didCreateWebSocket(identifier(), url, m_context->url());
+#endif
}
WebSocketChannel::~WebSocketChannel()
@@ -113,6 +123,11 @@ void WebSocketChannel::close()
void WebSocketChannel::disconnect()
{
LOG(Network, "WebSocketChannel %p disconnect", this);
+#if ENABLE(INSPECTOR)
+ if (m_context)
+ if (InspectorController* controller = m_context->inspectorController())
+ controller->didCloseWebSocket(identifier());
+#endif
m_handshake.clearScriptExecutionContext();
m_client = 0;
m_context = 0;
@@ -138,6 +153,10 @@ void WebSocketChannel::didOpen(SocketStreamHandle* handle)
ASSERT(handle == m_handle);
if (!m_context)
return;
+#if ENABLE(INSPECTOR)
+ if (InspectorController* controller = m_context->inspectorController())
+ controller->willSendWebSocketHandshakeRequest(identifier(), m_handshake.clientHandshakeRequest());
+#endif
const CString& handshakeMessage = m_handshake.clientHandshakeMessage();
if (!handle->send(handshakeMessage.data(), handshakeMessage.length())) {
m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Error sending handshake message.", 0, m_handshake.clientOrigin());
@@ -148,6 +167,11 @@ void WebSocketChannel::didOpen(SocketStreamHandle* handle)
void WebSocketChannel::didClose(SocketStreamHandle* handle)
{
LOG(Network, "WebSocketChannel %p didClose", this);
+#if ENABLE(INSPECTOR)
+ if (m_context)
+ if (InspectorController* controller = m_context->inspectorController())
+ controller->didCloseWebSocket(identifier());
+#endif
ASSERT_UNUSED(handle, handle == m_handle || !m_handle);
m_closed = true;
if (m_handle) {
@@ -251,6 +275,10 @@ bool WebSocketChannel::processBuffer()
if (headerLength <= 0)
return false;
if (m_handshake.mode() == WebSocketHandshake::Connected) {
+#if ENABLE(INSPECTOR)
+ if (InspectorController* controller = m_context->inspectorController())
+ controller->didReceiveWebSocketHandshakeResponse(identifier(), m_handshake.serverHandshakeResponse());
+#endif
if (!m_handshake.serverSetCookie().isEmpty()) {
if (m_context->isDocument()) {
Document* document = static_cast<Document*>(m_context);
@@ -368,6 +396,21 @@ void WebSocketChannel::resumeTimerFired(Timer<WebSocketChannel>* timer)
didClose(m_handle.get());
}
+#if ENABLE(INSPECTOR)
+unsigned long WebSocketChannel::identifier()
+{
+ if (m_identifier)
+ return m_identifier;
+
+ if (InspectorController* controller = m_context->inspectorController())
+ if (Page* page = controller->inspectedPage())
+ m_identifier = page->progress()->createUniqueIdentifier();
+
+ ASSERT(m_identifier);
+ return m_identifier;
+}
+#endif // ENABLE(INSPECTOR)
+
} // namespace WebCore
#endif // ENABLE(WEB_SOCKETS)
diff --git a/WebCore/websockets/WebSocketChannel.h b/WebCore/websockets/WebSocketChannel.h
index 43d431a..a08e6bb 100644
--- a/WebCore/websockets/WebSocketChannel.h
+++ b/WebCore/websockets/WebSocketChannel.h
@@ -84,6 +84,10 @@ namespace WebCore {
bool processBuffer();
void resumeTimerFired(Timer<WebSocketChannel>* timer);
+#if ENABLE(INSPECTOR)
+ unsigned long identifier();
+#endif
+
ScriptExecutionContext* m_context;
WebSocketChannelClient* m_client;
WebSocketHandshake m_handshake;
@@ -96,6 +100,10 @@ namespace WebCore {
bool m_closed;
bool m_shouldDiscardReceivedData;
unsigned long m_unhandledBufferedAmount;
+
+#if ENABLE(INSPECTOR)
+ unsigned long m_identifier;
+#endif
};
} // namespace WebCore
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list