| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 // Ideally, we would rely on platform support for parsing a cookie, since | 30 // Ideally, we would rely on platform support for parsing a cookie, since |
| 31 // this would save us from any potential inconsistency. However, exposing | 31 // this would save us from any potential inconsistency. However, exposing |
| 32 // platform cookie parsing logic would require quite a bit of additional | 32 // platform cookie parsing logic would require quite a bit of additional |
| 33 // plumbing, and at least some platforms lack support for parsing Cookie, | 33 // plumbing, and at least some platforms lack support for parsing Cookie, |
| 34 // which is in a format slightly different from Set-Cookie and is normally | 34 // which is in a format slightly different from Set-Cookie and is normally |
| 35 // only required on the server side. | 35 // only required on the server side. |
| 36 | 36 |
| 37 /** | 37 /** |
| 38 * @unrestricted | 38 * @unrestricted |
| 39 */ | 39 */ |
| 40 WebInspector.CookieParser = class { | 40 SDK.CookieParser = class { |
| 41 /** | 41 /** |
| 42 * @param {!WebInspector.Target} target | 42 * @param {!SDK.Target} target |
| 43 */ | 43 */ |
| 44 constructor(target) { | 44 constructor(target) { |
| 45 this._target = target; | 45 this._target = target; |
| 46 } | 46 } |
| 47 | 47 |
| 48 /** | 48 /** |
| 49 * @param {!WebInspector.Target} target | 49 * @param {!SDK.Target} target |
| 50 * @param {string|undefined} header | 50 * @param {string|undefined} header |
| 51 * @return {?Array.<!WebInspector.Cookie>} | 51 * @return {?Array.<!SDK.Cookie>} |
| 52 */ | 52 */ |
| 53 static parseCookie(target, header) { | 53 static parseCookie(target, header) { |
| 54 return (new WebInspector.CookieParser(target)).parseCookie(header); | 54 return (new SDK.CookieParser(target)).parseCookie(header); |
| 55 } | 55 } |
| 56 | 56 |
| 57 /** | 57 /** |
| 58 * @param {!WebInspector.Target} target | 58 * @param {!SDK.Target} target |
| 59 * @param {string|undefined} header | 59 * @param {string|undefined} header |
| 60 * @return {?Array.<!WebInspector.Cookie>} | 60 * @return {?Array.<!SDK.Cookie>} |
| 61 */ | 61 */ |
| 62 static parseSetCookie(target, header) { | 62 static parseSetCookie(target, header) { |
| 63 return (new WebInspector.CookieParser(target)).parseSetCookie(header); | 63 return (new SDK.CookieParser(target)).parseSetCookie(header); |
| 64 } | 64 } |
| 65 | 65 |
| 66 /** | 66 /** |
| 67 * @return {!Array.<!WebInspector.Cookie>} | 67 * @return {!Array.<!SDK.Cookie>} |
| 68 */ | 68 */ |
| 69 cookies() { | 69 cookies() { |
| 70 return this._cookies; | 70 return this._cookies; |
| 71 } | 71 } |
| 72 | 72 |
| 73 /** | 73 /** |
| 74 * @param {string|undefined} cookieHeader | 74 * @param {string|undefined} cookieHeader |
| 75 * @return {?Array.<!WebInspector.Cookie>} | 75 * @return {?Array.<!SDK.Cookie>} |
| 76 */ | 76 */ |
| 77 parseCookie(cookieHeader) { | 77 parseCookie(cookieHeader) { |
| 78 if (!this._initialize(cookieHeader)) | 78 if (!this._initialize(cookieHeader)) |
| 79 return null; | 79 return null; |
| 80 | 80 |
| 81 for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) { | 81 for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) { |
| 82 if (kv.key.charAt(0) === '$' && this._lastCookie) | 82 if (kv.key.charAt(0) === '$' && this._lastCookie) |
| 83 this._lastCookie.addAttribute(kv.key.slice(1), kv.value); | 83 this._lastCookie.addAttribute(kv.key.slice(1), kv.value); |
| 84 else if (kv.key.toLowerCase() !== '$version' && typeof kv.value === 'strin
g') | 84 else if (kv.key.toLowerCase() !== '$version' && typeof kv.value === 'strin
g') |
| 85 this._addCookie(kv, WebInspector.Cookie.Type.Request); | 85 this._addCookie(kv, SDK.Cookie.Type.Request); |
| 86 this._advanceAndCheckCookieDelimiter(); | 86 this._advanceAndCheckCookieDelimiter(); |
| 87 } | 87 } |
| 88 this._flushCookie(); | 88 this._flushCookie(); |
| 89 return this._cookies; | 89 return this._cookies; |
| 90 } | 90 } |
| 91 | 91 |
| 92 /** | 92 /** |
| 93 * @param {string|undefined} setCookieHeader | 93 * @param {string|undefined} setCookieHeader |
| 94 * @return {?Array.<!WebInspector.Cookie>} | 94 * @return {?Array.<!SDK.Cookie>} |
| 95 */ | 95 */ |
| 96 parseSetCookie(setCookieHeader) { | 96 parseSetCookie(setCookieHeader) { |
| 97 if (!this._initialize(setCookieHeader)) | 97 if (!this._initialize(setCookieHeader)) |
| 98 return null; | 98 return null; |
| 99 for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) { | 99 for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) { |
| 100 if (this._lastCookie) | 100 if (this._lastCookie) |
| 101 this._lastCookie.addAttribute(kv.key, kv.value); | 101 this._lastCookie.addAttribute(kv.key, kv.value); |
| 102 else | 102 else |
| 103 this._addCookie(kv, WebInspector.Cookie.Type.Response); | 103 this._addCookie(kv, SDK.Cookie.Type.Response); |
| 104 if (this._advanceAndCheckCookieDelimiter()) | 104 if (this._advanceAndCheckCookieDelimiter()) |
| 105 this._flushCookie(); | 105 this._flushCookie(); |
| 106 } | 106 } |
| 107 this._flushCookie(); | 107 this._flushCookie(); |
| 108 return this._cookies; | 108 return this._cookies; |
| 109 } | 109 } |
| 110 | 110 |
| 111 /** | 111 /** |
| 112 * @param {string|undefined} headerValue | 112 * @param {string|undefined} headerValue |
| 113 * @return {boolean} | 113 * @return {boolean} |
| 114 */ | 114 */ |
| 115 _initialize(headerValue) { | 115 _initialize(headerValue) { |
| 116 this._input = headerValue; | 116 this._input = headerValue; |
| 117 if (typeof headerValue !== 'string') | 117 if (typeof headerValue !== 'string') |
| 118 return false; | 118 return false; |
| 119 this._cookies = []; | 119 this._cookies = []; |
| 120 this._lastCookie = null; | 120 this._lastCookie = null; |
| 121 this._originalInputLength = this._input.length; | 121 this._originalInputLength = this._input.length; |
| 122 return true; | 122 return true; |
| 123 } | 123 } |
| 124 | 124 |
| 125 _flushCookie() { | 125 _flushCookie() { |
| 126 if (this._lastCookie) | 126 if (this._lastCookie) |
| 127 this._lastCookie.setSize(this._originalInputLength - this._input.length -
this._lastCookiePosition); | 127 this._lastCookie.setSize(this._originalInputLength - this._input.length -
this._lastCookiePosition); |
| 128 this._lastCookie = null; | 128 this._lastCookie = null; |
| 129 } | 129 } |
| 130 | 130 |
| 131 /** | 131 /** |
| 132 * @return {?WebInspector.CookieParser.KeyValue} | 132 * @return {?SDK.CookieParser.KeyValue} |
| 133 */ | 133 */ |
| 134 _extractKeyValue() { | 134 _extractKeyValue() { |
| 135 if (!this._input || !this._input.length) | 135 if (!this._input || !this._input.length) |
| 136 return null; | 136 return null; |
| 137 // Note: RFCs offer an option for quoted values that may contain commas and
semicolons. | 137 // Note: RFCs offer an option for quoted values that may contain commas and
semicolons. |
| 138 // Many browsers/platforms do not support this, however (see http://webkit.o
rg/b/16699 | 138 // Many browsers/platforms do not support this, however (see http://webkit.o
rg/b/16699 |
| 139 // and http://crbug.com/12361). The logic below matches latest versions of I
E, Firefox, | 139 // and http://crbug.com/12361). The logic below matches latest versions of I
E, Firefox, |
| 140 // Chrome and Safari on some old platforms. The latest version of Safari sup
ports quoted | 140 // Chrome and Safari on some old platforms. The latest version of Safari sup
ports quoted |
| 141 // cookie values, though. | 141 // cookie values, though. |
| 142 var keyValueMatch = /^[ \t]*([^\s=;]+)[ \t]*(?:=[ \t]*([^;\n]*))?/.exec(this
._input); | 142 var keyValueMatch = /^[ \t]*([^\s=;]+)[ \t]*(?:=[ \t]*([^;\n]*))?/.exec(this
._input); |
| 143 if (!keyValueMatch) { | 143 if (!keyValueMatch) { |
| 144 console.log('Failed parsing cookie header before: ' + this._input); | 144 console.log('Failed parsing cookie header before: ' + this._input); |
| 145 return null; | 145 return null; |
| 146 } | 146 } |
| 147 | 147 |
| 148 var result = new WebInspector.CookieParser.KeyValue( | 148 var result = new SDK.CookieParser.KeyValue( |
| 149 keyValueMatch[1], keyValueMatch[2] && keyValueMatch[2].trim(), this._ori
ginalInputLength - this._input.length); | 149 keyValueMatch[1], keyValueMatch[2] && keyValueMatch[2].trim(), this._ori
ginalInputLength - this._input.length); |
| 150 this._input = this._input.slice(keyValueMatch[0].length); | 150 this._input = this._input.slice(keyValueMatch[0].length); |
| 151 return result; | 151 return result; |
| 152 } | 152 } |
| 153 | 153 |
| 154 /** | 154 /** |
| 155 * @return {boolean} | 155 * @return {boolean} |
| 156 */ | 156 */ |
| 157 _advanceAndCheckCookieDelimiter() { | 157 _advanceAndCheckCookieDelimiter() { |
| 158 var match = /^\s*[\n;]\s*/.exec(this._input); | 158 var match = /^\s*[\n;]\s*/.exec(this._input); |
| 159 if (!match) | 159 if (!match) |
| 160 return false; | 160 return false; |
| 161 this._input = this._input.slice(match[0].length); | 161 this._input = this._input.slice(match[0].length); |
| 162 return match[0].match('\n') !== null; | 162 return match[0].match('\n') !== null; |
| 163 } | 163 } |
| 164 | 164 |
| 165 /** | 165 /** |
| 166 * @param {!WebInspector.CookieParser.KeyValue} keyValue | 166 * @param {!SDK.CookieParser.KeyValue} keyValue |
| 167 * @param {!WebInspector.Cookie.Type} type | 167 * @param {!SDK.Cookie.Type} type |
| 168 */ | 168 */ |
| 169 _addCookie(keyValue, type) { | 169 _addCookie(keyValue, type) { |
| 170 if (this._lastCookie) | 170 if (this._lastCookie) |
| 171 this._lastCookie.setSize(keyValue.position - this._lastCookiePosition); | 171 this._lastCookie.setSize(keyValue.position - this._lastCookiePosition); |
| 172 // Mozilla bug 169091: Mozilla, IE and Chrome treat single token (w/o "=") a
s | 172 // Mozilla bug 169091: Mozilla, IE and Chrome treat single token (w/o "=") a
s |
| 173 // specifying a value for a cookie with empty name. | 173 // specifying a value for a cookie with empty name. |
| 174 this._lastCookie = typeof keyValue.value === 'string' ? | 174 this._lastCookie = typeof keyValue.value === 'string' ? |
| 175 new WebInspector.Cookie(this._target, keyValue.key, keyValue.value, type
) : | 175 new SDK.Cookie(this._target, keyValue.key, keyValue.value, type) : |
| 176 new WebInspector.Cookie(this._target, '', keyValue.key, type); | 176 new SDK.Cookie(this._target, '', keyValue.key, type); |
| 177 this._lastCookiePosition = keyValue.position; | 177 this._lastCookiePosition = keyValue.position; |
| 178 this._cookies.push(this._lastCookie); | 178 this._cookies.push(this._lastCookie); |
| 179 } | 179 } |
| 180 }; | 180 }; |
| 181 | 181 |
| 182 /** | 182 /** |
| 183 * @unrestricted | 183 * @unrestricted |
| 184 */ | 184 */ |
| 185 WebInspector.CookieParser.KeyValue = class { | 185 SDK.CookieParser.KeyValue = class { |
| 186 /** | 186 /** |
| 187 * @param {string} key | 187 * @param {string} key |
| 188 * @param {string|undefined} value | 188 * @param {string|undefined} value |
| 189 * @param {number} position | 189 * @param {number} position |
| 190 */ | 190 */ |
| 191 constructor(key, value, position) { | 191 constructor(key, value, position) { |
| 192 this.key = key; | 192 this.key = key; |
| 193 this.value = value; | 193 this.value = value; |
| 194 this.position = position; | 194 this.position = position; |
| 195 } | 195 } |
| 196 }; | 196 }; |
| 197 | 197 |
| 198 | 198 |
| 199 /** | 199 /** |
| 200 * @unrestricted | 200 * @unrestricted |
| 201 */ | 201 */ |
| 202 WebInspector.Cookie = class { | 202 SDK.Cookie = class { |
| 203 /** | 203 /** |
| 204 * @param {!WebInspector.Target} target | 204 * @param {!SDK.Target} target |
| 205 * @param {string} name | 205 * @param {string} name |
| 206 * @param {string} value | 206 * @param {string} value |
| 207 * @param {?WebInspector.Cookie.Type} type | 207 * @param {?SDK.Cookie.Type} type |
| 208 */ | 208 */ |
| 209 constructor(target, name, value, type) { | 209 constructor(target, name, value, type) { |
| 210 this._target = target; | 210 this._target = target; |
| 211 this._name = name; | 211 this._name = name; |
| 212 this._value = value; | 212 this._value = value; |
| 213 this._type = type; | 213 this._type = type; |
| 214 this._attributes = {}; | 214 this._attributes = {}; |
| 215 } | 215 } |
| 216 | 216 |
| 217 /** | 217 /** |
| 218 * @return {string} | 218 * @return {string} |
| 219 */ | 219 */ |
| 220 name() { | 220 name() { |
| 221 return this._name; | 221 return this._name; |
| 222 } | 222 } |
| 223 | 223 |
| 224 /** | 224 /** |
| 225 * @return {string} | 225 * @return {string} |
| 226 */ | 226 */ |
| 227 value() { | 227 value() { |
| 228 return this._value; | 228 return this._value; |
| 229 } | 229 } |
| 230 | 230 |
| 231 /** | 231 /** |
| 232 * @return {?WebInspector.Cookie.Type} | 232 * @return {?SDK.Cookie.Type} |
| 233 */ | 233 */ |
| 234 type() { | 234 type() { |
| 235 return this._type; | 235 return this._type; |
| 236 } | 236 } |
| 237 | 237 |
| 238 /** | 238 /** |
| 239 * @return {boolean} | 239 * @return {boolean} |
| 240 */ | 240 */ |
| 241 httpOnly() { | 241 httpOnly() { |
| 242 return 'httponly' in this._attributes; | 242 return 'httponly' in this._attributes; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 */ | 350 */ |
| 351 remove(callback) { | 351 remove(callback) { |
| 352 this._target.networkAgent().deleteCookie( | 352 this._target.networkAgent().deleteCookie( |
| 353 this.name(), (this.secure() ? 'https://' : 'http://') + this.domain() +
this.path(), callback); | 353 this.name(), (this.secure() ? 'https://' : 'http://') + this.domain() +
this.path(), callback); |
| 354 } | 354 } |
| 355 }; | 355 }; |
| 356 | 356 |
| 357 /** | 357 /** |
| 358 * @enum {number} | 358 * @enum {number} |
| 359 */ | 359 */ |
| 360 WebInspector.Cookie.Type = { | 360 SDK.Cookie.Type = { |
| 361 Request: 0, | 361 Request: 0, |
| 362 Response: 1 | 362 Response: 1 |
| 363 }; | 363 }; |
| 364 | 364 |
| 365 WebInspector.Cookies = {}; | 365 SDK.Cookies = {}; |
| 366 | 366 |
| 367 /** | 367 /** |
| 368 * @param {function(!Array.<!WebInspector.Cookie>)} callback | 368 * @param {function(!Array.<!SDK.Cookie>)} callback |
| 369 */ | 369 */ |
| 370 WebInspector.Cookies.getCookiesAsync = function(callback) { | 370 SDK.Cookies.getCookiesAsync = function(callback) { |
| 371 var allCookies = []; | 371 var allCookies = []; |
| 372 /** | 372 /** |
| 373 * @param {!WebInspector.Target} target | 373 * @param {!SDK.Target} target |
| 374 * @param {?Protocol.Error} error | 374 * @param {?Protocol.Error} error |
| 375 * @param {!Array.<!Protocol.Network.Cookie>} cookies | 375 * @param {!Array.<!Protocol.Network.Cookie>} cookies |
| 376 */ | 376 */ |
| 377 function mycallback(target, error, cookies) { | 377 function mycallback(target, error, cookies) { |
| 378 if (error) { | 378 if (error) { |
| 379 console.error(error); | 379 console.error(error); |
| 380 return; | 380 return; |
| 381 } | 381 } |
| 382 for (var i = 0; i < cookies.length; ++i) | 382 for (var i = 0; i < cookies.length; ++i) |
| 383 allCookies.push(WebInspector.Cookies._parseProtocolCookie(target, cookies[
i])); | 383 allCookies.push(SDK.Cookies._parseProtocolCookie(target, cookies[i])); |
| 384 } | 384 } |
| 385 | 385 |
| 386 var barrier = new CallbackBarrier(); | 386 var barrier = new CallbackBarrier(); |
| 387 for (var target of WebInspector.targetManager.targets(WebInspector.Target.Capa
bility.Network)) | 387 for (var target of SDK.targetManager.targets(SDK.Target.Capability.Network)) |
| 388 target.networkAgent().getCookies(barrier.createCallback(mycallback.bind(null
, target))); | 388 target.networkAgent().getCookies(barrier.createCallback(mycallback.bind(null
, target))); |
| 389 barrier.callWhenDone(callback.bind(null, allCookies)); | 389 barrier.callWhenDone(callback.bind(null, allCookies)); |
| 390 }; | 390 }; |
| 391 | 391 |
| 392 /** | 392 /** |
| 393 * @param {!WebInspector.Target} target | 393 * @param {!SDK.Target} target |
| 394 * @param {!Protocol.Network.Cookie} protocolCookie | 394 * @param {!Protocol.Network.Cookie} protocolCookie |
| 395 * @return {!WebInspector.Cookie} | 395 * @return {!SDK.Cookie} |
| 396 */ | 396 */ |
| 397 WebInspector.Cookies._parseProtocolCookie = function(target, protocolCookie) { | 397 SDK.Cookies._parseProtocolCookie = function(target, protocolCookie) { |
| 398 var cookie = new WebInspector.Cookie(target, protocolCookie.name, protocolCook
ie.value, null); | 398 var cookie = new SDK.Cookie(target, protocolCookie.name, protocolCookie.value,
null); |
| 399 cookie.addAttribute('domain', protocolCookie['domain']); | 399 cookie.addAttribute('domain', protocolCookie['domain']); |
| 400 cookie.addAttribute('path', protocolCookie['path']); | 400 cookie.addAttribute('path', protocolCookie['path']); |
| 401 cookie.addAttribute('port', protocolCookie['port']); | 401 cookie.addAttribute('port', protocolCookie['port']); |
| 402 if (protocolCookie['expires']) | 402 if (protocolCookie['expires']) |
| 403 cookie.addAttribute('expires', protocolCookie['expires']); | 403 cookie.addAttribute('expires', protocolCookie['expires']); |
| 404 if (protocolCookie['httpOnly']) | 404 if (protocolCookie['httpOnly']) |
| 405 cookie.addAttribute('httpOnly'); | 405 cookie.addAttribute('httpOnly'); |
| 406 if (protocolCookie['secure']) | 406 if (protocolCookie['secure']) |
| 407 cookie.addAttribute('secure'); | 407 cookie.addAttribute('secure'); |
| 408 if (protocolCookie['sameSite']) | 408 if (protocolCookie['sameSite']) |
| 409 cookie.addAttribute('sameSite', protocolCookie['sameSite']); | 409 cookie.addAttribute('sameSite', protocolCookie['sameSite']); |
| 410 cookie.setSize(protocolCookie['size']); | 410 cookie.setSize(protocolCookie['size']); |
| 411 return cookie; | 411 return cookie; |
| 412 }; | 412 }; |
| 413 | 413 |
| 414 /** | 414 /** |
| 415 * @param {!WebInspector.Cookie} cookie | 415 * @param {!SDK.Cookie} cookie |
| 416 * @param {string} resourceURL | 416 * @param {string} resourceURL |
| 417 * @return {boolean} | 417 * @return {boolean} |
| 418 */ | 418 */ |
| 419 WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL) { | 419 SDK.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL) { |
| 420 var url = resourceURL.asParsedURL(); | 420 var url = resourceURL.asParsedURL(); |
| 421 if (!url || !WebInspector.Cookies.cookieDomainMatchesResourceDomain(cookie.dom
ain(), url.host)) | 421 if (!url || !SDK.Cookies.cookieDomainMatchesResourceDomain(cookie.domain(), ur
l.host)) |
| 422 return false; | 422 return false; |
| 423 return ( | 423 return ( |
| 424 url.path.startsWith(cookie.path()) && (!cookie.port() || url.port === cook
ie.port()) && | 424 url.path.startsWith(cookie.path()) && (!cookie.port() || url.port === cook
ie.port()) && |
| 425 (!cookie.secure() || url.scheme === 'https')); | 425 (!cookie.secure() || url.scheme === 'https')); |
| 426 }; | 426 }; |
| 427 | 427 |
| 428 /** | 428 /** |
| 429 * @param {string} cookieDomain | 429 * @param {string} cookieDomain |
| 430 * @param {string} resourceDomain | 430 * @param {string} resourceDomain |
| 431 * @return {boolean} | 431 * @return {boolean} |
| 432 */ | 432 */ |
| 433 WebInspector.Cookies.cookieDomainMatchesResourceDomain = function(cookieDomain,
resourceDomain) { | 433 SDK.Cookies.cookieDomainMatchesResourceDomain = function(cookieDomain, resourceD
omain) { |
| 434 if (cookieDomain.charAt(0) !== '.') | 434 if (cookieDomain.charAt(0) !== '.') |
| 435 return resourceDomain === cookieDomain; | 435 return resourceDomain === cookieDomain; |
| 436 return !!resourceDomain.match(new RegExp('^([^\\.]+\\.)*' + cookieDomain.subst
ring(1).escapeForRegExp() + '$', 'i')); | 436 return !!resourceDomain.match(new RegExp('^([^\\.]+\\.)*' + cookieDomain.subst
ring(1).escapeForRegExp() + '$', 'i')); |
| 437 }; | 437 }; |
| OLD | NEW |