From 61814fd5bf4f1febc1c41b608dcbcd8a1e46e2c0 Mon Sep 17 00:00:00 2001 From: davidben Date: Wed, 15 Oct 2014 12:45:07 -0700 Subject: Split up streams logic to prepare for PlzNavigate RDH changes. This was split out from https://codereview.chromium.org/519533002/ StreamHandle is now split into a StreamHandle and StreamInfo. StreamHandle only manages the stream URL. StreamInfo also contains the headers and other metadata that the streams_private mechanism uses. StreamResourceHandler is also split out into a StreamWriter so other resource handlers may also use it. BUG=376015 Review URL: https://codereview.chromium.org/625993002 Cr-Commit-Position: refs/heads/master@{#299745} --- .../api/streams_private/streams_private_api.cc | 15 ++-- .../api/streams_private/streams_private_api.h | 3 +- .../chrome_resource_dispatcher_host_delegate.cc | 6 +- .../chrome_resource_dispatcher_host_delegate.h | 2 +- .../browser/frame_host/navigator_impl_unittest.cc | 73 ++++++------------- .../loader/resource_dispatcher_host_impl.cc | 17 +++-- content/browser/loader/stream_resource_handler.cc | 57 +++------------ content/browser/loader/stream_resource_handler.h | 15 ++-- content/browser/loader/stream_writer.cc | 82 +++++++++++++++++++++ content/browser/loader/stream_writer.h | 83 ++++++++++++++++++++++ content/browser/streams/stream.cc | 10 +-- content/browser/streams/stream.h | 6 +- content/browser/streams/stream_handle_impl.cc | 31 +------- content/browser/streams/stream_handle_impl.h | 12 +--- content/content_browser.gypi | 4 ++ .../browser/resource_dispatcher_host_delegate.cc | 4 +- .../browser/resource_dispatcher_host_delegate.h | 4 +- content/public/browser/stream_handle.h | 18 +---- content/public/browser/stream_info.cc | 16 +++++ content/public/browser/stream_info.h | 47 ++++++++++++ 20 files changed, 307 insertions(+), 198 deletions(-) create mode 100644 content/browser/loader/stream_writer.cc create mode 100644 content/browser/loader/stream_writer.h create mode 100644 content/public/browser/stream_info.cc create mode 100644 content/public/browser/stream_info.h diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.cc b/chrome/browser/extensions/api/streams_private/streams_private_api.cc index c794141..a47b544 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_api.cc +++ b/chrome/browser/extensions/api/streams_private/streams_private_api.cc @@ -9,6 +9,7 @@ #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/common/extensions/api/streams_private.h" #include "content/public/browser/stream_handle.h" +#include "content/public/browser/stream_info.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_function_registry.h" #include "extensions/browser/extension_registry.h" @@ -60,14 +61,14 @@ StreamsPrivateAPI::~StreamsPrivateAPI() { void StreamsPrivateAPI::ExecuteMimeTypeHandler( const std::string& extension_id, content::WebContents* web_contents, - scoped_ptr stream, + scoped_ptr stream, const std::string& view_id, int64 expected_content_size) { // Create the event's arguments value. streams_private::StreamInfo info; - info.mime_type = stream->GetMimeType(); - info.original_url = stream->GetOriginalURL().spec(); - info.stream_url = stream->GetURL().spec(); + info.mime_type = stream->mime_type; + info.original_url = stream->original_url.spec(); + info.stream_url = stream->handle->GetURL().spec(); info.tab_id = ExtensionTabUtil::GetTabId(web_contents); if (!view_id.empty()) { @@ -79,7 +80,7 @@ void StreamsPrivateAPI::ExecuteMimeTypeHandler( size = expected_content_size; info.expected_content_size = size; - CreateResponseHeadersDictionary(stream->GetResponseHeaders().get(), + CreateResponseHeadersDictionary(stream->response_headers.get(), &info.response_headers.additional_properties); scoped_ptr event( @@ -89,8 +90,8 @@ void StreamsPrivateAPI::ExecuteMimeTypeHandler( EventRouter::Get(browser_context_) ->DispatchEventToExtension(extension_id, event.Pass()); - GURL url = stream->GetURL(); - streams_[extension_id][url] = make_linked_ptr(stream.release()); + GURL url = stream->handle->GetURL(); + streams_[extension_id][url] = make_linked_ptr(stream->handle.release()); } void StreamsPrivateAPI::AbortStream(const std::string& extension_id, diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.h b/chrome/browser/extensions/api/streams_private/streams_private_api.h index 2861041..f416ac1 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_api.h +++ b/chrome/browser/extensions/api/streams_private/streams_private_api.h @@ -16,6 +16,7 @@ namespace content { class BrowserContext; class StreamHandle; +struct StreamInfo; } namespace extensions { @@ -37,7 +38,7 @@ class StreamsPrivateAPI : public BrowserContextKeyedAPI, // in a BrowserPlugin, specify a non-empty |view_id| of the plugin. void ExecuteMimeTypeHandler(const std::string& extension_id, content::WebContents* web_contents, - scoped_ptr stream, + scoped_ptr stream, const std::string& view_id, int64 expected_content_size); diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc index 0863976..88e6de7 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc @@ -43,7 +43,7 @@ #include "content/public/browser/resource_context.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/resource_request_info.h" -#include "content/public/browser/stream_handle.h" +#include "content/public/browser/stream_info.h" #include "content/public/browser/web_contents.h" #include "content/public/common/resource_response.h" #include "net/base/load_flags.h" @@ -167,7 +167,7 @@ void UpdatePrerenderNetworkBytesCallback(int render_process_id, } #if defined(ENABLE_EXTENSIONS) -void SendExecuteMimeTypeHandlerEvent(scoped_ptr stream, +void SendExecuteMimeTypeHandlerEvent(scoped_ptr stream, int64 expected_content_size, int render_process_id, int render_view_id, @@ -615,7 +615,7 @@ bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream( void ChromeResourceDispatcherHostDelegate::OnStreamCreated( net::URLRequest* request, - scoped_ptr stream) { + scoped_ptr stream) { #if defined(ENABLE_EXTENSIONS) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); std::map::iterator ix = diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h index e18298d..915e24c 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h @@ -72,7 +72,7 @@ class ChromeResourceDispatcherHostDelegate std::string* payload) override; virtual void OnStreamCreated( net::URLRequest* request, - scoped_ptr stream) override; + scoped_ptr stream) override; virtual void OnResponseStarted( net::URLRequest* request, content::ResourceContext* resource_context, diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc index f0e4694..8b0ae22 100644 --- a/content/browser/frame_host/navigator_impl_unittest.cc +++ b/content/browser/frame_host/navigator_impl_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/command_line.h" +#include "base/guid.h" #include "base/macros.h" #include "base/test/histogram_tester.h" #include "base/time/time.h" @@ -14,6 +15,8 @@ #include "content/browser/frame_host/navigator_impl.h" #include "content/browser/frame_host/render_frame_host_manager.h" #include "content/browser/site_instance_impl.h" +#include "content/browser/streams/stream.h" +#include "content/browser/streams/stream_registry.h" #include "content/common/navigation_params.h" #include "content/public/browser/stream_handle.h" #include "content/public/common/content_switches.h" @@ -24,53 +27,14 @@ #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "ui/base/page_transition_types.h" +#include "url/url_constants.h" namespace content { -namespace { - -// Mocked out stream handle to commit the navigation with. -class TestStreamHandle : public StreamHandle { +class NavigatorTest : public RenderViewHostImplTestHarness { public: - TestStreamHandle() : url_("test:stream") {} - - virtual const GURL& GetURL() override { - return url_; - } - - virtual const GURL& GetOriginalURL() override { - NOTREACHED(); - return original_url_; - } - - virtual const std::string& GetMimeType() override { - NOTREACHED(); - return mime_type_; - } - - virtual scoped_refptr - GetResponseHeaders() override { - NOTREACHED(); - return NULL; - } - - virtual void AddCloseListener(const base::Closure& callback) override { - NOTREACHED(); - } + NavigatorTest() : stream_registry_(new StreamRegistry) {} - private: - GURL url_; - GURL original_url_; - std::string mime_type_; - - DISALLOW_COPY_AND_ASSIGN(TestStreamHandle); -}; - -} - -class NavigatorTest - : public RenderViewHostImplTestHarness { - public: NavigationRequest* GetNavigationRequestForFrameTreeNode( FrameTreeNode* frame_tree_node) const { NavigatorImpl* navigator = @@ -109,6 +73,16 @@ class NavigatorTest static_cast(node->navigator())->RequestNavigation( node, *entry, reload_type, base::TimeTicks::Now()); } + + scoped_ptr MakeEmptyStream() { + GURL url(std::string(url::kBlobScheme) + "://" + base::GenerateGUID()); + scoped_refptr stream(new Stream(stream_registry_.get(), NULL, url)); + stream->Finalize(); + return stream->CreateHandle(); + } + + private: + scoped_ptr stream_registry_; }; // PlzNavigate: Test that a proper NavigationRequest is created by @@ -172,8 +146,7 @@ TEST_F(NavigatorTest, BrowserSideNavigationRequestNavigationNoLiveRenderer) { // Now commit the same url. scoped_refptr response(new ResourceResponse); - node->navigator()->CommitNavigation( - node, response.get(), scoped_ptr(new TestStreamHandle)); + node->navigator()->CommitNavigation(node, response.get(), MakeEmptyStream()); main_request = GetNavigationRequestForFrameTreeNode(node); // The main RFH should not have been changed, and the renderer should have @@ -208,8 +181,7 @@ TEST_F(NavigatorTest, BrowserSideNavigationNoContent) { const char kNoContentHeaders[] = "HTTP/1.1 204 No Content\0\0"; response->head.headers = new net::HttpResponseHeaders( std::string(kNoContentHeaders, arraysize(kNoContentHeaders))); - node->navigator()->CommitNavigation( - node, response.get(), scoped_ptr(new TestStreamHandle)); + node->navigator()->CommitNavigation(node, response.get(), MakeEmptyStream()); // There should be no pending RenderFrameHost; the navigation was aborted. EXPECT_FALSE(GetNavigationRequestForFrameTreeNode(node)); @@ -228,8 +200,7 @@ TEST_F(NavigatorTest, BrowserSideNavigationNoContent) { const char kResetContentHeaders[] = "HTTP/1.1 205 Reset Content\0\0"; response->head.headers = new net::HttpResponseHeaders( std::string(kResetContentHeaders, arraysize(kResetContentHeaders))); - node->navigator()->CommitNavigation( - node, response.get(), scoped_ptr(new TestStreamHandle)); + node->navigator()->CommitNavigation(node, response.get(), MakeEmptyStream()); // There should be no pending RenderFrameHost; the navigation was aborted. EXPECT_FALSE(GetNavigationRequestForFrameTreeNode(node)); @@ -256,8 +227,7 @@ TEST_F(NavigatorTest, BrowserSideNavigationCrossSiteNavigation) { ASSERT_TRUE(main_request); scoped_refptr response(new ResourceResponse); - node->navigator()->CommitNavigation( - node, response.get(), scoped_ptr(new TestStreamHandle)); + node->navigator()->CommitNavigation(node, response.get(), MakeEmptyStream()); RenderFrameHostImpl* pending_rfh = node->render_manager()->pending_frame_host(); ASSERT_TRUE(pending_rfh); @@ -298,8 +268,7 @@ TEST_F(NavigatorTest, BrowserSideNavigationReplacePendingNavigation) { // Confirm that the commit corresonds to the new request. scoped_refptr response(new ResourceResponse); - node->navigator()->CommitNavigation( - node, response.get(), scoped_ptr(new TestStreamHandle)); + node->navigator()->CommitNavigation(node, response.get(), MakeEmptyStream()); RenderFrameHostImpl* pending_rfh = node->render_manager()->pending_frame_host(); ASSERT_TRUE(pending_rfh); diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 94d9029..e073710 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc @@ -67,6 +67,7 @@ #include "content/public/browser/resource_request_details.h" #include "content/public/browser/resource_throttle.h" #include "content/public/browser/stream_handle.h" +#include "content/public/browser/stream_info.h" #include "content/public/browser/user_metrics.h" #include "content/public/common/content_switches.h" #include "content/public/common/process_type.h" @@ -737,12 +738,16 @@ ResourceDispatcherHostImpl::MaybeInterceptAsStream(net::URLRequest* request, origin)); info->set_is_stream(true); - delegate_->OnStreamCreated( - request, - handler->stream()->CreateHandle( - request->url(), - mime_type, - response->head.headers)); + scoped_ptr stream_info(new StreamInfo); + stream_info->handle = handler->stream()->CreateHandle(); + stream_info->original_url = request->url(); + stream_info->mime_type = mime_type; + // Make a copy of the response headers so it is safe to pass across threads; + // the old handler (AsyncResourceHandler) may modify it in parallel via the + // ResourceDispatcherHostDelegate. + stream_info->response_headers = + new net::HttpResponseHeaders(response->head.headers->raw_headers()); + delegate_->OnStreamCreated(request, stream_info.Pass()); return handler.PassAs(); } diff --git a/content/browser/loader/stream_resource_handler.cc b/content/browser/loader/stream_resource_handler.cc index 0a2d6e8..08827e1 100644 --- a/content/browser/loader/stream_resource_handler.cc +++ b/content/browser/loader/stream_resource_handler.cc @@ -4,31 +4,23 @@ #include "content/browser/loader/stream_resource_handler.h" -#include "base/guid.h" #include "base/logging.h" -#include "content/browser/streams/stream.h" -#include "content/browser/streams/stream_registry.h" -#include "content/public/browser/resource_controller.h" -#include "net/base/io_buffer.h" -#include "net/url_request/url_request_status.h" -#include "url/url_constants.h" namespace content { StreamResourceHandler::StreamResourceHandler(net::URLRequest* request, StreamRegistry* registry, const GURL& origin) - : ResourceHandler(request), - read_buffer_(NULL) { - // TODO(tyoshino): Find a way to share this with the blob URL creation in - // WebKit. - GURL url(std::string(url::kBlobScheme) + ":" + origin.spec() + - base::GenerateGUID()); - stream_ = new Stream(registry, this, url); + : ResourceHandler(request) { + writer_.InitializeStream(registry, origin); } StreamResourceHandler::~StreamResourceHandler() { - stream_->RemoveWriteObserver(this); +} + +void StreamResourceHandler::SetController(ResourceController* controller) { + writer_.set_controller(controller); + ResourceHandler::SetController(controller); } bool StreamResourceHandler::OnUploadProgress(uint64 position, @@ -59,33 +51,12 @@ bool StreamResourceHandler::OnBeforeNetworkStart(const GURL& url, bool* defer) { bool StreamResourceHandler::OnWillRead(scoped_refptr* buf, int* buf_size, int min_size) { - static const int kReadBufSize = 32768; - - DCHECK(buf && buf_size); - if (!read_buffer_.get()) - read_buffer_ = new net::IOBuffer(kReadBufSize); - *buf = read_buffer_.get(); - *buf_size = kReadBufSize; - + writer_.OnWillRead(buf, buf_size, min_size); return true; } bool StreamResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { - if (!bytes_read) - return true; - - // We have more data to read. - DCHECK(read_buffer_.get()); - - // Release the ownership of the buffer, and store a reference - // to it. A new one will be allocated in OnWillRead(). - scoped_refptr buffer; - read_buffer_.swap(buffer); - stream_->AddData(buffer, bytes_read); - - if (!stream_->can_add_data()) - *defer = true; - + writer_.OnReadCompleted(bytes_read, defer); return true; } @@ -93,19 +64,11 @@ void StreamResourceHandler::OnResponseCompleted( const net::URLRequestStatus& status, const std::string& sec_info, bool* defer) { - stream_->Finalize(); + writer_.Finalize(); } void StreamResourceHandler::OnDataDownloaded(int bytes_downloaded) { NOTREACHED(); } -void StreamResourceHandler::OnSpaceAvailable(Stream* stream) { - controller()->Resume(); -} - -void StreamResourceHandler::OnClose(Stream* stream) { - controller()->Cancel(); -} - } // namespace content diff --git a/content/browser/loader/stream_resource_handler.h b/content/browser/loader/stream_resource_handler.h index a850d7a..cdce727 100644 --- a/content/browser/loader/stream_resource_handler.h +++ b/content/browser/loader/stream_resource_handler.h @@ -8,8 +8,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "content/browser/loader/resource_handler.h" -#include "content/browser/streams/stream_write_observer.h" -#include "url/gurl.h" +#include "content/browser/loader/stream_writer.h" namespace net { class URLRequest; @@ -20,8 +19,7 @@ namespace content { class StreamRegistry; // Redirect this resource to a stream. -class StreamResourceHandler : public StreamWriteObserver, - public ResourceHandler { +class StreamResourceHandler : public ResourceHandler { public: // |origin| will be used to construct the URL for the Stream. See // WebCore::BlobURL and and WebCore::SecurityOrigin in Blink to understand @@ -31,6 +29,8 @@ class StreamResourceHandler : public StreamWriteObserver, const GURL& origin); virtual ~StreamResourceHandler(); + virtual void SetController(ResourceController* controller) override; + virtual bool OnUploadProgress(uint64 position, uint64 size) override; // Not needed, as this event handler ought to be the final resource. @@ -59,14 +59,11 @@ class StreamResourceHandler : public StreamWriteObserver, virtual void OnDataDownloaded(int bytes_downloaded) override; - Stream* stream() { return stream_.get(); } + Stream* stream() { return writer_.stream(); } private: - virtual void OnSpaceAvailable(Stream* stream) override; - virtual void OnClose(Stream* stream) override; + StreamWriter writer_; - scoped_refptr stream_; - scoped_refptr read_buffer_; DISALLOW_COPY_AND_ASSIGN(StreamResourceHandler); }; diff --git a/content/browser/loader/stream_writer.cc b/content/browser/loader/stream_writer.cc new file mode 100644 index 0000000..99b5ee1 --- /dev/null +++ b/content/browser/loader/stream_writer.cc @@ -0,0 +1,82 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/loader/stream_writer.h" + +#include "base/guid.h" +#include "content/browser/streams/stream.h" +#include "content/browser/streams/stream_registry.h" +#include "content/public/browser/resource_controller.h" +#include "net/base/io_buffer.h" +#include "url/gurl.h" +#include "url/url_constants.h" + +namespace content { + +StreamWriter::StreamWriter() : controller_(nullptr) { +} + +StreamWriter::~StreamWriter() { + if (stream_.get()) + Finalize(); +} + +void StreamWriter::InitializeStream(StreamRegistry* registry, + const GURL& origin) { + DCHECK(!stream_.get()); + + // TODO(tyoshino): Find a way to share this with the blob URL creation in + // WebKit. + GURL url(std::string(url::kBlobScheme) + ":" + origin.spec() + + base::GenerateGUID()); + stream_ = new Stream(registry, this, url); +} + +void StreamWriter::OnWillRead(scoped_refptr* buf, + int* buf_size, + int min_size) { + static const int kReadBufSize = 32768; + + DCHECK(buf); + DCHECK(buf_size); + DCHECK_LE(min_size, kReadBufSize); + if (!read_buffer_.get()) + read_buffer_ = new net::IOBuffer(kReadBufSize); + *buf = read_buffer_.get(); + *buf_size = kReadBufSize; +} + +void StreamWriter::OnReadCompleted(int bytes_read, bool* defer) { + if (!bytes_read) + return; + + // We have more data to read. + DCHECK(read_buffer_.get()); + + // Release the ownership of the buffer, and store a reference + // to it. A new one will be allocated in OnWillRead(). + scoped_refptr buffer; + read_buffer_.swap(buffer); + stream_->AddData(buffer, bytes_read); + + if (!stream_->can_add_data()) + *defer = true; +} + +void StreamWriter::Finalize() { + DCHECK(stream_.get()); + stream_->Finalize(); + stream_->RemoveWriteObserver(this); + stream_ = nullptr; +} + +void StreamWriter::OnSpaceAvailable(Stream* stream) { + controller_->Resume(); +} + +void StreamWriter::OnClose(Stream* stream) { + controller_->Cancel(); +} + +} // namespace content diff --git a/content/browser/loader/stream_writer.h b/content/browser/loader/stream_writer.h new file mode 100644 index 0000000..b9f3e62 --- /dev/null +++ b/content/browser/loader/stream_writer.h @@ -0,0 +1,83 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_LOADER_STREAM_WRITER_H_ +#define CONTENT_BROWSER_LOADER_STREAM_WRITER_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "content/browser/streams/stream_write_observer.h" + +class GURL; + +namespace net { +class IOBuffer; +} + +namespace content { + +class ResourceController; +class Stream; +class StreamRegistry; + +// StreamWriter is a helper class for ResourceHandlers which route their output +// into a Stream. It manages an internal buffer and handles back-pressure from +// the Stream's reader. +class StreamWriter : public StreamWriteObserver { + public: + // Creates a new StreamWriter without an initialized Stream or controller. The + // controller must be set before the writer is used. + StreamWriter(); + virtual ~StreamWriter(); + + Stream* stream() { return stream_.get(); } + + void set_controller(ResourceController* controller) { + controller_ = controller; + } + + // Initializes the writer with a new Stream in |registry|. |origin| will be + // used to construct the URL for the Stream. See WebCore::BlobURL and and + // WebCore::SecurityOrigin in Blink to understand how origin check is done on + // resource loading. + void InitializeStream(StreamRegistry* registry, + const GURL& origin); + + // Prepares a buffer to read data from the request. This call will be followed + // by either OnReadCompleted (on successful read or EOF) or destruction. The + // buffer may not be recycled until OnReadCompleted is called. If |min_size| + // is not -1, it is the minimum size of the returned buffer. + // + // OnWillRead may be called before the stream is initialized. This is to + // support BufferedResourceHandler which reads the initial chunk of data + // early. + void OnWillRead(scoped_refptr* buf, + int* buf_size, + int min_size); + + // A read was completed, forward the data to the Stream. If |*defer| is set to + // true, the implementation must not continue to process the request until + // Resume is called on |controller_|. + // + // InitializeStream must have been called before calling OnReadCompleted. + void OnReadCompleted(int bytes_read, bool* defer); + + // Called when there is no more data to read to the stream. + void Finalize(); + + private: + // StreamWriteObserver implementation. + virtual void OnSpaceAvailable(Stream* stream) override; + virtual void OnClose(Stream* stream) override; + + ResourceController* controller_; + scoped_refptr stream_; + scoped_refptr read_buffer_; + + DISALLOW_COPY_AND_ASSIGN(StreamWriter); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_LOADER_STREAM_WRITER_H_ diff --git a/content/browser/streams/stream.cc b/content/browser/streams/stream.cc index d10770c..966313c 100644 --- a/content/browser/streams/stream.cc +++ b/content/browser/streams/stream.cc @@ -160,15 +160,9 @@ Stream::StreamState Stream::ReadRawData(net::IOBuffer* buf, return STREAM_HAS_DATA; } -scoped_ptr Stream::CreateHandle( - const GURL& original_url, - const std::string& mime_type, - scoped_refptr response_headers) { +scoped_ptr Stream::CreateHandle() { CHECK(!stream_handle_); - stream_handle_ = new StreamHandleImpl(weak_ptr_factory_.GetWeakPtr(), - original_url, - mime_type, - response_headers); + stream_handle_ = new StreamHandleImpl(weak_ptr_factory_.GetWeakPtr()); return scoped_ptr(stream_handle_).Pass(); } diff --git a/content/browser/streams/stream.h b/content/browser/streams/stream.h index e7e9586..7c938b8 100644 --- a/content/browser/streams/stream.h +++ b/content/browser/streams/stream.h @@ -13,7 +13,6 @@ #include "url/gurl.h" namespace net { -class HttpResponseHeaders; class IOBuffer; } @@ -78,10 +77,7 @@ class CONTENT_EXPORT Stream : public base::RefCountedThreadSafe { // and STREAM_COMPLETE if the stream is finalized and all data has been read. StreamState ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read); - scoped_ptr CreateHandle( - const GURL& original_url, - const std::string& mime_type, - scoped_refptr response_headers); + scoped_ptr CreateHandle(); void CloseHandle(); // Indicates whether there is space in the buffer to add more data. diff --git a/content/browser/streams/stream_handle_impl.cc b/content/browser/streams/stream_handle_impl.cc index 949e2fb..5bc2acb 100644 --- a/content/browser/streams/stream_handle_impl.cc +++ b/content/browser/streams/stream_handle_impl.cc @@ -8,7 +8,6 @@ #include "base/location.h" #include "base/message_loop/message_loop_proxy.h" #include "content/browser/streams/stream.h" -#include "net/http/http_response_headers.h" namespace content { @@ -21,24 +20,10 @@ void RunCloseListeners(const std::vector& close_listeners) { } // namespace -StreamHandleImpl::StreamHandleImpl( - const base::WeakPtr& stream, - const GURL& original_url, - const std::string& mime_type, - scoped_refptr response_headers) +StreamHandleImpl::StreamHandleImpl(const base::WeakPtr& stream) : stream_(stream), url_(stream->url()), - original_url_(original_url), - mime_type_(mime_type), - response_headers_(NULL), - stream_message_loop_(base::MessageLoopProxy::current().get()) { - // Make a copy of the response headers so it is safe to pass this across - // threads. - if (response_headers.get()) { - response_headers_ = - new net::HttpResponseHeaders(response_headers->raw_headers()); - } -} + stream_message_loop_(base::MessageLoopProxy::current().get()) {} StreamHandleImpl::~StreamHandleImpl() { stream_message_loop_->PostTaskAndReply(FROM_HERE, @@ -50,18 +35,6 @@ const GURL& StreamHandleImpl::GetURL() { return url_; } -const GURL& StreamHandleImpl::GetOriginalURL() { - return original_url_; -} - -const std::string& StreamHandleImpl::GetMimeType() { - return mime_type_; -} - -scoped_refptr StreamHandleImpl::GetResponseHeaders() { - return response_headers_; -} - void StreamHandleImpl::AddCloseListener(const base::Closure& callback) { close_listeners_.push_back(callback); } diff --git a/content/browser/streams/stream_handle_impl.h b/content/browser/streams/stream_handle_impl.h index 762aaeb..f642ad5 100644 --- a/content/browser/streams/stream_handle_impl.h +++ b/content/browser/streams/stream_handle_impl.h @@ -8,7 +8,6 @@ #include #include "base/memory/weak_ptr.h" -#include "base/synchronization/lock.h" #include "content/public/browser/stream_handle.h" namespace base { @@ -21,25 +20,16 @@ class Stream; class StreamHandleImpl : public StreamHandle { public: - StreamHandleImpl(const base::WeakPtr& stream, - const GURL& original_url, - const std::string& mime_type, - scoped_refptr response_headers); + StreamHandleImpl(const base::WeakPtr& stream); virtual ~StreamHandleImpl(); private: // StreamHandle overrides virtual const GURL& GetURL() override; - virtual const GURL& GetOriginalURL() override; - virtual const std::string& GetMimeType() override; - virtual scoped_refptr GetResponseHeaders() override; virtual void AddCloseListener(const base::Closure& callback) override; base::WeakPtr stream_; GURL url_; - GURL original_url_; - std::string mime_type_; - scoped_refptr response_headers_; base::MessageLoopProxy* stream_message_loop_; std::vector close_listeners_; }; diff --git a/content/content_browser.gypi b/content/content_browser.gypi index bf32d28..bd01e66 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -211,6 +211,8 @@ 'public/browser/ssl_host_state_delegate.h', 'public/browser/storage_partition.h', 'public/browser/stream_handle.h', + 'public/browser/stream_info.cc', + 'public/browser/stream_info.h', 'public/browser/tracing_controller.h', 'public/browser/user_metrics.h', 'public/browser/utility_process_host.h', @@ -844,6 +846,8 @@ 'browser/loader/resource_scheduler_filter.h', 'browser/loader/stream_resource_handler.cc', 'browser/loader/stream_resource_handler.h', + 'browser/loader/stream_writer.cc', + 'browser/loader/stream_writer.h', 'browser/loader/sync_resource_handler.cc', 'browser/loader/sync_resource_handler.h', 'browser/loader/temporary_file_stream.cc', diff --git a/content/public/browser/resource_dispatcher_host_delegate.cc b/content/public/browser/resource_dispatcher_host_delegate.cc index 40a4d98..49eece0 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.cc +++ b/content/public/browser/resource_dispatcher_host_delegate.cc @@ -4,7 +4,7 @@ #include "content/public/browser/resource_dispatcher_host_delegate.h" -#include "content/public/browser/stream_handle.h" +#include "content/public/browser/stream_info.h" namespace content { @@ -64,7 +64,7 @@ bool ResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream( void ResourceDispatcherHostDelegate::OnStreamCreated( net::URLRequest* request, - scoped_ptr stream) { + scoped_ptr stream) { } void ResourceDispatcherHostDelegate::OnResponseStarted( diff --git a/content/public/browser/resource_dispatcher_host_delegate.h b/content/public/browser/resource_dispatcher_host_delegate.h index 8bc3084..7942df5 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.h +++ b/content/public/browser/resource_dispatcher_host_delegate.h @@ -30,9 +30,9 @@ class AppCacheService; class ResourceContext; class ResourceDispatcherHostLoginDelegate; class ResourceThrottle; -class StreamHandle; struct Referrer; struct ResourceResponse; +struct StreamInfo; // Interface that the embedder provides to ResourceDispatcherHost to allow // observing and modifying requests. @@ -100,7 +100,7 @@ class CONTENT_EXPORT ResourceDispatcherHostDelegate { // Informs the delegate that a Stream was created. The Stream can be read from // the blob URL of the Stream, but can only be read once. virtual void OnStreamCreated(net::URLRequest* request, - scoped_ptr stream); + scoped_ptr stream); // Informs the delegate that a response has started. virtual void OnResponseStarted(net::URLRequest* request, diff --git a/content/public/browser/stream_handle.h b/content/public/browser/stream_handle.h index 94591d7..7a8fb32 100644 --- a/content/public/browser/stream_handle.h +++ b/content/public/browser/stream_handle.h @@ -5,17 +5,14 @@ #ifndef CONTENT_PUBLIC_BROWSER_STREAM_HANDLE_H_ #define CONTENT_PUBLIC_BROWSER_STREAM_HANDLE_H_ -#include "base/callback.h" -#include "base/memory/ref_counted.h" +#include "base/callback_forward.h" #include "content/common/content_export.h" #include "url/gurl.h" -namespace net { -class HttpResponseHeaders; -} - namespace content { +// A handle to a Stream. When the handle is destroyed, the stream is released +// and the URL is invalidated. class CONTENT_EXPORT StreamHandle { public: virtual ~StreamHandle() {} @@ -23,15 +20,6 @@ class CONTENT_EXPORT StreamHandle { // Gets the URL the stream can be read from. virtual const GURL& GetURL() = 0; - // Gets the original URL being redirected to this Stream. - virtual const GURL& GetOriginalURL() = 0; - - // Get the MIME type associated with this Stream. - virtual const std::string& GetMimeType() = 0; - - // Get the HTTP response headers associated with this Stream. - virtual scoped_refptr GetResponseHeaders() = 0; - // Add a callback which will be called when the Stream is closed. virtual void AddCloseListener(const base::Closure& callback) = 0; }; diff --git a/content/public/browser/stream_info.cc b/content/public/browser/stream_info.cc new file mode 100644 index 0000000..5472b98 --- /dev/null +++ b/content/public/browser/stream_info.cc @@ -0,0 +1,16 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/browser/stream_info.h" + +#include "content/public/browser/stream_handle.h" +#include "net/http/http_response_headers.h" + +namespace content { + +StreamInfo::StreamInfo() {} + +StreamInfo::~StreamInfo() {} + +} // namespace content diff --git a/content/public/browser/stream_info.h b/content/public/browser/stream_info.h new file mode 100644 index 0000000..1882371 --- /dev/null +++ b/content/public/browser/stream_info.h @@ -0,0 +1,47 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_BROWSER_STREAM_INFO_H_ +#define CONTENT_PUBLIC_BROWSER_STREAM_INFO_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "content/common/content_export.h" +#include "url/gurl.h" + +namespace net { +class HttpResponseHeaders; +} + +namespace content { + +class StreamHandle; + +// A convenience structure for passing around both a StreamHandle and associated +// metadata. The intent is so, when passing the stream's URL to a child process, +// the handle can be retained as long as it is needed while the rest of the +// StreamInfo is released. +struct CONTENT_EXPORT StreamInfo { + StreamInfo(); + ~StreamInfo(); + + // The handle to the stream itself. + scoped_ptr handle; + + // The original URL being redirected to this stream. + GURL original_url; + + // The MIME type associated with this stream. + std::string mime_type; + + // The HTTP response headers associated with this stream. + scoped_refptr response_headers; + + DISALLOW_COPY_AND_ASSIGN(StreamInfo); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_STREAM_INFO_H_ -- cgit v1.1