| 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 "content/renderer/npapi/webplugin_impl.h" | 5 #include "content/renderer/npapi/webplugin_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" |
| 8 #include "base/debug/crash_logging.h" | 9 #include "base/debug/crash_logging.h" |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/memory/linked_ptr.h" | 11 #include "base/memory/linked_ptr.h" |
| 11 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 12 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 13 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 15 #include "cc/layers/io_surface_layer.h" | 16 #include "cc/layers/io_surface_layer.h" |
| 16 #include "content/child/appcache/web_application_cache_host_impl.h" | 17 #include "content/child/appcache/web_application_cache_host_impl.h" |
| 17 #include "content/child/npapi/plugin_host.h" | 18 #include "content/child/npapi/plugin_host.h" |
| 18 #include "content/child/npapi/plugin_instance.h" | 19 #include "content/child/npapi/plugin_instance.h" |
| 19 #include "content/child/npapi/webplugin_delegate_impl.h" | 20 #include "content/child/npapi/webplugin_delegate_impl.h" |
| 20 #include "content/child/npapi/webplugin_resource_client.h" | 21 #include "content/child/npapi/webplugin_resource_client.h" |
| 21 #include "content/common/view_messages.h" | 22 #include "content/common/view_messages.h" |
| 22 #include "content/public/common/content_constants.h" | 23 #include "content/public/common/content_constants.h" |
| 24 #include "content/public/common/content_switches.h" |
| 23 #include "content/public/renderer/content_renderer_client.h" | 25 #include "content/public/renderer/content_renderer_client.h" |
| 24 #include "content/renderer/npapi/webplugin_delegate_proxy.h" | 26 #include "content/renderer/npapi/webplugin_delegate_proxy.h" |
| 25 #include "content/renderer/render_process.h" | 27 #include "content/renderer/render_process.h" |
| 26 #include "content/renderer/render_view_impl.h" | 28 #include "content/renderer/render_view_impl.h" |
| 27 #include "net/base/escape.h" | 29 #include "net/base/escape.h" |
| 28 #include "net/base/net_errors.h" | 30 #include "net/base/net_errors.h" |
| 29 #include "net/http/http_response_headers.h" | 31 #include "net/http/http_response_headers.h" |
| 30 #include "skia/ext/platform_canvas.h" | 32 #include "skia/ext/platform_canvas.h" |
| 31 #include "third_party/WebKit/public/platform/WebCString.h" | 33 #include "third_party/WebKit/public/platform/WebCString.h" |
| 32 #include "third_party/WebKit/public/platform/WebCookieJar.h" | 34 #include "third_party/WebKit/public/platform/WebCookieJar.h" |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 // Store the plugin's unique identifier, used by the container to track its | 251 // Store the plugin's unique identifier, used by the container to track its |
| 250 // script objects. | 252 // script objects. |
| 251 npp_ = plugin_delegate->GetPluginNPP(); | 253 npp_ = plugin_delegate->GetPluginNPP(); |
| 252 | 254 |
| 253 // Set the container before Initialize because the plugin may | 255 // Set the container before Initialize because the plugin may |
| 254 // synchronously call NPN_GetValue to get its container, or make calls | 256 // synchronously call NPN_GetValue to get its container, or make calls |
| 255 // passing script objects that need to be tracked, during initialization. | 257 // passing script objects that need to be tracked, during initialization. |
| 256 SetContainer(container); | 258 SetContainer(container); |
| 257 | 259 |
| 258 bool ok = plugin_delegate->Initialize( | 260 bool ok = plugin_delegate->Initialize( |
| 259 plugin_url_, arg_names_, arg_values_, this, load_manually_); | 261 plugin_url_, arg_names_, arg_values_, load_manually_); |
| 260 if (!ok) { | 262 if (!ok) { |
| 261 plugin_delegate->PluginDestroyed(); | 263 plugin_delegate->PluginDestroyed(); |
| 262 | 264 |
| 263 WebKit::WebPlugin* replacement_plugin = | 265 WebKit::WebPlugin* replacement_plugin = |
| 264 GetContentClient()->renderer()->CreatePluginReplacement( | 266 GetContentClient()->renderer()->CreatePluginReplacement( |
| 265 render_view_.get(), file_path_); | 267 render_view_.get(), file_path_); |
| 266 if (!replacement_plugin) | 268 if (!replacement_plugin) |
| 267 return false; | 269 return false; |
| 268 | 270 |
| 269 // Disable scripting by this plugin before replacing it with the new | 271 // Disable scripting by this plugin before replacing it with the new |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 WebHTTPBody http_body; | 619 WebHTTPBody http_body; |
| 618 if (body.size()) { | 620 if (body.size()) { |
| 619 http_body.initialize(); | 621 http_body.initialize(); |
| 620 http_body.appendData(WebData(&body[0], body.size())); | 622 http_body.appendData(WebData(&body[0], body.size())); |
| 621 } | 623 } |
| 622 request->setHTTPBody(http_body); | 624 request->setHTTPBody(http_body); |
| 623 | 625 |
| 624 return rv; | 626 return rv; |
| 625 } | 627 } |
| 626 | 628 |
| 627 WebPluginDelegate* WebPluginImpl::delegate() { | |
| 628 return delegate_; | |
| 629 } | |
| 630 | |
| 631 bool WebPluginImpl::IsValidUrl(const GURL& url, Referrer referrer_flag) { | 629 bool WebPluginImpl::IsValidUrl(const GURL& url, Referrer referrer_flag) { |
| 632 if (referrer_flag == PLUGIN_SRC && | 630 if (referrer_flag == PLUGIN_SRC && |
| 633 mime_type_ == kFlashPluginSwfMimeType && | 631 mime_type_ == kFlashPluginSwfMimeType && |
| 634 url.GetOrigin() != plugin_url_.GetOrigin()) { | 632 url.GetOrigin() != plugin_url_.GetOrigin()) { |
| 635 // Do url check to make sure that there are no @, ;, \ chars in between url | 633 // Do url check to make sure that there are no @, ;, \ chars in between url |
| 636 // scheme and url path. | 634 // scheme and url path. |
| 637 const char* url_to_check(url.spec().data()); | 635 const char* url_to_check(url.spec().data()); |
| 638 url_parse::Parsed parsed; | 636 url_parse::Parsed parsed; |
| 639 url_parse::ParseStandardURL(url_to_check, strlen(url_to_check), &parsed); | 637 url_parse::ParseStandardURL(url_to_check, strlen(url_to_check), &parsed); |
| 640 if (parsed.path.begin <= parsed.scheme.end()) | 638 if (parsed.path.begin <= parsed.scheme.end()) |
| 641 return true; | 639 return true; |
| 642 std::string string_to_search; | 640 std::string string_to_search; |
| 643 string_to_search.assign(url_to_check + parsed.scheme.end(), | 641 string_to_search.assign(url_to_check + parsed.scheme.end(), |
| 644 parsed.path.begin - parsed.scheme.end()); | 642 parsed.path.begin - parsed.scheme.end()); |
| 645 if (string_to_search.find("@") != std::string::npos || | 643 if (string_to_search.find("@") != std::string::npos || |
| 646 string_to_search.find(";") != std::string::npos || | 644 string_to_search.find(";") != std::string::npos || |
| 647 string_to_search.find("\\") != std::string::npos) | 645 string_to_search.find("\\") != std::string::npos) |
| 648 return false; | 646 return false; |
| 649 } | 647 } |
| 650 | 648 |
| 651 return true; | 649 return true; |
| 652 } | 650 } |
| 653 | 651 |
| 654 WebPluginDelegate* WebPluginImpl::CreatePluginDelegate() { | 652 WebPluginDelegate* WebPluginImpl::CreatePluginDelegate() { |
| 655 bool in_process_plugin = RenderProcess::current()->UseInProcessPlugins(); | 653 bool in_process_plugin = RenderProcess::current()->UseInProcessPlugins(); |
| 656 if (in_process_plugin) { | 654 if (in_process_plugin) { |
| 657 #if defined(OS_WIN) && !defined(USE_AURA) | 655 #if defined(OS_WIN) && !defined(USE_AURA) |
| 658 return WebPluginDelegateImpl::Create(file_path_, mime_type_); | 656 return WebPluginDelegateImpl::Create(this, file_path_, mime_type_); |
| 659 #else | 657 #else |
| 660 // In-proc plugins aren't supported on non-Windows. | 658 // In-proc plugins aren't supported on non-Windows. |
| 661 NOTIMPLEMENTED(); | 659 NOTIMPLEMENTED(); |
| 662 return NULL; | 660 return NULL; |
| 663 #endif | 661 #endif |
| 664 } | 662 } |
| 665 | 663 |
| 666 return new WebPluginDelegateProxy(mime_type_, render_view_); | 664 return new WebPluginDelegateProxy(this, mime_type_, render_view_); |
| 667 } | 665 } |
| 668 | 666 |
| 669 WebPluginImpl::RoutingStatus WebPluginImpl::RouteToFrame( | 667 WebPluginImpl::RoutingStatus WebPluginImpl::RouteToFrame( |
| 670 const char* url, | 668 const char* url, |
| 671 bool is_javascript_url, | 669 bool is_javascript_url, |
| 672 bool popups_allowed, | 670 bool popups_allowed, |
| 673 const char* method, | 671 const char* method, |
| 674 const char* target, | 672 const char* target, |
| 675 const char* buf, | 673 const char* buf, |
| 676 unsigned int len, | 674 unsigned int len, |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 clients_[i].loader->cancel(); | 796 clients_[i].loader->cancel(); |
| 799 if (clients_[i].client) | 797 if (clients_[i].client) |
| 800 clients_[i].client->DidFail(clients_[i].id); | 798 clients_[i].client->DidFail(clients_[i].id); |
| 801 } | 799 } |
| 802 } | 800 } |
| 803 break; | 801 break; |
| 804 } | 802 } |
| 805 } | 803 } |
| 806 } | 804 } |
| 807 | 805 |
| 806 bool WebPluginImpl::CheckIfRunInsecureContent(const GURL& url) { |
| 807 if (!webframe_) |
| 808 return true; |
| 809 |
| 810 return webframe_->checkIfRunInsecureContent(url); |
| 811 } |
| 812 |
| 808 #if defined(OS_MACOSX) | 813 #if defined(OS_MACOSX) |
| 809 WebPluginAcceleratedSurface* WebPluginImpl::GetAcceleratedSurface( | 814 WebPluginAcceleratedSurface* WebPluginImpl::GetAcceleratedSurface( |
| 810 gfx::GpuPreference gpu_preference) { | 815 gfx::GpuPreference gpu_preference) { |
| 811 return NULL; | 816 return NULL; |
| 812 } | 817 } |
| 813 | 818 |
| 814 void WebPluginImpl::AcceleratedPluginEnabledRendering() { | 819 void WebPluginImpl::AcceleratedPluginEnabledRendering() { |
| 815 } | 820 } |
| 816 | 821 |
| 817 void WebPluginImpl::AcceleratedPluginAllocatedIOSurface(int32 width, | 822 void WebPluginImpl::AcceleratedPluginAllocatedIOSurface(int32 width, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 return &clients_[i]; | 892 return &clients_[i]; |
| 888 } | 893 } |
| 889 | 894 |
| 890 NOTREACHED(); | 895 NOTREACHED(); |
| 891 return 0; | 896 return 0; |
| 892 } | 897 } |
| 893 | 898 |
| 894 void WebPluginImpl::willSendRequest(WebURLLoader* loader, | 899 void WebPluginImpl::willSendRequest(WebURLLoader* loader, |
| 895 WebURLRequest& request, | 900 WebURLRequest& request, |
| 896 const WebURLResponse& response) { | 901 const WebURLResponse& response) { |
| 902 // TODO(jam): THIS LOGIC IS COPIED IN PluginURLFetcher::OnReceivedRedirect |
| 903 // until kDirectNPAPIRequests is the default and we can remove this old path. |
| 897 WebPluginImpl::ClientInfo* client_info = GetClientInfoFromLoader(loader); | 904 WebPluginImpl::ClientInfo* client_info = GetClientInfoFromLoader(loader); |
| 898 if (client_info) { | 905 if (client_info) { |
| 899 // Currently this check is just to catch an https -> http redirect when | 906 // Currently this check is just to catch an https -> http redirect when |
| 900 // loading the main plugin src URL. Longer term, we could investigate | 907 // loading the main plugin src URL. Longer term, we could investigate |
| 901 // firing mixed diplay or scripting issues for subresource loads | 908 // firing mixed diplay or scripting issues for subresource loads |
| 902 // initiated by plug-ins. | 909 // initiated by plug-ins. |
| 903 if (client_info->is_plugin_src_load && | 910 if (client_info->is_plugin_src_load && |
| 904 webframe_ && | 911 webframe_ && |
| 905 !webframe_->checkIfRunInsecureContent(request.url())) { | 912 !webframe_->checkIfRunInsecureContent(request.url())) { |
| 906 loader->cancel(); | 913 loader->cancel(); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 | 1183 |
| 1177 unsigned long resource_id = GetNextResourceId(); | 1184 unsigned long resource_id = GetNextResourceId(); |
| 1178 if (!resource_id) | 1185 if (!resource_id) |
| 1179 return; | 1186 return; |
| 1180 | 1187 |
| 1181 GURL complete_url = CompleteURL(url); | 1188 GURL complete_url = CompleteURL(url); |
| 1182 // Remove when flash bug is fixed. http://crbug.com/40016. | 1189 // Remove when flash bug is fixed. http://crbug.com/40016. |
| 1183 if (!WebPluginImpl::IsValidUrl(complete_url, referrer_flag)) | 1190 if (!WebPluginImpl::IsValidUrl(complete_url, referrer_flag)) |
| 1184 return; | 1191 return; |
| 1185 | 1192 |
| 1186 WebPluginResourceClient* resource_client = delegate_->CreateResourceClient( | |
| 1187 resource_id, complete_url, notify_id); | |
| 1188 if (!resource_client) | |
| 1189 return; | |
| 1190 | |
| 1191 // If the RouteToFrame call returned a failure then inform the result | 1193 // If the RouteToFrame call returned a failure then inform the result |
| 1192 // back to the plugin asynchronously. | 1194 // back to the plugin asynchronously. |
| 1193 if ((routing_status == INVALID_URL) || | 1195 if ((routing_status == INVALID_URL) || |
| 1194 (routing_status == GENERAL_FAILURE)) { | 1196 (routing_status == GENERAL_FAILURE)) { |
| 1195 resource_client->DidFail(resource_id); | 1197 WebPluginResourceClient* resource_client = delegate_->CreateResourceClient( |
| 1198 resource_id, complete_url, notify_id); |
| 1199 if (resource_client) |
| 1200 resource_client->DidFail(resource_id); |
| 1196 return; | 1201 return; |
| 1197 } | 1202 } |
| 1198 | 1203 |
| 1199 // CreateResourceClient() sends a synchronous IPC message so it's possible | 1204 // CreateResourceClient() sends a synchronous IPC message so it's possible |
| 1200 // that TearDownPluginInstance() may have been called in the nested | 1205 // that TearDownPluginInstance() may have been called in the nested |
| 1201 // message loop. If so, don't start the request. | 1206 // message loop. If so, don't start the request. |
| 1202 if (!delegate_) | 1207 if (!delegate_) |
| 1203 return; | 1208 return; |
| 1204 | 1209 |
| 1205 InitiateHTTPRequest(resource_id, resource_client, complete_url, method, buf, | 1210 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 1206 len, NULL, referrer_flag, notify_redirects, | 1211 switches::kDirectNPAPIRequests)) { |
| 1207 is_plugin_src_load); | 1212 // We got here either because the plugin called GetURL/PostURL, or because |
| 1213 // we're fetching the data for an embed tag. If we're in multi-process mode, |
| 1214 // we want to fetch the data in the plugin process as the renderer won't be |
| 1215 // able to request any origin when site isolation is in place. So bounce |
| 1216 // this request back to the plugin process which will use ResourceDispatcher |
| 1217 // to fetch the url. |
| 1218 |
| 1219 // TODO(jam): any better way of getting this? Can't find a way to get |
| 1220 // frame()->loader()->outgoingReferrer() which |
| 1221 // WebFrameImpl::setReferrerForRequest does. |
| 1222 WebURLRequest request(complete_url); |
| 1223 SetReferrer(&request, referrer_flag); |
| 1224 GURL referrer( |
| 1225 request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); |
| 1226 |
| 1227 GURL first_party_for_cookies = webframe_->document().firstPartyForCookies(); |
| 1228 delegate_->FetchURL(resource_id, notify_id, complete_url, |
| 1229 first_party_for_cookies, method, std::string(buf, len), |
| 1230 referrer, notify_redirects, is_plugin_src_load, 0, |
| 1231 render_view_->routing_id()); |
| 1232 } else { |
| 1233 WebPluginResourceClient* resource_client = delegate_->CreateResourceClient( |
| 1234 resource_id, complete_url, notify_id); |
| 1235 if (!resource_client) |
| 1236 return; |
| 1237 InitiateHTTPRequest(resource_id, resource_client, complete_url, method, buf, |
| 1238 len, NULL, referrer_flag, notify_redirects, |
| 1239 is_plugin_src_load); |
| 1240 } |
| 1208 } | 1241 } |
| 1209 | 1242 |
| 1210 unsigned long WebPluginImpl::GetNextResourceId() { | 1243 unsigned long WebPluginImpl::GetNextResourceId() { |
| 1211 if (!webframe_) | 1244 if (!webframe_) |
| 1212 return 0; | 1245 return 0; |
| 1213 WebView* view = webframe_->view(); | 1246 WebView* view = webframe_->view(); |
| 1214 if (!view) | 1247 if (!view) |
| 1215 return 0; | 1248 return 0; |
| 1216 return view->createUniqueIdentifierForRequest(); | 1249 return view->createUniqueIdentifierForRequest(); |
| 1217 } | 1250 } |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 | 1407 |
| 1375 WebPluginDelegate* plugin_delegate = CreatePluginDelegate(); | 1408 WebPluginDelegate* plugin_delegate = CreatePluginDelegate(); |
| 1376 | 1409 |
| 1377 // Store the plugin's unique identifier, used by the container to track its | 1410 // Store the plugin's unique identifier, used by the container to track its |
| 1378 // script objects, and enable script objects (since Initialize may use them | 1411 // script objects, and enable script objects (since Initialize may use them |
| 1379 // even if it fails). | 1412 // even if it fails). |
| 1380 npp_ = plugin_delegate->GetPluginNPP(); | 1413 npp_ = plugin_delegate->GetPluginNPP(); |
| 1381 container_->allowScriptObjects(); | 1414 container_->allowScriptObjects(); |
| 1382 | 1415 |
| 1383 bool ok = plugin_delegate && plugin_delegate->Initialize( | 1416 bool ok = plugin_delegate && plugin_delegate->Initialize( |
| 1384 plugin_url_, arg_names_, arg_values_, this, load_manually_); | 1417 plugin_url_, arg_names_, arg_values_, load_manually_); |
| 1385 | 1418 |
| 1386 if (!ok) { | 1419 if (!ok) { |
| 1387 container_->clearScriptObjects(); | 1420 container_->clearScriptObjects(); |
| 1388 container_ = NULL; | 1421 container_ = NULL; |
| 1389 // TODO(iyengar) Should we delete the current plugin instance here? | 1422 // TODO(iyengar) Should we delete the current plugin instance here? |
| 1390 return false; | 1423 return false; |
| 1391 } | 1424 } |
| 1392 | 1425 |
| 1393 delegate_ = plugin_delegate; | 1426 delegate_ = plugin_delegate; |
| 1394 | 1427 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1466 case PLUGIN_SRC: | 1499 case PLUGIN_SRC: |
| 1467 webframe_->setReferrerForRequest(*request, plugin_url_); | 1500 webframe_->setReferrerForRequest(*request, plugin_url_); |
| 1468 break; | 1501 break; |
| 1469 | 1502 |
| 1470 default: | 1503 default: |
| 1471 break; | 1504 break; |
| 1472 } | 1505 } |
| 1473 } | 1506 } |
| 1474 | 1507 |
| 1475 } // namespace content | 1508 } // namespace content |
| OLD | NEW |