[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
caseq at chromium.org
caseq at chromium.org
Wed Dec 22 14:47:22 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit ec5968c5e35a487b58c2e570dbb3db4d5eee25e2
Author: caseq at chromium.org <caseq at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Oct 20 09:14:09 2010 +0000
2010-10-19 Andrey Kosyakov <caseq at chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: expose request/response cookies in HAR
https://bugs.webkit.org/show_bug.cgi?id=47894
Test: inspector/cookie-parser.html
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* inspector/front-end/CookieParser.js: Added.
* inspector/front-end/HAREntry.js:
(WebInspector.HAREntry.prototype._buildRequest):
(WebInspector.HAREntry.prototype._buildResponse):
(WebInspector.HAREntry.prototype._buildCookies):
(WebInspector.HAREntry.prototype._buildCookie):
* inspector/front-end/Resource.js: Parse Cookie/Set-Cookie headers and expose cookies.
(WebInspector.Resource.prototype.set requestHeaders):
(WebInspector.Resource.prototype.get requestCookies):
(WebInspector.Resource.prototype.set responseHeaders):
(WebInspector.Resource.prototype.get responseCookies):
(WebInspector.Resource.prototype._parseRequestCookies):
(WebInspector.Resource.prototype._parseResponseCookies):
* inspector/front-end/WebKit.qrc:
* inspector/front-end/inspector.html:
2010-10-19 Andrey Kosyakov <caseq at chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: expose request/response cookies in HAR
https://bugs.webkit.org/show_bug.cgi?id=47894
* src/WebResourceRawHeaders.cpp:
(WebKit::addHeader): paste coalescent headers using "\n: as a separator instead of ", "
2010-10-19 Andrey Kosyakov <caseq at chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: expose request/response cookies in HAR
https://bugs.webkit.org/show_bug.cgi?id=47894
* http/tests/inspector/inspector-test.js:
(dumpObject): Handle null objects as a special case (display null instead of empty object)
* http/tests/inspector/inspector-test2.js:
(initialize_InspectorTest.InspectorTest.addObject): Ditto.
* http/tests/inspector/resource-har-conversion-expected.txt:
* http/tests/inspector/resource-har-conversion.html:
* inspector/cookie-parser-expected.txt: Added.
* inspector/cookie-parser.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70137 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 4d90a9f..97281ec 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2010-10-19 Andrey Kosyakov <caseq at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: expose request/response cookies in HAR
+ https://bugs.webkit.org/show_bug.cgi?id=47894
+
+ * http/tests/inspector/inspector-test.js:
+ (dumpObject): Handle null objects as a special case (display null instead of empty object)
+ * http/tests/inspector/inspector-test2.js:
+ (initialize_InspectorTest.InspectorTest.addObject): Ditto.
+ * http/tests/inspector/resource-har-conversion-expected.txt:
+ * http/tests/inspector/resource-har-conversion.html:
+ * inspector/cookie-parser-expected.txt: Added.
+ * inspector/cookie-parser.html: Added.
+
2010-10-20 Shinichiro Hamaji <hamaji at chromium.org>
Reviewed by Kent Tamura.
diff --git a/LayoutTests/http/tests/inspector/inspector-test.js b/LayoutTests/http/tests/inspector/inspector-test.js
index f3028fb..f183f02 100755
--- a/LayoutTests/http/tests/inspector/inspector-test.js
+++ b/LayoutTests/http/tests/inspector/inspector-test.js
@@ -53,6 +53,8 @@ function dumpObject(object, nondeterministicProps, prefix, firstLinePrefix)
var propValue = object[prop];
if (nondeterministicProps && prop in nondeterministicProps)
output(prefixWithName + "<" + typeof propValue + ">");
+ else if (propValue === null)
+ output(prefixWithName + "null");
else if (typeof propValue === "object")
dumpObject(propValue, nondeterministicProps, prefix + " ", prefixWithName);
else if (typeof propValue === "string")
diff --git a/LayoutTests/http/tests/inspector/inspector-test2.js b/LayoutTests/http/tests/inspector/inspector-test2.js
index df65d8a..e73672c 100644
--- a/LayoutTests/http/tests/inspector/inspector-test2.js
+++ b/LayoutTests/http/tests/inspector/inspector-test2.js
@@ -61,6 +61,8 @@ InspectorTest.addObject = function(object, nondeterministicProps, prefix, firstL
var propValue = object[prop];
if (nondeterministicProps && prop in nondeterministicProps)
InspectorTest.addResult(prefixWithName + "<" + typeof propValue + ">");
+ else if (propValue === null)
+ InspectorTest.addResult(prefixWithName + "null");
else if (typeof propValue === "object")
InspectorTest.addObject(propValue, nondeterministicProps, prefix + " ", prefixWithName);
else if (typeof propValue === "string")
diff --git a/LayoutTests/http/tests/inspector/resource-har-conversion-expected.txt b/LayoutTests/http/tests/inspector/resource-har-conversion-expected.txt
index 93daf90..8179431 100644
--- a/LayoutTests/http/tests/inspector/resource-har-conversion-expected.txt
+++ b/LayoutTests/http/tests/inspector/resource-har-conversion-expected.txt
@@ -12,6 +12,35 @@ Page reloaded.
headers : <object>
headersSize : -1
bodySize : <number>
+ cookies : {
+ 0 : {
+ name : "a"
+ value : "b"
+ path : "/path"
+ domain : "example.com"
+ expires : null
+ httpOnly : false
+ secure : false
+ }
+ 1 : {
+ name : "a1"
+ value : "b1"
+ path : undefined
+ domain : undefined
+ expires : null
+ httpOnly : false
+ secure : false
+ }
+ 2 : {
+ name : "c1"
+ value : "d1"
+ path : undefined
+ domain : undefined
+ expires : null
+ httpOnly : false
+ secure : false
+ }
+ }
}
response : {
status : 304
@@ -24,6 +53,35 @@ Page reloaded.
redirectURL : ""
headersSize : -1
bodySize : <number>
+ cookies : {
+ 0 : {
+ name : "x"
+ value : "y"
+ path : "/path"
+ domain : "example.com"
+ expires : null
+ httpOnly : true
+ secure : true
+ }
+ 1 : {
+ name : "x1"
+ value : "y1"
+ path : undefined
+ domain : undefined
+ expires : null
+ httpOnly : false
+ secure : false
+ }
+ 2 : {
+ name : "z2"
+ value : "y2"
+ path : undefined
+ domain : undefined
+ expires : null
+ httpOnly : false
+ secure : false
+ }
+ }
}
timings : <object>
}
diff --git a/LayoutTests/http/tests/inspector/resource-har-conversion.html b/LayoutTests/http/tests/inspector/resource-har-conversion.html
index 14273ad..0593834 100644
--- a/LayoutTests/http/tests/inspector/resource-har-conversion.html
+++ b/LayoutTests/http/tests/inspector/resource-har-conversion.html
@@ -12,8 +12,27 @@ var test = function()
return new WebInspector.HAREntry(WebInspector.resources[id]).build();
}
+ function addCookieHeadersToResource(resource)
+ {
+ resource.requestHeaders = {
+ "Cookie": "a=b; $Path=/path; $Domain=example.com; a1=b1\nc1=d1"
+ };
+ resource.responseHeaders = {
+ "Set-Cookie": "x=y; Path=/path; Domain=example.com; Discard; httpOnly; Secure; Version=1\nx1=y1\nz2=y2"
+ };
+ }
+
+ function findResourceByURL(url)
+ {
+ for (var resource in WebInspector.resources) {
+ if (url.test(WebInspector.resources[resource].url))
+ return WebInspector.resources[resource];
+ }
+ }
+
InspectorTest.enableResourceTracking(function() {
InjectedScriptAccess.getDefault().evaluate("doXHR()", "console", function() {
+ addCookieHeadersToResource(findResourceByURL(/inspector-test2\.js$/));
var resources = Object.keys(WebInspector.resources).map(getHAR).sort(InspectorTest.resourceURLComparer);
InspectorTest.addObject(resources, InspectorTest.HARNondeterministicPropertiesWithSize);
InspectorTest.disableResourceTracking();
diff --git a/LayoutTests/inspector/cookie-parser-expected.txt b/LayoutTests/inspector/cookie-parser-expected.txt
new file mode 100644
index 0000000..02bb326
--- /dev/null
+++ b/LayoutTests/inspector/cookie-parser-expected.txt
@@ -0,0 +1,133 @@
+Tests inspector cookie parser
+
+source: cookie=value
+name: cookie, value: value, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 12
+{
+}
+source: $version=1; a=b,c = d, e=f
+name: a, value: b,c = d, e=f, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 17
+{
+}
+source: $version=1; a=b;c = d; e =f
+name: a, value: b, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 4
+{
+}
+name: c, value: d, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 10
+{
+}
+name: e, value: f, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 4
+{
+}
+source: cooke1 = value1; another cookie = another value
+name: cooke1, value: value1, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 25
+{
+}
+name: cookie, value: another value, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 22
+{
+}
+source: cooke1 = value; $Path=/; $Domain=.example.com;
+name: cooke1, value: value, httpOnly: false, secure: false, session: true, path: /, domain: .example.com, port: undefined, expires: n/a, size: 46
+{
+ path : "/"
+ domain : ".example.com"
+}
+source: cooke1 = value; $Path=/; $Domain=.example.com ; Cookie2 = value2; $Path = /foo; $DOMAIN = foo.example.com;
+name: cooke1, value: value, httpOnly: false, secure: false, session: true, path: /, domain: .example.com, port: undefined, expires: n/a, size: 48
+{
+ path : "/"
+ domain : ".example.com"
+}
+name: Cookie2, value: value2, httpOnly: false, secure: false, session: true, path: /foo, domain: foo.example.com, port: undefined, expires: n/a, size: 58
+{
+ path : "/foo"
+ domain : "foo.example.com"
+}
+source: cooke1 = value; $Path=/; $Domain=.example.com
+Cookie2 = value2; $Path = /foo; $DOMAIN = foo.example.com;
+name: cooke1, value: value, httpOnly: false, secure: false, session: true, path: /, domain: .example.com, port: undefined, expires: n/a, size: 46
+{
+ path : "/"
+ domain : ".example.com"
+}
+name: Cookie2, value: value2, httpOnly: false, secure: false, session: true, path: /foo, domain: foo.example.com, port: undefined, expires: n/a, size: 59
+{
+ path : "/foo"
+ domain : "foo.example.com"
+}
+source: $version =1; cooke1 = value; $Path=/; $Domain =.example.com;
+ Cookie2 = value2; $Path = /foo; $DOMAIN = foo.example.com;
+name: cooke1, value: value, httpOnly: false, secure: false, session: true, path: /, domain: .example.com, port: undefined, expires: n/a, size: 53
+{
+ path : "/"
+ domain : ".example.com"
+}
+name: Cookie2, value: value2, httpOnly: false, secure: false, session: true, path: /foo, domain: foo.example.com, port: undefined, expires: n/a, size: 58
+{
+ path : "/foo"
+ domain : "foo.example.com"
+}
+source: cookie=value
+name: cookie, value: value, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 12
+{
+}
+source: a=b
+ c=d
+ f
+name: a, value: b, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 5
+{
+}
+name: c, value: d, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 5
+{
+}
+name: , value: f, httpOnly: false, secure: false, session: true, path: undefined, domain: undefined, port: undefined, expires: n/a, size: 1
+{
+}
+source: cooke1 = value; Path=/; Domain=.example.com;
+name: cooke1, value: value, httpOnly: false, secure: false, session: true, path: /, domain: .example.com, port: undefined, expires: n/a, size: 44
+{
+ path : "/"
+ domain : ".example.com"
+}
+source: cooke1 = value; Path=/; Domain= .example.com
+Cookie2 = value2; Path = /foo; Domain = foo.example.com
+name: cooke1, value: value, httpOnly: false, secure: false, session: true, path: /, domain: .example.com, port: undefined, expires: n/a, size: 47
+{
+ path : "/"
+ domain : ".example.com"
+}
+name: Cookie2, value: value2, httpOnly: false, secure: false, session: true, path: /foo, domain: foo.example.com, port: undefined, expires: n/a, size: 55
+{
+ path : "/foo"
+ domain : "foo.example.com"
+}
+source: cooke1 = value; expires = Mon, Oct 18 2010 17:00 GMT+0000; Domain =.example.com
+Cookie2 = value2; Path = /foo; DOMAIN = foo.example.com; HttpOnly; Secure; Discard;
+name: cooke1, value: value, httpOnly: false, secure: false, session: true, path: undefined, domain: .example.com, port: undefined, expires: 1287421200000, size: 82
+{
+ expires : "Mon, Oct 18 2010 17:00 GMT+0000"
+ domain : ".example.com"
+}
+name: Cookie2, value: value2, httpOnly: true, secure: true, session: true, path: /foo, domain: foo.example.com, port: undefined, expires: n/a, size: 83
+{
+ path : "/foo"
+ domain : "foo.example.com"
+ httponly : undefined
+ secure : undefined
+ discard : undefined
+}
+source: cooke1 = value; max-age= 1440; Domain =.example.com
+ Cookie2 = value2; Path = /foo; DOMAIN = foo.example.com; HttpOnly; Secure; Discard;
+name: cooke1, value: value, httpOnly: false, secure: false, session: false, path: undefined, domain: .example.com, port: undefined, expires: 1287422640000, size: 55
+{
+ max-age : "1440"
+ domain : ".example.com"
+}
+name: Cookie2, value: value2, httpOnly: true, secure: true, session: true, path: /foo, domain: foo.example.com, port: undefined, expires: n/a, size: 83
+{
+ path : "/foo"
+ domain : "foo.example.com"
+ httponly : undefined
+ secure : undefined
+ discard : undefined
+}
+
diff --git a/LayoutTests/inspector/cookie-parser.html b/LayoutTests/inspector/cookie-parser.html
new file mode 100755
index 0000000..fa7d479
--- /dev/null
+++ b/LayoutTests/inspector/cookie-parser.html
@@ -0,0 +1,71 @@
+<html>
+<head>
+<script src="../http/tests/inspector/inspector-test2.js"></script>
+<script type="text/javascript">
+
+function initialize_CookieTests()
+{
+
+InspectorTest.dumpCookie = function(cookie)
+{
+ var requestDate = new Date("Mon Oct 18 2010 17:00:00 GMT+0000");
+ var expires = cookie.expires(requestDate);
+
+ var output = "name: " + cookie.name + ", value: " + cookie.value + ", httpOnly: " + cookie.httpOnly +
+ ", secure: " + cookie.secure + ", session: " + cookie.session + ", path: " + cookie.path +
+ ", domain: " + cookie.domain + ", port: " + cookie.port +
+ ", expires: " + (expires ? expires.getTime() : "n/a") +
+ ", size: " + cookie.size;
+
+ InspectorTest.addResult(output);
+ InspectorTest.addObject(cookie.attributes);
+}
+
+InspectorTest.dumpCookies = function(cookies)
+{
+ for (var i = 0; i < cookies.length; ++i)
+ InspectorTest.dumpCookie(cookies[i]);
+}
+
+InspectorTest.parseAndDumpCookie = function(header)
+{
+ var parser = new WebInspector.CookieParser();
+ InspectorTest.addResult("source: " + header);
+ InspectorTest.dumpCookies(parser.parseCookie(header));
+}
+
+InspectorTest.parseAndDumpSetCookie = function(header)
+{
+ var parser = new WebInspector.CookieParser();
+ InspectorTest.addResult("source: " + header);
+ InspectorTest.dumpCookies(parser.parseSetCookie(header));
+}
+
+}
+
+var test = function()
+{
+ InspectorTest.parseAndDumpCookie("cookie=value");
+ InspectorTest.parseAndDumpCookie("$version=1; a=b,c = d, e=f");
+ InspectorTest.parseAndDumpCookie("$version=1; a=b;c = d; e =f");
+ InspectorTest.parseAndDumpCookie("cooke1 = value1; another cookie = another value");
+ InspectorTest.parseAndDumpCookie("cooke1 = value; $Path=/; $Domain=.example.com;");
+ InspectorTest.parseAndDumpCookie("cooke1 = value; $Path=/; $Domain=.example.com ; Cookie2 = value2; $Path = /foo; $DOMAIN = foo.example.com;");
+ InspectorTest.parseAndDumpCookie("cooke1 = value; $Path=/; $Domain=.example.com\nCookie2 = value2; $Path = /foo; $DOMAIN = foo.example.com; ");
+ InspectorTest.parseAndDumpCookie("$version =1; cooke1 = value; $Path=/; $Domain =.example.com; \n Cookie2 = value2; $Path = /foo; $DOMAIN = foo.example.com;");
+
+ InspectorTest.parseAndDumpSetCookie("cookie=value");
+ InspectorTest.parseAndDumpSetCookie("a=b\n c=d\n f");
+ InspectorTest.parseAndDumpSetCookie("cooke1 = value; Path=/; Domain=.example.com;");
+ InspectorTest.parseAndDumpSetCookie("cooke1 = value; Path=/; Domain= .example.com \nCookie2 = value2; Path = /foo; Domain = foo.example.com");
+ InspectorTest.parseAndDumpSetCookie("cooke1 = value; expires = Mon, Oct 18 2010 17:00 GMT+0000; Domain =.example.com\nCookie2 = value2; Path = /foo; DOMAIN = foo.example.com; HttpOnly; Secure; Discard;");
+ InspectorTest.parseAndDumpSetCookie("cooke1 = value; max-age= 1440; Domain =.example.com\n Cookie2 = value2; Path = /foo; DOMAIN = foo.example.com; HttpOnly; Secure; Discard;");
+ InspectorTest.completeTest();
+}
+
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests inspector cookie parser</p>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 9dc3719..1925e84 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,30 @@
+2010-10-19 Andrey Kosyakov <caseq at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: expose request/response cookies in HAR
+ https://bugs.webkit.org/show_bug.cgi?id=47894
+
+ Test: inspector/cookie-parser.html
+
+ * WebCore.gypi:
+ * WebCore.vcproj/WebCore.vcproj:
+ * inspector/front-end/CookieParser.js: Added.
+ * inspector/front-end/HAREntry.js:
+ (WebInspector.HAREntry.prototype._buildRequest):
+ (WebInspector.HAREntry.prototype._buildResponse):
+ (WebInspector.HAREntry.prototype._buildCookies):
+ (WebInspector.HAREntry.prototype._buildCookie):
+ * inspector/front-end/Resource.js: Parse Cookie/Set-Cookie headers and expose cookies.
+ (WebInspector.Resource.prototype.set requestHeaders):
+ (WebInspector.Resource.prototype.get requestCookies):
+ (WebInspector.Resource.prototype.set responseHeaders):
+ (WebInspector.Resource.prototype.get responseCookies):
+ (WebInspector.Resource.prototype._parseRequestCookies):
+ (WebInspector.Resource.prototype._parseResponseCookies):
+ * inspector/front-end/WebKit.qrc:
+ * inspector/front-end/inspector.html:
+
2010-10-20 Nikolas Zimmermann <nzimmermann at rim.com>
Not reviewed.
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 350bdac..48e0ed2 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -4358,6 +4358,7 @@
'inspector/front-end/ConsoleView.js',
'inspector/front-end/ContextMenu.js',
'inspector/front-end/CookieItemsView.js',
+ 'inspector/front-end/CookieParser.js',
'inspector/front-end/CSSCompletions.js',
'inspector/front-end/CSSStyleModel.js',
'inspector/front-end/Database.js',
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index 488ecda..ebd9296 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -63458,6 +63458,14 @@
>
</File>
<File
+ RelativePath="..\inspector\front-end\CookieItemsView.js"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\front-end\CookieParser.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\CSSStyleModel.js"
>
</File>
diff --git a/WebCore/inspector/front-end/CookieParser.js b/WebCore/inspector/front-end/CookieParser.js
new file mode 100755
index 0000000..2be5df7
--- /dev/null
+++ b/WebCore/inspector/front-end/CookieParser.js
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Ideally, we would rely on platform support for parsing a cookie, since
+// this would save us from any potential inconsistency. However, exposing
+// platform cookie parsing logic would require quite a bit of additional
+// plumbing, and at least some platforms lack support for parsing Cookie,
+// which is in a format slightly different from Set-Cookie and is normally
+// only required on the server side.
+
+WebInspector.CookieParser = function()
+{
+}
+
+WebInspector.CookieParser.prototype = {
+ get cookies()
+ {
+ return this._cookies;
+ },
+
+ parseCookie: function(cookieHeader)
+ {
+ if (!this._initialize(cookieHeader))
+ return;
+
+ for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
+ if (kv.key.charAt(0) === "$" && this._lastCookie)
+ this._lastCookie.addAttribute(kv.key.slice(1), kv.value);
+ else if (kv.key.toLowerCase() !== "$version" && typeof kv.value === "string")
+ this._addCookie(kv);
+ this._advanceAndCheckCookieDelimiter();
+ }
+ this._flushCookie();
+ return this._cookies;
+ },
+
+ parseSetCookie: function(setCookieHeader)
+ {
+ if (!this._initialize(setCookieHeader))
+ return;
+ for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
+ if (this._lastCookie)
+ this._lastCookie.addAttribute(kv.key, kv.value);
+ else
+ this._addCookie(kv);
+ if (this._advanceAndCheckCookieDelimiter())
+ this._flushCookie();
+ }
+ this._flushCookie();
+ return this._cookies;
+ },
+
+ _initialize: function(headerValue)
+ {
+ this._input = headerValue;
+ if (typeof headerValue !== "string")
+ return false;
+ this._cookies = [];
+ this._lastCookie = null;
+ this._originalInputLength = this._input.length;
+ return true;
+ },
+
+ _flushCookie: function()
+ {
+ if (this._lastCookie)
+ this._lastCookie.size = this._originalInputLength - this._input.length - this._lastCookiePosition;
+ this._lastCookie = null;
+ },
+
+ _extractKeyValue: function()
+ {
+ if (!this._input || !this._input.length)
+ return null;
+ // Note: RFCs offer an option for quoted values that may contain commas and semicolons.
+ // Many browsers/platforms do not support this, however (see http://webkit.org/b/16699
+ // and http://crbug.com/12361). The logic below matches latest versions of IE, Firefox,
+ // Chrome and Safari on some old platforms. The latest version of Safari supports quoted
+ // cookie values, though.
+ var keyValueMatch = /^[ \t]*([^\s=;]+)[ \t]*(?:=[ \t]*([^;\n]*))?/.exec(this._input);
+ if (!keyValueMatch) {
+ console.log("Failed parsing cookie header before: " + this._input);
+ return null;
+ }
+
+ var result = {
+ key: keyValueMatch[1],
+ value: keyValueMatch[2] && keyValueMatch[2].trim(),
+ position: this._originalInputLength - this._input.length
+ };
+ this._input = this._input.slice(keyValueMatch[0].length);
+ return result;
+ },
+
+ _advanceAndCheckCookieDelimiter: function()
+ {
+ var match = /^\s*[\n;]\s*/.exec(this._input);
+ if (!match)
+ return false;
+ this._input = this._input.slice(match[0].length);
+ return match[0].match("\n") !== null;
+ },
+
+ _addCookie: function(keyValue)
+ {
+ if (this._lastCookie)
+ this._lastCookie.size = keyValue.position - this._lastCookiePosition;
+ // Mozilla bug 169091: Mozilla, IE and Chrome treat signle token (w/o "=") as
+ // specifying a value for a cookie with empty name.
+ this._lastCookie = keyValue.value ? new WebInspector.Cookie(keyValue.key, keyValue.value) :
+ new WebInspector.Cookie("", keyValue.key);
+ this._lastCookiePosition = keyValue.position;
+ this._cookies.push(this._lastCookie);
+ }
+};
+
+WebInspector.CookieParser.parseCookie = function(header)
+{
+ return (new WebInspector.CookieParser()).parseCookie(header);
+}
+
+WebInspector.CookieParser.parseSetCookie = function(header)
+{
+ return (new WebInspector.CookieParser()).parseSetCookie(header);
+}
+
+WebInspector.Cookie = function(name, value)
+{
+ this.name = name;
+ this.value = value;
+ this._attributes = {};
+}
+
+WebInspector.Cookie.prototype = {
+ get httpOnly()
+ {
+ return "httponly" in this._attributes;
+ },
+
+ get secure()
+ {
+ return "secure" in this._attributes;
+ },
+
+ get session()
+ {
+ // RFC 2965 suggests using Discard attribute to mark session cookies, but this does not seem to be widely used.
+ // Check for absence of explicity max-age or expiry date instead.
+ return !("expries" in this._attributes || "max-age" in this._attributes);
+ },
+
+ get path()
+ {
+ return this._attributes.path;
+ },
+
+ get domain()
+ {
+ return this._attributes.domain;
+ },
+
+ expires: function(requestDate)
+ {
+ return this._attributes.expires ? new Date(this._attributes.expires) :
+ (this._attributes["max-age"] ? new Date(requestDate.getTime() + 1000 * this._attributes["max-age"]) : null);
+ },
+
+ get attributes()
+ {
+ return this._attributes;
+ },
+
+ addAttribute: function(key, value)
+ {
+ this._attributes[key.toLowerCase()] = value;
+ }
+}
diff --git a/WebCore/inspector/front-end/HAREntry.js b/WebCore/inspector/front-end/HAREntry.js
index b9f75a2..2b8f41b 100644
--- a/WebCore/inspector/front-end/HAREntry.js
+++ b/WebCore/inspector/front-end/HAREntry.js
@@ -56,7 +56,6 @@ WebInspector.HAREntry.prototype = {
method: this._resource.requestMethod,
url: this._resource.url,
// httpVersion: "HTTP/1.1" -- Not available.
- // cookies: [] -- Not available.
headers: this._buildHeaders(this._resource.requestHeaders),
headersSize: -1, // Not available.
bodySize: -1 // Not available.
@@ -65,22 +64,26 @@ WebInspector.HAREntry.prototype = {
res.queryString = this._buildParameters(this._resource.queryParameters);
if (this._resource.requestFormData)
res.postData = this._buildPostData();
+ if (this._resource.requestCookies)
+ res.cookies = this._buildCookies(this._resource.requestCookies);
return res;
},
_buildResponse: function()
{
- return {
+ var res = {
status: this._resource.statusCode,
statusText: this._resource.statusText,
// "httpVersion": "HTTP/1.1" -- Not available.
- // "cookies": [], -- Not available.
headers: this._buildHeaders(this._resource.responseHeaders),
content: this._buildContent(),
redirectURL: this._resource.responseHeaderValue("Location") || "",
headersSize: -1, // Not available.
bodySize: this._resource.resourceSize
};
+ if (this._resource.responseCookies)
+ res.cookies = this._buildCookies(this._resource.responseCookies);
+ return res;
},
_buildContent: function()
@@ -150,6 +153,25 @@ WebInspector.HAREntry.prototype = {
return parameters.slice();
},
+ _buildCookies: function(cookies)
+ {
+ return cookies.map(this._buildCookie.bind(this));
+ },
+
+ _buildCookie: function(cookie)
+ {
+
+ return {
+ name: cookie.name,
+ value: cookie.value,
+ path: cookie.path,
+ domain: cookie.domain,
+ expires: cookie.expires(new Date(this._resource.startTime * 1000)),
+ httpOnly: cookie.httpOnly,
+ secure: cookie.secure
+ };
+ },
+
_interval: function(start, end)
{
var timing = this._resource.timing;
diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js
index 1848a3a..fe2f7d2 100644
--- a/WebCore/inspector/front-end/Resource.js
+++ b/WebCore/inspector/front-end/Resource.js
@@ -350,6 +350,7 @@ WebInspector.Resource.prototype = {
{
this._requestHeaders = x;
delete this._sortedRequestHeaders;
+ delete this._requestCookies;
this.dispatchEventToListeners("requestHeaders changed");
},
@@ -372,6 +373,13 @@ WebInspector.Resource.prototype = {
return this._headerValue(this.requestHeaders, headerName);
},
+ get requestCookies()
+ {
+ if (!this._requestCookies)
+ this._requestCookies = WebInspector.CookieParser.parseCookie(this.requestHeaderValue("Cookie"));
+ return this._requestCookies;
+ },
+
get requestFormData()
{
return this._requestFormData;
@@ -392,6 +400,7 @@ WebInspector.Resource.prototype = {
{
this._responseHeaders = x;
delete this._sortedResponseHeaders;
+ delete this._responseCookies;
this.dispatchEventToListeners("responseHeaders changed");
},
@@ -414,6 +423,13 @@ WebInspector.Resource.prototype = {
return this._headerValue(this.responseHeaders, headerName);
},
+ get responseCookies()
+ {
+ if (!this._responseCookies)
+ this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.responseHeaderValue("Set-Cookie"));
+ return this._responseCookies;
+ },
+
get queryParameters()
{
if (this._parsedQueryParameters)
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index a5933af..1e5a508 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -20,6 +20,7 @@
<file>ConsoleView.js</file>
<file>ContextMenu.js</file>
<file>CookieItemsView.js</file>
+ <file>CookieParser.js</file>
<file>CSSCompletions.js</file>
<file>CSSStyleModel.js</file>
<file>Database.js</file>
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index 59a5f79..96d0cfe 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -144,6 +144,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="GoToLineDialog.js"></script>
<script type="text/javascript" src="ShortcutsHelp.js"></script>
<script type="text/javascript" src="HAREntry.js"></script>
+ <script type="text/javascript" src="CookieParser.js"></script>
</head>
<body class="detached">
<div id="toolbar">
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 541bd26..3fa8ec0 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,13 @@
+2010-10-19 Andrey Kosyakov <caseq at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: expose request/response cookies in HAR
+ https://bugs.webkit.org/show_bug.cgi?id=47894
+
+ * src/WebResourceRawHeaders.cpp:
+ (WebKit::addHeader): paste coalescent headers using "\n: as a separator instead of ", "
+
2010-10-19 Tony Chang <tony at chromium.org>
Reviewed by Kent Tamura.
diff --git a/WebKit/chromium/src/WebResourceRawHeaders.cpp b/WebKit/chromium/src/WebResourceRawHeaders.cpp
index b597ce2..259365e 100644
--- a/WebKit/chromium/src/WebResourceRawHeaders.cpp
+++ b/WebKit/chromium/src/WebResourceRawHeaders.cpp
@@ -69,7 +69,7 @@ static void addHeader(HTTPHeaderMap* map, const WebString& name, const WebString
{
pair<HTTPHeaderMap::iterator, bool> result = map->add(name, value);
if (!result.second)
- result.first->second += String(", ") + value;
+ result.first->second += String("\n") + value;
}
void WebResourceRawHeaders::addRequestHeader(const WebString& name, const WebString& value)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list