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