InspectorResourceAgent.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. /*
  2. * Copyright (C) 2011 Google Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are
  6. * met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above
  11. * copyright notice, this list of conditions and the following disclaimer
  12. * in the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Google Inc. nor the names of its
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "config.h"
  31. #if ENABLE(INSPECTOR)
  32. #include "InspectorResourceAgent.h"
  33. #include "CachedRawResource.h"
  34. #include "CachedResource.h"
  35. #include "CachedResourceLoader.h"
  36. #include "Document.h"
  37. #include "DocumentLoader.h"
  38. #include "ExceptionCodePlaceholder.h"
  39. #include "Frame.h"
  40. #include "FrameLoader.h"
  41. #include "HTTPHeaderMap.h"
  42. #include "IconController.h"
  43. #include "IdentifiersFactory.h"
  44. #include "InspectorClient.h"
  45. #include "InspectorFrontend.h"
  46. #include "InspectorPageAgent.h"
  47. #include "InspectorState.h"
  48. #include "InspectorValues.h"
  49. #include "InstrumentingAgents.h"
  50. #include "KURL.h"
  51. #include "MemoryCache.h"
  52. #include "NetworkResourcesData.h"
  53. #include "Page.h"
  54. #include "ProgressTracker.h"
  55. #include "ResourceBuffer.h"
  56. #include "ResourceError.h"
  57. #include "ResourceLoader.h"
  58. #include "ResourceRequest.h"
  59. #include "ResourceResponse.h"
  60. #include "ScriptCallStack.h"
  61. #include "ScriptCallStackFactory.h"
  62. #include "ScriptableDocumentParser.h"
  63. #include "Settings.h"
  64. #include "SubresourceLoader.h"
  65. #include "WebSocketFrame.h"
  66. #include "XMLHttpRequest.h"
  67. #include <wtf/CurrentTime.h>
  68. #include <wtf/HexNumber.h>
  69. #include <wtf/ListHashSet.h>
  70. #include <wtf/RefPtr.h>
  71. #include <wtf/text/StringBuilder.h>
  72. namespace WebCore {
  73. namespace ResourceAgentState {
  74. static const char resourceAgentEnabled[] = "resourceAgentEnabled";
  75. static const char extraRequestHeaders[] = "extraRequestHeaders";
  76. static const char cacheDisabled[] = "cacheDisabled";
  77. static const char userAgentOverride[] = "userAgentOverride";
  78. }
  79. void InspectorResourceAgent::setFrontend(InspectorFrontend* frontend)
  80. {
  81. m_frontend = frontend->network();
  82. }
  83. void InspectorResourceAgent::clearFrontend()
  84. {
  85. m_frontend = 0;
  86. ErrorString error;
  87. disable(&error);
  88. }
  89. void InspectorResourceAgent::restore()
  90. {
  91. if (m_state->getBoolean(ResourceAgentState::resourceAgentEnabled))
  92. enable();
  93. }
  94. static PassRefPtr<InspectorObject> buildObjectForHeaders(const HTTPHeaderMap& headers)
  95. {
  96. RefPtr<InspectorObject> headersObject = InspectorObject::create();
  97. HTTPHeaderMap::const_iterator end = headers.end();
  98. for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
  99. headersObject->setString(it->key.string(), it->value);
  100. return headersObject;
  101. }
  102. static PassRefPtr<TypeBuilder::Network::ResourceTiming> buildObjectForTiming(const ResourceLoadTiming& timing, DocumentLoader* loader)
  103. {
  104. return TypeBuilder::Network::ResourceTiming::create()
  105. .setRequestTime(loader->timing()->monotonicTimeToPseudoWallTime(timing.convertResourceLoadTimeToMonotonicTime(0)))
  106. .setProxyStart(timing.proxyStart)
  107. .setProxyEnd(timing.proxyEnd)
  108. .setDnsStart(timing.dnsStart)
  109. .setDnsEnd(timing.dnsEnd)
  110. .setConnectStart(timing.connectStart)
  111. .setConnectEnd(timing.connectEnd)
  112. .setSslStart(timing.sslStart)
  113. .setSslEnd(timing.sslEnd)
  114. .setSendStart(timing.sendStart)
  115. .setSendEnd(timing.sendEnd)
  116. .setReceiveHeadersEnd(timing.receiveHeadersEnd)
  117. .release();
  118. }
  119. static PassRefPtr<TypeBuilder::Network::Request> buildObjectForResourceRequest(const ResourceRequest& request)
  120. {
  121. RefPtr<TypeBuilder::Network::Request> requestObject = TypeBuilder::Network::Request::create()
  122. .setUrl(request.url().string())
  123. .setMethod(request.httpMethod())
  124. .setHeaders(buildObjectForHeaders(request.httpHeaderFields()));
  125. if (request.httpBody() && !request.httpBody()->isEmpty())
  126. requestObject->setPostData(request.httpBody()->flattenToString());
  127. return requestObject;
  128. }
  129. static PassRefPtr<TypeBuilder::Network::Response> buildObjectForResourceResponse(const ResourceResponse& response, DocumentLoader* loader)
  130. {
  131. if (response.isNull())
  132. return 0;
  133. double status = response.httpStatusCode();
  134. RefPtr<InspectorObject> headers = buildObjectForHeaders(response.httpHeaderFields());
  135. RefPtr<TypeBuilder::Network::Response> responseObject = TypeBuilder::Network::Response::create()
  136. .setUrl(response.url().string())
  137. .setStatus(status)
  138. .setStatusText(response.httpStatusText())
  139. .setHeaders(headers)
  140. .setMimeType(response.mimeType())
  141. .setConnectionReused(response.connectionReused())
  142. .setConnectionId(response.connectionID());
  143. responseObject->setFromDiskCache(response.wasCached());
  144. if (response.resourceLoadTiming())
  145. responseObject->setTiming(buildObjectForTiming(*response.resourceLoadTiming(), loader));
  146. return responseObject;
  147. }
  148. static PassRefPtr<TypeBuilder::Network::CachedResource> buildObjectForCachedResource(CachedResource* cachedResource, DocumentLoader* loader)
  149. {
  150. RefPtr<TypeBuilder::Network::CachedResource> resourceObject = TypeBuilder::Network::CachedResource::create()
  151. .setUrl(cachedResource->url())
  152. .setType(InspectorPageAgent::cachedResourceTypeJson(*cachedResource))
  153. .setBodySize(cachedResource->encodedSize());
  154. RefPtr<TypeBuilder::Network::Response> resourceResponse = buildObjectForResourceResponse(cachedResource->response(), loader);
  155. if (resourceResponse)
  156. resourceObject->setResponse(resourceResponse);
  157. String sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(cachedResource);
  158. if (!sourceMappingURL.isEmpty())
  159. resourceObject->setSourceMapURL(sourceMappingURL);
  160. return resourceObject;
  161. }
  162. InspectorResourceAgent::~InspectorResourceAgent()
  163. {
  164. if (m_state->getBoolean(ResourceAgentState::resourceAgentEnabled)) {
  165. ErrorString error;
  166. disable(&error);
  167. }
  168. ASSERT(!m_instrumentingAgents->inspectorResourceAgent());
  169. }
  170. void InspectorResourceAgent::willSendRequest(unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
  171. {
  172. String requestId = IdentifiersFactory::requestId(identifier);
  173. m_resourcesData->resourceCreated(requestId, m_pageAgent->loaderId(loader));
  174. CachedResource* cachedResource = loader ? InspectorPageAgent::cachedResource(loader->frame(), request.url()) : 0;
  175. InspectorPageAgent::ResourceType type = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : m_resourcesData->resourceType(requestId);
  176. if (type == InspectorPageAgent::OtherResource) {
  177. if (m_loadingXHRSynchronously)
  178. type = InspectorPageAgent::XHRResource;
  179. else if (equalIgnoringFragmentIdentifier(request.url(), loader->frameLoader()->icon()->url()))
  180. type = InspectorPageAgent::ImageResource;
  181. else if (equalIgnoringFragmentIdentifier(request.url(), loader->url()) && !loader->isCommitted())
  182. type = InspectorPageAgent::DocumentResource;
  183. }
  184. m_resourcesData->setResourceType(requestId, type);
  185. if (RefPtr<InspectorObject> headers = m_state->getObject(ResourceAgentState::extraRequestHeaders)) {
  186. InspectorObject::const_iterator end = headers->end();
  187. for (InspectorObject::const_iterator it = headers->begin(); it != end; ++it) {
  188. String value;
  189. if (it->value->asString(&value))
  190. request.setHTTPHeaderField(it->key, value);
  191. }
  192. }
  193. request.setReportLoadTiming(true);
  194. request.setReportRawHeaders(true);
  195. if (m_state->getBoolean(ResourceAgentState::cacheDisabled)) {
  196. request.setHTTPHeaderField("Pragma", "no-cache");
  197. request.setCachePolicy(ReloadIgnoringCacheData);
  198. request.setHTTPHeaderField("Cache-Control", "no-cache");
  199. }
  200. TypeBuilder::Page::ResourceType::Enum resourceType = InspectorPageAgent::resourceTypeJson(type);
  201. RefPtr<TypeBuilder::Network::Initiator> initiatorObject = buildInitiatorObject(loader->frame() ? loader->frame()->document() : 0);
  202. m_frontend->requestWillBeSent(requestId, m_pageAgent->frameId(loader->frame()), m_pageAgent->loaderId(loader), loader->url().string(), buildObjectForResourceRequest(request), currentTime(), initiatorObject, buildObjectForResourceResponse(redirectResponse, loader), type != InspectorPageAgent::OtherResource ? &resourceType : 0);
  203. }
  204. void InspectorResourceAgent::markResourceAsCached(unsigned long identifier)
  205. {
  206. m_frontend->requestServedFromCache(IdentifiersFactory::requestId(identifier));
  207. }
  208. void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
  209. {
  210. String requestId = IdentifiersFactory::requestId(identifier);
  211. RefPtr<TypeBuilder::Network::Response> resourceResponse = buildObjectForResourceResponse(response, loader);
  212. bool isNotModified = response.httpStatusCode() == 304;
  213. CachedResource* cachedResource = 0;
  214. if (resourceLoader && resourceLoader->isSubresourceLoader() && !isNotModified)
  215. cachedResource = static_cast<SubresourceLoader*>(resourceLoader)->cachedResource();
  216. if (!cachedResource)
  217. cachedResource = InspectorPageAgent::cachedResource(loader->frame(), response.url());
  218. if (cachedResource) {
  219. // Use mime type from cached resource in case the one in response is empty.
  220. if (resourceResponse && response.mimeType().isEmpty())
  221. resourceResponse->setString(TypeBuilder::Network::Response::MimeType, cachedResource->response().mimeType());
  222. m_resourcesData->addCachedResource(requestId, cachedResource);
  223. }
  224. InspectorPageAgent::ResourceType type = m_resourcesData->resourceType(requestId);
  225. InspectorPageAgent::ResourceType newType = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : type;
  226. // FIXME: XHRResource is returned for CachedResource::RawResource, it should be OtherResource unless it truly is an XHR.
  227. // RawResource is used for loading worker scripts, and those should stay as ScriptResource and not change to XHRResource.
  228. if (type != newType && newType != InspectorPageAgent::XHRResource && newType != InspectorPageAgent::OtherResource)
  229. type = newType;
  230. m_resourcesData->responseReceived(requestId, m_pageAgent->frameId(loader->frame()), response);
  231. m_resourcesData->setResourceType(requestId, type);
  232. m_frontend->responseReceived(requestId, m_pageAgent->frameId(loader->frame()), m_pageAgent->loaderId(loader), currentTime(), InspectorPageAgent::resourceTypeJson(type), resourceResponse);
  233. // If we revalidated the resource and got Not modified, send content length following didReceiveResponse
  234. // as there will be no calls to didReceiveData from the network stack.
  235. if (isNotModified && cachedResource && cachedResource->encodedSize())
  236. didReceiveData(identifier, 0, cachedResource->encodedSize(), 0);
  237. }
  238. static bool isErrorStatusCode(int statusCode)
  239. {
  240. return statusCode >= 400;
  241. }
  242. void InspectorResourceAgent::didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength)
  243. {
  244. String requestId = IdentifiersFactory::requestId(identifier);
  245. if (data) {
  246. NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId);
  247. if (resourceData && !m_loadingXHRSynchronously && (!resourceData->cachedResource() || resourceData->cachedResource()->dataBufferingPolicy() == DoNotBufferData || isErrorStatusCode(resourceData->httpStatusCode())))
  248. m_resourcesData->maybeAddResourceData(requestId, data, dataLength);
  249. }
  250. m_frontend->dataReceived(requestId, currentTime(), dataLength, encodedDataLength);
  251. }
  252. void InspectorResourceAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, double finishTime)
  253. {
  254. String requestId = IdentifiersFactory::requestId(identifier);
  255. if (m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource) {
  256. RefPtr<ResourceBuffer> buffer = loader->frameLoader()->documentLoader()->mainResourceData();
  257. m_resourcesData->addResourceSharedBuffer(requestId, buffer ? buffer->sharedBuffer() : 0, loader->frame()->document()->inputEncoding());
  258. }
  259. m_resourcesData->maybeDecodeDataToContent(requestId);
  260. if (!finishTime)
  261. finishTime = currentTime();
  262. String sourceMappingURL;
  263. NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId);
  264. if (resourceData && resourceData->cachedResource())
  265. sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(resourceData->cachedResource());
  266. m_frontend->loadingFinished(requestId, finishTime, !sourceMappingURL.isEmpty() ? &sourceMappingURL : 0);
  267. }
  268. void InspectorResourceAgent::didFailLoading(unsigned long identifier, DocumentLoader* loader, const ResourceError& error)
  269. {
  270. String requestId = IdentifiersFactory::requestId(identifier);
  271. if (m_resourcesData->resourceType(requestId) == InspectorPageAgent::DocumentResource) {
  272. Frame* frame = loader ? loader->frame() : 0;
  273. if (frame && frame->loader()->documentLoader() && frame->document()) {
  274. RefPtr<ResourceBuffer> buffer = frame->loader()->documentLoader()->mainResourceData();
  275. m_resourcesData->addResourceSharedBuffer(requestId, buffer ? buffer->sharedBuffer() : 0, frame->document()->inputEncoding());
  276. }
  277. }
  278. bool canceled = error.isCancellation();
  279. m_frontend->loadingFailed(requestId, currentTime(), error.localizedDescription(), canceled ? &canceled : 0);
  280. }
  281. void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* loader, CachedResource* resource)
  282. {
  283. String loaderId = m_pageAgent->loaderId(loader);
  284. String frameId = m_pageAgent->frameId(loader->frame());
  285. unsigned long identifier = loader->frame()->page()->progress()->createUniqueIdentifier();
  286. String requestId = IdentifiersFactory::requestId(identifier);
  287. m_resourcesData->resourceCreated(requestId, loaderId);
  288. m_resourcesData->addCachedResource(requestId, resource);
  289. if (resource->type() == CachedResource::RawResource) {
  290. CachedRawResource* rawResource = static_cast<CachedRawResource*>(resource);
  291. String rawRequestId = IdentifiersFactory::requestId(rawResource->identifier());
  292. m_resourcesData->reuseXHRReplayData(requestId, rawRequestId);
  293. }
  294. RefPtr<TypeBuilder::Network::Initiator> initiatorObject = buildInitiatorObject(loader->frame() ? loader->frame()->document() : 0);
  295. m_frontend->requestServedFromMemoryCache(requestId, frameId, loaderId, loader->url().string(), currentTime(), initiatorObject, buildObjectForCachedResource(resource, loader));
  296. }
  297. void InspectorResourceAgent::setInitialScriptContent(unsigned long identifier, const String& sourceString)
  298. {
  299. m_resourcesData->setResourceContent(IdentifiersFactory::requestId(identifier), sourceString);
  300. }
  301. void InspectorResourceAgent::didReceiveScriptResponse(unsigned long identifier)
  302. {
  303. m_resourcesData->setResourceType(IdentifiersFactory::requestId(identifier), InspectorPageAgent::ScriptResource);
  304. }
  305. void InspectorResourceAgent::documentThreadableLoaderStartedLoadingForClient(unsigned long identifier, ThreadableLoaderClient* client)
  306. {
  307. if (!client)
  308. return;
  309. PendingXHRReplayDataMap::iterator it = m_pendingXHRReplayData.find(client);
  310. if (it == m_pendingXHRReplayData.end())
  311. return;
  312. XHRReplayData* xhrReplayData = it->value.get();
  313. String requestId = IdentifiersFactory::requestId(identifier);
  314. m_resourcesData->setXHRReplayData(requestId, xhrReplayData);
  315. }
  316. void InspectorResourceAgent::willLoadXHR(ThreadableLoaderClient* client, const String& method, const KURL& url, bool async, PassRefPtr<FormData> formData, const HTTPHeaderMap& headers, bool includeCredentials)
  317. {
  318. RefPtr<XHRReplayData> xhrReplayData = XHRReplayData::create(method, url, async, formData, includeCredentials);
  319. HTTPHeaderMap::const_iterator end = headers.end();
  320. for (HTTPHeaderMap::const_iterator it = headers.begin(); it!= end; ++it)
  321. xhrReplayData->addHeader(it->key, it->value);
  322. m_pendingXHRReplayData.set(client, xhrReplayData);
  323. }
  324. void InspectorResourceAgent::didFailXHRLoading(ThreadableLoaderClient* client)
  325. {
  326. m_pendingXHRReplayData.remove(client);
  327. }
  328. void InspectorResourceAgent::didFinishXHRLoading(ThreadableLoaderClient* client, unsigned long identifier, const String& sourceString)
  329. {
  330. // For Asynchronous XHRs, the inspector can grab the data directly off of the CachedResource. For sync XHRs, we need to
  331. // provide the data here, since no CachedResource was involved.
  332. if (m_loadingXHRSynchronously)
  333. m_resourcesData->setResourceContent(IdentifiersFactory::requestId(identifier), sourceString);
  334. m_pendingXHRReplayData.remove(client);
  335. }
  336. void InspectorResourceAgent::didReceiveXHRResponse(unsigned long identifier)
  337. {
  338. m_resourcesData->setResourceType(IdentifiersFactory::requestId(identifier), InspectorPageAgent::XHRResource);
  339. }
  340. void InspectorResourceAgent::willLoadXHRSynchronously()
  341. {
  342. m_loadingXHRSynchronously = true;
  343. }
  344. void InspectorResourceAgent::didLoadXHRSynchronously()
  345. {
  346. m_loadingXHRSynchronously = false;
  347. }
  348. void InspectorResourceAgent::willDestroyCachedResource(CachedResource* cachedResource)
  349. {
  350. Vector<String> requestIds = m_resourcesData->removeCachedResource(cachedResource);
  351. if (!requestIds.size())
  352. return;
  353. String content;
  354. bool base64Encoded;
  355. if (!InspectorPageAgent::cachedResourceContent(cachedResource, &content, &base64Encoded))
  356. return;
  357. Vector<String>::iterator end = requestIds.end();
  358. for (Vector<String>::iterator it = requestIds.begin(); it != end; ++it)
  359. m_resourcesData->setResourceContent(*it, content, base64Encoded);
  360. }
  361. void InspectorResourceAgent::applyUserAgentOverride(String* userAgent)
  362. {
  363. String userAgentOverride = m_state->getString(ResourceAgentState::userAgentOverride);
  364. if (!userAgentOverride.isEmpty())
  365. *userAgent = userAgentOverride;
  366. }
  367. void InspectorResourceAgent::willRecalculateStyle()
  368. {
  369. m_isRecalculatingStyle = true;
  370. }
  371. void InspectorResourceAgent::didRecalculateStyle()
  372. {
  373. m_isRecalculatingStyle = false;
  374. m_styleRecalculationInitiator = nullptr;
  375. }
  376. void InspectorResourceAgent::didScheduleStyleRecalculation(Document* document)
  377. {
  378. if (!m_styleRecalculationInitiator)
  379. m_styleRecalculationInitiator = buildInitiatorObject(document);
  380. }
  381. PassRefPtr<TypeBuilder::Network::Initiator> InspectorResourceAgent::buildInitiatorObject(Document* document)
  382. {
  383. RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
  384. if (stackTrace && stackTrace->size() > 0) {
  385. RefPtr<TypeBuilder::Network::Initiator> initiatorObject = TypeBuilder::Network::Initiator::create()
  386. .setType(TypeBuilder::Network::Initiator::Type::Script);
  387. initiatorObject->setStackTrace(stackTrace->buildInspectorArray());
  388. return initiatorObject;
  389. }
  390. if (document && document->scriptableDocumentParser()) {
  391. RefPtr<TypeBuilder::Network::Initiator> initiatorObject = TypeBuilder::Network::Initiator::create()
  392. .setType(TypeBuilder::Network::Initiator::Type::Parser);
  393. initiatorObject->setUrl(document->url().string());
  394. initiatorObject->setLineNumber(document->scriptableDocumentParser()->lineNumber().oneBasedInt());
  395. return initiatorObject;
  396. }
  397. if (m_isRecalculatingStyle && m_styleRecalculationInitiator)
  398. return m_styleRecalculationInitiator;
  399. return TypeBuilder::Network::Initiator::create()
  400. .setType(TypeBuilder::Network::Initiator::Type::Other)
  401. .release();
  402. }
  403. #if ENABLE(WEB_SOCKETS)
  404. void InspectorResourceAgent::didCreateWebSocket(unsigned long identifier, const KURL& requestURL)
  405. {
  406. m_frontend->webSocketCreated(IdentifiersFactory::requestId(identifier), requestURL.string());
  407. }
  408. void InspectorResourceAgent::willSendWebSocketHandshakeRequest(unsigned long identifier, const ResourceRequest& request)
  409. {
  410. RefPtr<TypeBuilder::Network::WebSocketRequest> requestObject = TypeBuilder::Network::WebSocketRequest::create()
  411. .setHeaders(buildObjectForHeaders(request.httpHeaderFields()));
  412. m_frontend->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), currentTime(), requestObject);
  413. }
  414. void InspectorResourceAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse& response)
  415. {
  416. RefPtr<TypeBuilder::Network::WebSocketResponse> responseObject = TypeBuilder::Network::WebSocketResponse::create()
  417. .setStatus(response.httpStatusCode())
  418. .setStatusText(response.httpStatusText())
  419. .setHeaders(buildObjectForHeaders(response.httpHeaderFields()));
  420. m_frontend->webSocketHandshakeResponseReceived(IdentifiersFactory::requestId(identifier), currentTime(), responseObject);
  421. }
  422. void InspectorResourceAgent::didCloseWebSocket(unsigned long identifier)
  423. {
  424. m_frontend->webSocketClosed(IdentifiersFactory::requestId(identifier), currentTime());
  425. }
  426. void InspectorResourceAgent::didReceiveWebSocketFrame(unsigned long identifier, const WebSocketFrame& frame)
  427. {
  428. RefPtr<TypeBuilder::Network::WebSocketFrame> frameObject = TypeBuilder::Network::WebSocketFrame::create()
  429. .setOpcode(frame.opCode)
  430. .setMask(frame.masked)
  431. .setPayloadData(String(frame.payload, frame.payloadLength));
  432. m_frontend->webSocketFrameReceived(IdentifiersFactory::requestId(identifier), currentTime(), frameObject);
  433. }
  434. void InspectorResourceAgent::didSendWebSocketFrame(unsigned long identifier, const WebSocketFrame& frame)
  435. {
  436. RefPtr<TypeBuilder::Network::WebSocketFrame> frameObject = TypeBuilder::Network::WebSocketFrame::create()
  437. .setOpcode(frame.opCode)
  438. .setMask(frame.masked)
  439. .setPayloadData(String(frame.payload, frame.payloadLength));
  440. m_frontend->webSocketFrameSent(IdentifiersFactory::requestId(identifier), currentTime(), frameObject);
  441. }
  442. void InspectorResourceAgent::didReceiveWebSocketFrameError(unsigned long identifier, const String& errorMessage)
  443. {
  444. m_frontend->webSocketFrameError(IdentifiersFactory::requestId(identifier), currentTime(), errorMessage);
  445. }
  446. #endif // ENABLE(WEB_SOCKETS)
  447. // called from Internals for layout test purposes.
  448. void InspectorResourceAgent::setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize)
  449. {
  450. m_resourcesData->setResourcesDataSizeLimits(maximumResourcesContentSize, maximumSingleResourceContentSize);
  451. }
  452. void InspectorResourceAgent::enable(ErrorString*)
  453. {
  454. enable();
  455. }
  456. void InspectorResourceAgent::enable()
  457. {
  458. if (!m_frontend)
  459. return;
  460. m_state->setBoolean(ResourceAgentState::resourceAgentEnabled, true);
  461. m_instrumentingAgents->setInspectorResourceAgent(this);
  462. }
  463. void InspectorResourceAgent::disable(ErrorString*)
  464. {
  465. m_state->setBoolean(ResourceAgentState::resourceAgentEnabled, false);
  466. m_state->setString(ResourceAgentState::userAgentOverride, "");
  467. m_instrumentingAgents->setInspectorResourceAgent(0);
  468. m_resourcesData->clear();
  469. }
  470. void InspectorResourceAgent::setUserAgentOverride(ErrorString*, const String& userAgent)
  471. {
  472. m_state->setString(ResourceAgentState::userAgentOverride, userAgent);
  473. }
  474. void InspectorResourceAgent::setExtraHTTPHeaders(ErrorString*, const RefPtr<InspectorObject>& headers)
  475. {
  476. m_state->setObject(ResourceAgentState::extraRequestHeaders, headers);
  477. }
  478. void InspectorResourceAgent::getResponseBody(ErrorString* errorString, const String& requestId, String* content, bool* base64Encoded)
  479. {
  480. NetworkResourcesData::ResourceData const* resourceData = m_resourcesData->data(requestId);
  481. if (!resourceData) {
  482. *errorString = "No resource with given identifier found";
  483. return;
  484. }
  485. if (resourceData->hasContent()) {
  486. *base64Encoded = resourceData->base64Encoded();
  487. *content = resourceData->content();
  488. return;
  489. }
  490. if (resourceData->isContentEvicted()) {
  491. *errorString = "Request content was evicted from inspector cache";
  492. return;
  493. }
  494. if (resourceData->buffer() && !resourceData->textEncodingName().isNull()) {
  495. *base64Encoded = false;
  496. if (InspectorPageAgent::sharedBufferContent(resourceData->buffer(), resourceData->textEncodingName(), *base64Encoded, content))
  497. return;
  498. }
  499. if (resourceData->cachedResource()) {
  500. if (InspectorPageAgent::cachedResourceContent(resourceData->cachedResource(), content, base64Encoded))
  501. return;
  502. }
  503. *errorString = "No data found for resource with given identifier";
  504. }
  505. void InspectorResourceAgent::replayXHR(ErrorString*, const String& requestId)
  506. {
  507. RefPtr<XMLHttpRequest> xhr = XMLHttpRequest::create(m_pageAgent->mainFrame()->document());
  508. String actualRequestId = requestId;
  509. XHRReplayData* xhrReplayData = m_resourcesData->xhrReplayData(requestId);
  510. if (!xhrReplayData)
  511. return;
  512. ResourceRequest request(xhrReplayData->url());
  513. #if ENABLE(CACHE_PARTITIONING)
  514. request.setCachePartition(m_pageAgent->mainFrame()->document()->topOrigin()->cachePartition());
  515. #endif
  516. CachedResource* cachedResource = memoryCache()->resourceForRequest(request);
  517. if (cachedResource)
  518. memoryCache()->remove(cachedResource);
  519. xhr->open(xhrReplayData->method(), xhrReplayData->url(), xhrReplayData->async(), IGNORE_EXCEPTION);
  520. HTTPHeaderMap::const_iterator end = xhrReplayData->headers().end();
  521. for (HTTPHeaderMap::const_iterator it = xhrReplayData->headers().begin(); it!= end; ++it)
  522. xhr->setRequestHeader(it->key, it->value, IGNORE_EXCEPTION);
  523. xhr->sendFromInspector(xhrReplayData->formData(), IGNORE_EXCEPTION);
  524. }
  525. void InspectorResourceAgent::canClearBrowserCache(ErrorString*, bool* result)
  526. {
  527. *result = m_client->canClearBrowserCache();
  528. }
  529. void InspectorResourceAgent::clearBrowserCache(ErrorString*)
  530. {
  531. m_client->clearBrowserCache();
  532. }
  533. void InspectorResourceAgent::canClearBrowserCookies(ErrorString*, bool* result)
  534. {
  535. *result = m_client->canClearBrowserCookies();
  536. }
  537. void InspectorResourceAgent::clearBrowserCookies(ErrorString*)
  538. {
  539. m_client->clearBrowserCookies();
  540. }
  541. void InspectorResourceAgent::setCacheDisabled(ErrorString*, bool cacheDisabled)
  542. {
  543. m_state->setBoolean(ResourceAgentState::cacheDisabled, cacheDisabled);
  544. if (cacheDisabled)
  545. memoryCache()->evictResources();
  546. }
  547. void InspectorResourceAgent::mainFrameNavigated(DocumentLoader* loader)
  548. {
  549. if (m_state->getBoolean(ResourceAgentState::cacheDisabled))
  550. memoryCache()->evictResources();
  551. m_resourcesData->clear(m_pageAgent->loaderId(loader));
  552. }
  553. InspectorResourceAgent::InspectorResourceAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorClient* client, InspectorCompositeState* state)
  554. : InspectorBaseAgent<InspectorResourceAgent>("Network", instrumentingAgents, state)
  555. , m_pageAgent(pageAgent)
  556. , m_client(client)
  557. , m_frontend(0)
  558. , m_resourcesData(adoptPtr(new NetworkResourcesData()))
  559. , m_loadingXHRSynchronously(false)
  560. , m_isRecalculatingStyle(false)
  561. {
  562. }
  563. } // namespace WebCore
  564. #endif // ENABLE(INSPECTOR)