plugin_url_fetcher.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/plugin_host.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/plugin_instance.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/plugin_stream_url.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/npapi/webplugin.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/npapi/webplugin_resource_client.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/plugin_messages.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/child/request_extra_data.h"
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/child/request_info.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/resource_dispatcher.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/web_url_loader_impl.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/resource_request_body.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/service_worker/service_worker_types.h"
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/load_flags.h"
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/net_errors.h"
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/http/http_response_headers.h"
24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "webkit/child/multipart_response_delegate.h"
274ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "webkit/common/resource_response_info.h"
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace content {
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace {
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This class handles individual multipart responses. It is instantiated when
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// we receive HTTP status code 206 in the HTTP response. This indicates
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// that the response could have multiple parts each separated by a boundary
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// specified in the response header.
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// TODO(jam): this is similar to MultiPartResponseClient in webplugin_impl.cc,
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// we should remove that other class once we switch to loading from the plugin
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// process by default.
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MultiPartResponseClient : public blink::WebURLLoaderClient {
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  explicit MultiPartResponseClient(PluginStreamUrl* plugin_stream)
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      : byte_range_lower_bound_(0), plugin_stream_(plugin_stream) {}
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // blink::WebURLLoaderClient implementation:
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void didReceiveResponse(
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebURLLoader* loader,
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const blink::WebURLResponse& response) OVERRIDE {
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int64 byte_range_upper_bound, instance_size;
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!webkit_glue::MultipartResponseDelegate::ReadContentRanges(
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            response, &byte_range_lower_bound_, &byte_range_upper_bound,
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            &instance_size)) {
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      NOTREACHED();
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void didReceiveData(blink::WebURLLoader* loader,
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              const char* data,
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              int data_length,
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              int encoded_data_length) OVERRIDE {
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(ananta)
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // We should defer further loads on multipart resources on the same lines
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // as regular resources requested by plugins to prevent reentrancy.
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int64 data_offset = byte_range_lower_bound_;
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    byte_range_lower_bound_ += data_length;
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    plugin_stream_->DidReceiveData(data, data_length, data_offset);
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // DANGER: this instance may be deleted at this point.
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The lower bound of the byte range.
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int64 byte_range_lower_bound_;
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The handler for the data.
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PluginStreamUrl* plugin_stream_;
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)PluginURLFetcher::PluginURLFetcher(PluginStreamUrl* plugin_stream,
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const GURL& url,
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const GURL& first_party_for_cookies,
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const std::string& method,
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   const char* buf,
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   unsigned int len,
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const GURL& referrer,
84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                   const std::string& range,
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   bool notify_redirects,
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   bool is_plugin_src_load,
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   int origin_pid,
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   int render_frame_id,
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   int render_view_id,
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   unsigned long resource_id,
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   bool copy_stream_data)
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : plugin_stream_(plugin_stream),
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      url_(url),
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      first_party_for_cookies_(first_party_for_cookies),
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      method_(method),
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      referrer_(referrer),
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      notify_redirects_(notify_redirects),
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      is_plugin_src_load_(is_plugin_src_load),
99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      origin_pid_(origin_pid),
100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      render_frame_id_(render_frame_id),
101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      render_view_id_(render_view_id),
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      resource_id_(resource_id),
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      copy_stream_data_(copy_stream_data),
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      data_offset_(0),
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pending_failure_notification_(false) {
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  RequestInfo request_info;
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.method = method;
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.url = url;
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.first_party_for_cookies = first_party_for_cookies;
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.referrer = referrer;
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.requestor_pid = origin_pid;
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.request_type = ResourceType::OBJECT;
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request_info.routing_id = render_view_id;
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  RequestExtraData extra_data;
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  extra_data.set_render_frame_id(render_frame_id);
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  extra_data.set_is_main_frame(false);
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request_info.extra_data = &extra_data;
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::vector<char> body;
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (method == "POST") {
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool content_type_found = false;
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::vector<std::string> names;
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::vector<std::string> values;
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    PluginHost::SetPostData(buf, len, &names, &values, &body);
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (size_t i = 0; i < names.size(); ++i) {
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (!request_info.headers.empty())
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        request_info.headers += "\r\n";
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_info.headers += names[i] + ": " + values[i];
131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (LowerCaseEqualsASCII(names[i], "content-type"))
132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        content_type_found = true;
133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!content_type_found) {
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (!request_info.headers.empty())
137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        request_info.headers += "\r\n";
138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      request_info.headers += "Content-Type: application/x-www-form-urlencoded";
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  } else {
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (!range.empty())
142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      request_info.headers = std::string("Range: ") + range;
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bridge_.reset(ChildThread::current()->resource_dispatcher()->CreateBridge(
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_info));
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!body.empty()) {
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_refptr<ResourceRequestBody> request_body =
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        new ResourceRequestBody;
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    request_body->AppendBytes(&body[0], body.size());
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bridge_->SetRequestBody(request_body.get());
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bridge_->Start(this);
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(jam): range requests
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)PluginURLFetcher::~PluginURLFetcher() {
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::Cancel() {
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bridge_->Cancel();
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::URLRedirectResponse(bool allow) {
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (allow) {
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bridge_->SetDefersLoading(false);
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bridge_->Cancel();
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    plugin_stream_->DidFail(resource_id_);  // That will delete |this|.
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnUploadProgress(uint64 position, uint64 size) {
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool PluginURLFetcher::OnReceivedRedirect(
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& new_url,
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const webkit_glue::ResourceResponseInfo& info,
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool* has_new_first_party_for_cookies,
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    GURL* new_first_party_for_cookies) {
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(jam): THIS LOGIC IS COPIED FROM WebPluginImpl::willSendRequest until
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // kDirectNPAPIRequests is the default and we can remove the old path there.
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Currently this check is just to catch an https -> http redirect when
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // loading the main plugin src URL. Longer term, we could investigate
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // firing mixed diplay or scripting issues for subresource loads
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // initiated by plug-ins.
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (is_plugin_src_load_ &&
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !plugin_stream_->instance()->webplugin()->CheckIfRunInsecureContent(
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          new_url)) {
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    plugin_stream_->DidFail(resource_id_);  // That will delete |this|.
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // It's unfortunate that this logic of when a redirect's method changes is
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // in url_request.cc, but weburlloader_impl.cc and this file have to duplicate
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // it instead of passing that information.
200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int response_code = info.headers->response_code();
201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (response_code != 307)
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    method_ = "GET";
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  GURL old_url = url_;
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  url_ = new_url;
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *has_new_first_party_for_cookies = true;
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *new_first_party_for_cookies = first_party_for_cookies_;
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // If the plugin does not participate in url redirect notifications then just
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // block cross origin 307 POST redirects.
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!notify_redirects_) {
211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (response_code == 307 && method_ == "POST" &&
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        old_url.GetOrigin() != new_url.GetOrigin()) {
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      plugin_stream_->DidFail(resource_id_);  // That will delete |this|.
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return false;
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Pause the request while we ask the plugin what to do about the redirect.
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bridge_->SetDefersLoading(true);
219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    plugin_stream_->WillSendRequest(url_, response_code);
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnReceivedResponse(
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const webkit_glue::ResourceResponseInfo& info) {
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(jam): THIS LOGIC IS COPIED FROM WebPluginImpl::didReceiveResponse
228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // GetAllHeaders, and GetResponseInfo until kDirectNPAPIRequests is the
229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // default and we can remove the old path there.
230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool request_is_seekable = true;
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(!multipart_delegate_.get());
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (plugin_stream_->seekable()) {
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int response_code = info.headers->response_code();
235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (response_code == 206) {
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebURLResponse response;
237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      response.initialize();
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      WebURLLoaderImpl::PopulateURLResponse(url_, info, &response);
239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      std::string multipart_boundary;
241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (webkit_glue::MultipartResponseDelegate::ReadMultipartBoundary(
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              response, &multipart_boundary)) {
243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        plugin_stream_->instance()->webplugin()->DidStartLoading();
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        MultiPartResponseClient* multi_part_response_client =
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            new MultiPartResponseClient(plugin_stream_);
247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        multipart_delegate_.reset(new webkit_glue::MultipartResponseDelegate(
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            multi_part_response_client, NULL, response, multipart_boundary));
250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        // Multiple ranges requested, data will be delivered by
252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        // MultipartResponseDelegate.
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        data_offset_ = 0;
254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        return;
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      int64 upper_bound = 0, instance_size = 0;
258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // Single range requested - go through original processing for
259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // non-multipart requests, but update data offset.
260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      webkit_glue::MultipartResponseDelegate::ReadContentRanges(
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          response, &data_offset_, &upper_bound, &instance_size);
262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else if (response_code == 200) {
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // TODO: should we handle this case? We used to but it's not clear that we
264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // still need to. This was bug 5403, fixed in r7139.
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // If the length comes in as -1, then it indicates that it was not
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // read off the HTTP headers. We replicate Safari webkit behavior here,
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // which is to set it to 0.
271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int expected_length = std::max(static_cast<int>(info.content_length), 0);
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::Time temp;
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  uint32 last_modified = 0;
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::string headers;
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (info.headers) {  // NULL for data: urls.
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (info.headers->GetLastModifiedValue(&temp))
278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      last_modified = static_cast<uint32>(temp.ToDoubleT());
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)     // TODO(darin): Shouldn't we also report HTTP version numbers?
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int response_code = info.headers->response_code();
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    headers = base::StringPrintf("HTTP %d ", response_code);
283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    headers += info.headers->GetStatusText();
284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    headers += "\n";
285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    void* iter = NULL;
287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::string name, value;
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    while (info.headers->EnumerateHeaderLines(&iter, &name, &value)) {
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // TODO(darin): Should we really exclude headers with an empty value?
290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (!name.empty() && !value.empty())
291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        headers += name + ": " + value + "\n";
292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // error codes in the stream header and as a result, was unaware of the fate
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF destroy
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // the stream and invoke the NPP_DestroyStream function on the plugin if the
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // HTTPrequest fails.
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if ((url_.SchemeIs("http") || url_.SchemeIs("https")) &&
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        (response_code < 100 || response_code >= 400)) {
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pending_failure_notification_ = true;
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  plugin_stream_->DidReceiveResponse(info.mime_type,
306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     headers,
307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     expected_length,
308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     last_modified,
309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     request_is_seekable);
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnDownloadedData(int len,
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                        int encoded_data_length) {
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnReceivedData(const char* data,
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      int data_length,
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      int encoded_data_length) {
319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (multipart_delegate_) {
320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length);
321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  } else {
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int64 offset = data_offset_;
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    data_offset_ += data_length;
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (copy_stream_data_) {
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // QuickTime writes to this memory, and since we got it from
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // ResourceDispatcher it's not mapped for write access in this process.
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // http://crbug.com/308466.
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<char[]> data_copy(new char[data_length]);
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      memcpy(data_copy.get(), data, data_length);
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      plugin_stream_->DidReceiveData(data_copy.get(), data_length, offset);
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      plugin_stream_->DidReceiveData(data, data_length, offset);
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // DANGER: this instance may be deleted at this point.
336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnCompletedRequest(
34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int error_code,
34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool was_ignored_by_handler,
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool stale_copy_in_cache,
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& security_info,
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::TimeTicks& completion_time,
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 total_transfer_size) {
346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (multipart_delegate_) {
347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    multipart_delegate_->OnCompletedRequest();
348d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    multipart_delegate_.reset();
349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
350d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (error_code == net::OK) {
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    plugin_stream_->DidFinishLoading(resource_id_);
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    plugin_stream_->DidFail(resource_id_);
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace content
359