Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/renderer/pepper/pepper_flash_renderer_host.h" | 5 #include "chrome/renderer/pepper/pepper_flash_renderer_host.h" |
| 6 | 6 |
| 7 #include <map> | |
| 7 #include <vector> | 8 #include <vector> |
| 8 | 9 |
| 10 #include "base/lazy_instance.h" | |
| 11 #include "base/metrics/histogram.h" | |
| 12 #include "base/strings/string_util.h" | |
| 9 #include "chrome/renderer/pepper/ppb_pdf_impl.h" | 13 #include "chrome/renderer/pepper/ppb_pdf_impl.h" |
| 10 #include "content/public/renderer/pepper_plugin_instance.h" | 14 #include "content/public/renderer/pepper_plugin_instance.h" |
| 11 #include "content/public/renderer/render_thread.h" | 15 #include "content/public/renderer/render_thread.h" |
| 12 #include "content/public/renderer/renderer_ppapi_host.h" | 16 #include "content/public/renderer/renderer_ppapi_host.h" |
| 13 #include "ipc/ipc_message_macros.h" | 17 #include "ipc/ipc_message_macros.h" |
| 18 #include "net/http/http_util.h" | |
| 14 #include "ppapi/c/pp_errors.h" | 19 #include "ppapi/c/pp_errors.h" |
| 15 #include "ppapi/c/trusted/ppb_browser_font_trusted.h" | 20 #include "ppapi/c/trusted/ppb_browser_font_trusted.h" |
| 16 #include "ppapi/host/dispatch_host_message.h" | 21 #include "ppapi/host/dispatch_host_message.h" |
| 17 #include "ppapi/proxy/host_dispatcher.h" | 22 #include "ppapi/proxy/host_dispatcher.h" |
| 18 #include "ppapi/proxy/ppapi_messages.h" | 23 #include "ppapi/proxy/ppapi_messages.h" |
| 19 #include "ppapi/proxy/resource_message_params.h" | 24 #include "ppapi/proxy/resource_message_params.h" |
| 20 #include "ppapi/proxy/serialized_structs.h" | 25 #include "ppapi/proxy/serialized_structs.h" |
| 21 #include "ppapi/thunk/enter.h" | 26 #include "ppapi/thunk/enter.h" |
| 22 #include "ppapi/thunk/ppb_image_data_api.h" | 27 #include "ppapi/thunk/ppb_image_data_api.h" |
| 23 #include "skia/ext/platform_canvas.h" | 28 #include "skia/ext/platform_canvas.h" |
| 24 #include "third_party/skia/include/core/SkCanvas.h" | 29 #include "third_party/skia/include/core/SkCanvas.h" |
| 25 #include "third_party/skia/include/core/SkMatrix.h" | 30 #include "third_party/skia/include/core/SkMatrix.h" |
| 26 #include "third_party/skia/include/core/SkPaint.h" | 31 #include "third_party/skia/include/core/SkPaint.h" |
| 27 #include "third_party/skia/include/core/SkPoint.h" | 32 #include "third_party/skia/include/core/SkPoint.h" |
| 28 #include "third_party/skia/include/core/SkTemplates.h" | 33 #include "third_party/skia/include/core/SkTemplates.h" |
| 29 #include "third_party/skia/include/core/SkTypeface.h" | 34 #include "third_party/skia/include/core/SkTypeface.h" |
| 30 #include "ui/gfx/rect.h" | 35 #include "ui/gfx/rect.h" |
| 31 #include "url/gurl.h" | 36 #include "url/gurl.h" |
| 32 | 37 |
| 33 using ppapi::thunk::EnterResourceNoLock; | 38 using ppapi::thunk::EnterResourceNoLock; |
| 34 using ppapi::thunk::PPB_ImageData_API; | 39 using ppapi::thunk::PPB_ImageData_API; |
| 35 | 40 |
| 41 namespace { | |
| 42 | |
| 43 // Some non-simple HTTP request headers that Flash may set. | |
| 44 // (Please see http://www.w3.org/TR/cors/#simple-header for the definition of | |
| 45 // simple headers.) | |
| 46 // | |
| 47 // The list and the enum defined below are used to collect data about request | |
| 48 // headers used in PPB_Flash.Navigate() calls, in order to understand the impact | |
| 49 // of rejecting PPB_Flash.Navigate() requests with non-simple headers. | |
| 50 // | |
| 51 // TODO(yzshen): We should be able to remove the histogram recording code once | |
| 52 // we get the answer. | |
| 53 const char* kRejectedHttpRequestHeaders[] = { | |
| 54 "authorization", | |
| 55 "cache-control", | |
| 56 "content-encoding", | |
| 57 "content-md5", | |
| 58 "content-type", // If the media type is not one of those covered by the | |
| 59 // simple header definition. | |
| 60 "expires", | |
| 61 "from", | |
| 62 "if-match", | |
| 63 "if-none-match", | |
| 64 "if-range", | |
| 65 "if-unmodified-since", | |
| 66 "pragma", | |
| 67 "referer" | |
| 68 }; | |
| 69 | |
| 70 enum FlashNavigateUsage { | |
| 71 // This section must be in the same order as kRejectedHttpRequestHeaders. | |
| 72 REJECT_AUTHORIZATION = 0, | |
| 73 REJECT_CACHE_CONTROL, | |
| 74 REJECT_CONTENT_ENCODING, | |
| 75 REJECT_CONTENT_MD5, | |
| 76 REJECT_CONTENT_TYPE, | |
| 77 REJECT_EXPIRES, | |
| 78 REJECT_FROM, | |
| 79 REJECT_IF_MATCH, | |
| 80 REJECT_IF_NONE_MATCH, | |
| 81 REJECT_IF_RANGE, | |
| 82 REJECT_IF_UNMODIFIED_SINCE, | |
| 83 REJECT_PRAGMA, | |
| 84 REJECT_REFERER, | |
| 85 | |
| 86 // The navigate request is rejected because of headers not listed above | |
| 87 // (e.g., custom headers). | |
| 88 REJECT_OTHER_HEADERS, | |
| 89 | |
| 90 // Total number of rejected navigate requests. | |
| 91 TOTAL_REJECTED_NAVIGATE_REQUESTS, | |
| 92 | |
| 93 // Total number of navigate requests. | |
| 94 TOTAL_NAVIGATE_REQUESTS, | |
| 95 | |
| 96 FLASH_NAVIGATE_USAGE_ENUM_COUNT | |
| 97 }; | |
| 98 | |
| 99 static base::LazyInstance<std::map<std::string, FlashNavigateUsage> > | |
| 100 g_rejected_headers = LAZY_INSTANCE_INITIALIZER; | |
| 101 | |
| 102 bool IsSimpleHeader(const std::string& lower_case_header_name, | |
|
abarth-chromium
2014/01/28 21:52:08
Can you add a comment about how we should share th
yzshen1
2014/01/28 22:05:10
Happy to make changes, just try to make sure I und
| |
| 103 const std::string& header_value) { | |
| 104 if (lower_case_header_name == "accept" || | |
| 105 lower_case_header_name == "accept-language" || | |
| 106 lower_case_header_name == "content-language") { | |
| 107 return true; | |
| 108 } | |
| 109 | |
| 110 if (lower_case_header_name == "content-type") { | |
| 111 std::string lower_case_mime_type; | |
| 112 std::string lower_case_charset; | |
| 113 bool had_charset = false; | |
| 114 net::HttpUtil::ParseContentType(header_value, &lower_case_mime_type, | |
| 115 &lower_case_charset, &had_charset, NULL); | |
| 116 return lower_case_mime_type == "application/x-www-form-urlencoded" || | |
| 117 lower_case_mime_type == "multipart/form-data" || | |
| 118 lower_case_mime_type == "text/plain"; | |
| 119 } | |
| 120 | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 124 } // namespace | |
| 125 | |
| 36 PepperFlashRendererHost::PepperFlashRendererHost( | 126 PepperFlashRendererHost::PepperFlashRendererHost( |
| 37 content::RendererPpapiHost* host, | 127 content::RendererPpapiHost* host, |
| 38 PP_Instance instance, | 128 PP_Instance instance, |
| 39 PP_Resource resource) | 129 PP_Resource resource) |
| 40 : ResourceHost(host->GetPpapiHost(), instance, resource), | 130 : ResourceHost(host->GetPpapiHost(), instance, resource), |
| 41 host_(host), | 131 host_(host), |
| 42 weak_factory_(this) { | 132 weak_factory_(this) { |
| 43 } | 133 } |
| 44 | 134 |
| 45 PepperFlashRendererHost::~PepperFlashRendererHost() { | 135 PepperFlashRendererHost::~PepperFlashRendererHost() { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 ppapi::host::HostMessageContext* host_context, | 293 ppapi::host::HostMessageContext* host_context, |
| 204 const ppapi::URLRequestInfoData& data, | 294 const ppapi::URLRequestInfoData& data, |
| 205 const std::string& target, | 295 const std::string& target, |
| 206 bool from_user_action) { | 296 bool from_user_action) { |
| 207 // If our PepperPluginInstance is already destroyed, just return a failure. | 297 // If our PepperPluginInstance is already destroyed, just return a failure. |
| 208 content::PepperPluginInstance* plugin_instance = | 298 content::PepperPluginInstance* plugin_instance = |
| 209 host_->GetPluginInstance(pp_instance()); | 299 host_->GetPluginInstance(pp_instance()); |
| 210 if (!plugin_instance) | 300 if (!plugin_instance) |
| 211 return PP_ERROR_FAILED; | 301 return PP_ERROR_FAILED; |
| 212 | 302 |
| 303 std::map<std::string, FlashNavigateUsage>& rejected_headers = | |
| 304 g_rejected_headers.Get(); | |
| 305 if (rejected_headers.empty()) { | |
| 306 for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i) | |
| 307 rejected_headers[kRejectedHttpRequestHeaders[i]] = | |
| 308 static_cast<FlashNavigateUsage>(i); | |
| 309 } | |
| 310 | |
| 311 net::HttpUtil::HeadersIterator header_iter(data.headers.begin(), | |
| 312 data.headers.end(), | |
| 313 "\n\r"); | |
| 314 bool rejected = false; | |
| 315 while (header_iter.GetNext()) { | |
| 316 std::string lower_case_header_name = StringToLowerASCII(header_iter.name()); | |
| 317 if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) { | |
| 318 rejected = true; | |
| 319 | |
| 320 std::map<std::string, FlashNavigateUsage>::const_iterator iter = | |
| 321 rejected_headers.find(lower_case_header_name); | |
| 322 FlashNavigateUsage usage = iter != rejected_headers.end() ? | |
| 323 iter->second : REJECT_OTHER_HEADERS; | |
| 324 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashNavigateUsage", usage, | |
| 325 FLASH_NAVIGATE_USAGE_ENUM_COUNT); | |
| 326 } | |
| 327 } | |
| 328 | |
| 329 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashNavigateUsage", | |
| 330 TOTAL_NAVIGATE_REQUESTS, | |
| 331 FLASH_NAVIGATE_USAGE_ENUM_COUNT); | |
| 332 if (rejected) { | |
| 333 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashNavigateUsage", | |
| 334 TOTAL_REJECTED_NAVIGATE_REQUESTS, | |
| 335 FLASH_NAVIGATE_USAGE_ENUM_COUNT); | |
| 336 return PP_ERROR_NOACCESS; | |
| 337 } | |
| 338 | |
| 213 // Navigate may call into Javascript (e.g. with a "javascript:" URL), | 339 // Navigate may call into Javascript (e.g. with a "javascript:" URL), |
| 214 // or do things like navigate away from the page, either one of which will | 340 // or do things like navigate away from the page, either one of which will |
| 215 // need to re-enter into the plugin. It is safe, because it is essentially | 341 // need to re-enter into the plugin. It is safe, because it is essentially |
| 216 // equivalent to NPN_GetURL, where Flash would expect re-entrancy. | 342 // equivalent to NPN_GetURL, where Flash would expect re-entrancy. |
| 217 ppapi::proxy::HostDispatcher* host_dispatcher = | 343 ppapi::proxy::HostDispatcher* host_dispatcher = |
| 218 ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); | 344 ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); |
| 219 host_dispatcher->set_allow_plugin_reentrancy(); | 345 host_dispatcher->set_allow_plugin_reentrancy(); |
| 220 | 346 |
| 221 // Grab a weak pointer to ourselves on the stack so we can check if we are | 347 // Grab a weak pointer to ourselves on the stack so we can check if we are |
| 222 // still alive. | 348 // still alive. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 246 gfx::Rect(rect.point.x, rect.point.y,rect.size.width, rect.size.height))) | 372 gfx::Rect(rect.point.x, rect.point.y,rect.size.width, rect.size.height))) |
| 247 return PP_OK; | 373 return PP_OK; |
| 248 return PP_ERROR_FAILED; | 374 return PP_ERROR_FAILED; |
| 249 } | 375 } |
| 250 | 376 |
| 251 int32_t PepperFlashRendererHost::OnInvokePrinting( | 377 int32_t PepperFlashRendererHost::OnInvokePrinting( |
| 252 ppapi::host::HostMessageContext* host_context) { | 378 ppapi::host::HostMessageContext* host_context) { |
| 253 PPB_PDF_Impl::InvokePrintingForInstance(pp_instance()); | 379 PPB_PDF_Impl::InvokePrintingForInstance(pp_instance()); |
| 254 return PP_OK; | 380 return PP_OK; |
| 255 } | 381 } |
| OLD | NEW |