webplugin_impl.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/renderer/npapi/webplugin_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/command_line.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/debug/crash_logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/user_metrics_action.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/stringprintf.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "cc/blink/web_layer_impl.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/io_surface_layer.h"
19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/child/appcache/web_application_cache_host_impl.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/child/multipart_response_delegate.h"
21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/plugin_host.h"
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/plugin_instance.h"
23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/webplugin_delegate_impl.h"
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/webplugin_resource_client.h"
25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/common/view_messages.h"
26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/public/common/content_constants.h"
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/common/content_switches.h"
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/renderer/content_renderer_client.h"
29bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/renderer/npapi/webplugin_delegate_proxy.h"
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/renderer/render_frame_impl.h"
31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/renderer/render_process.h"
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/renderer/render_thread_impl.h"
33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/renderer/render_view_impl.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebCString.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebCookieJar.h"
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebCursorInfo.h"
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebData.h"
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebHTTPBody.h"
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLError.h"
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLLoader.h"
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebConsoleMessage.h"
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebDocument.h"
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebFrame.h"
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebInputEvent.h"
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebKit.h"
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebPluginContainer.h"
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebPluginParams.h"
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebURLLoaderOptions.h"
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebView.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/url_util.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing blink::WebCString;
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebCanvas;
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebConsoleMessage;
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebCookieJar;
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebCursorInfo;
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebData;
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebDataSource;
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFrame;
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebHTTPBody;
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebHTTPHeaderVisitor;
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebInputEvent;
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebKeyboardEvent;
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebMouseEvent;
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginContainer;
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginParams;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebRect;
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString;
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURL;
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLError;
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoader;
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoaderClient;
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoaderOptions;
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLRequest;
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLResponse;
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebVector;
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebView;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace content {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class handles individual multipart responses. It is instantiated when
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we receive HTTP status code 206 in the HTTP response. This indicates
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the response could have multiple parts each separated by a boundary
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specified in the response header.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultiPartResponseClient : public WebURLLoaderClient {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MultiPartResponseClient(WebPluginResourceClient* resource_client)
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      : byte_range_lower_bound_(0), resource_client_(resource_client) {}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void willSendRequest(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebURLLoader*, WebURLRequest&, const WebURLResponse&) {}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didSendData(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebURLLoader*, unsigned long long, unsigned long long) {}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the multipart parser encounters an embedded multipart
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // response.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didReceiveResponse(
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebURLLoader*, const WebURLResponse& response) {
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int64 byte_range_upper_bound, instance_size;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!MultipartResponseDelegate::ReadContentRanges(
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            response,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &byte_range_lower_bound_,
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            &byte_range_upper_bound,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &instance_size)) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Receives individual part data from a multipart response.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didReceiveData(WebURLLoader*,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const char* data,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int data_length,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int encoded_data_length) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(ananta)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We should defer further loads on multipart resources on the same lines
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // as regular resources requested by plugins to prevent reentrancy.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource_client_->DidReceiveData(
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data, data_length, byte_range_lower_bound_);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    byte_range_lower_bound_ += data_length;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void didFinishLoading(WebURLLoader*,
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                double finishTime,
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                int64_t total_encoded_data_length) {}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didFail(WebURLLoader*, const WebURLError&) {}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The lower bound of the byte range.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 byte_range_lower_bound_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The handler for the data.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginResourceClient* resource_client_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HeaderFlattener : public WebHTTPHeaderVisitor {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit HeaderFlattener(std::string* buf) : buf_(buf) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void visitHeader(const WebString& name, const WebString& value) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(darin): Should we really exclude headers with an empty value?
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!name.isEmpty() && !value.isEmpty()) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buf_->append(name.utf8());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buf_->append(": ");
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buf_->append(value.utf8());
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buf_->append("\n");
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string* buf_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetAllHeaders(const WebURLResponse& response) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): It is possible for httpStatusText to be empty and still have
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an interesting response, so this check seems wrong.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string result;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WebString& status = response.httpStatusText();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status.isEmpty())
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): Shouldn't we also report HTTP version numbers?
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = base::StringPrintf("HTTP %d ", response.httpStatusCode());
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.append(status.utf8());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.append("\n");
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeaderFlattener flattener(&result);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.visitHTTPHeaderFields(&flattener);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ResponseInfo {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string mime_type;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 last_modified;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 expected_length;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetResponseInfo(const WebURLResponse& response,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ResponseInfo* response_info) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_info->url = response.url();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_info->mime_type = response.mimeType().utf8();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Measured in seconds since 12:00 midnight GMT, January 1, 1970.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_info->last_modified =
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<uint32>(response.lastModifiedDate());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the length comes in as -1, then it indicates that it was not
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read off the HTTP headers. We replicate Safari webkit behavior here,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which is to set it to 0.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_info->expected_length =
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<uint32>(std::max(response.expectedContentLength(), 0LL));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebString content_encoding =
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response.httpHeaderField(WebString::fromUTF8("Content-Encoding"));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!content_encoding.isNull() &&
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !EqualsASCII(content_encoding, "identity")) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't send the compressed content length to the plugin, which only
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cares about the decoded length.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_info->expected_length = 0;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// blink::WebPlugin ----------------------------------------------------------
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WebPluginImpl::ClientInfo {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long id;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginResourceClient* client;
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebURLRequest request;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool pending_failure_notification;
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  linked_ptr<blink::WebURLLoader> loader;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool notify_redirects;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_plugin_src_load;
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int64 data_offset;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::initialize(WebPluginContainer* container) {
232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!render_view_.get()) {
233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    LOG(ERROR) << "No RenderView";
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebPluginDelegateProxy* plugin_delegate = new WebPluginDelegateProxy(
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this, mime_type_, render_view_, render_frame_);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Store the plugin's unique identifier, used by the container to track its
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // script objects.
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  npp_ = plugin_delegate->GetPluginNPP();
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the container before Initialize because the plugin may
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // synchronously call NPN_GetValue to get its container, or make calls
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // passing script objects that need to be tracked, during initialization.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetContainer(container);
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ok = plugin_delegate->Initialize(
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      plugin_url_, arg_names_, arg_values_, load_manually_);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ok) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    plugin_delegate->PluginDestroyed();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebPlugin* replacement_plugin =
255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        GetContentClient()->renderer()->CreatePluginReplacement(
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            render_frame_, file_path_);
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!replacement_plugin)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Disable scripting by this plugin before replacing it with the new
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // one. This plugin also needs destroying, so use destroy(), which will
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // implicitly disable scripting while un-setting the container.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destroy();
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Inform the container of the replacement plugin, then initialize it.
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    container->setPlugin(replacement_plugin);
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return replacement_plugin->initialize(container);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = plugin_delegate;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::destroy() {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetContainer(NULL);
277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPObject* WebPluginImpl::scriptableObject() {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return delegate_->GetPluginScriptableObject();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NPP WebPluginImpl::pluginNPP() {
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return npp_;
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool WebPluginImpl::getFormValue(blink::WebString& value) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 form_value;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_->GetFormValue(&form_value))
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  value = form_value;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::paint(WebCanvas* canvas, const WebRect& paint_rect) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_ || !container_)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force a geometry update if needed to allow plugins like media player
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which defer the initial geometry update to work.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_->reportGeometry();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that |canvas| is only used when in windowless mode.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->Paint(canvas, paint_rect);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::updateGeometry(
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebRect& window_rect, const WebRect& clip_rect,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebVector<WebRect>& cutout_rects, bool is_visible) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginGeometry new_geometry;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_geometry.window = window_;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_geometry.window_rect = window_rect;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_geometry.clip_rect = clip_rect;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_geometry.visible = is_visible;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_geometry.rects_valid = true;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < cutout_rects.size(); ++i)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_geometry.cutout_rects.push_back(cutout_rects[i]);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only send DidMovePlugin if the geometry changed in some way.
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (window_ && (first_geometry_update_ || !new_geometry.Equals(geometry_))) {
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    render_frame_->GetRenderWidget()->SchedulePluginMove(new_geometry);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We invalidate windowed plugins during the first geometry update to
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ensure that they get reparented to the wrapper window in the browser.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This ensures that they become visible and are painted by the OS. This is
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // required as some pages don't invalidate when the plugin is added.
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (first_geometry_update_ && window_) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InvalidateRect(window_rect);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only UpdateGeometry if either the window or clip rects have changed.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_ && (first_geometry_update_ ||
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_geometry.window_rect != geometry_.window_rect ||
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_geometry.clip_rect != geometry_.clip_rect)) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Notify the plugin that its parameters have changed.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->UpdateGeometry(new_geometry.window_rect, new_geometry.clip_rect);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initiate a download on the plugin url. This should be done for the
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first update geometry sequence. We need to ensure that the plugin
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // receives the geometry update before it starts receiving data.
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (first_geometry_update_) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // An empty url corresponds to an EMBED tag with no src attribute.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!load_manually_ && plugin_url_.is_valid()) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The Flash plugin hangs for a while if it receives data before
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // receiving valid plugin geometry. By valid geometry we mean the
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // geometry received by a call to setFrameRect in the Webkit
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // layout code path. To workaround this issue we download the
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // plugin source url on a timer.
358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::MessageLoop::current()->PostTask(
359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          FROM_HERE,
360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          base::Bind(&WebPluginImpl::OnDownloadPluginSrcUrl,
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                     weak_factory_.GetWeakPtr()));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't cache the geometry during the first geometry update. The first
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // geometry update sequence is received when Widget::setParent is called.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For plugins like media player which have a bug where they only honor
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the first geometry update, we have a quirk which ignores the first
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // geometry update. To ensure that these plugins work correctly in cases
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // where we receive only one geometry update from webkit, we also force
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a geometry update during paint which should go out correctly as the
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initial geometry update was not cached.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!first_geometry_update_)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    geometry_ = new_geometry;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  // OS_WIN
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  geometry_ = new_geometry;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_geometry_update_ = false;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::updateFocus(bool focused) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (accepts_input_events_)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->SetFocus(focused);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::updateVisibility(bool visible) {
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!window_)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginGeometry move;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  move.window = window_;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  move.window_rect = gfx::Rect();
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  move.clip_rect = gfx::Rect();
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  move.rects_valid = false;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  move.visible = visible;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  render_frame_->GetRenderWidget()->SchedulePluginMove(move);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::acceptsInputEvents() {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return accepts_input_events_;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::handleInputEvent(
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebInputEvent& event, WebCursorInfo& cursor_info) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swallow context menu events in order to suppress the default context menu.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event.type == WebInputEvent::ContextMenu)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  WebCursor::CursorInfo web_cursor_info;
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool ret = delegate_->HandleInputEvent(event, &web_cursor_info);
41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  cursor_info.type = web_cursor_info.type;
41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  cursor_info.hotSpot = web_cursor_info.hotspot;
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  cursor_info.customImage = web_cursor_info.custom_image;
41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  cursor_info.imageScaleFactor = web_cursor_info.image_scale_factor;
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN)
41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  cursor_info.externalHandle = web_cursor_info.external_handle;
41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return ret;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didReceiveResponse(const WebURLResponse& response) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ignore_response_error_ = false;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResponseInfo response_info;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetResponseInfo(response, &response_info);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->DidReceiveManualResponse(
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_info.url,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_info.mime_type,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetAllHeaders(response),
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_info.expected_length,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_info.last_modified);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didReceiveData(const char* data, int data_length) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->DidReceiveManualData(data, data_length);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didFinishLoading() {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->DidFinishManualLoading();
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didFailLoading(const WebURLError& error) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ignore_response_error_)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->DidManualLoadFail();
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didFinishLoadingFrameRequest(
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebURL& url, void* notify_data) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We're converting a void* into an arbitrary int id.  Though
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // these types are the same size on all the platforms we support,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the compiler may complain as though they are different, so to
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // make the casting gods happy go through an intptr_t (the union
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of void* and int) rather than converting straight across.
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->DidFinishLoadWithReason(
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, NPRES_DONE, reinterpret_cast<intptr_t>(notify_data));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didFailLoadingFrameRequest(
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebURL& url, void* notify_data, const WebURLError& error) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NPReason reason =
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error.reason == net::ERR_ABORTED ? NPRES_USER_BREAK : NPRES_NETWORK_ERR;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See comment in didFinishLoadingFrameRequest about the cast here.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->DidFinishLoadWithReason(
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, reason, reinterpret_cast<intptr_t>(notify_data));
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::isPlaceholder() {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WebPluginImpl::LoaderClient::LoaderClient(WebPluginImpl* parent)
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : parent_(parent) {}
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPluginImpl::LoaderClient::willSendRequest(
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blink::WebURLLoader* loader, blink::WebURLRequest& newRequest,
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const blink::WebURLResponse& redirectResponse) {
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent_->willSendRequest(loader, newRequest, redirectResponse);
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPluginImpl::LoaderClient::didSendData(
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blink::WebURLLoader* loader, unsigned long long bytesSent,
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    unsigned long long totalBytesToBeSent) {
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent_->didSendData(loader, bytesSent, totalBytesToBeSent);
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPluginImpl::LoaderClient::didReceiveResponse(
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blink::WebURLLoader* loader, const blink::WebURLResponse& response) {
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent_->didReceiveResponse(loader, response);
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPluginImpl::LoaderClient::didDownloadData(
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blink::WebURLLoader* loader, int dataLength, int encodedDataLength) {
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPluginImpl::LoaderClient::didReceiveData(
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blink::WebURLLoader* loader, const char* data,
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int dataLength, int encodedDataLength) {
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent_->didReceiveData(loader, data, dataLength, encodedDataLength);
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPluginImpl::LoaderClient::didReceiveCachedMetadata(
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blink::WebURLLoader* loader, const char* data, int dataLength) {
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPluginImpl::LoaderClient::didFinishLoading(
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blink::WebURLLoader* loader, double finishTime,
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64_t total_encoded_data_length) {
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent_->didFinishLoading(loader, finishTime);
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebPluginImpl::LoaderClient::didFail(
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blink::WebURLLoader* loader, const blink::WebURLError& error) {
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent_->didFail(loader, error);
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebPluginImpl::WebPluginImpl(
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* webframe,
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebPluginParams& params,
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& file_path,
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::WeakPtr<RenderViewImpl>& render_view,
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RenderFrameImpl* render_frame)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : windowless_(false),
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_(gfx::kNullPluginWindow),
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accepts_input_events_(false),
535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame_(render_frame),
536ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      render_view_(render_view),
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      webframe_(webframe),
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(NULL),
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      container_(NULL),
54090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      npp_(NULL),
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      plugin_url_(params.url),
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_manually_(params.loadManually),
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      first_geometry_update_(true),
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ignore_response_error_(false),
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_path_(file_path),
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mime_type_(base::UTF16ToASCII(params.mimeType)),
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      loader_client_(this),
5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_factory_(this) {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size());
5506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::StringToLowerASCII(&mime_type_);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < params.attributeNames.size(); ++i) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arg_names_.push_back(params.attributeNames[i].utf8());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arg_values_.push_back(params.attributeValues[i].utf8());
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set subresource URL for crash reporting.
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::debug::SetCrashKeyValue("subresource_url", plugin_url_.spec());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebPluginImpl::~WebPluginImpl() {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::SetWindow(gfx::PluginWindowHandle window) {
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (window) {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!windowless_);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_ = window;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(kbr): remove. http://crbug.com/105344
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lie to ourselves about being windowless even if we got a fake
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // plugin window handle, so we continue to get input events.
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    windowless_ = true;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accepts_input_events_ = true;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We do not really need to notify the page delegate that a plugin
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // window was created -- so don't.
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accepts_input_events_ = false;
579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
580ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif  // OS_MACOSX
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!window_);  // Make sure not called twice.
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    windowless_ = true;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accepts_input_events_ = true;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::SetAcceptsInputEvents(bool accepts) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  accepts_input_events_ = accepts;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::WillDestroyWindow(gfx::PluginWindowHandle window) {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(window, window_);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = gfx::kNullPluginWindow;
595a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (render_view_.get())
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    render_frame_->GetRenderWidget()->CleanupWindowInPluginMoves(window);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL WebPluginImpl::CompleteURL(const char* url) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!webframe_) {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GURL();
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): Is conversion from UTF8 correct here?
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return webframe_->document().completeURL(WebString::fromUTF8(url));
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::CancelResource(unsigned long id) {
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (clients_[i].id == id) {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (clients_[i].loader.get()) {
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        clients_[i].loader->setDefersLoading(false);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        clients_[i].loader->cancel();
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RemoveClient(i);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::SetPostData(WebURLRequest* request,
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const char *buf,
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                uint32 length) {
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> names;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> values;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> body;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = PluginHost::SetPostData(buf, length, &names, &values, &body);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < names.size(); ++i) {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request->addHTTPHeaderField(WebString::fromUTF8(names[i]),
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                WebString::fromUTF8(values[i]));
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebString content_type_header = WebString::fromUTF8("Content-Type");
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WebString& content_type =
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request->httpHeaderField(content_type_header);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (content_type.isEmpty()) {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request->setHTTPHeaderField(
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_type_header,
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WebString::fromUTF8("application/x-www-form-urlencoded"));
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebHTTPBody http_body;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (body.size()) {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    http_body.initialize();
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    http_body.appendData(WebData(&body[0], body.size()));
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request->setHTTPBody(http_body);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::IsValidUrl(const GURL& url, Referrer referrer_flag) {
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (referrer_flag == PLUGIN_SRC &&
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mime_type_ == kFlashPluginSwfMimeType &&
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.GetOrigin() != plugin_url_.GetOrigin()) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do url check to make sure that there are no @, ;, \ chars in between url
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // scheme and url path.
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* url_to_check(url.spec().data());
6605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    url::Parsed parsed;
6615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    url::ParseStandardURL(url_to_check, strlen(url_to_check), &parsed);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (parsed.path.begin <= parsed.scheme.end())
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string string_to_search;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string_to_search.assign(url_to_check + parsed.scheme.end(),
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        parsed.path.begin - parsed.scheme.end());
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (string_to_search.find("@") != std::string::npos ||
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        string_to_search.find(";") != std::string::npos ||
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        string_to_search.find("\\") != std::string::npos)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebPluginImpl::RoutingStatus WebPluginImpl::RouteToFrame(
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* url,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_javascript_url,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool popups_allowed,
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* method,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* target,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* buf,
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int len,
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int notify_id,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Referrer referrer_flag) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is no target, there is nothing to do
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!target)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NOT_ROUTED;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This could happen if the WebPluginContainer was already deleted.
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!webframe_)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NOT_ROUTED;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebString target_str = WebString::fromUTF8(target);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Take special action for JavaScript URLs
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_javascript_url) {
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* target_frame =
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        webframe_->view()->findFrameByName(target_str, webframe_);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For security reasons, do not allow JavaScript on frames
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // other than this frame.
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (target_frame != webframe_) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(darin): Localize this message.
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char kMessage[] =
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Ignoring cross-frame javascript URL load requested by plugin.";
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      webframe_->addMessageToConsole(
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          WebConsoleMessage(WebConsoleMessage::LevelError,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            WebString::fromUTF8(kMessage)));
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ROUTED;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Route javascript calls back to the plugin.
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NOT_ROUTED;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we got this far, we're routing content to a target frame.
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go fetch the URL.
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL complete_url = CompleteURL(url);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove when flash bug is fixed. http://crbug.com/40016.
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!WebPluginImpl::IsValidUrl(complete_url, referrer_flag))
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return INVALID_URL;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (strcmp(method, "GET") != 0) {
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We're only going to route HTTP/HTTPS requests
7263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!complete_url.SchemeIsHTTPOrHTTPS())
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return INVALID_URL;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLRequest request(complete_url);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetReferrer(&request, referrer_flag);
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.setHTTPMethod(WebString::fromUTF8(method));
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.setFirstPartyForCookies(
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      webframe_->document().firstPartyForCookies());
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.setHasUserGesture(popups_allowed);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (len > 0) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SetPostData(&request, buf, len)) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Uhoh - we're in trouble.  There isn't a good way
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // to recover at this point.  Break out.
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ROUTED;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_->loadFrameRequest(
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request, target_str, notify_id != 0, reinterpret_cast<void*>(notify_id));
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ROUTED;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPObject* WebPluginImpl::GetWindowScriptNPObject() {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!webframe_) {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return webframe_->windowObject();
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPObject* WebPluginImpl::GetPluginElement() {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return container_->scriptableObjectForElement();
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::FindProxyForUrl(const GURL& url, std::string* proxy_list) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Proxy resolving doesn't work in single-process mode.
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::SetCookie(const GURL& url,
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const GURL& first_party_for_cookies,
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const std::string& cookie) {
771ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!render_view_.get())
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebCookieJar* cookie_jar = render_frame_->cookie_jar();
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cookie_jar) {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "No cookie jar!";
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_jar->setCookie(
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, first_party_for_cookies, WebString::fromUTF8(cookie));
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string WebPluginImpl::GetCookies(const GURL& url,
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const GURL& first_party_for_cookies) {
786ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!render_view_.get())
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebCookieJar* cookie_jar = render_frame_->cookie_jar();
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cookie_jar) {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "No cookie jar!";
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::UTF16ToUTF8(cookie_jar->cookies(url, first_party_for_cookies));
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::URLRedirectResponse(bool allow, int resource_id) {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (clients_[i].id == static_cast<unsigned long>(resource_id)) {
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (clients_[i].loader.get()) {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (allow) {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          clients_[i].loader->setDefersLoading(false);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          clients_[i].loader->cancel();
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (clients_[i].client)
8077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            clients_[i].client->DidFail(clients_[i].id);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool WebPluginImpl::CheckIfRunInsecureContent(const GURL& url) {
81658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!webframe_)
81758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return true;
81858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
81958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return webframe_->checkIfRunInsecureContent(url);
82058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
82158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebPluginAcceleratedSurface* WebPluginImpl::GetAcceleratedSurface(
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GpuPreference gpu_preference) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::AcceleratedPluginEnabledRendering() {
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::AcceleratedPluginAllocatedIOSurface(int32 width,
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        int32 height,
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        uint32 surface_id) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_io_surface_allocated_ = true;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_io_surface_width_ = width;
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_io_surface_height_ = height;
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_io_surface_id_ = surface_id;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::AcceleratedPluginSwappedIOSurface() {
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!container_)
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Deferring the call to setBackingIOSurfaceId is an attempt to
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // work around garbage occasionally showing up in the plugin's
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // area during live resizing of Core Animation plugins. The
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // assumption was that by the time this was called, the plugin
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // process would have populated the newly allocated IOSurface. It
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is not 100% clear at this point why any garbage is getting
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // through. More investigation is needed. http://crbug.com/105346
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (next_io_surface_allocated_) {
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (next_io_surface_id_) {
8527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (!io_surface_layer_.get()) {
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        io_surface_layer_ = cc::IOSurfaceLayer::Create();
85403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        web_layer_.reset(new cc_blink::WebLayerImpl(io_surface_layer_));
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        container_->setWebLayer(web_layer_.get());
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      io_surface_layer_->SetIOSurfaceProperties(
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          next_io_surface_id_,
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gfx::Size(next_io_surface_width_, next_io_surface_height_));
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      container_->setWebLayer(NULL);
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_layer_.reset();
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      io_surface_layer_ = NULL;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_io_surface_allocated_ = false;
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
8677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (io_surface_layer_.get())
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      io_surface_layer_->SetNeedsDisplay();
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::Invalidate() {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (container_)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container_->invalidate();
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::InvalidateRect(const gfx::Rect& rect) {
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (container_)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container_->invalidateRect(rect);
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::OnDownloadPluginSrcUrl() {
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HandleURLRequestInternal(
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      plugin_url_.spec().c_str(), "GET", NULL, NULL, 0, 0, false, DOCUMENT_URL,
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false, true);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebPluginResourceClient* WebPluginImpl::GetClientFromLoader(
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebURLLoader* loader) {
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientInfo* client_info = GetClientInfoFromLoader(loader);
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_info)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return client_info->client;
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebPluginImpl::ClientInfo* WebPluginImpl::GetClientInfoFromLoader(
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebURLLoader* loader) {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (clients_[i].loader.get() == loader)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &clients_[i];
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::willSendRequest(WebURLLoader* loader,
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    WebURLRequest& request,
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const WebURLResponse& response) {
91158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(jam): THIS LOGIC IS COPIED IN PluginURLFetcher::OnReceivedRedirect
91258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // until kDirectNPAPIRequests is the default and we can remove this old path.
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginImpl::ClientInfo* client_info = GetClientInfoFromLoader(loader);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_info) {
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Currently this check is just to catch an https -> http redirect when
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // loading the main plugin src URL. Longer term, we could investigate
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // firing mixed diplay or scripting issues for subresource loads
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // initiated by plug-ins.
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (client_info->is_plugin_src_load &&
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        webframe_ &&
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !webframe_->checkIfRunInsecureContent(request.url())) {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loader->cancel();
9237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      client_info->client->DidFail(client_info->id);
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (net::HttpResponseHeaders::IsRedirectResponseCode(
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            response.httpStatusCode())) {
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If the plugin does not participate in url redirect notifications then
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // just block cross origin 307 POST redirects.
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!client_info->notify_redirects) {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (response.httpStatusCode() == 307 &&
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            LowerCaseEqualsASCII(request.httpMethod().utf8(), "post")) {
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GURL original_request_url(response.url());
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GURL response_url(request.url());
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (original_request_url.GetOrigin() != response_url.GetOrigin()) {
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            loader->setDefersLoading(true);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            loader->cancel();
9387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            client_info->client->DidFail(client_info->id);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        loader->setDefersLoading(true);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_info->client->WillSendRequest(request.url(),
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         response.httpStatusCode());
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didSendData(WebURLLoader* loader,
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                unsigned long long bytes_sent,
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                unsigned long long total_bytes_to_be_sent) {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didReceiveResponse(WebURLLoader* loader,
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const WebURLResponse& response) {
958d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(jam): THIS LOGIC IS COPIED IN PluginURLFetcher::OnReceivedResponse
959d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // until kDirectNPAPIRequests is the default and we can remove this old path.
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kHttpPartialResponseStatusCode = 206;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kHttpResponseSuccessStatusCode = 200;
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginResourceClient* client = GetClientFromLoader(loader);
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResponseInfo response_info;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetResponseInfo(response, &response_info);
9697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ClientInfo* client_info = GetClientInfoFromLoader(loader);
9707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!client_info)
9717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool request_is_seekable = true;
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client->IsMultiByteResponseExpected()) {
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response.httpStatusCode() == kHttpPartialResponseStatusCode) {
976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ClientInfo* client_info = GetClientInfoFromLoader(loader);
977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!client_info)
978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return;
979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (HandleHttpMultipartResponse(response, client)) {
980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        // Multiple ranges requested, data will be delivered by
981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        // MultipartResponseDelegate.
982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        client_info->data_offset = 0;
983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return;
984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int64 upper_bound = 0, instance_size = 0;
986eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Single range requested - go through original processing for
987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // non-multipart requests, but update data offset.
988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      MultipartResponseDelegate::ReadContentRanges(response,
989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                   &client_info->data_offset,
990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                   &upper_bound,
991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                   &instance_size);
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (response.httpStatusCode() == kHttpResponseSuccessStatusCode) {
993a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      RenderThreadImpl::current()->RecordAction(
9945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UserMetricsAction("Plugin_200ForByteRange"));
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If the client issued a byte range request and the server responds with
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // HTTP 200 OK, it indicates that the server does not support byte range
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // requests.
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We need to emulate Firefox behavior by doing the following:-
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // 1. Destroy the plugin instance in the plugin process. Ensure that
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //    existing resource requests initiated for the plugin instance
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //    continue to remain valid.
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // 2. Create a new plugin instance and notify it about the response
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //    received here.
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!ReinitializePluginForResponse(loader)) {
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The server does not support byte range requests. No point in creating
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // seekable streams.
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_is_seekable = false;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete client;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client = NULL;
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Create a new resource client for this request.
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t i = 0; i < clients_.size(); ++i) {
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (clients_[i].loader.get() == loader) {
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          WebPluginResourceClient* resource_client =
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              delegate_->CreateResourceClient(clients_[i].id, plugin_url_, 0);
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          clients_[i].client = resource_client;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          client = resource_client;
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(client != NULL);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling into a plugin could result in reentrancy if the plugin yields
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // control to the OS like entering a modal loop etc. Prevent this by
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stopping further loading until the plugin notifies us that it is ready to
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // accept data
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  loader->setDefersLoading(true);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->DidReceiveResponse(
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_info.mime_type,
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetAllHeaders(response),
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_info.expected_length,
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response_info.last_modified,
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_is_seekable);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // error codes in the stream header and as a result, was unaware of the
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fate of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroy the stream and invoke the NPP_DestroyStream function on the
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // plugin if the HTTP request fails.
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& url = response.url();
10501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme)) {
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response.httpStatusCode() < 100 || response.httpStatusCode() >= 400) {
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The plugin instance could be in the process of deletion here.
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Verify if the WebPluginResourceClient instance still exists before
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // use.
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClientInfo* client_info = GetClientInfoFromLoader(loader);
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (client_info) {
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        client_info->pending_failure_notification = true;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didReceiveData(WebURLLoader* loader,
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const char *buffer,
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int data_length,
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int encoded_data_length) {
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginResourceClient* client = GetClientFromLoader(loader);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client)
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiPartResponseHandlerMap::iterator index =
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_part_response_map_.find(client);
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index != multi_part_response_map_.end()) {
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MultipartResponseDelegate* multi_part_handler = (*index).second;
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(multi_part_handler != NULL);
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    multi_part_handler->OnReceivedData(buffer,
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       data_length,
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       encoded_data_length);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    loader->setDefersLoading(true);
1081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ClientInfo* client_info = GetClientInfoFromLoader(loader);
1082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    client->DidReceiveData(buffer, data_length, client_info->data_offset);
1083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    client_info->data_offset += data_length;
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didFinishLoading(WebURLLoader* loader, double finishTime) {
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientInfo* client_info = GetClientInfoFromLoader(loader);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_info && client_info->client) {
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MultiPartResponseHandlerMap::iterator index =
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_part_response_map_.find(client_info->client);
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (index != multi_part_response_map_.end()) {
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete (*index).second;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_part_response_map_.erase(index);
1095d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      DidStopLoading();
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    loader->setDefersLoading(true);
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebPluginResourceClient* resource_client = client_info->client;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The ClientInfo can get deleted in the call to DidFinishLoading below.
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // It is not safe to access this structure after that.
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_info->client = NULL;
11027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    resource_client->DidFinishLoading(client_info->id);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::didFail(WebURLLoader* loader,
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const WebURLError& error) {
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientInfo* client_info = GetClientInfoFromLoader(loader);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_info && client_info->client) {
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    loader->setDefersLoading(true);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebPluginResourceClient* resource_client = client_info->client;
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The ClientInfo can get deleted in the call to DidFail below.
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // It is not safe to access this structure after that.
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_info->client = NULL;
11157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    resource_client->DidFail(client_info->id);
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::RemoveClient(size_t i) {
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  clients_.erase(clients_.begin() + i);
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::RemoveClient(WebURLLoader* loader) {
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < clients_.size(); ++i) {
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (clients_[i].loader.get() == loader) {
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RemoveClient(i);
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::SetContainer(WebPluginContainer* container) {
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!container)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TearDownPluginInstance(NULL);
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_ = container;
113690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (container_)
113790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    container_->allowScriptObjects();
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::HandleURLRequest(const char* url,
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const char* method,
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const char* target,
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const char* buf,
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     unsigned int len,
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int notify_id,
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool popups_allowed,
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool notify_redirects) {
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetURL/PostURL requests initiated explicitly by plugins should specify the
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // plugin SRC url as the referrer if it is available.
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HandleURLRequestInternal(
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, method, target, buf, len, notify_id, popups_allowed, PLUGIN_SRC,
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notify_redirects, false);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::HandleURLRequestInternal(const char* url,
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const char* method,
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const char* target,
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const char* buf,
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             unsigned int len,
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int notify_id,
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             bool popups_allowed,
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             Referrer referrer_flag,
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             bool notify_redirects,
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             bool is_plugin_src_load) {
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For this request, we either route the output to a frame
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because a target has been specified, or we handle the request
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here, i.e. by executing the script if it is a javascript url
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or by initiating a download on the URL, etc. There is one special
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // case in that the request is a javascript url and the target is "_self",
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in which case we route the output to the plugin rather than routing it
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the plugin's frame.
11725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool is_javascript_url =
11731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url::FindAndCompareScheme(url, strlen(url), url::kJavaScriptScheme, NULL);
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RoutingStatus routing_status = RouteToFrame(
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, is_javascript_url, popups_allowed, method, target, buf, len,
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notify_id, referrer_flag);
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (routing_status == ROUTED)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_javascript_url) {
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL gurl(url);
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebString result = container_->executeScriptURL(gurl, popups_allowed);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // delegate_ could be NULL because executeScript caused the container to
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be deleted.
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate_) {
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->SendJavaScriptStream(
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          gurl, result.utf8(), !result.isNull(), notify_id);
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long resource_id = GetNextResourceId();
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!resource_id)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL complete_url = CompleteURL(url);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove when flash bug is fixed. http://crbug.com/40016.
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!WebPluginImpl::IsValidUrl(complete_url, referrer_flag))
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the RouteToFrame call returned a failure then inform the result
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // back to the plugin asynchronously.
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((routing_status == INVALID_URL) ||
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (routing_status == GENERAL_FAILURE)) {
120758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    WebPluginResourceClient* resource_client = delegate_->CreateResourceClient(
120858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        resource_id, complete_url, notify_id);
120958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (resource_client)
121058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      resource_client->DidFail(resource_id);
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CreateResourceClient() sends a synchronous IPC message so it's possible
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that TearDownPluginInstance() may have been called in the nested
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message loop.  If so, don't start the request.
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
12214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          switches::kDisableDirectNPAPIRequests)) {
122258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We got here either because the plugin called GetURL/PostURL, or because
122358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // we're fetching the data for an embed tag. If we're in multi-process mode,
122458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // we want to fetch the data in the plugin process as the renderer won't be
122558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // able to request any origin when site isolation is in place. So bounce
122658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // this request back to the plugin process which will use ResourceDispatcher
122758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // to fetch the url.
122858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
122958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(jam): any better way of getting this? Can't find a way to get
123058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // frame()->loader()->outgoingReferrer() which
123158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // WebFrameImpl::setReferrerForRequest does.
123258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    WebURLRequest request(complete_url);
123358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    SetReferrer(&request, referrer_flag);
123458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    GURL referrer(
123558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        request.httpHeaderField(WebString::fromUTF8("Referer")).utf8());
123658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
123758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    GURL first_party_for_cookies = webframe_->document().firstPartyForCookies();
123858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    delegate_->FetchURL(resource_id, notify_id, complete_url,
1239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        first_party_for_cookies, method, buf, len, referrer,
1240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        notify_redirects, is_plugin_src_load, 0,
12415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        render_frame_->GetRoutingID(),
12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        render_view_->GetRoutingID());
124358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
124458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    WebPluginResourceClient* resource_client = delegate_->CreateResourceClient(
124558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        resource_id, complete_url, notify_id);
124658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!resource_client)
124758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
124858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    InitiateHTTPRequest(resource_id, resource_client, complete_url, method, buf,
124958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        len, NULL, referrer_flag, notify_redirects,
125058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        is_plugin_src_load);
125158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned long WebPluginImpl::GetNextResourceId() {
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!webframe_)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebView* view = webframe_->view();
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!view)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return view->createUniqueIdentifierForRequest();
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::InitiateHTTPRequest(unsigned long resource_id,
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        WebPluginResourceClient* client,
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const GURL& url,
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const char* method,
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const char* buf,
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int buf_len,
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const char* range_info,
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        Referrer referrer_flag,
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool notify_redirects,
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool is_plugin_src_load) {
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!client) {
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientInfo info;
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.id = resource_id;
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.client = client;
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.request.initialize();
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.request.setURL(url);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.request.setFirstPartyForCookies(
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      webframe_->document().firstPartyForCookies());
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.request.setRequestorProcessID(delegate_->GetProcessId());
12865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(mkwst): Is this a request for a plugin object itself
12875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // (RequestContextObject), or a request that the plugin makes
12885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // (RequestContextPlugin)?
12895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  info.request.setRequestContext(WebURLRequest::RequestContextPlugin);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.request.setHTTPMethod(WebString::fromUTF8(method));
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.pending_failure_notification = false;
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.notify_redirects = notify_redirects;
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.is_plugin_src_load = is_plugin_src_load;
1294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  info.data_offset = 0;
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (range_info) {
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.request.addHTTPHeaderField(WebString::fromUTF8("Range"),
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    WebString::fromUTF8(range_info));
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (strcmp(method, "POST") == 0) {
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Adds headers or form data to a request.  This must be called before
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we initiate the actual request.
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetPostData(&info.request, buf, buf_len);
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetReferrer(&info.request, referrer_flag);
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLLoaderOptions options;
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.allowCredentials = true;
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options.crossOriginRequestPolicy =
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.loader.reset(webframe_->createAssociatedURLLoader(options));
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!info.loader.get())
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
13165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  info.loader->loadAsynchronously(info.request, &loader_client_);
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  clients_.push_back(info);
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::CancelDocumentLoad() {
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (webframe_) {
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ignore_response_error_ = true;
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    webframe_->stopLoading();
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::InitiateHTTPRangeRequest(
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* url, const char* range_info, int range_request_id) {
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long resource_id = GetNextResourceId();
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!resource_id)
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL complete_url = CompleteURL(url);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove when flash bug is fixed. http://crbug.com/40016.
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!WebPluginImpl::IsValidUrl(complete_url,
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 load_manually_ ? NO_REFERRER : PLUGIN_SRC))
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginResourceClient* resource_client =
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->CreateSeekableResourceClient(resource_id, range_request_id);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitiateHTTPRequest(
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resource_id, resource_client, complete_url, "GET", NULL, 0, range_info,
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_manually_ ? NO_REFERRER : PLUGIN_SRC, false, false);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1348d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void WebPluginImpl::DidStartLoading() {
1349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (render_view_.get()) {
1350d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(darin): Make is_loading_ be a counter!
1351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_->DidStartLoading();
1352d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
1353d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
1354d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1355d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void WebPluginImpl::DidStopLoading() {
1356d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (render_view_.get()) {
1357d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(darin): Make is_loading_ be a counter!
1358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_view_->DidStopLoading();
1359d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
1360d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
1361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::SetDeferResourceLoading(unsigned long resource_id,
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            bool defer) {
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ClientInfo>::iterator client_index = clients_.begin();
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (client_index != clients_.end()) {
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientInfo& client_info = *client_index;
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (client_info.id == resource_id) {
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_info.loader->setDefersLoading(defer);
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If we determined that the request had failed via the HTTP headers
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // in the response then we send out a failure notification to the
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // plugin process, as certain plugins don't handle HTTP failure codes
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // correctly.
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!defer && client_info.client &&
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          client_info.pending_failure_notification) {
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // The ClientInfo and the iterator can become invalid due to the call
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // to DidFail below.
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WebPluginResourceClient* resource_client = client_info.client;
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        client_info.loader->cancel();
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        clients_.erase(client_index++);
13827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        resource_client->DidFail(resource_id);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_index++;
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::IsOffTheRecord() {
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool WebPluginImpl::HandleHttpMultipartResponse(
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebURLResponse& response, WebPluginResourceClient* client) {
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string multipart_boundary;
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!MultipartResponseDelegate::ReadMultipartBoundary(
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          response, &multipart_boundary)) {
1399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DidStartLoading();
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiPartResponseClient* multi_part_response_client =
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MultiPartResponseClient(client);
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate* multi_part_response_handler =
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MultipartResponseDelegate(multi_part_response_client, NULL,
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    response,
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    multipart_boundary);
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  multi_part_response_map_[client] = multi_part_response_handler;
1412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return true;
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginImpl::ReinitializePluginForResponse(
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebURLLoader* loader) {
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebFrame* webframe = webframe_;
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!webframe)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebView* webview = webframe->view();
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!webview)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebPluginContainer* container_widget = container_;
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy the current plugin instance.
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TearDownPluginInstance(loader);
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_ = container_widget;
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  webframe_ = webframe;
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebPluginDelegateProxy* plugin_delegate = new WebPluginDelegateProxy(
14345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this, mime_type_, render_view_, render_frame_);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Store the plugin's unique identifier, used by the container to track its
1437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // script objects, and enable script objects (since Initialize may use them
1438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // even if it fails).
1439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  npp_ = plugin_delegate->GetPluginNPP();
1440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  container_->allowScriptObjects();
1441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ok = plugin_delegate && plugin_delegate->Initialize(
144358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      plugin_url_, arg_names_, arg_values_, load_manually_);
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ok) {
1446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    container_->clearScriptObjects();
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container_ = NULL;
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(iyengar) Should we delete the current plugin instance here?
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = plugin_delegate;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force a geometry update to occur to ensure that the plugin becomes
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // visible.
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_->reportGeometry();
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The plugin move sequences accumulated via DidMove are sent to the browser
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whenever the renderer paints. Force a paint here to ensure that changes
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the plugin window are propagated to the browser.
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container_->invalidate();
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginImpl::TearDownPluginInstance(
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebURLLoader* loader_to_ignore) {
146790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // JavaScript garbage collection may cause plugin script object references to
146890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // be retained long after the plugin is destroyed. Some plugins won't cope
146990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // with their objects being released after they've been destroyed, and once
147090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // we've actually unloaded the plugin the object's releaseobject() code may
147190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // no longer be in memory. The container tracks the plugin's objects and lets
147290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // us invalidate them, releasing the references to them held by the JavaScript
147390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // runtime.
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (container_) {
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container_->clearScriptObjects();
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    container_->setWebLayer(NULL);
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Call PluginDestroyed() first to prevent the plugin from calling us back
148090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // in the middle of tearing down the render tree.
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
148290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // The plugin may call into the browser and pass script objects even during
148390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // teardown, so temporarily re-enable plugin script objects.
148490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(container_);
148590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    container_->allowScriptObjects();
148690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->PluginDestroyed();
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_ = NULL;
148990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
149090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Invalidate any script objects created during teardown here, before the
149190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // plugin might actually be unloaded.
149290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    container_->clearScriptObjects();
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel any pending requests because otherwise this deleted object will
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be called by the ResourceDispatcher.
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ClientInfo>::iterator client_index = clients_.begin();
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (client_index != clients_.end()) {
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientInfo& client_info = *client_index;
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (loader_to_ignore == client_info.loader) {
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_index++;
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (client_info.loader.get())
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_info.loader->cancel();
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_index = clients_.erase(client_index);
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This needs to be called now and not in the destructor since the
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // webframe_ might not be valid anymore.
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  webframe_ = NULL;
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebPluginImpl::SetReferrer(blink::WebURLRequest* request,
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Referrer referrer_flag) {
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (referrer_flag) {
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DOCUMENT_URL:
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      webframe_->setReferrerForRequest(*request, GURL());
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PLUGIN_SRC:
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      webframe_->setReferrerForRequest(*request, plugin_url_);
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1534ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}  // namespace content
1535