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/command_line.h" |
9 #include "base/debug/crash_logging.h" | 9 #include "base/debug/crash_logging.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 } | 355 } |
356 | 356 |
357 // Only UpdateGeometry if either the window or clip rects have changed. | 357 // Only UpdateGeometry if either the window or clip rects have changed. |
358 if (delegate_ && (first_geometry_update_ || | 358 if (delegate_ && (first_geometry_update_ || |
359 new_geometry.window_rect != geometry_.window_rect || | 359 new_geometry.window_rect != geometry_.window_rect || |
360 new_geometry.clip_rect != geometry_.clip_rect)) { | 360 new_geometry.clip_rect != geometry_.clip_rect)) { |
361 // Notify the plugin that its parameters have changed. | 361 // Notify the plugin that its parameters have changed. |
362 delegate_->UpdateGeometry(new_geometry.window_rect, new_geometry.clip_rect); | 362 delegate_->UpdateGeometry(new_geometry.window_rect, new_geometry.clip_rect); |
363 } | 363 } |
364 | 364 |
365 // Initiate a download on the plugin url. This should be done for the | |
366 // first update geometry sequence. We need to ensure that the plugin | |
367 // receives the geometry update before it starts receiving data. | |
368 if (first_geometry_update_) { | |
369 // An empty url corresponds to an EMBED tag with no src attribute. | |
370 if (!load_manually_ && plugin_url_.is_valid()) { | |
371 // The Flash plugin hangs for a while if it receives data before | |
372 // receiving valid plugin geometry. By valid geometry we mean the | |
373 // geometry received by a call to setFrameRect in the Webkit | |
374 // layout code path. To workaround this issue we download the | |
375 // plugin source url on a timer. | |
376 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
377 FROM_HERE, base::Bind(&WebPluginImpl::OnDownloadPluginSrcUrl, | |
378 weak_factory_.GetWeakPtr())); | |
379 } | |
380 } | |
381 | |
382 #if defined(OS_WIN) | 365 #if defined(OS_WIN) |
383 // Don't cache the geometry during the first geometry update. The first | 366 // Don't cache the geometry during the first geometry update. The first |
384 // geometry update sequence is received when Widget::setParent is called. | 367 // geometry update sequence is received when Widget::setParent is called. |
385 // For plugins like media player which have a bug where they only honor | 368 // For plugins like media player which have a bug where they only honor |
386 // the first geometry update, we have a quirk which ignores the first | 369 // the first geometry update, we have a quirk which ignores the first |
387 // geometry update. To ensure that these plugins work correctly in cases | 370 // geometry update. To ensure that these plugins work correctly in cases |
388 // where we receive only one geometry update from webkit, we also force | 371 // where we receive only one geometry update from webkit, we also force |
389 // a geometry update during paint which should go out correctly as the | 372 // a geometry update during paint which should go out correctly as the |
390 // initial geometry update was not cached. | 373 // initial geometry update was not cached. |
391 if (!first_geometry_update_) | 374 if (!first_geometry_update_) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 cursor_info.hotSpot = web_cursor_info.hotspot; | 415 cursor_info.hotSpot = web_cursor_info.hotspot; |
433 cursor_info.customImage = web_cursor_info.custom_image; | 416 cursor_info.customImage = web_cursor_info.custom_image; |
434 cursor_info.imageScaleFactor = web_cursor_info.image_scale_factor; | 417 cursor_info.imageScaleFactor = web_cursor_info.image_scale_factor; |
435 #if defined(OS_WIN) | 418 #if defined(OS_WIN) |
436 cursor_info.externalHandle = web_cursor_info.external_handle; | 419 cursor_info.externalHandle = web_cursor_info.external_handle; |
437 #endif | 420 #endif |
438 return ret ? WebInputEventResult::HandledApplication | 421 return ret ? WebInputEventResult::HandledApplication |
439 : WebInputEventResult::NotHandled; | 422 : WebInputEventResult::NotHandled; |
440 } | 423 } |
441 | 424 |
442 void WebPluginImpl::didReceiveResponse(const WebURLResponse& response) { | |
443 ignore_response_error_ = false; | |
444 | |
445 ResponseInfo response_info; | |
446 GetResponseInfo(response, &response_info); | |
447 | |
448 delegate_->DidReceiveManualResponse( | |
449 response_info.url, | |
450 response_info.mime_type, | |
451 GetAllHeaders(response), | |
452 response_info.expected_length, | |
453 response_info.last_modified); | |
454 } | |
455 | |
456 void WebPluginImpl::didReceiveData(const char* data, int data_length) { | |
457 delegate_->DidReceiveManualData(data, data_length); | |
458 } | |
459 | |
460 void WebPluginImpl::didFinishLoading() { | |
461 delegate_->DidFinishManualLoading(); | |
462 } | |
463 | |
464 void WebPluginImpl::didFailLoading(const WebURLError& error) { | |
465 if (!ignore_response_error_) | |
466 delegate_->DidManualLoadFail(); | |
467 } | |
468 | |
469 void WebPluginImpl::didFinishLoadingFrameRequest( | |
470 const WebURL& url, void* notify_data) { | |
471 if (delegate_) { | |
472 // We're converting a void* into an arbitrary int id. Though | |
473 // these types are the same size on all the platforms we support, | |
474 // the compiler may complain as though they are different, so to | |
475 // make the casting gods happy go through an intptr_t (the union | |
476 // of void* and int) rather than converting straight across. | |
477 delegate_->DidFinishLoadWithReason( | |
478 url, NPRES_DONE, reinterpret_cast<intptr_t>(notify_data)); | |
479 } | |
480 } | |
481 | |
482 void WebPluginImpl::didFailLoadingFrameRequest( | |
483 const WebURL& url, void* notify_data, const WebURLError& error) { | |
484 if (!delegate_) | |
485 return; | |
486 | |
487 NPReason reason = | |
488 error.reason == net::ERR_ABORTED ? NPRES_USER_BREAK : NPRES_NETWORK_ERR; | |
489 // See comment in didFinishLoadingFrameRequest about the cast here. | |
490 delegate_->DidFinishLoadWithReason( | |
491 url, reason, reinterpret_cast<intptr_t>(notify_data)); | |
492 } | |
493 | |
494 bool WebPluginImpl::isPlaceholder() { | 425 bool WebPluginImpl::isPlaceholder() { |
495 return false; | 426 return false; |
496 } | 427 } |
497 | 428 |
498 WebPluginImpl::LoaderClient::LoaderClient(WebPluginImpl* parent) | 429 WebPluginImpl::LoaderClient::LoaderClient(WebPluginImpl* parent) |
499 : parent_(parent) {} | 430 : parent_(parent) {} |
500 | 431 |
501 void WebPluginImpl::LoaderClient::willFollowRedirect( | 432 void WebPluginImpl::LoaderClient::willFollowRedirect( |
502 blink::WebURLLoader* loader, blink::WebURLRequest& new_request, | 433 blink::WebURLLoader* loader, blink::WebURLRequest& new_request, |
503 const blink::WebURLResponse& redirect_response) { | 434 const blink::WebURLResponse& redirect_response) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 delegate_(NULL), | 488 delegate_(NULL), |
558 container_(NULL), | 489 container_(NULL), |
559 npp_(NULL), | 490 npp_(NULL), |
560 plugin_url_(params.url), | 491 plugin_url_(params.url), |
561 load_manually_(params.loadManually), | 492 load_manually_(params.loadManually), |
562 first_geometry_update_(true), | 493 first_geometry_update_(true), |
563 ignore_response_error_(false), | 494 ignore_response_error_(false), |
564 file_path_(file_path), | 495 file_path_(file_path), |
565 mime_type_(base::ToLowerASCII(base::UTF16ToASCII( | 496 mime_type_(base::ToLowerASCII(base::UTF16ToASCII( |
566 base::StringPiece16(params.mimeType)))), | 497 base::StringPiece16(params.mimeType)))), |
567 loader_client_(this), | 498 loader_client_(this) { |
568 weak_factory_(this) { | |
569 DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); | 499 DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); |
570 | 500 |
571 for (size_t i = 0; i < params.attributeNames.size(); ++i) { | 501 for (size_t i = 0; i < params.attributeNames.size(); ++i) { |
572 arg_names_.push_back(params.attributeNames[i].utf8()); | 502 arg_names_.push_back(params.attributeNames[i].utf8()); |
573 arg_values_.push_back(params.attributeValues[i].utf8()); | 503 arg_values_.push_back(params.attributeValues[i].utf8()); |
574 } | 504 } |
575 | 505 |
576 // Set subresource URL for crash reporting. | 506 // Set subresource URL for crash reporting. |
577 base::debug::SetCrashKeyValue("subresource_url", plugin_url_.spec()); | 507 base::debug::SetCrashKeyValue("subresource_url", plugin_url_.spec()); |
578 } | 508 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 } | 623 } |
694 | 624 |
695 WebPluginImpl::RoutingStatus WebPluginImpl::RouteToFrame( | 625 WebPluginImpl::RoutingStatus WebPluginImpl::RouteToFrame( |
696 const char* url, | 626 const char* url, |
697 bool is_javascript_url, | 627 bool is_javascript_url, |
698 bool popups_allowed, | 628 bool popups_allowed, |
699 const char* method, | 629 const char* method, |
700 const char* target, | 630 const char* target, |
701 const char* buf, | 631 const char* buf, |
702 unsigned int len, | 632 unsigned int len, |
703 int notify_id, | |
704 ReferrerValue referrer_flag) { | 633 ReferrerValue referrer_flag) { |
705 // If there is no target, there is nothing to do | 634 // If there is no target, there is nothing to do |
706 if (!target) | 635 if (!target) |
707 return NOT_ROUTED; | 636 return NOT_ROUTED; |
708 | 637 |
709 // This could happen if the WebPluginContainer was already deleted. | 638 // This could happen if the WebPluginContainer was already deleted. |
710 if (!webframe_) | 639 if (!webframe_) |
711 return NOT_ROUTED; | 640 return NOT_ROUTED; |
712 | 641 |
713 WebString target_str = WebString::fromUTF8(target); | 642 WebString target_str = WebString::fromUTF8(target); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 request.setSkipServiceWorker(true); | 686 request.setSkipServiceWorker(true); |
758 if (len > 0) { | 687 if (len > 0) { |
759 if (!SetPostData(&request, buf, len)) { | 688 if (!SetPostData(&request, buf, len)) { |
760 // Uhoh - we're in trouble. There isn't a good way | 689 // Uhoh - we're in trouble. There isn't a good way |
761 // to recover at this point. Break out. | 690 // to recover at this point. Break out. |
762 NOTREACHED(); | 691 NOTREACHED(); |
763 return ROUTED; | 692 return ROUTED; |
764 } | 693 } |
765 } | 694 } |
766 | 695 |
767 container_->loadFrameRequest( | 696 container_->loadFrameRequest(request, target_str); |
768 request, target_str, notify_id != 0, reinterpret_cast<void*>(notify_id)); | |
769 return ROUTED; | 697 return ROUTED; |
770 } | 698 } |
771 | 699 |
772 NPObject* WebPluginImpl::GetWindowScriptNPObject() { | 700 NPObject* WebPluginImpl::GetWindowScriptNPObject() { |
773 if (!webframe_) { | 701 if (!webframe_) { |
774 NOTREACHED(); | 702 NOTREACHED(); |
775 return NULL; | 703 return NULL; |
776 } | 704 } |
777 return webframe_->windowObject(); | 705 return webframe_->windowObject(); |
778 } | 706 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 void WebPluginImpl::Invalidate() { | 824 void WebPluginImpl::Invalidate() { |
897 if (container_) | 825 if (container_) |
898 container_->invalidate(); | 826 container_->invalidate(); |
899 } | 827 } |
900 | 828 |
901 void WebPluginImpl::InvalidateRect(const gfx::Rect& rect) { | 829 void WebPluginImpl::InvalidateRect(const gfx::Rect& rect) { |
902 if (container_) | 830 if (container_) |
903 container_->invalidateRect(rect); | 831 container_->invalidateRect(rect); |
904 } | 832 } |
905 | 833 |
906 void WebPluginImpl::OnDownloadPluginSrcUrl() { | |
907 HandleURLRequestInternal( | |
908 plugin_url_.spec().c_str(), "GET", NULL, NULL, 0, 0, false, DOCUMENT_URL, | |
909 false, true); | |
910 } | |
911 | |
912 WebPluginResourceClient* WebPluginImpl::GetClientFromLoader( | 834 WebPluginResourceClient* WebPluginImpl::GetClientFromLoader( |
913 WebURLLoader* loader) { | 835 WebURLLoader* loader) { |
914 ClientInfo* client_info = GetClientInfoFromLoader(loader); | 836 ClientInfo* client_info = GetClientInfoFromLoader(loader); |
915 if (client_info) | 837 if (client_info) |
916 return client_info->client; | 838 return client_info->client; |
917 return NULL; | 839 return NULL; |
918 } | 840 } |
919 | 841 |
920 WebPluginImpl::ClientInfo* WebPluginImpl::GetClientInfoFromLoader( | 842 WebPluginImpl::ClientInfo* WebPluginImpl::GetClientInfoFromLoader( |
921 WebURLLoader* loader) { | 843 WebURLLoader* loader) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 | 896 |
975 void WebPluginImpl::didSendData(WebURLLoader* loader, | 897 void WebPluginImpl::didSendData(WebURLLoader* loader, |
976 unsigned long long bytes_sent, | 898 unsigned long long bytes_sent, |
977 unsigned long long total_bytes_to_be_sent) { | 899 unsigned long long total_bytes_to_be_sent) { |
978 } | 900 } |
979 | 901 |
980 void WebPluginImpl::didReceiveResponse(WebURLLoader* loader, | 902 void WebPluginImpl::didReceiveResponse(WebURLLoader* loader, |
981 const WebURLResponse& response) { | 903 const WebURLResponse& response) { |
982 // TODO(jam): THIS LOGIC IS COPIED IN PluginURLFetcher::OnReceivedResponse | 904 // TODO(jam): THIS LOGIC IS COPIED IN PluginURLFetcher::OnReceivedResponse |
983 // until kDirectNPAPIRequests is the default and we can remove this old path. | 905 // until kDirectNPAPIRequests is the default and we can remove this old path. |
984 static const int kHttpPartialResponseStatusCode = 206; | |
985 static const int kHttpResponseSuccessStatusCode = 200; | |
986 | 906 |
987 WebPluginResourceClient* client = GetClientFromLoader(loader); | 907 WebPluginResourceClient* client = GetClientFromLoader(loader); |
988 if (!client) | 908 if (!client) |
989 return; | 909 return; |
990 | 910 |
991 ResponseInfo response_info; | 911 ResponseInfo response_info; |
992 GetResponseInfo(response, &response_info); | 912 GetResponseInfo(response, &response_info); |
993 ClientInfo* client_info = GetClientInfoFromLoader(loader); | 913 ClientInfo* client_info = GetClientInfoFromLoader(loader); |
994 if (!client_info) | 914 if (!client_info) |
995 return; | 915 return; |
996 | 916 |
997 bool request_is_seekable = true; | |
998 if (client->IsMultiByteResponseExpected()) { | |
999 if (response.httpStatusCode() == kHttpPartialResponseStatusCode) { | |
1000 ClientInfo* client_info = GetClientInfoFromLoader(loader); | |
1001 if (!client_info) | |
1002 return; | |
1003 if (HandleHttpMultipartResponse(response, client)) { | |
1004 // Multiple ranges requested, data will be delivered by | |
1005 // MultipartResponseDelegate. | |
1006 client_info->data_offset = 0; | |
1007 return; | |
1008 } | |
1009 int64 upper_bound = 0, instance_size = 0; | |
1010 // Single range requested - go through original processing for | |
1011 // non-multipart requests, but update data offset. | |
1012 MultipartResponseDelegate::ReadContentRanges(response, | |
1013 &client_info->data_offset, | |
1014 &upper_bound, | |
1015 &instance_size); | |
1016 } else if (response.httpStatusCode() == kHttpResponseSuccessStatusCode) { | |
1017 RenderThreadImpl::current()->RecordAction( | |
1018 base::UserMetricsAction("Plugin_200ForByteRange")); | |
1019 // If the client issued a byte range request and the server responds with | |
1020 // HTTP 200 OK, it indicates that the server does not support byte range | |
1021 // requests. | |
1022 // We need to emulate Firefox behavior by doing the following:- | |
1023 // 1. Destroy the plugin instance in the plugin process. Ensure that | |
1024 // existing resource requests initiated for the plugin instance | |
1025 // continue to remain valid. | |
1026 // 2. Create a new plugin instance and notify it about the response | |
1027 // received here. | |
1028 if (!ReinitializePluginForResponse(loader)) { | |
1029 NOTREACHED(); | |
1030 return; | |
1031 } | |
1032 | |
1033 // The server does not support byte range requests. No point in creating | |
1034 // seekable streams. | |
1035 request_is_seekable = false; | |
1036 | |
1037 delete client; | |
1038 client = NULL; | |
1039 | |
1040 // Create a new resource client for this request. | |
1041 for (size_t i = 0; i < clients_.size(); ++i) { | |
1042 if (clients_[i].loader.get() == loader) { | |
1043 WebPluginResourceClient* resource_client = | |
1044 delegate_->CreateResourceClient(clients_[i].id, plugin_url_, 0); | |
1045 clients_[i].client = resource_client; | |
1046 client = resource_client; | |
1047 break; | |
1048 } | |
1049 } | |
1050 | |
1051 DCHECK(client != NULL); | |
1052 } | |
1053 } | |
1054 | |
1055 // Calling into a plugin could result in reentrancy if the plugin yields | 917 // Calling into a plugin could result in reentrancy if the plugin yields |
1056 // control to the OS like entering a modal loop etc. Prevent this by | 918 // control to the OS like entering a modal loop etc. Prevent this by |
1057 // stopping further loading until the plugin notifies us that it is ready to | 919 // stopping further loading until the plugin notifies us that it is ready to |
1058 // accept data | 920 // accept data |
1059 loader->setDefersLoading(true); | 921 loader->setDefersLoading(true); |
1060 | 922 |
1061 client->DidReceiveResponse( | 923 client->DidReceiveResponse( |
1062 response_info.mime_type, | 924 response_info.mime_type, |
1063 GetAllHeaders(response), | 925 GetAllHeaders(response), |
1064 response_info.expected_length, | 926 response_info.expected_length, |
1065 response_info.last_modified, | 927 response_info.last_modified, |
1066 request_is_seekable); | 928 true); |
1067 | 929 |
1068 // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP | 930 // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP |
1069 // error codes in the stream header and as a result, was unaware of the | 931 // error codes in the stream header and as a result, was unaware of the |
1070 // fate of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF | 932 // fate of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF |
1071 // destroy the stream and invoke the NPP_DestroyStream function on the | 933 // destroy the stream and invoke the NPP_DestroyStream function on the |
1072 // plugin if the HTTP request fails. | 934 // plugin if the HTTP request fails. |
1073 const GURL& url = response.url(); | 935 const GURL& url = response.url(); |
1074 if (url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme)) { | 936 if (url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme)) { |
1075 if (response.httpStatusCode() < 100 || response.httpStatusCode() >= 400) { | 937 if (response.httpStatusCode() < 100 || response.httpStatusCode() >= 400) { |
1076 // The plugin instance could be in the process of deletion here. | 938 // The plugin instance could be in the process of deletion here. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 } | 1016 } |
1155 | 1017 |
1156 void WebPluginImpl::SetContainer(WebPluginContainer* container) { | 1018 void WebPluginImpl::SetContainer(WebPluginContainer* container) { |
1157 if (!container) | 1019 if (!container) |
1158 TearDownPluginInstance(NULL); | 1020 TearDownPluginInstance(NULL); |
1159 container_ = container; | 1021 container_ = container; |
1160 if (container_) | 1022 if (container_) |
1161 container_->allowScriptObjects(); | 1023 container_->allowScriptObjects(); |
1162 } | 1024 } |
1163 | 1025 |
1164 void WebPluginImpl::HandleURLRequest(const char* url, | |
1165 const char* method, | |
1166 const char* target, | |
1167 const char* buf, | |
1168 unsigned int len, | |
1169 int notify_id, | |
1170 bool popups_allowed, | |
1171 bool notify_redirects) { | |
1172 // GetURL/PostURL requests initiated explicitly by plugins should specify the | |
1173 // plugin SRC url as the referrer if it is available. | |
1174 HandleURLRequestInternal( | |
1175 url, method, target, buf, len, notify_id, popups_allowed, PLUGIN_SRC, | |
1176 notify_redirects, false); | |
1177 } | |
1178 | |
1179 void WebPluginImpl::HandleURLRequestInternal(const char* url, | |
1180 const char* method, | |
1181 const char* target, | |
1182 const char* buf, | |
1183 unsigned int len, | |
1184 int notify_id, | |
1185 bool popups_allowed, | |
1186 ReferrerValue referrer_flag, | |
1187 bool notify_redirects, | |
1188 bool is_plugin_src_load) { | |
1189 // For this request, we either route the output to a frame | |
1190 // because a target has been specified, or we handle the request | |
1191 // here, i.e. by executing the script if it is a javascript url | |
1192 // or by initiating a download on the URL, etc. There is one special | |
1193 // case in that the request is a javascript url and the target is "_self", | |
1194 // in which case we route the output to the plugin rather than routing it | |
1195 // to the plugin's frame. | |
1196 bool is_javascript_url = | |
1197 url::FindAndCompareScheme(url, strlen(url), url::kJavaScriptScheme, NULL); | |
1198 RoutingStatus routing_status = RouteToFrame( | |
1199 url, is_javascript_url, popups_allowed, method, target, buf, len, | |
1200 notify_id, referrer_flag); | |
1201 if (routing_status == ROUTED) | |
1202 return; | |
1203 | |
1204 if (is_javascript_url) { | |
1205 GURL gurl(url); | |
1206 WebString result = container_->executeScriptURL(gurl, popups_allowed); | |
1207 | |
1208 // delegate_ could be NULL because executeScript caused the container to | |
1209 // be deleted. | |
1210 if (delegate_) { | |
1211 delegate_->SendJavaScriptStream( | |
1212 gurl, result.utf8(), !result.isNull(), notify_id); | |
1213 } | |
1214 | |
1215 return; | |
1216 } | |
1217 | |
1218 unsigned long resource_id = GetNextResourceId(); | |
1219 if (!resource_id) | |
1220 return; | |
1221 | |
1222 GURL complete_url = CompleteURL(url); | |
1223 // Remove when flash bug is fixed. http://crbug.com/40016. | |
1224 if (!WebPluginImpl::IsValidUrl(complete_url, referrer_flag)) | |
1225 return; | |
1226 | |
1227 // If the RouteToFrame call returned a failure then inform the result | |
1228 // back to the plugin asynchronously. | |
1229 if ((routing_status == INVALID_URL) || | |
1230 (routing_status == GENERAL_FAILURE)) { | |
1231 WebPluginResourceClient* resource_client = delegate_->CreateResourceClient( | |
1232 resource_id, complete_url, notify_id); | |
1233 if (resource_client) | |
1234 resource_client->DidFail(resource_id); | |
1235 return; | |
1236 } | |
1237 | |
1238 // CreateResourceClient() sends a synchronous IPC message so it's possible | |
1239 // that TearDownPluginInstance() may have been called in the nested | |
1240 // message loop. If so, don't start the request. | |
1241 if (!delegate_) | |
1242 return; | |
1243 | |
1244 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | |
1245 switches::kDisableDirectNPAPIRequests)) { | |
1246 // We got here either because the plugin called GetURL/PostURL, or because | |
1247 // we're fetching the data for an embed tag. If we're in multi-process mode, | |
1248 // we want to fetch the data in the plugin process as the renderer won't be | |
1249 // able to request any origin when site isolation is in place. So bounce | |
1250 // this request back to the plugin process which will use ResourceDispatcher | |
1251 // to fetch the url. | |
1252 | |
1253 // TODO(jam): any better way of getting this? Can't find a way to get | |
1254 // frame()->loader()->outgoingReferrer() which | |
1255 // WebFrameImpl::setReferrerForRequest does. | |
1256 WebURLRequest request(complete_url); | |
1257 SetReferrer(&request, referrer_flag); | |
1258 Referrer referrer( | |
1259 GURL(request.httpHeaderField(WebString::fromUTF8("Referer"))), | |
1260 request.referrerPolicy()); | |
1261 | |
1262 GURL first_party_for_cookies = webframe_->document().firstPartyForCookies(); | |
1263 delegate_->FetchURL(resource_id, notify_id, complete_url, | |
1264 first_party_for_cookies, method, buf, len, referrer, | |
1265 notify_redirects, is_plugin_src_load, 0, | |
1266 render_frame_->GetRoutingID(), | |
1267 render_view_->GetRoutingID()); | |
1268 } else { | |
1269 WebPluginResourceClient* resource_client = delegate_->CreateResourceClient( | |
1270 resource_id, complete_url, notify_id); | |
1271 if (!resource_client) | |
1272 return; | |
1273 InitiateHTTPRequest(resource_id, resource_client, complete_url, method, buf, | |
1274 len, NULL, referrer_flag, notify_redirects, | |
1275 is_plugin_src_load); | |
1276 } | |
1277 } | |
1278 | |
1279 unsigned long WebPluginImpl::GetNextResourceId() { | 1026 unsigned long WebPluginImpl::GetNextResourceId() { |
1280 if (!webframe_) | 1027 if (!webframe_) |
1281 return 0; | 1028 return 0; |
1282 WebView* view = webframe_->view(); | 1029 WebView* view = webframe_->view(); |
1283 if (!view) | 1030 if (!view) |
1284 return 0; | 1031 return 0; |
1285 return view->createUniqueIdentifierForRequest(); | 1032 return view->createUniqueIdentifierForRequest(); |
1286 } | 1033 } |
1287 | 1034 |
1288 bool WebPluginImpl::InitiateHTTPRequest(unsigned long resource_id, | |
1289 WebPluginResourceClient* client, | |
1290 const GURL& url, | |
1291 const char* method, | |
1292 const char* buf, | |
1293 int buf_len, | |
1294 const char* range_info, | |
1295 ReferrerValue referrer_flag, | |
1296 bool notify_redirects, | |
1297 bool is_plugin_src_load) { | |
1298 if (!client) { | |
1299 NOTREACHED(); | |
1300 return false; | |
1301 } | |
1302 | |
1303 ClientInfo info; | |
1304 info.id = resource_id; | |
1305 info.client = client; | |
1306 info.request.initialize(); | |
1307 info.request.setURL(url); | |
1308 info.request.setFirstPartyForCookies( | |
1309 webframe_->document().firstPartyForCookies()); | |
1310 info.request.setRequestorProcessID(delegate_->GetProcessId()); | |
1311 // TODO(mkwst): Is this a request for a plugin object itself | |
1312 // (RequestContextObject), or a request that the plugin makes | |
1313 // (RequestContextPlugin)? | |
1314 info.request.setRequestContext(WebURLRequest::RequestContextPlugin); | |
1315 info.request.setHTTPMethod(WebString::fromUTF8(method)); | |
1316 // ServiceWorker is disabled for NPAPI. | |
1317 info.request.setSkipServiceWorker(true); | |
1318 info.pending_failure_notification = false; | |
1319 info.notify_redirects = notify_redirects; | |
1320 info.is_plugin_src_load = is_plugin_src_load; | |
1321 info.data_offset = 0; | |
1322 | |
1323 if (range_info) { | |
1324 info.request.addHTTPHeaderField(WebString::fromUTF8("Range"), | |
1325 WebString::fromUTF8(range_info)); | |
1326 } | |
1327 | |
1328 if (strcmp(method, "POST") == 0) { | |
1329 // Adds headers or form data to a request. This must be called before | |
1330 // we initiate the actual request. | |
1331 SetPostData(&info.request, buf, buf_len); | |
1332 } | |
1333 | |
1334 SetReferrer(&info.request, referrer_flag); | |
1335 | |
1336 WebURLLoaderOptions options; | |
1337 options.allowCredentials = true; | |
1338 options.crossOriginRequestPolicy = | |
1339 WebURLLoaderOptions::CrossOriginRequestPolicyAllow; | |
1340 info.loader.reset(webframe_->createAssociatedURLLoader(options)); | |
1341 if (!info.loader.get()) | |
1342 return false; | |
1343 info.loader->loadAsynchronously(info.request, &loader_client_); | |
1344 | |
1345 clients_.push_back(info); | |
1346 return true; | |
1347 } | |
1348 | |
1349 void WebPluginImpl::CancelDocumentLoad() { | 1035 void WebPluginImpl::CancelDocumentLoad() { |
1350 if (webframe_) { | 1036 if (webframe_) { |
1351 ignore_response_error_ = true; | 1037 ignore_response_error_ = true; |
1352 webframe_->stopLoading(); | 1038 webframe_->stopLoading(); |
1353 } | 1039 } |
1354 } | 1040 } |
1355 | 1041 |
1356 void WebPluginImpl::InitiateHTTPRangeRequest( | |
1357 const char* url, const char* range_info, int range_request_id) { | |
1358 unsigned long resource_id = GetNextResourceId(); | |
1359 if (!resource_id) | |
1360 return; | |
1361 | |
1362 GURL complete_url = CompleteURL(url); | |
1363 // Remove when flash bug is fixed. http://crbug.com/40016. | |
1364 if (!WebPluginImpl::IsValidUrl(complete_url, | |
1365 load_manually_ ? NO_REFERRER : PLUGIN_SRC)) | |
1366 return; | |
1367 | |
1368 WebPluginResourceClient* resource_client = | |
1369 delegate_->CreateSeekableResourceClient(resource_id, range_request_id); | |
1370 InitiateHTTPRequest( | |
1371 resource_id, resource_client, complete_url, "GET", NULL, 0, range_info, | |
1372 load_manually_ ? NO_REFERRER : PLUGIN_SRC, false, false); | |
1373 } | |
1374 | |
1375 void WebPluginImpl::DidStartLoading() { | 1042 void WebPluginImpl::DidStartLoading() { |
1376 if (render_view_.get()) { | 1043 if (render_view_.get()) { |
1377 // TODO(darin): Make is_loading_ be a counter! | 1044 // TODO(darin): Make is_loading_ be a counter! |
1378 render_view_->DidStartLoading(); | 1045 render_view_->DidStartLoading(); |
1379 } | 1046 } |
1380 } | 1047 } |
1381 | 1048 |
1382 void WebPluginImpl::DidStopLoading() { | 1049 void WebPluginImpl::DidStopLoading() { |
1383 if (render_view_.get()) { | 1050 if (render_view_.get()) { |
1384 // TODO(darin): Make is_loading_ be a counter! | 1051 // TODO(darin): Make is_loading_ be a counter! |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 | 1199 |
1533 if (client_info.loader.get()) | 1200 if (client_info.loader.get()) |
1534 client_info.loader->cancel(); | 1201 client_info.loader->cancel(); |
1535 | 1202 |
1536 client_index = clients_.erase(client_index); | 1203 client_index = clients_.erase(client_index); |
1537 } | 1204 } |
1538 | 1205 |
1539 // This needs to be called now and not in the destructor since the | 1206 // This needs to be called now and not in the destructor since the |
1540 // webframe_ might not be valid anymore. | 1207 // webframe_ might not be valid anymore. |
1541 webframe_ = NULL; | 1208 webframe_ = NULL; |
1542 weak_factory_.InvalidateWeakPtrs(); | |
1543 } | 1209 } |
1544 | 1210 |
1545 void WebPluginImpl::SetReferrer(blink::WebURLRequest* request, | 1211 void WebPluginImpl::SetReferrer(blink::WebURLRequest* request, |
1546 ReferrerValue referrer_flag) { | 1212 ReferrerValue referrer_flag) { |
1547 switch (referrer_flag) { | 1213 switch (referrer_flag) { |
1548 case DOCUMENT_URL: | 1214 case DOCUMENT_URL: |
1549 webframe_->setReferrerForRequest(*request, GURL()); | 1215 webframe_->setReferrerForRequest(*request, GURL()); |
1550 break; | 1216 break; |
1551 | 1217 |
1552 case PLUGIN_SRC: | 1218 case PLUGIN_SRC: |
1553 webframe_->setReferrerForRequest(*request, plugin_url_); | 1219 webframe_->setReferrerForRequest(*request, plugin_url_); |
1554 break; | 1220 break; |
1555 | 1221 |
1556 default: | 1222 default: |
1557 break; | 1223 break; |
1558 } | 1224 } |
1559 } | 1225 } |
1560 | 1226 |
1561 } // namespace content | 1227 } // namespace content |
OLD | NEW |