| 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 // Please note that new entries should be added right above | 
 |   71 // FLASH_NAVIGATE_USAGE_ENUM_COUNT, and existing entries shouldn't be re-ordered | 
 |   72 // or removed, since this ordering is used in a histogram. | 
 |   73 enum FlashNavigateUsage { | 
 |   74   // This section must be in the same order as kRejectedHttpRequestHeaders. | 
 |   75   REJECT_AUTHORIZATION = 0, | 
 |   76   REJECT_CACHE_CONTROL, | 
 |   77   REJECT_CONTENT_ENCODING, | 
 |   78   REJECT_CONTENT_MD5, | 
 |   79   REJECT_CONTENT_TYPE, | 
 |   80   REJECT_EXPIRES, | 
 |   81   REJECT_FROM, | 
 |   82   REJECT_IF_MATCH, | 
 |   83   REJECT_IF_NONE_MATCH, | 
 |   84   REJECT_IF_RANGE, | 
 |   85   REJECT_IF_UNMODIFIED_SINCE, | 
 |   86   REJECT_PRAGMA, | 
 |   87   REJECT_REFERER, | 
 |   88  | 
 |   89   // The navigate request is rejected because of headers not listed above | 
 |   90   // (e.g., custom headers). | 
 |   91   REJECT_OTHER_HEADERS, | 
 |   92  | 
 |   93   // Total number of rejected navigate requests. | 
 |   94   TOTAL_REJECTED_NAVIGATE_REQUESTS, | 
 |   95  | 
 |   96   // Total number of navigate requests. | 
 |   97   TOTAL_NAVIGATE_REQUESTS, | 
 |   98  | 
 |   99   FLASH_NAVIGATE_USAGE_ENUM_COUNT | 
 |  100 }; | 
 |  101  | 
 |  102 static base::LazyInstance<std::map<std::string, FlashNavigateUsage> > | 
 |  103     g_rejected_headers = LAZY_INSTANCE_INITIALIZER; | 
 |  104  | 
 |  105 bool IsSimpleHeader(const std::string& lower_case_header_name, | 
 |  106                     const std::string& header_value) { | 
 |  107   if (lower_case_header_name == "accept" || | 
 |  108       lower_case_header_name == "accept-language" || | 
 |  109       lower_case_header_name == "content-language") { | 
 |  110     return true; | 
 |  111   } | 
 |  112  | 
 |  113   if (lower_case_header_name == "content-type") { | 
 |  114     std::string lower_case_mime_type; | 
 |  115     std::string lower_case_charset; | 
 |  116     bool had_charset = false; | 
 |  117     net::HttpUtil::ParseContentType(header_value, &lower_case_mime_type, | 
 |  118                                     &lower_case_charset, &had_charset, NULL); | 
 |  119     return lower_case_mime_type == "application/x-www-form-urlencoded" || | 
 |  120            lower_case_mime_type == "multipart/form-data" || | 
 |  121            lower_case_mime_type == "text/plain"; | 
 |  122   } | 
 |  123  | 
 |  124   return false; | 
 |  125 } | 
 |  126  | 
 |  127 void RecordFlashNavigateUsage(FlashNavigateUsage usage) { | 
 |  128   DCHECK_NE(FLASH_NAVIGATE_USAGE_ENUM_COUNT, usage); | 
 |  129   UMA_HISTOGRAM_ENUMERATION("Plugin.FlashNavigateUsage", usage, | 
 |  130                             FLASH_NAVIGATE_USAGE_ENUM_COUNT); | 
 |  131 } | 
 |  132  | 
 |  133 }  // namespace | 
 |  134  | 
|   36 PepperFlashRendererHost::PepperFlashRendererHost( |  135 PepperFlashRendererHost::PepperFlashRendererHost( | 
|   37     content::RendererPpapiHost* host, |  136     content::RendererPpapiHost* host, | 
|   38     PP_Instance instance, |  137     PP_Instance instance, | 
|   39     PP_Resource resource) |  138     PP_Resource resource) | 
|   40     : ResourceHost(host->GetPpapiHost(), instance, resource), |  139     : ResourceHost(host->GetPpapiHost(), instance, resource), | 
|   41       host_(host), |  140       host_(host), | 
|   42       weak_factory_(this) { |  141       weak_factory_(this) { | 
|   43 } |  142 } | 
|   44  |  143  | 
|   45 PepperFlashRendererHost::~PepperFlashRendererHost() { |  144 PepperFlashRendererHost::~PepperFlashRendererHost() { | 
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  203     ppapi::host::HostMessageContext* host_context, |  302     ppapi::host::HostMessageContext* host_context, | 
|  204     const ppapi::URLRequestInfoData& data, |  303     const ppapi::URLRequestInfoData& data, | 
|  205     const std::string& target, |  304     const std::string& target, | 
|  206     bool from_user_action) { |  305     bool from_user_action) { | 
|  207   // If our PepperPluginInstance is already destroyed, just return a failure. |  306   // If our PepperPluginInstance is already destroyed, just return a failure. | 
|  208   content::PepperPluginInstance* plugin_instance = |  307   content::PepperPluginInstance* plugin_instance = | 
|  209       host_->GetPluginInstance(pp_instance()); |  308       host_->GetPluginInstance(pp_instance()); | 
|  210   if (!plugin_instance) |  309   if (!plugin_instance) | 
|  211     return PP_ERROR_FAILED; |  310     return PP_ERROR_FAILED; | 
|  212  |  311  | 
 |  312   std::map<std::string, FlashNavigateUsage>& rejected_headers = | 
 |  313       g_rejected_headers.Get(); | 
 |  314   if (rejected_headers.empty()) { | 
 |  315     for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i) | 
 |  316       rejected_headers[kRejectedHttpRequestHeaders[i]] = | 
 |  317           static_cast<FlashNavigateUsage>(i); | 
 |  318   } | 
 |  319  | 
 |  320   net::HttpUtil::HeadersIterator header_iter(data.headers.begin(), | 
 |  321                                              data.headers.end(), | 
 |  322                                              "\n\r"); | 
 |  323   bool rejected = false; | 
 |  324   while (header_iter.GetNext()) { | 
 |  325     std::string lower_case_header_name = StringToLowerASCII(header_iter.name()); | 
 |  326     if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) { | 
 |  327       rejected = true; | 
 |  328  | 
 |  329       std::map<std::string, FlashNavigateUsage>::const_iterator iter = | 
 |  330           rejected_headers.find(lower_case_header_name); | 
 |  331       FlashNavigateUsage usage = iter != rejected_headers.end() ? | 
 |  332           iter->second : REJECT_OTHER_HEADERS; | 
 |  333       RecordFlashNavigateUsage(usage); | 
 |  334     } | 
 |  335   } | 
 |  336  | 
 |  337   RecordFlashNavigateUsage(TOTAL_NAVIGATE_REQUESTS); | 
 |  338   if (rejected) { | 
 |  339     RecordFlashNavigateUsage(TOTAL_REJECTED_NAVIGATE_REQUESTS); | 
 |  340     return PP_ERROR_NOACCESS; | 
 |  341   } | 
 |  342  | 
|  213   // Navigate may call into Javascript (e.g. with a "javascript:" URL), |  343   // 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 |  344   // 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 |  345   // 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. |  346   // equivalent to NPN_GetURL, where Flash would expect re-entrancy. | 
|  217   ppapi::proxy::HostDispatcher* host_dispatcher = |  347   ppapi::proxy::HostDispatcher* host_dispatcher = | 
|  218       ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); |  348       ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); | 
|  219   host_dispatcher->set_allow_plugin_reentrancy(); |  349   host_dispatcher->set_allow_plugin_reentrancy(); | 
|  220  |  350  | 
|  221   // Grab a weak pointer to ourselves on the stack so we can check if we are |  351   // Grab a weak pointer to ourselves on the stack so we can check if we are | 
|  222   // still alive. |  352   // still alive. | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  246       gfx::Rect(rect.point.x, rect.point.y,rect.size.width, rect.size.height))) |  376       gfx::Rect(rect.point.x, rect.point.y,rect.size.width, rect.size.height))) | 
|  247     return PP_OK; |  377     return PP_OK; | 
|  248   return PP_ERROR_FAILED; |  378   return PP_ERROR_FAILED; | 
|  249 } |  379 } | 
|  250  |  380  | 
|  251 int32_t PepperFlashRendererHost::OnInvokePrinting( |  381 int32_t PepperFlashRendererHost::OnInvokePrinting( | 
|  252     ppapi::host::HostMessageContext* host_context) { |  382     ppapi::host::HostMessageContext* host_context) { | 
|  253   PPB_PDF_Impl::InvokePrintingForInstance(pp_instance()); |  383   PPB_PDF_Impl::InvokePrintingForInstance(pp_instance()); | 
|  254   return PP_OK; |  384   return PP_OK; | 
|  255 } |  385 } | 
| OLD | NEW |