| 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 29 matching lines...) Expand all  Loading... | 
| 40 #include "skia/ext/platform_canvas.h" | 40 #include "skia/ext/platform_canvas.h" | 
| 41 #include "third_party/WebKit/public/platform/WebCString.h" | 41 #include "third_party/WebKit/public/platform/WebCString.h" | 
| 42 #include "third_party/WebKit/public/platform/WebCookieJar.h" | 42 #include "third_party/WebKit/public/platform/WebCookieJar.h" | 
| 43 #include "third_party/WebKit/public/platform/WebCursorInfo.h" | 43 #include "third_party/WebKit/public/platform/WebCursorInfo.h" | 
| 44 #include "third_party/WebKit/public/platform/WebData.h" | 44 #include "third_party/WebKit/public/platform/WebData.h" | 
| 45 #include "third_party/WebKit/public/platform/WebHTTPBody.h" | 45 #include "third_party/WebKit/public/platform/WebHTTPBody.h" | 
| 46 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" | 46 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" | 
| 47 #include "third_party/WebKit/public/platform/WebURL.h" | 47 #include "third_party/WebKit/public/platform/WebURL.h" | 
| 48 #include "third_party/WebKit/public/platform/WebURLError.h" | 48 #include "third_party/WebKit/public/platform/WebURLError.h" | 
| 49 #include "third_party/WebKit/public/platform/WebURLLoader.h" | 49 #include "third_party/WebKit/public/platform/WebURLLoader.h" | 
| 50 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" |  | 
| 51 #include "third_party/WebKit/public/platform/WebURLResponse.h" | 50 #include "third_party/WebKit/public/platform/WebURLResponse.h" | 
| 52 #include "third_party/WebKit/public/web/WebConsoleMessage.h" | 51 #include "third_party/WebKit/public/web/WebConsoleMessage.h" | 
| 53 #include "third_party/WebKit/public/web/WebDocument.h" | 52 #include "third_party/WebKit/public/web/WebDocument.h" | 
| 54 #include "third_party/WebKit/public/web/WebFrame.h" | 53 #include "third_party/WebKit/public/web/WebFrame.h" | 
| 55 #include "third_party/WebKit/public/web/WebInputEvent.h" | 54 #include "third_party/WebKit/public/web/WebInputEvent.h" | 
| 56 #include "third_party/WebKit/public/web/WebKit.h" | 55 #include "third_party/WebKit/public/web/WebKit.h" | 
| 57 #include "third_party/WebKit/public/web/WebPluginContainer.h" | 56 #include "third_party/WebKit/public/web/WebPluginContainer.h" | 
| 58 #include "third_party/WebKit/public/web/WebPluginParams.h" | 57 #include "third_party/WebKit/public/web/WebPluginParams.h" | 
| 59 #include "third_party/WebKit/public/web/WebURLLoaderOptions.h" | 58 #include "third_party/WebKit/public/web/WebURLLoaderOptions.h" | 
| 60 #include "third_party/WebKit/public/web/WebView.h" | 59 #include "third_party/WebKit/public/web/WebView.h" | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 76 using blink::WebInputEventResult; | 75 using blink::WebInputEventResult; | 
| 77 using blink::WebKeyboardEvent; | 76 using blink::WebKeyboardEvent; | 
| 78 using blink::WebMouseEvent; | 77 using blink::WebMouseEvent; | 
| 79 using blink::WebPluginContainer; | 78 using blink::WebPluginContainer; | 
| 80 using blink::WebPluginParams; | 79 using blink::WebPluginParams; | 
| 81 using blink::WebRect; | 80 using blink::WebRect; | 
| 82 using blink::WebString; | 81 using blink::WebString; | 
| 83 using blink::WebURL; | 82 using blink::WebURL; | 
| 84 using blink::WebURLError; | 83 using blink::WebURLError; | 
| 85 using blink::WebURLLoader; | 84 using blink::WebURLLoader; | 
| 86 using blink::WebURLLoaderClient; |  | 
| 87 using blink::WebURLLoaderOptions; | 85 using blink::WebURLLoaderOptions; | 
| 88 using blink::WebURLRequest; | 86 using blink::WebURLRequest; | 
| 89 using blink::WebURLResponse; | 87 using blink::WebURLResponse; | 
| 90 using blink::WebVector; | 88 using blink::WebVector; | 
| 91 using blink::WebView; | 89 using blink::WebView; | 
| 92 | 90 | 
| 93 namespace content { | 91 namespace content { | 
| 94 | 92 | 
| 95 namespace { |  | 
| 96 |  | 
| 97 // This class handles individual multipart responses. It is instantiated when |  | 
| 98 // we receive HTTP status code 206 in the HTTP response. This indicates |  | 
| 99 // that the response could have multiple parts each separated by a boundary |  | 
| 100 // specified in the response header. |  | 
| 101 class MultiPartResponseClient : public WebURLLoaderClient { |  | 
| 102  public: |  | 
| 103   explicit MultiPartResponseClient(WebPluginResourceClient* resource_client) |  | 
| 104       : byte_range_lower_bound_(0), resource_client_(resource_client) {} |  | 
| 105 |  | 
| 106   void willFollowRedirect(WebURLLoader*, |  | 
| 107                           WebURLRequest&, |  | 
| 108                           const WebURLResponse&) override {} |  | 
| 109   void didSendData(WebURLLoader*, |  | 
| 110                    unsigned long long, |  | 
| 111                    unsigned long long) override {} |  | 
| 112 |  | 
| 113   // Called when the multipart parser encounters an embedded multipart |  | 
| 114   // response. |  | 
| 115   void didReceiveResponse(WebURLLoader*, |  | 
| 116                           const WebURLResponse& response) override { |  | 
| 117     int64_t byte_range_upper_bound, instance_size; |  | 
| 118     if (!MultipartResponseDelegate::ReadContentRanges( |  | 
| 119             response, |  | 
| 120             &byte_range_lower_bound_, |  | 
| 121             &byte_range_upper_bound, |  | 
| 122             &instance_size)) { |  | 
| 123       NOTREACHED(); |  | 
| 124     } |  | 
| 125   } |  | 
| 126 |  | 
| 127   // Receives individual part data from a multipart response. |  | 
| 128   void didReceiveData(WebURLLoader*, |  | 
| 129                       const char* data, |  | 
| 130                       int data_length, |  | 
| 131                       int encoded_data_length) override { |  | 
| 132     // TODO(ananta) |  | 
| 133     // We should defer further loads on multipart resources on the same lines |  | 
| 134     // as regular resources requested by plugins to prevent reentrancy. |  | 
| 135     resource_client_->DidReceiveData( |  | 
| 136         data, data_length, byte_range_lower_bound_); |  | 
| 137     byte_range_lower_bound_ += data_length; |  | 
| 138   } |  | 
| 139 |  | 
| 140   void didFinishLoading(WebURLLoader*, |  | 
| 141                         double finishTime, |  | 
| 142                         int64_t total_encoded_data_length) override {} |  | 
| 143   void didFail(WebURLLoader*, const WebURLError&) override {} |  | 
| 144 |  | 
| 145  private: |  | 
| 146   // The lower bound of the byte range. |  | 
| 147   int64_t byte_range_lower_bound_; |  | 
| 148   // The handler for the data. |  | 
| 149   WebPluginResourceClient* resource_client_; |  | 
| 150 }; |  | 
| 151 |  | 
| 152 class HeaderFlattener : public WebHTTPHeaderVisitor { |  | 
| 153  public: |  | 
| 154   explicit HeaderFlattener(std::string* buf) : buf_(buf) { |  | 
| 155   } |  | 
| 156 |  | 
| 157   void visitHeader(const WebString& name, const WebString& value) override { |  | 
| 158     // TODO(darin): Should we really exclude headers with an empty value? |  | 
| 159     if (!name.isEmpty() && !value.isEmpty()) { |  | 
| 160       buf_->append(name.utf8()); |  | 
| 161       buf_->append(": "); |  | 
| 162       buf_->append(value.utf8()); |  | 
| 163       buf_->append("\n"); |  | 
| 164     } |  | 
| 165   } |  | 
| 166 |  | 
| 167  private: |  | 
| 168   std::string* buf_; |  | 
| 169 }; |  | 
| 170 |  | 
| 171 std::string GetAllHeaders(const WebURLResponse& response) { |  | 
| 172   // TODO(darin): It is possible for httpStatusText to be empty and still have |  | 
| 173   // an interesting response, so this check seems wrong. |  | 
| 174   std::string result; |  | 
| 175   const WebString& status = response.httpStatusText(); |  | 
| 176   if (status.isEmpty()) |  | 
| 177     return result; |  | 
| 178 |  | 
| 179   // TODO(darin): Shouldn't we also report HTTP version numbers? |  | 
| 180   result = base::StringPrintf("HTTP %d ", response.httpStatusCode()); |  | 
| 181   result.append(status.utf8()); |  | 
| 182   result.append("\n"); |  | 
| 183 |  | 
| 184   HeaderFlattener flattener(&result); |  | 
| 185   response.visitHTTPHeaderFields(&flattener); |  | 
| 186 |  | 
| 187   return result; |  | 
| 188 } |  | 
| 189 |  | 
| 190 struct ResponseInfo { |  | 
| 191   GURL url; |  | 
| 192   std::string mime_type; |  | 
| 193   uint32_t last_modified; |  | 
| 194   uint32_t expected_length; |  | 
| 195 }; |  | 
| 196 |  | 
| 197 void GetResponseInfo(const WebURLResponse& response, |  | 
| 198                      ResponseInfo* response_info) { |  | 
| 199   response_info->url = response.url(); |  | 
| 200   response_info->mime_type = response.mimeType().utf8(); |  | 
| 201 |  | 
| 202   // Measured in seconds since 12:00 midnight GMT, January 1, 1970. |  | 
| 203   response_info->last_modified = |  | 
| 204       static_cast<uint32_t>(response.lastModifiedDate()); |  | 
| 205 |  | 
| 206   // If the length comes in as -1, then it indicates that it was not |  | 
| 207   // read off the HTTP headers. We replicate Safari webkit behavior here, |  | 
| 208   // which is to set it to 0. |  | 
| 209   response_info->expected_length = |  | 
| 210       static_cast<uint32_t>(std::max(response.expectedContentLength(), 0LL)); |  | 
| 211 |  | 
| 212   WebString content_encoding = |  | 
| 213       response.httpHeaderField(WebString::fromUTF8("Content-Encoding")); |  | 
| 214   if (!content_encoding.isNull() && |  | 
| 215       !base::EqualsASCII(base::StringPiece16(content_encoding), "identity")) { |  | 
| 216     // Don't send the compressed content length to the plugin, which only |  | 
| 217     // cares about the decoded length. |  | 
| 218     response_info->expected_length = 0; |  | 
| 219   } |  | 
| 220 } |  | 
| 221 |  | 
| 222 }  // namespace |  | 
| 223 |  | 
| 224 // blink::WebPlugin ---------------------------------------------------------- | 93 // blink::WebPlugin ---------------------------------------------------------- | 
| 225 | 94 | 
| 226 struct WebPluginImpl::ClientInfo { |  | 
| 227   unsigned long id; |  | 
| 228   WebPluginResourceClient* client; |  | 
| 229   blink::WebURLRequest request; |  | 
| 230   bool pending_failure_notification; |  | 
| 231   linked_ptr<blink::WebURLLoader> loader; |  | 
| 232   bool notify_redirects; |  | 
| 233   bool is_plugin_src_load; |  | 
| 234   int64_t data_offset; |  | 
| 235 }; |  | 
| 236 |  | 
| 237 bool WebPluginImpl::initialize(WebPluginContainer* container) { | 95 bool WebPluginImpl::initialize(WebPluginContainer* container) { | 
| 238   if (!render_view_.get()) { | 96   if (!render_view_.get()) { | 
| 239     LOG(ERROR) << "No RenderView"; | 97     LOG(ERROR) << "No RenderView"; | 
| 240     return false; | 98     return false; | 
| 241   } | 99   } | 
| 242 | 100 | 
| 243   WebPluginDelegateProxy* plugin_delegate = new WebPluginDelegateProxy( | 101   WebPluginDelegateProxy* plugin_delegate = new WebPluginDelegateProxy( | 
| 244       this, mime_type_, render_view_, render_frame_); | 102       this, mime_type_, render_view_, render_frame_); | 
| 245 | 103 | 
| 246   // Store the plugin's unique identifier, used by the container to track its | 104   // Store the plugin's unique identifier, used by the container to track its | 
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 420   cursor_info.externalHandle = web_cursor_info.external_handle; | 278   cursor_info.externalHandle = web_cursor_info.external_handle; | 
| 421 #endif | 279 #endif | 
| 422   return ret ? WebInputEventResult::HandledApplication | 280   return ret ? WebInputEventResult::HandledApplication | 
| 423              : WebInputEventResult::NotHandled; | 281              : WebInputEventResult::NotHandled; | 
| 424 } | 282 } | 
| 425 | 283 | 
| 426 bool WebPluginImpl::isPlaceholder() { | 284 bool WebPluginImpl::isPlaceholder() { | 
| 427   return false; | 285   return false; | 
| 428 } | 286 } | 
| 429 | 287 | 
| 430 WebPluginImpl::LoaderClient::LoaderClient(WebPluginImpl* parent) |  | 
| 431     : parent_(parent) {} |  | 
| 432 |  | 
| 433 void WebPluginImpl::LoaderClient::willFollowRedirect( |  | 
| 434     blink::WebURLLoader* loader, blink::WebURLRequest& new_request, |  | 
| 435     const blink::WebURLResponse& redirect_response) { |  | 
| 436   parent_->willFollowRedirect(loader, new_request, redirect_response); |  | 
| 437 } |  | 
| 438 |  | 
| 439 void WebPluginImpl::LoaderClient::didSendData( |  | 
| 440     blink::WebURLLoader* loader, unsigned long long bytesSent, |  | 
| 441     unsigned long long totalBytesToBeSent) { |  | 
| 442   parent_->didSendData(loader, bytesSent, totalBytesToBeSent); |  | 
| 443 } |  | 
| 444 |  | 
| 445 void WebPluginImpl::LoaderClient::didReceiveResponse( |  | 
| 446     blink::WebURLLoader* loader, const blink::WebURLResponse& response) { |  | 
| 447   parent_->didReceiveResponse(loader, response); |  | 
| 448 } |  | 
| 449 |  | 
| 450 void WebPluginImpl::LoaderClient::didDownloadData( |  | 
| 451     blink::WebURLLoader* loader, int dataLength, int encodedDataLength) { |  | 
| 452 } |  | 
| 453 |  | 
| 454 void WebPluginImpl::LoaderClient::didReceiveData( |  | 
| 455     blink::WebURLLoader* loader, const char* data, |  | 
| 456     int dataLength, int encodedDataLength) { |  | 
| 457   parent_->didReceiveData(loader, data, dataLength, encodedDataLength); |  | 
| 458 } |  | 
| 459 |  | 
| 460 void WebPluginImpl::LoaderClient::didReceiveCachedMetadata( |  | 
| 461     blink::WebURLLoader* loader, const char* data, int dataLength) { |  | 
| 462 } |  | 
| 463 |  | 
| 464 void WebPluginImpl::LoaderClient::didFinishLoading( |  | 
| 465     blink::WebURLLoader* loader, double finishTime, |  | 
| 466     int64_t total_encoded_data_length) { |  | 
| 467   parent_->didFinishLoading(loader, finishTime); |  | 
| 468 } |  | 
| 469 |  | 
| 470 void WebPluginImpl::LoaderClient::didFail( |  | 
| 471     blink::WebURLLoader* loader, const blink::WebURLError& error) { |  | 
| 472   parent_->didFail(loader, error); |  | 
| 473 } |  | 
| 474 |  | 
| 475 // ----------------------------------------------------------------------------- | 288 // ----------------------------------------------------------------------------- | 
| 476 | 289 | 
| 477 WebPluginImpl::WebPluginImpl( | 290 WebPluginImpl::WebPluginImpl( | 
| 478     WebFrame* webframe, | 291     WebFrame* webframe, | 
| 479     const WebPluginParams& params, | 292     const WebPluginParams& params, | 
| 480     const base::FilePath& file_path, | 293     const base::FilePath& file_path, | 
| 481     const base::WeakPtr<RenderViewImpl>& render_view, | 294     const base::WeakPtr<RenderViewImpl>& render_view, | 
| 482     RenderFrameImpl* render_frame) | 295     RenderFrameImpl* render_frame) | 
| 483     : windowless_(false), | 296     : windowless_(false), | 
| 484       window_(gfx::kNullPluginWindow), | 297       window_(gfx::kNullPluginWindow), | 
| 485       accepts_input_events_(false), | 298       accepts_input_events_(false), | 
| 486       render_frame_(render_frame), | 299       render_frame_(render_frame), | 
| 487       render_view_(render_view), | 300       render_view_(render_view), | 
| 488       webframe_(webframe), | 301       webframe_(webframe), | 
| 489       delegate_(NULL), | 302       delegate_(NULL), | 
| 490       container_(NULL), | 303       container_(NULL), | 
| 491       npp_(NULL), | 304       npp_(NULL), | 
| 492       plugin_url_(params.url), | 305       plugin_url_(params.url), | 
| 493       load_manually_(params.loadManually), | 306       load_manually_(params.loadManually), | 
| 494       first_geometry_update_(true), | 307       first_geometry_update_(true), | 
| 495       ignore_response_error_(false), | 308       ignore_response_error_(false), | 
| 496       file_path_(file_path), | 309       file_path_(file_path), | 
| 497       mime_type_(base::ToLowerASCII(base::UTF16ToASCII( | 310       mime_type_(base::ToLowerASCII(base::UTF16ToASCII( | 
| 498           base::StringPiece16(params.mimeType)))), | 311           base::StringPiece16(params.mimeType)))) { | 
| 499       loader_client_(this) { |  | 
| 500   DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); | 312   DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); | 
| 501 | 313 | 
| 502   for (size_t i = 0; i < params.attributeNames.size(); ++i) { | 314   for (size_t i = 0; i < params.attributeNames.size(); ++i) { | 
| 503     arg_names_.push_back(params.attributeNames[i].utf8()); | 315     arg_names_.push_back(params.attributeNames[i].utf8()); | 
| 504     arg_values_.push_back(params.attributeValues[i].utf8()); | 316     arg_values_.push_back(params.attributeValues[i].utf8()); | 
| 505   } | 317   } | 
| 506 | 318 | 
| 507   // Set subresource URL for crash reporting. | 319   // Set subresource URL for crash reporting. | 
| 508   base::debug::SetCrashKeyValue("subresource_url", plugin_url_.spec()); | 320   base::debug::SetCrashKeyValue("subresource_url", plugin_url_.spec()); | 
| 509 } | 321 } | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 548 | 360 | 
| 549 GURL WebPluginImpl::CompleteURL(const char* url) { | 361 GURL WebPluginImpl::CompleteURL(const char* url) { | 
| 550   if (!webframe_) { | 362   if (!webframe_) { | 
| 551     NOTREACHED(); | 363     NOTREACHED(); | 
| 552     return GURL(); | 364     return GURL(); | 
| 553   } | 365   } | 
| 554   // TODO(darin): Is conversion from UTF8 correct here? | 366   // TODO(darin): Is conversion from UTF8 correct here? | 
| 555   return webframe_->document().completeURL(WebString::fromUTF8(url)); | 367   return webframe_->document().completeURL(WebString::fromUTF8(url)); | 
| 556 } | 368 } | 
| 557 | 369 | 
| 558 void WebPluginImpl::CancelResource(unsigned long id) { |  | 
| 559   for (size_t i = 0; i < clients_.size(); ++i) { |  | 
| 560     if (clients_[i].id == id) { |  | 
| 561       if (clients_[i].loader.get()) { |  | 
| 562         clients_[i].loader->setDefersLoading(false); |  | 
| 563         clients_[i].loader->cancel(); |  | 
| 564         RemoveClient(i); |  | 
| 565       } |  | 
| 566       return; |  | 
| 567     } |  | 
| 568   } |  | 
| 569 } |  | 
| 570 |  | 
| 571 bool WebPluginImpl::SetPostData(WebURLRequest* request, | 370 bool WebPluginImpl::SetPostData(WebURLRequest* request, | 
| 572                                 const char* buf, | 371                                 const char* buf, | 
| 573                                 uint32_t length) { | 372                                 uint32_t length) { | 
| 574   std::vector<std::string> names; | 373   std::vector<std::string> names; | 
| 575   std::vector<std::string> values; | 374   std::vector<std::string> values; | 
| 576   std::vector<char> body; | 375   std::vector<char> body; | 
| 577   bool rv = PluginHost::SetPostData(buf, length, &names, &values, &body); | 376   bool rv = PluginHost::SetPostData(buf, length, &names, &values, &body); | 
| 578 | 377 | 
| 579   for (size_t i = 0; i < names.size(); ++i) { | 378   for (size_t i = 0; i < names.size(); ++i) { | 
| 580     request->addHTTPHeaderField(WebString::fromUTF8(names[i]), | 379     request->addHTTPHeaderField(WebString::fromUTF8(names[i]), | 
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 739   WebCookieJar* cookie_jar = render_frame_->cookie_jar(); | 538   WebCookieJar* cookie_jar = render_frame_->cookie_jar(); | 
| 740   if (!cookie_jar) { | 539   if (!cookie_jar) { | 
| 741     DLOG(WARNING) << "No cookie jar!"; | 540     DLOG(WARNING) << "No cookie jar!"; | 
| 742     return std::string(); | 541     return std::string(); | 
| 743   } | 542   } | 
| 744 | 543 | 
| 745   return base::UTF16ToUTF8(base::StringPiece16( | 544   return base::UTF16ToUTF8(base::StringPiece16( | 
| 746       cookie_jar->cookies(url, first_party_for_cookies))); | 545       cookie_jar->cookies(url, first_party_for_cookies))); | 
| 747 } | 546 } | 
| 748 | 547 | 
| 749 void WebPluginImpl::URLRedirectResponse(bool allow, int resource_id) { |  | 
| 750   for (size_t i = 0; i < clients_.size(); ++i) { |  | 
| 751     if (clients_[i].id == static_cast<unsigned long>(resource_id)) { |  | 
| 752       if (clients_[i].loader.get()) { |  | 
| 753         if (allow) { |  | 
| 754           clients_[i].loader->setDefersLoading(false); |  | 
| 755         } else { |  | 
| 756           clients_[i].loader->cancel(); |  | 
| 757           if (clients_[i].client) |  | 
| 758             clients_[i].client->DidFail(clients_[i].id); |  | 
| 759         } |  | 
| 760       } |  | 
| 761       break; |  | 
| 762     } |  | 
| 763   } |  | 
| 764 } |  | 
| 765 |  | 
| 766 #if defined(OS_MACOSX) | 548 #if defined(OS_MACOSX) | 
| 767 WebPluginAcceleratedSurface* WebPluginImpl::GetAcceleratedSurface( | 549 WebPluginAcceleratedSurface* WebPluginImpl::GetAcceleratedSurface( | 
| 768     gfx::GpuPreference gpu_preference) { | 550     gfx::GpuPreference gpu_preference) { | 
| 769   return NULL; | 551   return NULL; | 
| 770 } | 552 } | 
| 771 | 553 | 
| 772 void WebPluginImpl::AcceleratedPluginEnabledRendering() { | 554 void WebPluginImpl::AcceleratedPluginEnabledRendering() { | 
| 773 } | 555 } | 
| 774 | 556 | 
| 775 void WebPluginImpl::AcceleratedPluginAllocatedIOSurface(int32_t width, | 557 void WebPluginImpl::AcceleratedPluginAllocatedIOSurface(int32_t width, | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 818 void WebPluginImpl::Invalidate() { | 600 void WebPluginImpl::Invalidate() { | 
| 819   if (container_) | 601   if (container_) | 
| 820     container_->invalidate(); | 602     container_->invalidate(); | 
| 821 } | 603 } | 
| 822 | 604 | 
| 823 void WebPluginImpl::InvalidateRect(const gfx::Rect& rect) { | 605 void WebPluginImpl::InvalidateRect(const gfx::Rect& rect) { | 
| 824   if (container_) | 606   if (container_) | 
| 825     container_->invalidateRect(rect); | 607     container_->invalidateRect(rect); | 
| 826 } | 608 } | 
| 827 | 609 | 
| 828 WebPluginResourceClient* WebPluginImpl::GetClientFromLoader( |  | 
| 829     WebURLLoader* loader) { |  | 
| 830   ClientInfo* client_info = GetClientInfoFromLoader(loader); |  | 
| 831   if (client_info) |  | 
| 832     return client_info->client; |  | 
| 833   return NULL; |  | 
| 834 } |  | 
| 835 |  | 
| 836 WebPluginImpl::ClientInfo* WebPluginImpl::GetClientInfoFromLoader( |  | 
| 837     WebURLLoader* loader) { |  | 
| 838   for (size_t i = 0; i < clients_.size(); ++i) { |  | 
| 839     if (clients_[i].loader.get() == loader) |  | 
| 840       return &clients_[i]; |  | 
| 841   } |  | 
| 842 |  | 
| 843   NOTREACHED(); |  | 
| 844   return 0; |  | 
| 845 } |  | 
| 846 |  | 
| 847 void WebPluginImpl::willFollowRedirect(WebURLLoader* loader, |  | 
| 848                                        WebURLRequest& new_request, |  | 
| 849                                        const WebURLResponse& response) { |  | 
| 850   // TODO(jam): THIS LOGIC IS COPIED IN PluginURLFetcher::OnReceivedRedirect |  | 
| 851   // until kDirectNPAPIRequests is the default and we can remove this old path. |  | 
| 852   WebPluginImpl::ClientInfo* client_info = GetClientInfoFromLoader(loader); |  | 
| 853   if (client_info) { |  | 
| 854     if (net::HttpResponseHeaders::IsRedirectResponseCode( |  | 
| 855             response.httpStatusCode())) { |  | 
| 856       // If the plugin does not participate in url redirect notifications then |  | 
| 857       // just block cross origin 307 POST redirects. |  | 
| 858       if (!client_info->notify_redirects) { |  | 
| 859         if (response.httpStatusCode() == 307 && |  | 
| 860             base::LowerCaseEqualsASCII( |  | 
| 861                 new_request.httpMethod().utf8(), "post")) { |  | 
| 862           GURL original_request_url(response.url()); |  | 
| 863           GURL response_url(new_request.url()); |  | 
| 864           if (original_request_url.GetOrigin() != response_url.GetOrigin()) { |  | 
| 865             loader->setDefersLoading(true); |  | 
| 866             loader->cancel(); |  | 
| 867             client_info->client->DidFail(client_info->id); |  | 
| 868             return; |  | 
| 869           } |  | 
| 870         } |  | 
| 871       } else { |  | 
| 872         loader->setDefersLoading(true); |  | 
| 873       } |  | 
| 874     } |  | 
| 875     client_info->client->WillSendRequest(new_request.url(), |  | 
| 876                                          response.httpStatusCode()); |  | 
| 877   } |  | 
| 878 } |  | 
| 879 |  | 
| 880 void WebPluginImpl::didSendData(WebURLLoader* loader, |  | 
| 881                                 unsigned long long bytes_sent, |  | 
| 882                                 unsigned long long total_bytes_to_be_sent) { |  | 
| 883 } |  | 
| 884 |  | 
| 885 void WebPluginImpl::didReceiveResponse(WebURLLoader* loader, |  | 
| 886                                        const WebURLResponse& response) { |  | 
| 887   // TODO(jam): THIS LOGIC IS COPIED IN PluginURLFetcher::OnReceivedResponse |  | 
| 888   // until kDirectNPAPIRequests is the default and we can remove this old path. |  | 
| 889 |  | 
| 890   WebPluginResourceClient* client = GetClientFromLoader(loader); |  | 
| 891   if (!client) |  | 
| 892     return; |  | 
| 893 |  | 
| 894   ResponseInfo response_info; |  | 
| 895   GetResponseInfo(response, &response_info); |  | 
| 896   ClientInfo* client_info = GetClientInfoFromLoader(loader); |  | 
| 897   if (!client_info) |  | 
| 898     return; |  | 
| 899 |  | 
| 900   // Calling into a plugin could result in reentrancy if the plugin yields |  | 
| 901   // control to the OS like entering a modal loop etc. Prevent this by |  | 
| 902   // stopping further loading until the plugin notifies us that it is ready to |  | 
| 903   // accept data |  | 
| 904   loader->setDefersLoading(true); |  | 
| 905 |  | 
| 906   client->DidReceiveResponse( |  | 
| 907       response_info.mime_type, |  | 
| 908       GetAllHeaders(response), |  | 
| 909       response_info.expected_length, |  | 
| 910       response_info.last_modified, |  | 
| 911       true); |  | 
| 912 |  | 
| 913   // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP |  | 
| 914   // error codes in the stream header and as a result, was unaware of the |  | 
| 915   // fate of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF |  | 
| 916   // destroy the stream and invoke the NPP_DestroyStream function on the |  | 
| 917   // plugin if the HTTP request fails. |  | 
| 918   const GURL& url = response.url(); |  | 
| 919   if (url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme)) { |  | 
| 920     if (response.httpStatusCode() < 100 || response.httpStatusCode() >= 400) { |  | 
| 921       // The plugin instance could be in the process of deletion here. |  | 
| 922       // Verify if the WebPluginResourceClient instance still exists before |  | 
| 923       // use. |  | 
| 924       ClientInfo* client_info = GetClientInfoFromLoader(loader); |  | 
| 925       if (client_info) { |  | 
| 926         client_info->pending_failure_notification = true; |  | 
| 927       } |  | 
| 928     } |  | 
| 929   } |  | 
| 930 } |  | 
| 931 |  | 
| 932 void WebPluginImpl::didReceiveData(WebURLLoader* loader, |  | 
| 933                                    const char *buffer, |  | 
| 934                                    int data_length, |  | 
| 935                                    int encoded_data_length) { |  | 
| 936   WebPluginResourceClient* client = GetClientFromLoader(loader); |  | 
| 937   if (!client) |  | 
| 938     return; |  | 
| 939 |  | 
| 940   MultiPartResponseHandlerMap::iterator index = |  | 
| 941       multi_part_response_map_.find(client); |  | 
| 942   if (index != multi_part_response_map_.end()) { |  | 
| 943     MultipartResponseDelegate* multi_part_handler = (*index).second; |  | 
| 944     DCHECK(multi_part_handler != NULL); |  | 
| 945     multi_part_handler->OnReceivedData(buffer, |  | 
| 946                                        data_length, |  | 
| 947                                        encoded_data_length); |  | 
| 948   } else { |  | 
| 949     loader->setDefersLoading(true); |  | 
| 950     ClientInfo* client_info = GetClientInfoFromLoader(loader); |  | 
| 951     client->DidReceiveData(buffer, data_length, client_info->data_offset); |  | 
| 952     client_info->data_offset += data_length; |  | 
| 953   } |  | 
| 954 } |  | 
| 955 |  | 
| 956 void WebPluginImpl::didFinishLoading(WebURLLoader* loader, double finishTime) { |  | 
| 957   ClientInfo* client_info = GetClientInfoFromLoader(loader); |  | 
| 958   if (client_info && client_info->client) { |  | 
| 959     MultiPartResponseHandlerMap::iterator index = |  | 
| 960       multi_part_response_map_.find(client_info->client); |  | 
| 961     if (index != multi_part_response_map_.end()) { |  | 
| 962       delete (*index).second; |  | 
| 963       multi_part_response_map_.erase(index); |  | 
| 964       DidStopLoading(); |  | 
| 965     } |  | 
| 966     loader->setDefersLoading(true); |  | 
| 967     WebPluginResourceClient* resource_client = client_info->client; |  | 
| 968     // The ClientInfo can get deleted in the call to DidFinishLoading below. |  | 
| 969     // It is not safe to access this structure after that. |  | 
| 970     client_info->client = NULL; |  | 
| 971     resource_client->DidFinishLoading(client_info->id); |  | 
| 972   } |  | 
| 973 } |  | 
| 974 |  | 
| 975 void WebPluginImpl::didFail(WebURLLoader* loader, |  | 
| 976                             const WebURLError& error) { |  | 
| 977   ClientInfo* client_info = GetClientInfoFromLoader(loader); |  | 
| 978   if (client_info && client_info->client) { |  | 
| 979     loader->setDefersLoading(true); |  | 
| 980     WebPluginResourceClient* resource_client = client_info->client; |  | 
| 981     // The ClientInfo can get deleted in the call to DidFail below. |  | 
| 982     // It is not safe to access this structure after that. |  | 
| 983     client_info->client = NULL; |  | 
| 984     resource_client->DidFail(client_info->id); |  | 
| 985   } |  | 
| 986 } |  | 
| 987 |  | 
| 988 void WebPluginImpl::RemoveClient(size_t i) { |  | 
| 989   clients_.erase(clients_.begin() + i); |  | 
| 990 } |  | 
| 991 |  | 
| 992 void WebPluginImpl::RemoveClient(WebURLLoader* loader) { |  | 
| 993   for (size_t i = 0; i < clients_.size(); ++i) { |  | 
| 994     if (clients_[i].loader.get() == loader) { |  | 
| 995       RemoveClient(i); |  | 
| 996       return; |  | 
| 997     } |  | 
| 998   } |  | 
| 999 } |  | 
| 1000 |  | 
| 1001 void WebPluginImpl::SetContainer(WebPluginContainer* container) { | 610 void WebPluginImpl::SetContainer(WebPluginContainer* container) { | 
| 1002   if (!container) | 611   if (!container) | 
| 1003     TearDownPluginInstance(NULL); | 612     TearDownPluginInstance(NULL); | 
| 1004   container_ = container; | 613   container_ = container; | 
| 1005   if (container_) | 614   if (container_) | 
| 1006     container_->allowScriptObjects(); | 615     container_->allowScriptObjects(); | 
| 1007 } | 616 } | 
| 1008 | 617 | 
| 1009 unsigned long WebPluginImpl::GetNextResourceId() { | 618 unsigned long WebPluginImpl::GetNextResourceId() { | 
| 1010   if (!webframe_) | 619   if (!webframe_) | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 1029   } | 638   } | 
| 1030 } | 639 } | 
| 1031 | 640 | 
| 1032 void WebPluginImpl::DidStopLoading() { | 641 void WebPluginImpl::DidStopLoading() { | 
| 1033   if (render_view_.get()) { | 642   if (render_view_.get()) { | 
| 1034     // TODO(darin): Make is_loading_ be a counter! | 643     // TODO(darin): Make is_loading_ be a counter! | 
| 1035     render_view_->DidStopLoading(); | 644     render_view_->DidStopLoading(); | 
| 1036   } | 645   } | 
| 1037 } | 646 } | 
| 1038 | 647 | 
| 1039 void WebPluginImpl::SetDeferResourceLoading(unsigned long resource_id, |  | 
| 1040                                             bool defer) { |  | 
| 1041   std::vector<ClientInfo>::iterator client_index = clients_.begin(); |  | 
| 1042   while (client_index != clients_.end()) { |  | 
| 1043     ClientInfo& client_info = *client_index; |  | 
| 1044 |  | 
| 1045     if (client_info.id == resource_id) { |  | 
| 1046       client_info.loader->setDefersLoading(defer); |  | 
| 1047 |  | 
| 1048       // If we determined that the request had failed via the HTTP headers |  | 
| 1049       // in the response then we send out a failure notification to the |  | 
| 1050       // plugin process, as certain plugins don't handle HTTP failure codes |  | 
| 1051       // correctly. |  | 
| 1052       if (!defer && client_info.client && |  | 
| 1053           client_info.pending_failure_notification) { |  | 
| 1054         // The ClientInfo and the iterator can become invalid due to the call |  | 
| 1055         // to DidFail below. |  | 
| 1056         WebPluginResourceClient* resource_client = client_info.client; |  | 
| 1057         client_info.loader->cancel(); |  | 
| 1058         clients_.erase(client_index++); |  | 
| 1059         resource_client->DidFail(resource_id); |  | 
| 1060       } |  | 
| 1061       break; |  | 
| 1062     } |  | 
| 1063     client_index++; |  | 
| 1064   } |  | 
| 1065 } |  | 
| 1066 |  | 
| 1067 bool WebPluginImpl::IsOffTheRecord() { | 648 bool WebPluginImpl::IsOffTheRecord() { | 
| 1068   return false; | 649   return false; | 
| 1069 } | 650 } | 
| 1070 | 651 | 
| 1071 bool WebPluginImpl::HandleHttpMultipartResponse( |  | 
| 1072     const WebURLResponse& response, WebPluginResourceClient* client) { |  | 
| 1073   std::string multipart_boundary; |  | 
| 1074   if (!MultipartResponseDelegate::ReadMultipartBoundary( |  | 
| 1075           response, &multipart_boundary)) { |  | 
| 1076     return false; |  | 
| 1077   } |  | 
| 1078 |  | 
| 1079   DidStartLoading(); |  | 
| 1080 |  | 
| 1081   MultiPartResponseClient* multi_part_response_client = |  | 
| 1082       new MultiPartResponseClient(client); |  | 
| 1083 |  | 
| 1084   MultipartResponseDelegate* multi_part_response_handler = |  | 
| 1085       new MultipartResponseDelegate(multi_part_response_client, NULL, |  | 
| 1086                                     response, |  | 
| 1087                                     multipart_boundary); |  | 
| 1088   multi_part_response_map_[client] = multi_part_response_handler; |  | 
| 1089   return true; |  | 
| 1090 } |  | 
| 1091 |  | 
| 1092 bool WebPluginImpl::ReinitializePluginForResponse( | 652 bool WebPluginImpl::ReinitializePluginForResponse( | 
| 1093     WebURLLoader* loader) { | 653     WebURLLoader* loader) { | 
| 1094   WebFrame* webframe = webframe_; | 654   WebFrame* webframe = webframe_; | 
| 1095   if (!webframe) | 655   if (!webframe) | 
| 1096     return false; | 656     return false; | 
| 1097 | 657 | 
| 1098   WebView* webview = webframe->view(); | 658   WebView* webview = webframe->view(); | 
| 1099   if (!webview) | 659   if (!webview) | 
| 1100     return false; | 660     return false; | 
| 1101 | 661 | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1162     container_->allowScriptObjects(); | 722     container_->allowScriptObjects(); | 
| 1163 | 723 | 
| 1164     delegate_->PluginDestroyed(); | 724     delegate_->PluginDestroyed(); | 
| 1165     delegate_ = NULL; | 725     delegate_ = NULL; | 
| 1166 | 726 | 
| 1167     // Invalidate any script objects created during teardown here, before the | 727     // Invalidate any script objects created during teardown here, before the | 
| 1168     // plugin might actually be unloaded. | 728     // plugin might actually be unloaded. | 
| 1169     container_->clearScriptObjects(); | 729     container_->clearScriptObjects(); | 
| 1170   } | 730   } | 
| 1171 | 731 | 
| 1172   // Cancel any pending requests because otherwise this deleted object will |  | 
| 1173   // be called by the ResourceDispatcher. |  | 
| 1174   std::vector<ClientInfo>::iterator client_index = clients_.begin(); |  | 
| 1175   while (client_index != clients_.end()) { |  | 
| 1176     ClientInfo& client_info = *client_index; |  | 
| 1177 |  | 
| 1178     if (loader_to_ignore == client_info.loader) { |  | 
| 1179       client_index++; |  | 
| 1180       continue; |  | 
| 1181     } |  | 
| 1182 |  | 
| 1183     if (client_info.loader.get()) |  | 
| 1184       client_info.loader->cancel(); |  | 
| 1185 |  | 
| 1186     client_index = clients_.erase(client_index); |  | 
| 1187   } |  | 
| 1188 |  | 
| 1189   // This needs to be called now and not in the destructor since the | 732   // This needs to be called now and not in the destructor since the | 
| 1190   // webframe_ might not be valid anymore. | 733   // webframe_ might not be valid anymore. | 
| 1191   webframe_ = NULL; | 734   webframe_ = NULL; | 
| 1192 } | 735 } | 
| 1193 | 736 | 
| 1194 void WebPluginImpl::SetReferrer(blink::WebURLRequest* request, | 737 void WebPluginImpl::SetReferrer(blink::WebURLRequest* request, | 
| 1195                                 ReferrerValue referrer_flag) { | 738                                 ReferrerValue referrer_flag) { | 
| 1196   switch (referrer_flag) { | 739   switch (referrer_flag) { | 
| 1197     case DOCUMENT_URL: | 740     case DOCUMENT_URL: | 
| 1198       webframe_->setReferrerForRequest(*request, GURL()); | 741       webframe_->setReferrerForRequest(*request, GURL()); | 
| 1199       break; | 742       break; | 
| 1200 | 743 | 
| 1201     case PLUGIN_SRC: | 744     case PLUGIN_SRC: | 
| 1202       webframe_->setReferrerForRequest(*request, plugin_url_); | 745       webframe_->setReferrerForRequest(*request, plugin_url_); | 
| 1203       break; | 746       break; | 
| 1204 | 747 | 
| 1205     default: | 748     default: | 
| 1206       break; | 749       break; | 
| 1207   } | 750   } | 
| 1208 } | 751 } | 
| 1209 | 752 | 
| 1210 }  // namespace content | 753 }  // namespace content | 
| OLD | NEW | 
|---|