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