158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/plugin_url_fetcher.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/child_thread.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/child/multipart_response_delegate.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/plugin_host.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/plugin_instance.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/plugin_stream_url.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/npapi/webplugin.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/webplugin_resource_client.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/plugin_messages.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/child/request_extra_data.h"
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/child/request_info.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/resource_dispatcher.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/child/resource_loader_bridge.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/web_url_loader_impl.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/resource_request_body.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/service_worker/service_worker_types.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/common/resource_response_info.h"
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/load_flags.h"
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/net_errors.h"
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/http/http_response_headers.h"
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "net/url_request/redirect_info.h"
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace content {
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace {
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This class handles individual multipart responses. It is instantiated when
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// we receive HTTP status code 206 in the HTTP response. This indicates
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// that the response could have multiple parts each separated by a boundary
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// specified in the response header.
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// TODO(jam): this is similar to MultiPartResponseClient in webplugin_impl.cc,
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// we should remove that other class once we switch to loading from the plugin
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// process by default.
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MultiPartResponseClient : public blink::WebURLLoaderClient {
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  explicit MultiPartResponseClient(PluginStreamUrl* plugin_stream)
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      : byte_range_lower_bound_(0), plugin_stream_(plugin_stream) {}
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // blink::WebURLLoaderClient implementation:
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void didReceiveResponse(
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebURLLoader* loader,
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const blink::WebURLResponse& response) OVERRIDE {
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int64 byte_range_upper_bound, instance_size;
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!MultipartResponseDelegate::ReadContentRanges(response,
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                      &byte_range_lower_bound_,
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                      &byte_range_upper_bound,
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                      &instance_size)) {
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      NOTREACHED();
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void didReceiveData(blink::WebURLLoader* loader,
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              const char* data,
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              int data_length,
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              int encoded_data_length) OVERRIDE {
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(ananta)
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // We should defer further loads on multipart resources on the same lines
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // as regular resources requested by plugins to prevent reentrancy.
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int64 data_offset = byte_range_lower_bound_;
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    byte_range_lower_bound_ += data_length;
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    plugin_stream_->DidReceiveData(data, data_length, data_offset);
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // DANGER: this instance may be deleted at this point.
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The lower bound of the byte range.
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int64 byte_range_lower_bound_;
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The handler for the data.
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PluginStreamUrl* plugin_stream_;
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)PluginURLFetcher::PluginURLFetcher(PluginStreamUrl* plugin_stream,
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const GURL& url,
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const GURL& first_party_for_cookies,
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const std::string& method,
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   const char* buf,
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   unsigned int len,
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const GURL& referrer,
87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                   const std::string& range,
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   bool notify_redirects,
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   bool is_plugin_src_load,
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   int origin_pid,
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   int render_frame_id,
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   int render_view_id,
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   unsigned long resource_id,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   bool copy_stream_data)
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : plugin_stream_(plugin_stream),
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      url_(url),
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      first_party_for_cookies_(first_party_for_cookies),
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      referrer_(referrer),
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      notify_redirects_(notify_redirects),
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      is_plugin_src_load_(is_plugin_src_load),
101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      origin_pid_(origin_pid),
102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      render_frame_id_(render_frame_id),
103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      render_view_id_(render_view_id),
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      resource_id_(resource_id),
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      copy_stream_data_(copy_stream_data),
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      data_offset_(0),
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pending_failure_notification_(false) {
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  RequestInfo request_info;
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.method = method;
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.url = url;
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.first_party_for_cookies = first_party_for_cookies;
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.referrer = referrer;
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.requestor_pid = origin_pid;
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  request_info.request_type = RESOURCE_TYPE_OBJECT;
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.routing_id = render_view_id;
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  RequestExtraData extra_data;
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  extra_data.set_render_frame_id(render_frame_id);
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  extra_data.set_is_main_frame(false);
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request_info.extra_data = &extra_data;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::vector<char> body;
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (method == "POST") {
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool content_type_found = false;
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::vector<std::string> names;
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::vector<std::string> values;
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    PluginHost::SetPostData(buf, len, &names, &values, &body);
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (size_t i = 0; i < names.size(); ++i) {
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (!request_info.headers.empty())
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        request_info.headers += "\r\n";
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_info.headers += names[i] + ": " + values[i];
133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (LowerCaseEqualsASCII(names[i], "content-type"))
134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        content_type_found = true;
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!content_type_found) {
138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (!request_info.headers.empty())
139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        request_info.headers += "\r\n";
140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      request_info.headers += "Content-Type: application/x-www-form-urlencoded";
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  } else {
143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (!range.empty())
144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      request_info.headers = std::string("Range: ") + range;
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bridge_.reset(ChildThread::current()->resource_dispatcher()->CreateBridge(
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_info));
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!body.empty()) {
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_refptr<ResourceRequestBody> request_body =
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        new ResourceRequestBody;
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    request_body->AppendBytes(&body[0], body.size());
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bridge_->SetRequestBody(request_body.get());
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bridge_->Start(this);
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(jam): range requests
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)PluginURLFetcher::~PluginURLFetcher() {
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::Cancel() {
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bridge_->Cancel();
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Due to races and nested event loops, PluginURLFetcher may still receive
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // events from the bridge before being destroyed. Do not forward additional
169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // events back to the plugin, via either |plugin_stream_| or
170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // |multipart_delegate_| which has its own pointer via
171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // MultiPartResponseClient.
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (multipart_delegate_)
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    multipart_delegate_->Cancel();
174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  plugin_stream_ = NULL;
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::URLRedirectResponse(bool allow) {
178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!plugin_stream_)
179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (allow) {
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bridge_->SetDefersLoading(false);
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bridge_->Cancel();
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    plugin_stream_->DidFail(resource_id_);  // That will delete |this|.
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnUploadProgress(uint64 position, uint64 size) {
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool PluginURLFetcher::OnReceivedRedirect(
1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const net::RedirectInfo& redirect_info,
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ResourceResponseInfo& info) {
195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!plugin_stream_)
196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(jam): THIS LOGIC IS COPIED FROM WebPluginImpl::willSendRequest until
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // kDirectNPAPIRequests is the default and we can remove the old path there.
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Currently this check is just to catch an https -> http redirect when
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // loading the main plugin src URL. Longer term, we could investigate
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // firing mixed diplay or scripting issues for subresource loads
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // initiated by plug-ins.
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (is_plugin_src_load_ &&
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !plugin_stream_->instance()->webplugin()->CheckIfRunInsecureContent(
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          redirect_info.new_url)) {
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    plugin_stream_->DidFail(resource_id_);  // That will delete |this|.
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  GURL old_url = url_;
2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  url_ = redirect_info.new_url;
2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  first_party_for_cookies_ = redirect_info.new_first_party_for_cookies;
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // If the plugin does not participate in url redirect notifications then just
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // block cross origin 307 POST redirects.
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!notify_redirects_) {
2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (redirect_info.status_code == 307 &&
2206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        redirect_info.new_method == "POST" &&
2216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        old_url.GetOrigin() != url_.GetOrigin()) {
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      plugin_stream_->DidFail(resource_id_);  // That will delete |this|.
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return false;
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Pause the request while we ask the plugin what to do about the redirect.
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bridge_->SetDefersLoading(true);
2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    plugin_stream_->WillSendRequest(url_, redirect_info.status_code);
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PluginURLFetcher::OnReceivedResponse(const ResourceResponseInfo& info) {
235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!plugin_stream_)
236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(jam): THIS LOGIC IS COPIED FROM WebPluginImpl::didReceiveResponse
239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // GetAllHeaders, and GetResponseInfo until kDirectNPAPIRequests is the
240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // default and we can remove the old path there.
241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool request_is_seekable = true;
243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(!multipart_delegate_.get());
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (plugin_stream_->seekable()) {
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int response_code = info.headers->response_code();
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (response_code == 206) {
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebURLResponse response;
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      response.initialize();
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      WebURLLoaderImpl::PopulateURLResponse(url_, info, &response);
250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      std::string multipart_boundary;
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (MultipartResponseDelegate::ReadMultipartBoundary(
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              response, &multipart_boundary)) {
254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        plugin_stream_->instance()->webplugin()->DidStartLoading();
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        MultiPartResponseClient* multi_part_response_client =
257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            new MultiPartResponseClient(plugin_stream_);
258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        multipart_delegate_.reset(new MultipartResponseDelegate(
260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            multi_part_response_client, NULL, response, multipart_boundary));
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        // Multiple ranges requested, data will be delivered by
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        // MultipartResponseDelegate.
264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        data_offset_ = 0;
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        return;
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      int64 upper_bound = 0, instance_size = 0;
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // Single range requested - go through original processing for
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // non-multipart requests, but update data offset.
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MultipartResponseDelegate::ReadContentRanges(
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          response, &data_offset_, &upper_bound, &instance_size);
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else if (response_code == 200) {
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // TODO: should we handle this case? We used to but it's not clear that we
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // still need to. This was bug 5403, fixed in r7139.
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // If the length comes in as -1, then it indicates that it was not
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // read off the HTTP headers. We replicate Safari webkit behavior here,
281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // which is to set it to 0.
282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int expected_length = std::max(static_cast<int>(info.content_length), 0);
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::Time temp;
285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  uint32 last_modified = 0;
286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::string headers;
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (info.headers.get()) {  // NULL for data: urls.
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (info.headers->GetLastModifiedValue(&temp))
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      last_modified = static_cast<uint32>(temp.ToDoubleT());
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)     // TODO(darin): Shouldn't we also report HTTP version numbers?
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int response_code = info.headers->response_code();
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    headers = base::StringPrintf("HTTP %d ", response_code);
294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    headers += info.headers->GetStatusText();
295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    headers += "\n";
296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    void* iter = NULL;
298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::string name, value;
299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    while (info.headers->EnumerateHeaderLines(&iter, &name, &value)) {
300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // TODO(darin): Should we really exclude headers with an empty value?
301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (!name.empty() && !value.empty())
302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        headers += name + ": " + value + "\n";
303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // error codes in the stream header and as a result, was unaware of the fate
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF destroy
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // the stream and invoke the NPP_DestroyStream function on the plugin if the
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // HTTPrequest fails.
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if ((url_.SchemeIs(url::kHttpScheme) || url_.SchemeIs(url::kHttpsScheme)) &&
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        (response_code < 100 || response_code >= 400)) {
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pending_failure_notification_ = true;
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  plugin_stream_->DidReceiveResponse(info.mime_type,
317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     headers,
318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     expected_length,
319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     last_modified,
320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     request_is_seekable);
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnDownloadedData(int len,
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                        int encoded_data_length) {
32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnReceivedData(const char* data,
32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      int data_length,
32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      int encoded_data_length) {
330c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!plugin_stream_)
331c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
332c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (multipart_delegate_) {
334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length);
335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  } else {
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int64 offset = data_offset_;
337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    data_offset_ += data_length;
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (copy_stream_data_) {
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // QuickTime writes to this memory, and since we got it from
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // ResourceDispatcher it's not mapped for write access in this process.
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // http://crbug.com/308466.
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<char[]> data_copy(new char[data_length]);
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      memcpy(data_copy.get(), data, data_length);
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      plugin_stream_->DidReceiveData(data_copy.get(), data_length, offset);
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      plugin_stream_->DidReceiveData(data, data_length, offset);
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // DANGER: this instance may be deleted at this point.
350d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnCompletedRequest(
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int error_code,
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool was_ignored_by_handler,
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool stale_copy_in_cache,
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& security_info,
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::TimeTicks& completion_time,
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 total_transfer_size) {
360c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!plugin_stream_)
361c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
362c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (multipart_delegate_) {
364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    multipart_delegate_->OnCompletedRequest();
365d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    multipart_delegate_.reset();
366d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (error_code == net::OK) {
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    plugin_stream_->DidFinishLoading(resource_id_);
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    plugin_stream_->DidFail(resource_id_);
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace content
376