Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: Source/core/loader/ImageLoader.cpp

Issue 1291613010: Implement referrerpolicy attribute for img elements (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: actually fix webexposed test this time Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/loader/ImageLoader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserv ed. 4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserv ed.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 28 matching lines...) Expand all
39 #include "core/frame/Settings.h" 39 #include "core/frame/Settings.h"
40 #include "core/frame/UseCounter.h" 40 #include "core/frame/UseCounter.h"
41 #include "core/html/HTMLImageElement.h" 41 #include "core/html/HTMLImageElement.h"
42 #include "core/html/parser/HTMLParserIdioms.h" 42 #include "core/html/parser/HTMLParserIdioms.h"
43 #include "core/layout/LayoutImage.h" 43 #include "core/layout/LayoutImage.h"
44 #include "core/layout/LayoutVideo.h" 44 #include "core/layout/LayoutVideo.h"
45 #include "core/layout/svg/LayoutSVGImage.h" 45 #include "core/layout/svg/LayoutSVGImage.h"
46 #include "core/svg/graphics/SVGImage.h" 46 #include "core/svg/graphics/SVGImage.h"
47 #include "platform/Logging.h" 47 #include "platform/Logging.h"
48 #include "platform/weborigin/SecurityOrigin.h" 48 #include "platform/weborigin/SecurityOrigin.h"
49 #include "platform/weborigin/SecurityPolicy.h"
49 #include "public/platform/WebURLRequest.h" 50 #include "public/platform/WebURLRequest.h"
50 51
51 namespace blink { 52 namespace blink {
52 53
53 static ImageEventSender& loadEventSender() 54 static ImageEventSender& loadEventSender()
54 { 55 {
55 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load)); 56 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load));
56 return sender; 57 return sender;
57 } 58 }
58 59
(...skipping 12 matching lines...) Expand all
71 { 72 {
72 ASSERT(loader); 73 ASSERT(loader);
73 ASSERT(loader->element()); 74 ASSERT(loader->element());
74 if (loader->element()->document().frame() && loader->element()->document().f rame()->script().shouldBypassMainWorldCSP()) 75 if (loader->element()->document().frame() && loader->element()->document().f rame()->script().shouldBypassMainWorldCSP())
75 return ImageLoader::BypassMainWorldCSP; 76 return ImageLoader::BypassMainWorldCSP;
76 return ImageLoader::DoNotBypassMainWorldCSP; 77 return ImageLoader::DoNotBypassMainWorldCSP;
77 } 78 }
78 79
79 class ImageLoader::Task : public WebThread::Task { 80 class ImageLoader::Task : public WebThread::Task {
80 public: 81 public:
81 static PassOwnPtr<Task> create(ImageLoader* loader, UpdateFromElementBehavio r updateBehavior) 82 static PassOwnPtr<Task> create(ImageLoader* loader, UpdateFromElementBehavio r updateBehavior, ReferrerPolicy referrerPolicy)
82 { 83 {
83 return adoptPtr(new Task(loader, updateBehavior)); 84 return adoptPtr(new Task(loader, updateBehavior, referrerPolicy));
84 } 85 }
85 86
86 Task(ImageLoader* loader, UpdateFromElementBehavior updateBehavior) 87 Task(ImageLoader* loader, UpdateFromElementBehavior updateBehavior, Referrer Policy referrerPolicy)
87 : m_loader(loader) 88 : m_loader(loader)
88 , m_shouldBypassMainWorldCSP(shouldBypassMainWorldCSP(loader)) 89 , m_shouldBypassMainWorldCSP(shouldBypassMainWorldCSP(loader))
89 , m_updateBehavior(updateBehavior) 90 , m_updateBehavior(updateBehavior)
90 , m_weakFactory(this) 91 , m_weakFactory(this)
92 , m_referrerPolicy(referrerPolicy)
91 { 93 {
92 v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate(); 94 v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate();
93 v8::HandleScope scope(isolate); 95 v8::HandleScope scope(isolate);
94 // If we're invoked from C++ without a V8 context on the stack, we shoul d 96 // If we're invoked from C++ without a V8 context on the stack, we shoul d
95 // run the microtask in the context of the element's document's main wor ld. 97 // run the microtask in the context of the element's document's main wor ld.
96 if (ScriptState::hasCurrentScriptState(isolate)) 98 if (ScriptState::hasCurrentScriptState(isolate))
97 m_scriptState = ScriptState::current(isolate); 99 m_scriptState = ScriptState::current(isolate);
98 else 100 else
99 m_scriptState = ScriptState::forMainWorld(loader->element()->documen t().frame()); 101 m_scriptState = ScriptState::forMainWorld(loader->element()->documen t().frame());
100 } 102 }
101 103
102 ~Task() override 104 ~Task() override
103 { 105 {
104 } 106 }
105 107
106 void run() override 108 void run() override
107 { 109 {
108 if (!m_loader) 110 if (!m_loader)
109 return; 111 return;
110 if (m_scriptState->contextIsValid()) { 112 if (m_scriptState->contextIsValid()) {
111 ScriptState::Scope scope(m_scriptState.get()); 113 ScriptState::Scope scope(m_scriptState.get());
112 m_loader->doUpdateFromElement(m_shouldBypassMainWorldCSP, m_updateBe havior); 114 m_loader->doUpdateFromElement(m_shouldBypassMainWorldCSP, m_updateBe havior, m_referrerPolicy);
113 } else { 115 } else {
114 m_loader->doUpdateFromElement(m_shouldBypassMainWorldCSP, m_updateBe havior); 116 m_loader->doUpdateFromElement(m_shouldBypassMainWorldCSP, m_updateBe havior, m_referrerPolicy);
115 } 117 }
116 } 118 }
117 119
118 void clearLoader() 120 void clearLoader()
119 { 121 {
120 m_loader = nullptr; 122 m_loader = nullptr;
121 m_scriptState.clear(); 123 m_scriptState.clear();
122 } 124 }
123 125
124 WeakPtr<Task> createWeakPtr() 126 WeakPtr<Task> createWeakPtr()
125 { 127 {
126 return m_weakFactory.createWeakPtr(); 128 return m_weakFactory.createWeakPtr();
127 } 129 }
128 130
129 private: 131 private:
130 RawPtrWillBeWeakPersistent<ImageLoader> m_loader; 132 RawPtrWillBeWeakPersistent<ImageLoader> m_loader;
131 BypassMainWorldBehavior m_shouldBypassMainWorldCSP; 133 BypassMainWorldBehavior m_shouldBypassMainWorldCSP;
132 UpdateFromElementBehavior m_updateBehavior; 134 UpdateFromElementBehavior m_updateBehavior;
133 RefPtr<ScriptState> m_scriptState; 135 RefPtr<ScriptState> m_scriptState;
134 WeakPtrFactory<Task> m_weakFactory; 136 WeakPtrFactory<Task> m_weakFactory;
137 ReferrerPolicy m_referrerPolicy;
135 }; 138 };
136 139
137 ImageLoader::ImageLoader(Element* element) 140 ImageLoader::ImageLoader(Element* element)
138 : m_element(element) 141 : m_element(element)
139 , m_image(0) 142 , m_image(0)
140 , m_derefElementTimer(this, &ImageLoader::timerFired) 143 , m_derefElementTimer(this, &ImageLoader::timerFired)
141 , m_hasPendingLoadEvent(false) 144 , m_hasPendingLoadEvent(false)
142 , m_hasPendingErrorEvent(false) 145 , m_hasPendingErrorEvent(false)
143 , m_imageComplete(true) 146 , m_imageComplete(true)
144 , m_loadingImageDocument(false) 147 , m_loadingImageDocument(false)
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 inline void ImageLoader::crossSiteOrCSPViolationOccurred(AtomicString imageSourc eURL) 269 inline void ImageLoader::crossSiteOrCSPViolationOccurred(AtomicString imageSourc eURL)
267 { 270 {
268 m_failedLoadURL = imageSourceURL; 271 m_failedLoadURL = imageSourceURL;
269 } 272 }
270 273
271 inline void ImageLoader::clearFailedLoadURL() 274 inline void ImageLoader::clearFailedLoadURL()
272 { 275 {
273 m_failedLoadURL = AtomicString(); 276 m_failedLoadURL = AtomicString();
274 } 277 }
275 278
276 inline void ImageLoader::enqueueImageLoadingMicroTask(UpdateFromElementBehavior updateBehavior) 279 inline void ImageLoader::enqueueImageLoadingMicroTask(UpdateFromElementBehavior updateBehavior, ReferrerPolicy referrerPolicy)
277 { 280 {
278 OwnPtr<Task> task = Task::create(this, updateBehavior); 281 OwnPtr<Task> task = Task::create(this, updateBehavior, referrerPolicy);
279 m_pendingTask = task->createWeakPtr(); 282 m_pendingTask = task->createWeakPtr();
280 Microtask::enqueueMicrotask(task.release()); 283 Microtask::enqueueMicrotask(task.release());
281 m_loadDelayCounter = IncrementLoadEventDelayCount::create(m_element->documen t()); 284 m_loadDelayCounter = IncrementLoadEventDelayCount::create(m_element->documen t());
282 } 285 }
283 286
284 void ImageLoader::doUpdateFromElement(BypassMainWorldBehavior bypassBehavior, Up dateFromElementBehavior updateBehavior) 287 void ImageLoader::doUpdateFromElement(BypassMainWorldBehavior bypassBehavior, Up dateFromElementBehavior updateBehavior, ReferrerPolicy referrerPolicy)
285 { 288 {
286 // FIXME: According to 289 // FIXME: According to
287 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-cont ent.html#the-img-element:the-img-element-55 290 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-cont ent.html#the-img-element:the-img-element-55
288 // When "update image" is called due to environment changes and the load fai ls, onerror should not be called. 291 // When "update image" is called due to environment changes and the load fai ls, onerror should not be called.
289 // That is currently not the case. 292 // That is currently not the case.
290 // 293 //
291 // We don't need to call clearLoader here: Either we were called from the 294 // We don't need to call clearLoader here: Either we were called from the
292 // task, or our caller updateFromElement cleared the task's loader (and set 295 // task, or our caller updateFromElement cleared the task's loader (and set
293 // m_pendingTask to null). 296 // m_pendingTask to null).
294 m_pendingTask.clear(); 297 m_pendingTask.clear();
(...skipping 12 matching lines...) Expand all
307 if (!url.isNull()) { 310 if (!url.isNull()) {
308 // Unlike raw <img>, we block mixed content inside of <picture> or <img srcset>. 311 // Unlike raw <img>, we block mixed content inside of <picture> or <img srcset>.
309 ResourceLoaderOptions resourceLoaderOptions = ResourceFetcher::defaultRe sourceOptions(); 312 ResourceLoaderOptions resourceLoaderOptions = ResourceFetcher::defaultRe sourceOptions();
310 ResourceRequest resourceRequest(url); 313 ResourceRequest resourceRequest(url);
311 resourceRequest.setFetchCredentialsMode(WebURLRequest::FetchCredentialsM odeSameOrigin); 314 resourceRequest.setFetchCredentialsMode(WebURLRequest::FetchCredentialsM odeSameOrigin);
312 if (updateBehavior == UpdateForcedReload) { 315 if (updateBehavior == UpdateForcedReload) {
313 resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadByp assingCache); 316 resourceRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadByp assingCache);
314 // ImageLoader defers the load of images when in an ImageDocument. D on't defer this load on a forced reload. 317 // ImageLoader defers the load of images when in an ImageDocument. D on't defer this load on a forced reload.
315 m_loadingImageDocument = false; 318 m_loadingImageDocument = false;
316 } 319 }
320
321 if (referrerPolicy != ReferrerPolicyDefault)
322 resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(ref errerPolicy, url, document.outgoingReferrer()));
323
317 if (isHTMLPictureElement(element()->parentNode()) || !element()->fastGet Attribute(HTMLNames::srcsetAttr).isNull()) 324 if (isHTMLPictureElement(element()->parentNode()) || !element()->fastGet Attribute(HTMLNames::srcsetAttr).isNull())
318 resourceRequest.setRequestContext(WebURLRequest::RequestContextImage Set); 325 resourceRequest.setRequestContext(WebURLRequest::RequestContextImage Set);
319 FetchRequest request(resourceRequest, element()->localName(), resourceLo aderOptions); 326 FetchRequest request(resourceRequest, element()->localName(), resourceLo aderOptions);
320 configureRequest(request, bypassBehavior, *m_element, document.clientHin tsPreferences()); 327 configureRequest(request, bypassBehavior, *m_element, document.clientHin tsPreferences());
321 328
322 // Prevent the immediate creation of a ResourceLoader (and therefore a n etwork 329 // Prevent the immediate creation of a ResourceLoader (and therefore a n etwork
323 // request) for ImageDocument loads. In this case, the image contents ha ve already 330 // request) for ImageDocument loads. In this case, the image contents ha ve already
324 // been requested as a main resource and ImageDocumentParser will take c are of 331 // been requested as a main resource and ImageDocumentParser will take c are of
325 // funneling the main resource bytes into the ImageResource. 332 // funneling the main resource bytes into the ImageResource.
326 if (m_loadingImageDocument) { 333 if (m_loadingImageDocument) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 } 389 }
383 390
384 if (LayoutImageResource* imageResource = layoutImageResource()) 391 if (LayoutImageResource* imageResource = layoutImageResource())
385 imageResource->resetAnimation(); 392 imageResource->resetAnimation();
386 393
387 // Only consider updating the protection ref-count of the Element immediatel y before returning 394 // Only consider updating the protection ref-count of the Element immediatel y before returning
388 // from this function as doing so might result in the destruction of this Im ageLoader. 395 // from this function as doing so might result in the destruction of this Im ageLoader.
389 updatedHasPendingEvent(); 396 updatedHasPendingEvent();
390 } 397 }
391 398
392 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior) 399 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior, Re ferrerPolicy referrerPolicy)
393 { 400 {
394 AtomicString imageSourceURL = m_element->imageSourceURL(); 401 AtomicString imageSourceURL = m_element->imageSourceURL();
395 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); 402 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged);
396 403
397 if (updateBehavior == UpdateIgnorePreviousError) 404 if (updateBehavior == UpdateIgnorePreviousError)
398 clearFailedLoadURL(); 405 clearFailedLoadURL();
399 406
400 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) 407 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL)
401 return; 408 return;
402 409
403 // If we have a pending task, we have to clear it -- either we're 410 // If we have a pending task, we have to clear it -- either we're
404 // now loading immediately, or we need to reset the task's state. 411 // now loading immediately, or we need to reset the task's state.
405 if (m_pendingTask) { 412 if (m_pendingTask) {
406 m_pendingTask->clearLoader(); 413 m_pendingTask->clearLoader();
407 m_pendingTask.clear(); 414 m_pendingTask.clear();
408 } 415 }
409 416
410 KURL url = imageSourceToKURL(imageSourceURL); 417 KURL url = imageSourceToKURL(imageSourceURL);
411 if (shouldLoadImmediately(url)) { 418 if (shouldLoadImmediately(url)) {
412 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior); 419 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior, referrerPol icy);
413 return; 420 return;
414 } 421 }
415 // Allow the idiom "img.src=''; img.src='.." to clear down the image before 422 // Allow the idiom "img.src=''; img.src='.." to clear down the image before
416 // an asynchronous load completes. 423 // an asynchronous load completes.
417 if (imageSourceURL.isEmpty()) { 424 if (imageSourceURL.isEmpty()) {
418 ImageResource* image = m_image.get(); 425 ImageResource* image = m_image.get();
419 if (image) 426 if (image)
420 image->removeClient(this); 427 image->removeClient(this);
421 m_image = nullptr; 428 m_image = nullptr;
422 } 429 }
423 430
424 // Don't load images for inactive documents. We don't want to slow down the 431 // Don't load images for inactive documents. We don't want to slow down the
425 // raw HTML parsing case by loading images we don't intend to display. 432 // raw HTML parsing case by loading images we don't intend to display.
426 Document& document = m_element->document(); 433 Document& document = m_element->document();
427 if (document.isActive()) 434 if (document.isActive())
428 enqueueImageLoadingMicroTask(updateBehavior); 435 enqueueImageLoadingMicroTask(updateBehavior, referrerPolicy);
429 } 436 }
430 437
431 KURL ImageLoader::imageSourceToKURL(AtomicString imageSourceURL) const 438 KURL ImageLoader::imageSourceToKURL(AtomicString imageSourceURL) const
432 { 439 {
433 KURL url; 440 KURL url;
434 441
435 // Don't load images for inactive documents. We don't want to slow down the 442 // Don't load images for inactive documents. We don't want to slow down the
436 // raw HTML parsing case by loading images we don't intend to display. 443 // raw HTML parsing case by loading images we don't intend to display.
437 Document& document = m_element->document(); 444 Document& document = m_element->document();
438 if (!document.isActive()) 445 if (!document.isActive())
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 673
667 void ImageLoader::sourceImageChanged() 674 void ImageLoader::sourceImageChanged()
668 { 675 {
669 for (auto& client : m_clients) { 676 for (auto& client : m_clients) {
670 ImageLoaderClient* handle = client; 677 ImageLoaderClient* handle = client;
671 handle->notifyImageSourceChanged(); 678 handle->notifyImageSourceChanged();
672 } 679 }
673 } 680 }
674 681
675 } // namespace blink 682 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/loader/ImageLoader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698