123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560 |
- /*
- * Copyright (C) 2011 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.Object}
- */
- WebInspector.NetworkManager = function()
- {
- WebInspector.Object.call(this);
- this._dispatcher = new WebInspector.NetworkDispatcher(this);
- if (WebInspector.settings.cacheDisabled.get())
- NetworkAgent.setCacheDisabled(true);
- NetworkAgent.enable();
- WebInspector.settings.cacheDisabled.addChangeListener(this._cacheDisabledSettingChanged, this);
- }
- WebInspector.NetworkManager.EventTypes = {
- RequestStarted: "RequestStarted",
- RequestUpdated: "RequestUpdated",
- RequestFinished: "RequestFinished",
- RequestUpdateDropped: "RequestUpdateDropped"
- }
- WebInspector.NetworkManager._MIMETypes = {
- "text/html": {"document": true},
- "text/xml": {"document": true},
- "text/plain": {"document": true},
- "application/xhtml+xml": {"document": true},
- "text/css": {"stylesheet": true},
- "text/xsl": {"stylesheet": true},
- "image/jpg": {"image": true},
- "image/jpeg": {"image": true},
- "image/pjpeg": {"image": true},
- "image/png": {"image": true},
- "image/gif": {"image": true},
- "image/bmp": {"image": true},
- "image/svg+xml": {"image": true, "font": true, "document": true},
- "image/vnd.microsoft.icon": {"image": true},
- "image/webp": {"image": true},
- "image/x-icon": {"image": true},
- "image/x-xbitmap": {"image": true},
- "font/ttf": {"font": true},
- "font/otf": {"font": true},
- "font/woff": {"font": true},
- "font/woff2": {"font": true},
- "font/truetype": {"font": true},
- "font/opentype": {"font": true},
- "application/octet-stream": {"font": true, "image": true},
- "application/font-woff": {"font": true},
- "application/x-font-woff": {"font": true},
- "application/x-font-type1": {"font": true},
- "application/x-font-ttf": {"font": true},
- "application/x-truetype-font": {"font": true},
- "text/javascript": {"script": true},
- "text/ecmascript": {"script": true},
- "application/javascript": {"script": true},
- "application/ecmascript": {"script": true},
- "application/x-javascript": {"script": true},
- "application/json": {"script": true},
- "text/javascript1.1": {"script": true},
- "text/javascript1.2": {"script": true},
- "text/javascript1.3": {"script": true},
- "text/jscript": {"script": true},
- "text/livescript": {"script": true},
- }
- WebInspector.NetworkManager.prototype = {
- /**
- * @param {string} url
- * @return {WebInspector.NetworkRequest}
- */
- inflightRequestForURL: function(url)
- {
- return this._dispatcher._inflightRequestsByURL[url];
- },
- /**
- * @param {WebInspector.Event} event
- */
- _cacheDisabledSettingChanged: function(event)
- {
- var enabled = /** @type {boolean} */ (event.data);
- NetworkAgent.setCacheDisabled(enabled);
- },
- __proto__: WebInspector.Object.prototype
- }
- /**
- * @constructor
- * @implements {NetworkAgent.Dispatcher}
- */
- WebInspector.NetworkDispatcher = function(manager)
- {
- this._manager = manager;
- this._inflightRequestsById = {};
- this._inflightRequestsByURL = {};
- InspectorBackend.registerNetworkDispatcher(this);
- }
- WebInspector.NetworkDispatcher.prototype = {
- /**
- * @param {NetworkAgent.Headers} headersMap
- * @return {!Array.<!WebInspector.NetworkRequest.NameValue>}
- */
- _headersMapToHeadersArray: function(headersMap)
- {
- var result = [];
- for (var name in headersMap) {
- var values = headersMap[name].split("\n");
- for (var i = 0; i < values.length; ++i)
- result.push({name: name, value: values[i]});
- }
- return result;
- },
- /**
- * @param {WebInspector.NetworkRequest} networkRequest
- * @param {NetworkAgent.Request} request
- */
- _updateNetworkRequestWithRequest: function(networkRequest, request)
- {
- networkRequest.requestMethod = request.method;
- networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
- networkRequest.requestFormData = request.postData;
- },
- /**
- * @param {WebInspector.NetworkRequest} networkRequest
- * @param {NetworkAgent.Response=} response
- */
- _updateNetworkRequestWithResponse: function(networkRequest, response)
- {
- if (!response)
- return;
- if (response.url && networkRequest.url !== response.url)
- networkRequest.url = response.url;
- networkRequest.mimeType = response.mimeType;
- networkRequest.statusCode = response.status;
- networkRequest.statusText = response.statusText;
- networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
- if (response.headersText)
- networkRequest.responseHeadersText = response.headersText;
- if (response.requestHeaders)
- networkRequest.requestHeaders = this._headersMapToHeadersArray(response.requestHeaders);
- if (response.requestHeadersText)
- networkRequest.requestHeadersText = response.requestHeadersText;
- networkRequest.connectionReused = response.connectionReused;
- networkRequest.connectionId = response.connectionId;
- if (response.fromDiskCache)
- networkRequest.cached = true;
- else
- networkRequest.timing = response.timing;
- if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
- WebInspector.console.addMessage(WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.Network,
- WebInspector.ConsoleMessage.MessageLevel.Log,
- WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.type.title(), networkRequest.mimeType, networkRequest.url),
- WebInspector.ConsoleMessage.MessageType.Log,
- "",
- 0,
- 0,
- 1,
- [],
- null,
- networkRequest.requestId));
- }
- },
- /**
- * @param {WebInspector.NetworkRequest} networkRequest
- * @return {boolean}
- */
- _mimeTypeIsConsistentWithType: function(networkRequest)
- {
- // If status is an error, content is likely to be of an inconsistent type,
- // as it's going to be an error message. We do not want to emit a warning
- // for this, though, as this will already be reported as resource loading failure.
- // Also, if a URL like http://localhost/wiki/load.php?debug=true&lang=en produces text/css and gets reloaded,
- // it is 304 Not Modified and its guessed mime-type is text/php, which is wrong.
- // Don't check for mime-types in 304-resources.
- if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)
- return true;
- if (typeof networkRequest.type === "undefined"
- || networkRequest.type === WebInspector.resourceTypes.Other
- || networkRequest.type === WebInspector.resourceTypes.XHR
- || networkRequest.type === WebInspector.resourceTypes.WebSocket)
- return true;
- if (!networkRequest.mimeType)
- return true; // Might be not known for cached resources with null responses.
- if (networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
- return networkRequest.type.name() in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];
- return false;
- },
- /**
- * @param {NetworkAgent.Response} response
- * @return {boolean}
- */
- _isNull: function(response)
- {
- if (!response)
- return true;
- return !response.status && !response.mimeType && (!response.headers || !Object.keys(response.headers).length);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {PageAgent.FrameId} frameId
- * @param {NetworkAgent.LoaderId} loaderId
- * @param {string} documentURL
- * @param {NetworkAgent.Request} request
- * @param {NetworkAgent.Timestamp} time
- * @param {NetworkAgent.Initiator} initiator
- * @param {NetworkAgent.Response=} redirectResponse
- */
- requestWillBeSent: function(requestId, frameId, loaderId, documentURL, request, time, initiator, redirectResponse)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (networkRequest) {
- // FIXME: move this check to the backend.
- if (!redirectResponse)
- return;
- this.responseReceived(requestId, frameId, loaderId, time, PageAgent.ResourceType.Other, redirectResponse);
- networkRequest = this._appendRedirect(requestId, time, request.url);
- } else
- networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, request.url, documentURL, initiator);
- networkRequest.hasNetworkData = true;
- this._updateNetworkRequestWithRequest(networkRequest, request);
- networkRequest.startTime = time;
- this._startNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- */
- requestServedFromCache: function(requestId)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- networkRequest.cached = true;
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {PageAgent.FrameId} frameId
- * @param {NetworkAgent.LoaderId} loaderId
- * @param {NetworkAgent.Timestamp} time
- * @param {PageAgent.ResourceType} resourceType
- * @param {NetworkAgent.Response} response
- */
- responseReceived: function(requestId, frameId, loaderId, time, resourceType, response)
- {
- // FIXME: move this check to the backend.
- if (this._isNull(response))
- return;
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest) {
- // We missed the requestWillBeSent.
- var eventData = {};
- eventData.url = response.url;
- eventData.frameId = frameId;
- eventData.loaderId = loaderId;
- eventData.resourceType = resourceType;
- eventData.mimeType = response.mimeType;
- this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, eventData);
- return;
- }
- networkRequest.responseReceivedTime = time;
- networkRequest.type = WebInspector.resourceTypes[resourceType];
- this._updateNetworkRequestWithResponse(networkRequest, response);
- this._updateNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- * @param {number} dataLength
- * @param {number} encodedDataLength
- */
- dataReceived: function(requestId, time, dataLength, encodedDataLength)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- networkRequest.resourceSize += dataLength;
- if (encodedDataLength != -1)
- networkRequest.increaseTransferSize(encodedDataLength);
- networkRequest.endTime = time;
- this._updateNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} finishTime
- */
- loadingFinished: function(requestId, finishTime)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- this._finishNetworkRequest(networkRequest, finishTime);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- * @param {string} localizedDescription
- * @param {boolean=} canceled
- */
- loadingFailed: function(requestId, time, localizedDescription, canceled)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- networkRequest.failed = true;
- networkRequest.canceled = canceled;
- networkRequest.localizedFailDescription = localizedDescription;
- this._finishNetworkRequest(networkRequest, time);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {string} requestURL
- */
- webSocketCreated: function(requestId, requestURL)
- {
- var networkRequest = new WebInspector.NetworkRequest(requestId, requestURL, "", "", "");
- networkRequest.type = WebInspector.resourceTypes.WebSocket;
- this._startNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- * @param {NetworkAgent.WebSocketRequest} request
- */
- webSocketWillSendHandshakeRequest: function(requestId, time, request)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- networkRequest.requestMethod = "GET";
- networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
- networkRequest.startTime = time;
- this._updateNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- * @param {NetworkAgent.WebSocketResponse} response
- */
- webSocketHandshakeResponseReceived: function(requestId, time, response)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- networkRequest.statusCode = response.status;
- networkRequest.statusText = response.statusText;
- networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
- networkRequest.responseReceivedTime = time;
- this._updateNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- * @param {NetworkAgent.WebSocketFrame} response
- */
- webSocketFrameReceived: function(requestId, time, response)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- networkRequest.addFrame(response, time);
- networkRequest.responseReceivedTime = time;
- this._updateNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- * @param {NetworkAgent.WebSocketFrame} response
- */
- webSocketFrameSent: function(requestId, time, response)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- networkRequest.addFrame(response, time, true);
- networkRequest.responseReceivedTime = time;
- this._updateNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- * @param {string} errorMessage
- */
- webSocketFrameError: function(requestId, time, errorMessage)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- networkRequest.addFrameError(errorMessage, time);
- networkRequest.responseReceivedTime = time;
- this._updateNetworkRequest(networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- */
- webSocketClosed: function(requestId, time)
- {
- var networkRequest = this._inflightRequestsById[requestId];
- if (!networkRequest)
- return;
- this._finishNetworkRequest(networkRequest, time);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {NetworkAgent.Timestamp} time
- * @param {string} redirectURL
- * @return {WebInspector.NetworkRequest}
- */
- _appendRedirect: function(requestId, time, redirectURL)
- {
- var originalNetworkRequest = this._inflightRequestsById[requestId];
- var previousRedirects = originalNetworkRequest.redirects || [];
- originalNetworkRequest.requestId = "redirected:" + requestId + "." + previousRedirects.length;
- delete originalNetworkRequest.redirects;
- if (previousRedirects.length > 0)
- originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1];
- this._finishNetworkRequest(originalNetworkRequest, time);
- var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId,
- redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator);
- newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest);
- return newNetworkRequest;
- },
- /**
- * @param {WebInspector.NetworkRequest} networkRequest
- */
- _startNetworkRequest: function(networkRequest)
- {
- this._inflightRequestsById[networkRequest.requestId] = networkRequest;
- this._inflightRequestsByURL[networkRequest.url] = networkRequest;
- this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted, networkRequest);
- },
- /**
- * @param {WebInspector.NetworkRequest} networkRequest
- */
- _updateNetworkRequest: function(networkRequest)
- {
- this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated, networkRequest);
- },
- /**
- * @param {WebInspector.NetworkRequest} networkRequest
- * @param {NetworkAgent.Timestamp} finishTime
- */
- _finishNetworkRequest: function(networkRequest, finishTime)
- {
- networkRequest.endTime = finishTime;
- networkRequest.finished = true;
- this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest);
- delete this._inflightRequestsById[networkRequest.requestId];
- delete this._inflightRequestsByURL[networkRequest.url];
- },
- /**
- * @param {string} eventType
- * @param {WebInspector.NetworkRequest} networkRequest
- */
- _dispatchEventToListeners: function(eventType, networkRequest)
- {
- this._manager.dispatchEventToListeners(eventType, networkRequest);
- },
- /**
- * @param {NetworkAgent.RequestId} requestId
- * @param {string} frameId
- * @param {NetworkAgent.LoaderId} loaderId
- * @param {string} url
- * @param {string} documentURL
- * @param {NetworkAgent.Initiator} initiator
- */
- _createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator)
- {
- var networkRequest = new WebInspector.NetworkRequest(requestId, url, documentURL, frameId, loaderId);
- networkRequest.initiator = initiator;
- return networkRequest;
- }
- }
- /**
- * @type {?WebInspector.NetworkManager}
- */
- WebInspector.networkManager = null;
|