Chromium Code Reviews| Index: chrome/renderer/pepper/pepper_flash_renderer_host.cc |
| diff --git a/chrome/renderer/pepper/pepper_flash_renderer_host.cc b/chrome/renderer/pepper/pepper_flash_renderer_host.cc |
| index e978b6a4e71fc68ce5656ad803d8ea3237c9a63a..48703d4a205d700abef73c48e2c49537f07ba9f2 100644 |
| --- a/chrome/renderer/pepper/pepper_flash_renderer_host.cc |
| +++ b/chrome/renderer/pepper/pepper_flash_renderer_host.cc |
| @@ -4,13 +4,18 @@ |
| #include "chrome/renderer/pepper/pepper_flash_renderer_host.h" |
| +#include <map> |
| #include <vector> |
| +#include "base/lazy_instance.h" |
| +#include "base/metrics/histogram.h" |
| +#include "base/strings/string_util.h" |
| #include "chrome/renderer/pepper/ppb_pdf_impl.h" |
| #include "content/public/renderer/pepper_plugin_instance.h" |
| #include "content/public/renderer/render_thread.h" |
| #include "content/public/renderer/renderer_ppapi_host.h" |
| #include "ipc/ipc_message_macros.h" |
| +#include "net/http/http_util.h" |
| #include "ppapi/c/pp_errors.h" |
| #include "ppapi/c/trusted/ppb_browser_font_trusted.h" |
| #include "ppapi/host/dispatch_host_message.h" |
| @@ -33,6 +38,91 @@ |
| using ppapi::thunk::EnterResourceNoLock; |
| using ppapi::thunk::PPB_ImageData_API; |
| +namespace { |
| + |
| +// Some non-simple HTTP request headers that Flash may set. |
| +// (Please see http://www.w3.org/TR/cors/#simple-header for the definition of |
| +// simple headers.) |
| +// |
| +// The list and the enum defined below are used to collect data about request |
| +// headers used in PPB_Flash.Navigate() calls, in order to understand the impact |
| +// of rejecting PPB_Flash.Navigate() requests with non-simple headers. |
|
Alexei Svitkine (slow)
2014/01/30 20:23:31
Can you expand the comment to mention that new ent
yzshen1
2014/01/31 18:14:12
Done.
|
| +// |
| +// TODO(yzshen): We should be able to remove the histogram recording code once |
| +// we get the answer. |
| +const char* kRejectedHttpRequestHeaders[] = { |
| + "authorization", |
| + "cache-control", |
| + "content-encoding", |
| + "content-md5", |
| + "content-type", // If the media type is not one of those covered by the |
| + // simple header definition. |
| + "expires", |
| + "from", |
| + "if-match", |
| + "if-none-match", |
| + "if-range", |
| + "if-unmodified-since", |
| + "pragma", |
| + "referer" |
| +}; |
| + |
| +enum FlashNavigateUsage { |
| + // This section must be in the same order as kRejectedHttpRequestHeaders. |
| + REJECT_AUTHORIZATION = 0, |
| + REJECT_CACHE_CONTROL, |
| + REJECT_CONTENT_ENCODING, |
| + REJECT_CONTENT_MD5, |
| + REJECT_CONTENT_TYPE, |
| + REJECT_EXPIRES, |
| + REJECT_FROM, |
| + REJECT_IF_MATCH, |
| + REJECT_IF_NONE_MATCH, |
| + REJECT_IF_RANGE, |
| + REJECT_IF_UNMODIFIED_SINCE, |
| + REJECT_PRAGMA, |
| + REJECT_REFERER, |
| + |
| + // The navigate request is rejected because of headers not listed above |
| + // (e.g., custom headers). |
| + REJECT_OTHER_HEADERS, |
| + |
| + // Total number of rejected navigate requests. |
| + TOTAL_REJECTED_NAVIGATE_REQUESTS, |
| + |
| + // Total number of navigate requests. |
| + TOTAL_NAVIGATE_REQUESTS, |
| + |
| + FLASH_NAVIGATE_USAGE_ENUM_COUNT |
| +}; |
| + |
| +static base::LazyInstance<std::map<std::string, FlashNavigateUsage> > |
| + g_rejected_headers = LAZY_INSTANCE_INITIALIZER; |
| + |
| +bool IsSimpleHeader(const std::string& lower_case_header_name, |
| + const std::string& header_value) { |
| + if (lower_case_header_name == "accept" || |
| + lower_case_header_name == "accept-language" || |
| + lower_case_header_name == "content-language") { |
| + return true; |
| + } |
| + |
| + if (lower_case_header_name == "content-type") { |
| + std::string lower_case_mime_type; |
| + std::string lower_case_charset; |
| + bool had_charset = false; |
| + net::HttpUtil::ParseContentType(header_value, &lower_case_mime_type, |
| + &lower_case_charset, &had_charset, NULL); |
| + return lower_case_mime_type == "application/x-www-form-urlencoded" || |
| + lower_case_mime_type == "multipart/form-data" || |
| + lower_case_mime_type == "text/plain"; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +} // namespace |
| + |
| PepperFlashRendererHost::PepperFlashRendererHost( |
| content::RendererPpapiHost* host, |
| PP_Instance instance, |
| @@ -210,6 +300,42 @@ int32_t PepperFlashRendererHost::OnNavigate( |
| if (!plugin_instance) |
| return PP_ERROR_FAILED; |
| + std::map<std::string, FlashNavigateUsage>& rejected_headers = |
| + g_rejected_headers.Get(); |
| + if (rejected_headers.empty()) { |
| + for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i) |
| + rejected_headers[kRejectedHttpRequestHeaders[i]] = |
| + static_cast<FlashNavigateUsage>(i); |
| + } |
| + |
| + net::HttpUtil::HeadersIterator header_iter(data.headers.begin(), |
| + data.headers.end(), |
| + "\n\r"); |
| + bool rejected = false; |
| + while (header_iter.GetNext()) { |
| + std::string lower_case_header_name = StringToLowerASCII(header_iter.name()); |
| + if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) { |
| + rejected = true; |
| + |
| + std::map<std::string, FlashNavigateUsage>::const_iterator iter = |
| + rejected_headers.find(lower_case_header_name); |
| + FlashNavigateUsage usage = iter != rejected_headers.end() ? |
| + iter->second : REJECT_OTHER_HEADERS; |
| + UMA_HISTOGRAM_ENUMERATION("Plugin.FlashNavigateUsage", usage, |
|
Alexei Svitkine (slow)
2014/01/30 20:23:31
Can you make a helper function in the anon namespa
yzshen1
2014/01/31 18:14:12
Good point! Done.
|
| + FLASH_NAVIGATE_USAGE_ENUM_COUNT); |
| + } |
| + } |
| + |
| + UMA_HISTOGRAM_ENUMERATION("Plugin.FlashNavigateUsage", |
| + TOTAL_NAVIGATE_REQUESTS, |
| + FLASH_NAVIGATE_USAGE_ENUM_COUNT); |
| + if (rejected) { |
| + UMA_HISTOGRAM_ENUMERATION("Plugin.FlashNavigateUsage", |
| + TOTAL_REJECTED_NAVIGATE_REQUESTS, |
| + FLASH_NAVIGATE_USAGE_ENUM_COUNT); |
| + return PP_ERROR_NOACCESS; |
| + } |
| + |
| // Navigate may call into Javascript (e.g. with a "javascript:" URL), |
| // or do things like navigate away from the page, either one of which will |
| // need to re-enter into the plugin. It is safe, because it is essentially |