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 |