15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CONTENT_BROWSER_LOADER_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CONTENT_BROWSER_LOADER_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/basictypes.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/callback.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/compiler_specific.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/loader/layered_resource_handler.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/loader/temporary_file_stream.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/content_export.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/url_request/url_request.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "url/gurl.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileStream; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GrowableIOBuffer; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ShareableFileReference; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Redirects network data to a file. This is intended to be layered in front of 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// either the AsyncResourceHandler or the SyncResourceHandler. The downstream 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// resource handler does not see OnWillRead or OnReadCompleted calls. Instead, 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the ResourceResponse contains the path to a temporary file and 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// OnDataDownloaded is called as the file downloads. 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class CONTENT_EXPORT RedirectToFileResourceHandler 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : public LayeredResourceHandler { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef base::Callback<void(const CreateTemporaryFileStreamCallback&)> 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTemporaryFileStreamFunction; 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Create a RedirectToFileResourceHandler for |request| which wraps 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |next_handler|. 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RedirectToFileResourceHandler(scoped_ptr<ResourceHandler> next_handler, 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequest* request); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~RedirectToFileResourceHandler(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Replace the CreateTemporaryFileStream implementation with a mocked one for 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // testing purposes. The function should create a net::FileStream and a 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // ShareableFileReference and then asynchronously pass them to the 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // CreateTemporaryFileStreamCallback. 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetCreateTemporaryFileStreamFunctionForTesting( 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const CreateTemporaryFileStreamFunction& create_temporary_file_stream); 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // LayeredResourceHandler implementation: 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual bool OnResponseStarted(ResourceResponse* response, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* defer) OVERRIDE; 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual bool OnWillStart(const GURL& url, bool* defer) OVERRIDE; 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual bool OnWillRead(scoped_refptr<net::IOBuffer>* buf, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* buf_size, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int min_size) OVERRIDE; 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual bool OnReadCompleted(int bytes_read, bool* defer) OVERRIDE; 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnResponseCompleted(const net::URLRequestStatus& status, 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& security_info, 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool* defer) OVERRIDE; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void DidCreateTemporaryFile(base::File::Error error_code, 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<net::FileStream> file_stream, 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::ShareableFileReference* deletable_file); 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Called by RedirectToFileResourceHandler::Writer. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidWriteToFile(int result); 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteMore(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BufIsFull() const; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResumeIfDeferred(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateTemporaryFileStreamFunction create_temporary_file_stream_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We allocate a single, fixed-size IO buffer (buf_) used to read from the 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // network (buf_write_pending_ is true while the system is copying data into 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buf_), and then write this buffer out to disk (write_callback_pending_ is 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // true while writing to disk). Reading from the network is suspended while 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the buffer is full (BufIsFull returns true). The write_cursor_ member 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tracks the offset into buf_ that we are writing to disk. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::GrowableIOBuffer> buf_; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool buf_write_pending_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_cursor_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Helper writer object which maintains references to the net::FileStream and 9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // storage::ShareableFileReference. This is maintained separately so that, 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // on Windows, the temporary file isn't deleted until after it is closed. 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) class Writer; 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Writer* writer_; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |next_buffer_size_| is the size of the buffer to be allocated on the next 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnWillRead() call. We exponentially grow the size of the buffer allocated 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when our owner fills our buffers. On the first OnWillRead() call, we 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allocate a buffer of 32k and double it in OnReadCompleted() if the buffer 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was filled, up to a maximum size of 512k. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int next_buffer_size_; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool did_defer_; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool completed_during_write_; 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL will_start_url_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestStatus completed_status_; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string completed_security_info_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WeakPtrFactory<RedirectToFileResourceHandler> weak_factory_; 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RedirectToFileResourceHandler); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // CONTENT_BROWSER_LOADER_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_ 123