plugin_url_fetcher.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/web_url_loader_impl.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/resource_request_body.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/service_worker/service_worker_types.h" 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/common/resource_response_info.h" 2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/load_flags.h" 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/net_errors.h" 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/http/http_response_headers.h" 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/url_request/url_request.h" 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLLoaderClient.h" 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h" 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "webkit/child/resource_loader_bridge.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) method_(method), 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) referrer_(referrer), 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) notify_redirects_(notify_redirects), 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) is_plugin_src_load_(is_plugin_src_load), 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch origin_pid_(origin_pid), 103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch render_frame_id_(render_frame_id), 104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch render_view_id_(render_view_id), 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) resource_id_(resource_id), 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) copy_stream_data_(copy_stream_data), 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) data_offset_(0), 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) pending_failure_notification_(false) { 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RequestInfo request_info; 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.method = method; 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.url = url; 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.first_party_for_cookies = first_party_for_cookies; 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.referrer = referrer; 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.load_flags = net::LOAD_NORMAL; 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.requestor_pid = origin_pid; 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) request_info.request_type = RESOURCE_TYPE_OBJECT; 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.routing_id = render_view_id; 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RequestExtraData extra_data; 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch extra_data.set_render_frame_id(render_frame_id); 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch extra_data.set_is_main_frame(false); 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_info.extra_data = &extra_data; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<char> body; 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (method == "POST") { 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool content_type_found = false; 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<std::string> names; 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<std::string> values; 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) PluginHost::SetPostData(buf, len, &names, &values, &body); 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < names.size(); ++i) { 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!request_info.headers.empty()) 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.headers += "\r\n"; 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info.headers += names[i] + ": " + values[i]; 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (LowerCaseEqualsASCII(names[i], "content-type")) 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) content_type_found = true; 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!content_type_found) { 139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!request_info.headers.empty()) 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) request_info.headers += "\r\n"; 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) request_info.headers += "Content-Type: application/x-www-form-urlencoded"; 14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } else { 144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!range.empty()) 145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch request_info.headers = std::string("Range: ") + range; 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bridge_.reset(ChildThread::current()->resource_dispatcher()->CreateBridge( 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_info)); 15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!body.empty()) { 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<ResourceRequestBody> request_body = 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new ResourceRequestBody; 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_body->AppendBytes(&body[0], body.size()); 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bridge_->SetRequestBody(request_body.get()); 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bridge_->Start(this); 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // TODO(jam): range requests 16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)PluginURLFetcher::~PluginURLFetcher() { 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::Cancel() { 16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bridge_->Cancel(); 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Due to races and nested event loops, PluginURLFetcher may still receive 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // events from the bridge before being destroyed. Do not forward additional 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // events back to the plugin, via either |plugin_stream_| or 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // |multipart_delegate_| which has its own pointer via 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // MultiPartResponseClient. 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (multipart_delegate_) 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch multipart_delegate_->Cancel(); 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch plugin_stream_ = NULL; 17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::URLRedirectResponse(bool allow) { 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!plugin_stream_) 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (allow) { 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bridge_->SetDefersLoading(false); 18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bridge_->Cancel(); 18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) plugin_stream_->DidFail(resource_id_); // That will delete |this|. 18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnUploadProgress(uint64 position, uint64 size) { 19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool PluginURLFetcher::OnReceivedRedirect( 19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const GURL& new_url, 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& new_first_party_for_cookies, 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ResourceResponseInfo& info) { 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!plugin_stream_) 198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // TODO(jam): THIS LOGIC IS COPIED FROM WebPluginImpl::willSendRequest until 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // kDirectNPAPIRequests is the default and we can remove the old path there. 20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Currently this check is just to catch an https -> http redirect when 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // loading the main plugin src URL. Longer term, we could investigate 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // firing mixed diplay or scripting issues for subresource loads 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // initiated by plug-ins. 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (is_plugin_src_load_ && 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !plugin_stream_->instance()->webplugin()->CheckIfRunInsecureContent( 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new_url)) { 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) plugin_stream_->DidFail(resource_id_); // That will delete |this|. 21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // It's unfortunate that this logic of when a redirect's method changes is 21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // in url_request.cc, but weburlloader_impl.cc and this file have to duplicate 21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // it instead of passing that information. 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int response_code; 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (info.headers) { 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response_code = info.headers->response_code(); 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // A redirect may have NULL headers if it came from URLRequestRedirectJob. 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(davidben): Get the actual response code from the browser. Either 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // fake enough of headers to have a response code or pass it down as part of 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // https://crbug.com/384609. 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response_code = 307; 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) method_ = net::URLRequest::ComputeMethodForRedirect(method_, response_code); 22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GURL old_url = url_; 23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) url_ = new_url; 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) first_party_for_cookies_ = new_first_party_for_cookies; 23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // If the plugin does not participate in url redirect notifications then just 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // block cross origin 307 POST redirects. 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!notify_redirects_) { 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (response_code == 307 && method_ == "POST" && 23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) old_url.GetOrigin() != new_url.GetOrigin()) { 23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) plugin_stream_->DidFail(resource_id_); // That will delete |this|. 23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Pause the request while we ask the plugin what to do about the redirect. 24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bridge_->SetDefersLoading(true); 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) plugin_stream_->WillSendRequest(url_, response_code); 24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PluginURLFetcher::OnReceivedResponse(const ResourceResponseInfo& info) { 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!plugin_stream_) 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(jam): THIS LOGIC IS COPIED FROM WebPluginImpl::didReceiveResponse 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // GetAllHeaders, and GetResponseInfo until kDirectNPAPIRequests is the 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // default and we can remove the old path there. 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool request_is_seekable = true; 259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!multipart_delegate_.get()); 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (plugin_stream_->seekable()) { 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int response_code = info.headers->response_code(); 262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (response_code == 206) { 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebURLResponse response; 264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) response.initialize(); 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WebURLLoaderImpl::PopulateURLResponse(url_, info, &response); 266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string multipart_boundary; 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (MultipartResponseDelegate::ReadMultipartBoundary( 269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) response, &multipart_boundary)) { 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) plugin_stream_->instance()->webplugin()->DidStartLoading(); 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) MultiPartResponseClient* multi_part_response_client = 273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) new MultiPartResponseClient(plugin_stream_); 274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch multipart_delegate_.reset(new MultipartResponseDelegate( 276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) multi_part_response_client, NULL, response, multipart_boundary)); 277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Multiple ranges requested, data will be delivered by 279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // MultipartResponseDelegate. 280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_offset_ = 0; 281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int64 upper_bound = 0, instance_size = 0; 285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Single range requested - go through original processing for 286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // non-multipart requests, but update data offset. 287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MultipartResponseDelegate::ReadContentRanges( 288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) response, &data_offset_, &upper_bound, &instance_size); 289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else if (response_code == 200) { 290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO: should we handle this case? We used to but it's not clear that we 291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // still need to. This was bug 5403, fixed in r7139. 292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If the length comes in as -1, then it indicates that it was not 296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // read off the HTTP headers. We replicate Safari webkit behavior here, 297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // which is to set it to 0. 298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int expected_length = std::max(static_cast<int>(info.content_length), 0); 29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Time temp; 301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) uint32 last_modified = 0; 302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string headers; 303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (info.headers) { // NULL for data: urls. 304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (info.headers->GetLastModifiedValue(&temp)) 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) last_modified = static_cast<uint32>(temp.ToDoubleT()); 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(darin): Shouldn't we also report HTTP version numbers? 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int response_code = info.headers->response_code(); 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) headers = base::StringPrintf("HTTP %d ", response_code); 310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) headers += info.headers->GetStatusText(); 311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) headers += "\n"; 312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void* iter = NULL; 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string name, value; 315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) while (info.headers->EnumerateHeaderLines(&iter, &name, &value)) { 316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(darin): Should we really exclude headers with an empty value? 317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!name.empty() && !value.empty()) 318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) headers += name + ": " + value + "\n"; 319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // error codes in the stream header and as a result, was unaware of the fate 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF destroy 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the stream and invoke the NPP_DestroyStream function on the plugin if the 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // HTTPrequest fails. 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if ((url_.SchemeIs("http") || url_.SchemeIs("https")) && 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (response_code < 100 || response_code >= 400)) { 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) pending_failure_notification_ = true; 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) plugin_stream_->DidReceiveResponse(info.mime_type, 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) headers, 334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) expected_length, 335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) last_modified, 336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) request_is_seekable); 33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnDownloadedData(int len, 34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int encoded_data_length) { 34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnReceivedData(const char* data, 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int data_length, 34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int encoded_data_length) { 346c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!plugin_stream_) 347c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 348c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (multipart_delegate_) { 350d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length); 351d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int64 offset = data_offset_; 353d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) data_offset_ += data_length; 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (copy_stream_data_) { 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // QuickTime writes to this memory, and since we got it from 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ResourceDispatcher it's not mapped for write access in this process. 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // http://crbug.com/308466. 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<char[]> data_copy(new char[data_length]); 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(data_copy.get(), data, data_length); 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) plugin_stream_->DidReceiveData(data_copy.get(), data_length, offset); 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) plugin_stream_->DidReceiveData(data, data_length, offset); 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // DANGER: this instance may be deleted at this point. 366d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PluginURLFetcher::OnCompletedRequest( 37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int error_code, 37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool was_ignored_by_handler, 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool stale_copy_in_cache, 37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& security_info, 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::TimeTicks& completion_time, 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 total_transfer_size) { 376c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!plugin_stream_) 377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 378c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 379d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (multipart_delegate_) { 380d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) multipart_delegate_->OnCompletedRequest(); 381d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) multipart_delegate_.reset(); 382d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 383d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (error_code == net::OK) { 38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) plugin_stream_->DidFinishLoading(resource_id_); 38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) plugin_stream_->DidFail(resource_id_); 38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} // namespace content 392