| /* |
| * Copyright (C) 2012 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. |
| */ |
| |
| /** |
| * @constructor |
| * @extends {WebInspector.SDKObject} |
| * @implements {WebInspector.ContentProvider} |
| * @param {!NetworkAgent.RequestId} requestId |
| * @param {!WebInspector.Target} target |
| * @param {string} url |
| * @param {string} documentURL |
| * @param {!PageAgent.FrameId} frameId |
| * @param {!NetworkAgent.LoaderId} loaderId |
| * @param {?NetworkAgent.Initiator} initiator |
| */ |
| WebInspector.NetworkRequest = function(target, requestId, url, documentURL, frameId, loaderId, initiator) |
| { |
| WebInspector.SDKObject.call(this, target); |
| |
| this._networkLog = /** @type {!WebInspector.NetworkLog} */ (WebInspector.NetworkLog.fromTarget(target)); |
| this._networkManager = /** @type {!WebInspector.NetworkManager} */ (WebInspector.NetworkManager.fromTarget(target)); |
| this._requestId = requestId; |
| this.url = url; |
| this._documentURL = documentURL; |
| this._frameId = frameId; |
| this._loaderId = loaderId; |
| /** @type {?NetworkAgent.Initiator} */ |
| this._initiator = initiator; |
| this._issueTime = -1; |
| this._startTime = -1; |
| this._endTime = -1; |
| /** @type {!NetworkAgent.BlockedReason|undefined} */ |
| this._blockedReason = undefined; |
| |
| this.statusCode = 0; |
| this.statusText = ""; |
| this.requestMethod = ""; |
| this.requestTime = 0; |
| this.protocol = ""; |
| /** @type {!NetworkAgent.RequestMixedContentType} */ |
| this.mixedContentType = NetworkAgent.RequestMixedContentType.None; |
| |
| /** @type {?NetworkAgent.ResourcePriority} */ |
| this._initialPriority = null; |
| /** @type {?NetworkAgent.ResourcePriority} */ |
| this._currentPriority = null; |
| |
| /** @type {!WebInspector.ResourceType} */ |
| this._resourceType = WebInspector.resourceTypes.Other; |
| this._contentEncoded = false; |
| this._pendingContentCallbacks = []; |
| /** @type {!Array.<!WebInspector.NetworkRequest.WebSocketFrame>} */ |
| this._frames = []; |
| /** @type {!Array.<!WebInspector.NetworkRequest.EventSourceMessage>} */ |
| this._eventSourceMessages = []; |
| |
| this._responseHeaderValues = {}; |
| |
| this._remoteAddress = ""; |
| |
| /** @type {!SecurityAgent.SecurityState} */ |
| this._securityState = SecurityAgent.SecurityState.Unknown; |
| /** @type {?NetworkAgent.SecurityDetails} */ |
| this._securityDetails = null; |
| |
| /** @type {string} */ |
| this.connectionId = "0"; |
| } |
| |
| WebInspector.NetworkRequest.Events = { |
| FinishedLoading: "FinishedLoading", |
| TimingChanged: "TimingChanged", |
| RemoteAddressChanged: "RemoteAddressChanged", |
| RequestHeadersChanged: "RequestHeadersChanged", |
| ResponseHeadersChanged: "ResponseHeadersChanged", |
| WebsocketFrameAdded: "WebsocketFrameAdded", |
| EventSourceMessageAdded: "EventSourceMessageAdded", |
| } |
| |
| /** @enum {string} */ |
| WebInspector.NetworkRequest.InitiatorType = { |
| Other: "other", |
| Parser: "parser", |
| Redirect: "redirect", |
| Script: "script" |
| } |
| |
| /** @typedef {!{name: string, value: string}} */ |
| WebInspector.NetworkRequest.NameValue; |
| |
| /** @enum {string} */ |
| WebInspector.NetworkRequest.WebSocketFrameType = { |
| Send: "send", |
| Receive: "receive", |
| Error: "error" |
| } |
| |
| /** @typedef {!{type: WebInspector.NetworkRequest.WebSocketFrameType, time: number, text: string, opCode: number, mask: boolean}} */ |
| WebInspector.NetworkRequest.WebSocketFrame; |
| |
| /** @typedef {!{time: number, eventName: string, eventId: string, data: string}} */ |
| WebInspector.NetworkRequest.EventSourceMessage; |
| |
| WebInspector.NetworkRequest.prototype = { |
| /** |
| * @param {!WebInspector.NetworkRequest} other |
| * @return {number} |
| */ |
| indentityCompare: function(other) |
| { |
| if (this._requestId > other._requestId) |
| return 1; |
| if (this._requestId < other._requestId) |
| return -1; |
| return 0; |
| }, |
| |
| /** |
| * @return {!NetworkAgent.RequestId} |
| */ |
| get requestId() |
| { |
| return this._requestId; |
| }, |
| |
| set requestId(requestId) |
| { |
| this._requestId = requestId; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| get url() |
| { |
| return this._url; |
| }, |
| |
| set url(x) |
| { |
| if (this._url === x) |
| return; |
| |
| this._url = x; |
| this._parsedURL = new WebInspector.ParsedURL(x); |
| delete this._queryString; |
| delete this._parsedQueryParameters; |
| delete this._name; |
| delete this._path; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| get documentURL() |
| { |
| return this._documentURL; |
| }, |
| |
| get parsedURL() |
| { |
| return this._parsedURL; |
| }, |
| |
| /** |
| * @return {!PageAgent.FrameId} |
| */ |
| get frameId() |
| { |
| return this._frameId; |
| }, |
| |
| /** |
| * @return {!NetworkAgent.LoaderId} |
| */ |
| get loaderId() |
| { |
| return this._loaderId; |
| }, |
| |
| /** |
| * @param {string} ip |
| * @param {number} port |
| */ |
| setRemoteAddress: function(ip, port) |
| { |
| this._remoteAddress = ip + ":" + port; |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RemoteAddressChanged, this); |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| remoteAddress: function() |
| { |
| return this._remoteAddress; |
| }, |
| |
| /** |
| * @return {!SecurityAgent.SecurityState} |
| */ |
| securityState: function() |
| { |
| return this._securityState; |
| }, |
| |
| /** |
| * @param {!SecurityAgent.SecurityState} securityState |
| */ |
| setSecurityState: function(securityState) |
| { |
| this._securityState = securityState; |
| }, |
| |
| /** |
| * @return {?NetworkAgent.SecurityDetails} |
| */ |
| securityDetails: function() |
| { |
| return this._securityDetails; |
| }, |
| |
| /** |
| * @param {!NetworkAgent.SecurityDetails} securityDetails |
| */ |
| setSecurityDetails: function(securityDetails) |
| { |
| this._securityDetails = securityDetails; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| get startTime() |
| { |
| return this._startTime || -1; |
| }, |
| |
| /** |
| * @param {number} monotonicTime |
| * @param {number} wallTime |
| */ |
| setIssueTime: function(monotonicTime, wallTime) |
| { |
| this._issueTime = monotonicTime; |
| this._wallIssueTime = wallTime; |
| this._startTime = monotonicTime; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| issueTime: function() |
| { |
| return this._issueTime; |
| }, |
| |
| /** |
| * @param {number} monotonicTime |
| * @return {number} |
| */ |
| pseudoWallTime: function(monotonicTime) |
| { |
| return this._wallIssueTime ? this._wallIssueTime - this._issueTime + monotonicTime : monotonicTime; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| get responseReceivedTime() |
| { |
| return this._responseReceivedTime || -1; |
| }, |
| |
| set responseReceivedTime(x) |
| { |
| this._responseReceivedTime = x; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| get endTime() |
| { |
| return this._endTime || -1; |
| }, |
| |
| set endTime(x) |
| { |
| if (this.timing && this.timing.requestTime) { |
| // Check against accurate responseReceivedTime. |
| this._endTime = Math.max(x, this.responseReceivedTime); |
| } else { |
| // Prefer endTime since it might be from the network stack. |
| this._endTime = x; |
| if (this._responseReceivedTime > x) |
| this._responseReceivedTime = x; |
| } |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this); |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| get duration() |
| { |
| if (this._endTime === -1 || this._startTime === -1) |
| return -1; |
| return this._endTime - this._startTime; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| get latency() |
| { |
| if (this._responseReceivedTime === -1 || this._startTime === -1) |
| return -1; |
| return this._responseReceivedTime - this._startTime; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| get resourceSize() |
| { |
| return this._resourceSize || 0; |
| }, |
| |
| set resourceSize(x) |
| { |
| this._resourceSize = x; |
| }, |
| |
| /** |
| * @return {number} |
| */ |
| get transferSize() |
| { |
| return this._transferSize || 0; |
| }, |
| |
| /** |
| * @param {number} x |
| */ |
| increaseTransferSize: function(x) |
| { |
| this._transferSize = (this._transferSize || 0) + x; |
| }, |
| |
| /** |
| * @param {number} x |
| */ |
| setTransferSize: function(x) |
| { |
| this._transferSize = x; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| get finished() |
| { |
| return this._finished; |
| }, |
| |
| set finished(x) |
| { |
| if (this._finished === x) |
| return; |
| |
| this._finished = x; |
| |
| if (x) { |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading, this); |
| if (this._pendingContentCallbacks.length) |
| this._innerRequestContent(); |
| } |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| get failed() |
| { |
| return this._failed; |
| }, |
| |
| set failed(x) |
| { |
| this._failed = x; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| get canceled() |
| { |
| return this._canceled; |
| }, |
| |
| set canceled(x) |
| { |
| this._canceled = x; |
| }, |
| |
| /** |
| * @return {!NetworkAgent.BlockedReason|undefined} |
| */ |
| blockedReason: function() |
| { |
| return this._blockedReason; |
| }, |
| |
| /** |
| * @param {!NetworkAgent.BlockedReason} reason |
| */ |
| setBlockedReason: function(reason) |
| { |
| this._blockedReason = reason; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| wasBlocked: function() |
| { |
| return !!this._blockedReason; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| cached: function() |
| { |
| return (!!this._fromMemoryCache || !!this._fromDiskCache) && !this._transferSize; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| cachedInMemory: function() |
| { |
| return !!this._fromMemoryCache && !this._transferSize; |
| }, |
| |
| setFromMemoryCache: function() |
| { |
| this._fromMemoryCache = true; |
| delete this._timing; |
| }, |
| |
| setFromDiskCache: function() |
| { |
| this._fromDiskCache = true; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| get fetchedViaServiceWorker() |
| { |
| return this._fetchedViaServiceWorker; |
| }, |
| |
| set fetchedViaServiceWorker(x) |
| { |
| this._fetchedViaServiceWorker = x; |
| }, |
| |
| /** |
| * @return {!NetworkAgent.ResourceTiming|undefined} |
| */ |
| get timing() |
| { |
| return this._timing; |
| }, |
| |
| set timing(x) |
| { |
| if (x && !this._fromMemoryCache) { |
| // Take startTime and responseReceivedTime from timing data for better accuracy. |
| // Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis. |
| this._startTime = x.requestTime; |
| this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0; |
| |
| this._timing = x; |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this); |
| } |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| get mimeType() |
| { |
| return this._mimeType; |
| }, |
| |
| set mimeType(x) |
| { |
| this._mimeType = x; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| get displayName() |
| { |
| return this._parsedURL.displayName; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| name: function() |
| { |
| if (this._name) |
| return this._name; |
| this._parseNameAndPathFromURL(); |
| return this._name; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| path: function() |
| { |
| if (this._path) |
| return this._path; |
| this._parseNameAndPathFromURL(); |
| return this._path; |
| }, |
| |
| _parseNameAndPathFromURL: function() |
| { |
| if (this._parsedURL.isDataURL()) { |
| this._name = this._parsedURL.dataURLDisplayName(); |
| this._path = ""; |
| } else if (this._parsedURL.isAboutBlank()) { |
| this._name = this._parsedURL.url; |
| this._path = ""; |
| } else { |
| this._path = this._parsedURL.host + this._parsedURL.folderPathComponents; |
| |
| this._path = this._path.trimURL(this.target().inspectedURL().asParsedURL().host); |
| if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams) |
| this._name = this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? "?" + this._parsedURL.queryParams : ""); |
| else if (this._parsedURL.folderPathComponents) { |
| this._name = this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf("/") + 1) + "/"; |
| this._path = this._path.substring(0, this._path.lastIndexOf("/")); |
| } else { |
| this._name = this._parsedURL.host; |
| this._path = ""; |
| } |
| } |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| get folder() |
| { |
| var path = this._parsedURL.path; |
| var indexOfQuery = path.indexOf("?"); |
| if (indexOfQuery !== -1) |
| path = path.substring(0, indexOfQuery); |
| var lastSlashIndex = path.lastIndexOf("/"); |
| return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : ""; |
| }, |
| |
| /** |
| * @return {!WebInspector.ResourceType} |
| */ |
| resourceType: function() |
| { |
| return this._resourceType; |
| }, |
| |
| /** |
| * @param {!WebInspector.ResourceType} resourceType |
| */ |
| setResourceType: function(resourceType) |
| { |
| this._resourceType = resourceType; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| get domain() |
| { |
| return this._parsedURL.host; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| get scheme() |
| { |
| return this._parsedURL.scheme; |
| }, |
| |
| /** |
| * @return {?WebInspector.NetworkRequest} |
| */ |
| get redirectSource() |
| { |
| if (this.redirects && this.redirects.length > 0) |
| return this.redirects[this.redirects.length - 1]; |
| return this._redirectSource; |
| }, |
| |
| set redirectSource(x) |
| { |
| this._redirectSource = x; |
| delete this._initiatorInfo; |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.NetworkRequest.NameValue>} |
| */ |
| requestHeaders: function() |
| { |
| return this._requestHeaders || []; |
| }, |
| |
| /** |
| * @param {!Array.<!WebInspector.NetworkRequest.NameValue>} headers |
| */ |
| setRequestHeaders: function(headers) |
| { |
| this._requestHeaders = headers; |
| delete this._requestCookies; |
| |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged); |
| }, |
| |
| /** |
| * @return {string|undefined} |
| */ |
| requestHeadersText: function() |
| { |
| return this._requestHeadersText; |
| }, |
| |
| /** |
| * @param {string} text |
| */ |
| setRequestHeadersText: function(text) |
| { |
| this._requestHeadersText = text; |
| |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged); |
| }, |
| |
| /** |
| * @param {string} headerName |
| * @return {string|undefined} |
| */ |
| requestHeaderValue: function(headerName) |
| { |
| return this._headerValue(this.requestHeaders(), headerName); |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.Cookie>} |
| */ |
| get requestCookies() |
| { |
| if (!this._requestCookies) |
| this._requestCookies = WebInspector.CookieParser.parseCookie(this.target(), this.requestHeaderValue("Cookie")); |
| return this._requestCookies; |
| }, |
| |
| /** |
| * @return {string|undefined} |
| */ |
| get requestFormData() |
| { |
| return this._requestFormData; |
| }, |
| |
| set requestFormData(x) |
| { |
| this._requestFormData = x; |
| delete this._parsedFormParameters; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| requestHttpVersion: function() |
| { |
| var headersText = this.requestHeadersText(); |
| if (!headersText) |
| return this.requestHeaderValue("version") || this.requestHeaderValue(":version") || "unknown"; |
| var firstLine = headersText.split(/\r\n/)[0]; |
| var match = firstLine.match(/(HTTP\/\d+\.\d+)$/); |
| return match ? match[1] : "HTTP/0.9"; |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.NetworkRequest.NameValue>} |
| */ |
| get responseHeaders() |
| { |
| return this._responseHeaders || []; |
| }, |
| |
| set responseHeaders(x) |
| { |
| this._responseHeaders = x; |
| delete this._sortedResponseHeaders; |
| delete this._serverTimings; |
| delete this._responseCookies; |
| this._responseHeaderValues = {}; |
| |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged); |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| get responseHeadersText() |
| { |
| return this._responseHeadersText; |
| }, |
| |
| set responseHeadersText(x) |
| { |
| this._responseHeadersText = x; |
| |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged); |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.NetworkRequest.NameValue>} |
| */ |
| get sortedResponseHeaders() |
| { |
| if (this._sortedResponseHeaders !== undefined) |
| return this._sortedResponseHeaders; |
| |
| this._sortedResponseHeaders = this.responseHeaders.slice(); |
| this._sortedResponseHeaders.sort(function(a, b) { return a.name.toLowerCase().compareTo(b.name.toLowerCase()); }); |
| return this._sortedResponseHeaders; |
| }, |
| |
| /** |
| * @param {string} headerName |
| * @return {string|undefined} |
| */ |
| responseHeaderValue: function(headerName) |
| { |
| var value = this._responseHeaderValues[headerName]; |
| if (value === undefined) { |
| value = this._headerValue(this.responseHeaders, headerName); |
| this._responseHeaderValues[headerName] = (value !== undefined) ? value : null; |
| } |
| return (value !== null) ? value : undefined; |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.Cookie>} |
| */ |
| get responseCookies() |
| { |
| if (!this._responseCookies) |
| this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.target(), this.responseHeaderValue("Set-Cookie")); |
| return this._responseCookies; |
| }, |
| |
| /** |
| * @return {?Array.<!WebInspector.ServerTiming>} |
| */ |
| get serverTimings() |
| { |
| if (typeof this._serverTimings === "undefined") |
| this._serverTimings = WebInspector.ServerTiming.parseHeaders(this.responseHeaders); |
| return this._serverTimings; |
| }, |
| |
| /** |
| * @return {?string} |
| */ |
| queryString: function() |
| { |
| if (this._queryString !== undefined) |
| return this._queryString; |
| |
| var queryString = null; |
| var url = this.url; |
| var questionMarkPosition = url.indexOf("?"); |
| if (questionMarkPosition !== -1) { |
| queryString = url.substring(questionMarkPosition + 1); |
| var hashSignPosition = queryString.indexOf("#"); |
| if (hashSignPosition !== -1) |
| queryString = queryString.substring(0, hashSignPosition); |
| } |
| this._queryString = queryString; |
| return this._queryString; |
| }, |
| |
| /** |
| * @return {?Array.<!WebInspector.NetworkRequest.NameValue>} |
| */ |
| get queryParameters() |
| { |
| if (this._parsedQueryParameters) |
| return this._parsedQueryParameters; |
| var queryString = this.queryString(); |
| if (!queryString) |
| return null; |
| this._parsedQueryParameters = this._parseParameters(queryString); |
| return this._parsedQueryParameters; |
| }, |
| |
| /** |
| * @return {?Array.<!WebInspector.NetworkRequest.NameValue>} |
| */ |
| get formParameters() |
| { |
| if (this._parsedFormParameters) |
| return this._parsedFormParameters; |
| if (!this.requestFormData) |
| return null; |
| var requestContentType = this.requestContentType(); |
| if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i)) |
| return null; |
| this._parsedFormParameters = this._parseParameters(this.requestFormData); |
| return this._parsedFormParameters; |
| }, |
| |
| /** |
| * @return {string} |
| */ |
| responseHttpVersion: function() |
| { |
| var headersText = this._responseHeadersText; |
| if (!headersText) |
| return this.responseHeaderValue("version") || this.responseHeaderValue(":version") || "unknown"; |
| var firstLine = headersText.split(/\r\n/)[0]; |
| var match = firstLine.match(/^(HTTP\/\d+\.\d+)/); |
| return match ? match[1] : "HTTP/0.9"; |
| }, |
| |
| /** |
| * @param {string} queryString |
| * @return {!Array.<!WebInspector.NetworkRequest.NameValue>} |
| */ |
| _parseParameters: function(queryString) |
| { |
| function parseNameValue(pair) |
| { |
| var position = pair.indexOf("="); |
| if (position === -1) |
| return {name: pair, value: ""}; |
| else |
| return {name: pair.substring(0, position), value: pair.substring(position + 1)}; |
| } |
| return queryString.split("&").map(parseNameValue); |
| }, |
| |
| /** |
| * @param {!Array.<!WebInspector.NetworkRequest.NameValue>} headers |
| * @param {string} headerName |
| * @return {string|undefined} |
| */ |
| _headerValue: function(headers, headerName) |
| { |
| headerName = headerName.toLowerCase(); |
| |
| var values = []; |
| for (var i = 0; i < headers.length; ++i) { |
| if (headers[i].name.toLowerCase() === headerName) |
| values.push(headers[i].value); |
| } |
| if (!values.length) |
| return undefined; |
| // Set-Cookie values should be separated by '\n', not comma, otherwise cookies could not be parsed. |
| if (headerName === "set-cookie") |
| return values.join("\n"); |
| return values.join(", "); |
| }, |
| |
| /** |
| * @return {?string|undefined} |
| */ |
| get content() |
| { |
| return this._content; |
| }, |
| |
| /** |
| * @return {?Protocol.Error|undefined} |
| */ |
| contentError: function() |
| { |
| return this._contentError; |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| get contentEncoded() |
| { |
| return this._contentEncoded; |
| }, |
| |
| /** |
| * @override |
| * @return {string} |
| */ |
| contentURL: function() |
| { |
| return this._url; |
| }, |
| |
| /** |
| * @override |
| * @return {!WebInspector.ResourceType} |
| */ |
| contentType: function() |
| { |
| return this._resourceType; |
| }, |
| |
| /** |
| * @override |
| * @return {!Promise<?string>} |
| */ |
| requestContent: function() |
| { |
| // We do not support content retrieval for WebSockets at the moment. |
| // Since WebSockets are potentially long-living, fail requests immediately |
| // to prevent caller blocking until resource is marked as finished. |
| if (this._resourceType === WebInspector.resourceTypes.WebSocket) |
| return Promise.resolve(/** @type {?string} */(null)); |
| if (typeof this._content !== "undefined") |
| return Promise.resolve(/** @type {?string} */(this.content || null)); |
| var callback; |
| var promise = new Promise(fulfill => callback = fulfill); |
| this._pendingContentCallbacks.push(callback); |
| if (this.finished) |
| this._innerRequestContent(); |
| return promise; |
| }, |
| |
| /** |
| * @override |
| * @param {string} query |
| * @param {boolean} caseSensitive |
| * @param {boolean} isRegex |
| * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback |
| */ |
| searchInContent: function(query, caseSensitive, isRegex, callback) |
| { |
| callback([]); |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| isHttpFamily: function() |
| { |
| return !!this.url.match(/^https?:/i); |
| }, |
| |
| /** |
| * @return {string|undefined} |
| */ |
| requestContentType: function() |
| { |
| return this.requestHeaderValue("Content-Type"); |
| }, |
| |
| /** |
| * @return {boolean} |
| */ |
| hasErrorStatusCode: function() |
| { |
| return this.statusCode >= 400; |
| }, |
| |
| /** |
| * @param {!NetworkAgent.ResourcePriority} priority |
| */ |
| setInitialPriority: function(priority) |
| { |
| this._initialPriority = priority; |
| }, |
| |
| /** |
| * @return {?NetworkAgent.ResourcePriority} |
| */ |
| initialPriority: function() |
| { |
| return this._initialPriority; |
| }, |
| |
| /** |
| * @param {!NetworkAgent.ResourcePriority} priority |
| */ |
| setPriority: function(priority) |
| { |
| this._currentPriority = priority; |
| }, |
| |
| /** |
| * @return {?NetworkAgent.ResourcePriority} |
| */ |
| priority: function() |
| { |
| return this._currentPriority || this._initialPriority || null; |
| }, |
| |
| /** |
| * @param {!Element} image |
| */ |
| populateImageSource: function(image) |
| { |
| WebInspector.Resource.populateImageSource(this._url, this._mimeType, this, image); |
| }, |
| |
| /** |
| * @return {?string} |
| */ |
| asDataURL: function() |
| { |
| var content = this._content; |
| var charset = null; |
| if (!this._contentEncoded) { |
| content = content.toBase64(); |
| charset = "utf-8"; |
| } |
| return WebInspector.Resource.contentAsDataURL(content, this.mimeType, true, charset); |
| }, |
| |
| _innerRequestContent: function() |
| { |
| if (this._contentRequested) |
| return; |
| this._contentRequested = true; |
| |
| /** |
| * @param {?Protocol.Error} error |
| * @param {string} content |
| * @param {boolean} contentEncoded |
| * @this {WebInspector.NetworkRequest} |
| */ |
| function onResourceContent(error, content, contentEncoded) |
| { |
| this._content = error ? null : content; |
| this._contentError = error; |
| this._contentEncoded = contentEncoded; |
| var callbacks = this._pendingContentCallbacks.slice(); |
| for (var i = 0; i < callbacks.length; ++i) |
| callbacks[i](this._content); |
| this._pendingContentCallbacks.length = 0; |
| delete this._contentRequested; |
| } |
| this.target().networkAgent().getResponseBody(this._requestId, onResourceContent.bind(this)); |
| }, |
| |
| /** |
| * @return {?NetworkAgent.Initiator} |
| */ |
| initiator: function() |
| { |
| return this._initiator; |
| }, |
| |
| /** |
| * @return {!{type: !WebInspector.NetworkRequest.InitiatorType, url: string, lineNumber: number, columnNumber: number, scriptId: ?string}} |
| */ |
| initiatorInfo: function() |
| { |
| if (this._initiatorInfo) |
| return this._initiatorInfo; |
| |
| var type = WebInspector.NetworkRequest.InitiatorType.Other; |
| var url = ""; |
| var lineNumber = -Infinity; |
| var columnNumber = -Infinity; |
| var scriptId = null; |
| var initiator = this._initiator; |
| |
| if (this.redirectSource) { |
| type = WebInspector.NetworkRequest.InitiatorType.Redirect; |
| url = this.redirectSource.url; |
| } else if (initiator) { |
| if (initiator.type === NetworkAgent.InitiatorType.Parser) { |
| type = WebInspector.NetworkRequest.InitiatorType.Parser; |
| url = initiator.url ? initiator.url : url; |
| lineNumber = initiator.lineNumber ? initiator.lineNumber : lineNumber; |
| } else if (initiator.type === NetworkAgent.InitiatorType.Script) { |
| for (var stack = initiator.stack; stack; stack = stack.parent) { |
| var topFrame = stack.callFrames.length ? stack.callFrames[0] : null; |
| if (!topFrame) |
| continue; |
| type = WebInspector.NetworkRequest.InitiatorType.Script; |
| url = topFrame.url || WebInspector.UIString("<anonymous>"); |
| lineNumber = topFrame.lineNumber; |
| columnNumber = topFrame.columnNumber; |
| scriptId = topFrame.scriptId; |
| break; |
| } |
| } |
| } |
| |
| this._initiatorInfo = {type: type, url: url, lineNumber: lineNumber, columnNumber: columnNumber, scriptId: scriptId}; |
| return this._initiatorInfo; |
| }, |
| |
| /** |
| * @return {?WebInspector.NetworkRequest} |
| */ |
| initiatorRequest: function() |
| { |
| if (this._initiatorRequest === undefined) |
| this._initiatorRequest = this._networkLog.requestForURL(this.initiatorInfo().url); |
| return this._initiatorRequest; |
| }, |
| |
| /** |
| * @return {!Set<!WebInspector.NetworkRequest>} |
| */ |
| initiatorChain: function() |
| { |
| if (this._initiatorChain) |
| return this._initiatorChain; |
| this._initiatorChain = new Set(); |
| var request = this; |
| while (request) { |
| this._initiatorChain.add(request); |
| request = request.initiatorRequest(); |
| } |
| return this._initiatorChain; |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.NetworkRequest.WebSocketFrame>} |
| */ |
| frames: function() |
| { |
| return this._frames; |
| }, |
| |
| /** |
| * @param {string} errorMessage |
| * @param {number} time |
| */ |
| addFrameError: function(errorMessage, time) |
| { |
| this._addFrame({ type: WebInspector.NetworkRequest.WebSocketFrameType.Error, text: errorMessage, time: this.pseudoWallTime(time), opCode: -1, mask: false }); |
| }, |
| |
| /** |
| * @param {!NetworkAgent.WebSocketFrame} response |
| * @param {number} time |
| * @param {boolean} sent |
| */ |
| addFrame: function(response, time, sent) |
| { |
| var type = sent ? WebInspector.NetworkRequest.WebSocketFrameType.Send : WebInspector.NetworkRequest.WebSocketFrameType.Receive; |
| this._addFrame({ type: type, text: response.payloadData, time: this.pseudoWallTime(time), opCode: response.opcode, mask: response.mask }); |
| }, |
| |
| /** |
| * @param {!WebInspector.NetworkRequest.WebSocketFrame} frame |
| */ |
| _addFrame: function(frame) |
| { |
| this._frames.push(frame); |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.WebsocketFrameAdded, frame); |
| }, |
| |
| /** |
| * @return {!Array.<!WebInspector.NetworkRequest.EventSourceMessage>} |
| */ |
| eventSourceMessages: function() |
| { |
| return this._eventSourceMessages; |
| }, |
| |
| /** |
| * @param {number} time |
| * @param {string} eventName |
| * @param {string} eventId |
| * @param {string} data |
| */ |
| addEventSourceMessage: function(time, eventName, eventId, data) |
| { |
| var message = {time: this.pseudoWallTime(time), eventName: eventName, eventId: eventId, data: data}; |
| this._eventSourceMessages.push(message); |
| this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.EventSourceMessageAdded, message); |
| }, |
| |
| replayXHR: function() |
| { |
| this.target().networkAgent().replayXHR(this.requestId); |
| }, |
| |
| /** |
| * @return {!WebInspector.NetworkLog} |
| */ |
| networkLog: function() |
| { |
| return this._networkLog; |
| }, |
| |
| /** |
| * @return {!WebInspector.NetworkManager} |
| */ |
| networkManager: function() |
| { |
| return this._networkManager; |
| }, |
| |
| __proto__: WebInspector.SDKObject.prototype |
| } |