| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "config.h" | |
| 6 | |
| 7 #include "CachedCSSStyleSheet.h" | |
| 8 #include "CachedResource.h" | |
| 9 #include "CachedScript.h" | |
| 10 #include "CachedXSLStyleSheet.h" | |
| 11 #include "DocLoader.h" | |
| 12 #include "Document.h" | |
| 13 #include "DocumentLoader.h" | |
| 14 #include "FrameLoader.h" | |
| 15 #include "PlatformString.h" | |
| 16 #include "ResourceError.h" | |
| 17 #include "ResourceRequest.h" | |
| 18 #include "ResourceResponse.h" | |
| 19 #include "ScriptString.h" | |
| 20 #include "TextEncoding.h" | |
| 21 #include <wtf/CurrentTime.h> | |
| 22 #undef LOG | |
| 23 | |
| 24 #include "base/basictypes.h" | |
| 25 #include "base/values.h" | |
| 26 #include "googleurl/src/gurl.h" | |
| 27 #include "webkit/glue/devtools/net_agent_impl.h" | |
| 28 #include "webkit/glue/glue_util.h" | |
| 29 | |
| 30 using namespace WebCore; | |
| 31 | |
| 32 NetAgentImpl::NetAgentImpl(NetAgentDelegate* delegate) | |
| 33 : delegate_(delegate), | |
| 34 document_(NULL), | |
| 35 main_loader_(NULL), | |
| 36 last_cached_identifier_(-2), | |
| 37 attached_(false) { | |
| 38 } | |
| 39 | |
| 40 NetAgentImpl::~NetAgentImpl() { | |
| 41 SetDocument(NULL); | |
| 42 DidCommitMainResourceLoad(); | |
| 43 deleteAllValues(pending_resources_); | |
| 44 pending_resources_.clear(); | |
| 45 } | |
| 46 | |
| 47 void NetAgentImpl::SetDocument(Document* doc) { | |
| 48 document_ = doc; | |
| 49 } | |
| 50 | |
| 51 void NetAgentImpl::Attach() { | |
| 52 for (FinishedResources::iterator it = finished_resources_.begin(); | |
| 53 it != finished_resources_.end(); ++it) { | |
| 54 DictionaryValue value; | |
| 55 Serialize(*it->second, &value); | |
| 56 delegate_->DidFinishLoading(it->first, value); | |
| 57 } | |
| 58 attached_ = true; | |
| 59 } | |
| 60 | |
| 61 void NetAgentImpl::Detach() { | |
| 62 attached_ = false; | |
| 63 xml_http_sources_.clear(); | |
| 64 ExpireFinishedResourcesCache(); | |
| 65 } | |
| 66 | |
| 67 void NetAgentImpl::DidCommitMainResourceLoad() { | |
| 68 for (FinishedResources::iterator it = finished_resources_.begin(); | |
| 69 it != finished_resources_.end(); ++it) { | |
| 70 delete it->second; | |
| 71 } | |
| 72 finished_resources_.clear(); | |
| 73 main_loader_ = NULL; | |
| 74 } | |
| 75 | |
| 76 void NetAgentImpl::AssignIdentifierToRequest( | |
| 77 DocumentLoader* loader, | |
| 78 int identifier, | |
| 79 const ResourceRequest& request) { | |
| 80 } | |
| 81 | |
| 82 void NetAgentImpl::WillSendRequest( | |
| 83 DocumentLoader* loader, | |
| 84 int identifier, | |
| 85 const ResourceRequest& request) { | |
| 86 if (pending_resources_.contains(identifier)) { | |
| 87 // We are going through redirect, nuke old resource. | |
| 88 delete pending_resources_.get(identifier); | |
| 89 } | |
| 90 | |
| 91 Resource* resource = new Resource(); | |
| 92 pending_resources_.set(identifier, resource); | |
| 93 KURL url = request.url(); | |
| 94 resource->start_time = WTF::currentTime(); | |
| 95 resource->url = request.url(); | |
| 96 resource->request_headers = request.httpHeaderFields(); | |
| 97 | |
| 98 if (attached_) { | |
| 99 DictionaryValue value; | |
| 100 Serialize(*resource, &value); | |
| 101 delegate_->WillSendRequest(identifier, value); | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 void NetAgentImpl::DidReceiveResponse( | |
| 106 DocumentLoader* loader, | |
| 107 int identifier, | |
| 108 const ResourceResponse &response) { | |
| 109 if (!pending_resources_.contains(identifier)) { | |
| 110 return; | |
| 111 } | |
| 112 | |
| 113 KURL url = response.url(); | |
| 114 Resource* resource = pending_resources_.get(identifier); | |
| 115 resource->response_received_time = WTF::currentTime(); | |
| 116 resource->expected_content_length = | |
| 117 static_cast<int>(response.expectedContentLength()); | |
| 118 resource->http_status_code = response.httpStatusCode(); | |
| 119 resource->mime_type = response.mimeType(); | |
| 120 resource->suggested_filename = response.suggestedFilename(); | |
| 121 resource->response_headers = response.httpHeaderFields(); | |
| 122 | |
| 123 if (attached_) { | |
| 124 DictionaryValue value; | |
| 125 Serialize(*resource, &value); | |
| 126 delegate_->DidReceiveResponse(identifier, value); | |
| 127 } | |
| 128 } | |
| 129 | |
| 130 void NetAgentImpl::DidReceiveContentLength( | |
| 131 DocumentLoader* loader, | |
| 132 int identifier, | |
| 133 int length) { | |
| 134 } | |
| 135 | |
| 136 void NetAgentImpl::DidFinishLoading( | |
| 137 DocumentLoader* loader, | |
| 138 int identifier) { | |
| 139 if (!pending_resources_.contains(identifier)) { | |
| 140 return; | |
| 141 } | |
| 142 | |
| 143 Resource* resource = pending_resources_.get(identifier); | |
| 144 resource->end_time = WTF::currentTime(); | |
| 145 | |
| 146 // This is the first command being dispatched after | |
| 147 // DidCommitMainResourceLoad, we know that the first resource to be reported | |
| 148 // as loaded is main resource. | |
| 149 if (!main_loader_.get()) { | |
| 150 main_loader_ = loader; | |
| 151 resource->main_resource = true; | |
| 152 } | |
| 153 | |
| 154 pending_resources_.remove(identifier); | |
| 155 finished_resources_.append(std::make_pair(identifier, resource)); | |
| 156 | |
| 157 if (attached_) { | |
| 158 DictionaryValue value; | |
| 159 Serialize(*resource, &value); | |
| 160 delegate_->DidFinishLoading(identifier, value); | |
| 161 } else { | |
| 162 ExpireFinishedResourcesCache(); | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 void NetAgentImpl::DidFailLoading( | |
| 167 DocumentLoader* loader, | |
| 168 int identifier, | |
| 169 const ResourceError& error) { | |
| 170 if (!pending_resources_.contains(identifier)) { | |
| 171 return; | |
| 172 } | |
| 173 Resource* resource = pending_resources_.get(identifier); | |
| 174 resource->error_code = error.errorCode(); | |
| 175 resource->error_description = error.localizedDescription(); | |
| 176 DidFinishLoading(loader, identifier); | |
| 177 } | |
| 178 | |
| 179 void NetAgentImpl::DidLoadResourceFromMemoryCache( | |
| 180 DocumentLoader* loader, | |
| 181 const ResourceRequest& request, | |
| 182 const ResourceResponse& response, | |
| 183 int length) { | |
| 184 int identifier = last_cached_identifier_--; | |
| 185 } | |
| 186 | |
| 187 void NetAgentImpl::DidLoadResourceByXMLHttpRequest( | |
| 188 int identifier, | |
| 189 const WebCore::ScriptString& source) { | |
| 190 if (attached_) { | |
| 191 // Only store XmlHttpRequests data when client is attached. | |
| 192 xml_http_sources_.set(identifier, source); | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 void NetAgentImpl::GetResourceContent( | |
| 197 int call_id, | |
| 198 int identifier, | |
| 199 const String& url) { | |
| 200 if (!document_) { | |
| 201 return; | |
| 202 } | |
| 203 | |
| 204 String source; | |
| 205 | |
| 206 WebCore::ScriptString script = xml_http_sources_.get(identifier); | |
| 207 if (!script.isNull()) { | |
| 208 source = String(script); | |
| 209 } else if (main_loader_.get() && main_loader_->requestURL() == url) { | |
| 210 RefPtr<SharedBuffer> buffer = main_loader_->mainResourceData(); | |
| 211 String text_encoding_name = document_->inputEncoding(); | |
| 212 if (buffer) { | |
| 213 WebCore::TextEncoding encoding(text_encoding_name); | |
| 214 if (!encoding.isValid()) | |
| 215 encoding = WindowsLatin1Encoding(); | |
| 216 source = encoding.decode(buffer->data(), buffer->size()); | |
| 217 } | |
| 218 } else { | |
| 219 CachedResource* cached_resource = document_-> | |
| 220 docLoader()->cachedResource(url); | |
| 221 if (!cached_resource) { | |
| 222 delegate_->GetResourceContentResult(call_id, ""); | |
| 223 return; | |
| 224 } | |
| 225 if (cached_resource->isPurgeable()) { | |
| 226 // If the resource is purgeable then make it unpurgeable to get its data. | |
| 227 // This might fail, in which case we return an empty string. | |
| 228 if (!cached_resource->makePurgeable(false)) { | |
| 229 delegate_->GetResourceContentResult(call_id, ""); | |
| 230 return; | |
| 231 } | |
| 232 } | |
| 233 | |
| 234 // Try to get the decoded source. Only applies to some CachedResource | |
| 235 // types. | |
| 236 switch (cached_resource->type()) { | |
| 237 case CachedResource::CSSStyleSheet: { | |
| 238 CachedCSSStyleSheet *sheet = | |
| 239 reinterpret_cast<CachedCSSStyleSheet*>(cached_resource); | |
| 240 source = sheet->sheetText(); | |
| 241 break; | |
| 242 } | |
| 243 case CachedResource::Script: { | |
| 244 CachedScript *script = | |
| 245 reinterpret_cast<CachedScript*>(cached_resource); | |
| 246 source = script->script(); | |
| 247 break; | |
| 248 } | |
| 249 #if ENABLE(XSLT) | |
| 250 case CachedResource::XSLStyleSheet: { | |
| 251 CachedXSLStyleSheet *sheet = | |
| 252 reinterpret_cast<CachedXSLStyleSheet*>(cached_resource); | |
| 253 source = sheet->sheet(); | |
| 254 break; | |
| 255 } | |
| 256 #endif | |
| 257 default: | |
| 258 break; | |
| 259 } | |
| 260 } | |
| 261 delegate_->GetResourceContentResult(call_id, | |
| 262 webkit_glue::StringToStdString(source)); | |
| 263 } | |
| 264 | |
| 265 // static | |
| 266 Value* NetAgentImpl::BuildValueForHeaders(const HTTPHeaderMap& headers) { | |
| 267 OwnPtr<DictionaryValue> value(new DictionaryValue()); | |
| 268 HTTPHeaderMap::const_iterator end = headers.end(); | |
| 269 for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it) { | |
| 270 value->SetString(webkit_glue::StringToStdWString(it->first), | |
| 271 webkit_glue::StringToStdString(it->second)); | |
| 272 } | |
| 273 return value.release(); | |
| 274 } | |
| 275 | |
| 276 // static | |
| 277 void NetAgentImpl::Serialize(const Resource& resource, | |
| 278 DictionaryValue* value) { | |
| 279 value->SetReal(L"startTime", resource.start_time); | |
| 280 value->SetReal(L"responseReceivedTime", resource.response_received_time); | |
| 281 value->SetReal(L"endTime", resource.end_time); | |
| 282 | |
| 283 value->SetString(L"requestURL", | |
| 284 webkit_glue::StringToStdString(resource.url.string())); | |
| 285 value->SetString(L"host", | |
| 286 webkit_glue::StringToStdString(resource.url.host())); | |
| 287 value->SetString(L"path", | |
| 288 webkit_glue::StringToStdString(resource.url.path())); | |
| 289 value->SetString( | |
| 290 L"lastPathComponent", | |
| 291 webkit_glue::StringToStdString(resource.url.lastPathComponent())); | |
| 292 | |
| 293 value->SetString(L"mimeType", | |
| 294 webkit_glue::StringToStdWString(resource.mime_type)); | |
| 295 value->SetString(L"suggestedFilename", | |
| 296 webkit_glue::StringToStdWString(resource.suggested_filename)); | |
| 297 | |
| 298 value->SetInteger(L"expectedContentLength", | |
| 299 resource.expected_content_length); | |
| 300 value->SetInteger(L"responseStatusCode", resource.http_status_code); | |
| 301 | |
| 302 value->Set(L"requestHeaders", | |
| 303 BuildValueForHeaders(resource.request_headers)); | |
| 304 value->Set(L"responseHeaders", | |
| 305 BuildValueForHeaders(resource.response_headers)); | |
| 306 | |
| 307 value->SetBoolean(L"isMainResource", resource.main_resource); | |
| 308 value->SetBoolean(L"cached", false); | |
| 309 | |
| 310 if (resource.error_code) { | |
| 311 value->SetInteger(L"errorCode", resource.error_code); | |
| 312 value->SetString(L"localizedDescription", | |
| 313 webkit_glue::StringToStdString(resource.error_description)); | |
| 314 } | |
| 315 } | |
| 316 | |
| 317 void NetAgentImpl::ExpireFinishedResourcesCache() { | |
| 318 if (finished_resources_.size() > 100) { | |
| 319 // Preserve main resource. | |
| 320 for (int i = 1; i < 21; ++i) { | |
| 321 delete finished_resources_[i].second; | |
| 322 } | |
| 323 finished_resources_.remove(1, 21); | |
| 324 } | |
| 325 } | |
| OLD | NEW |