1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef WEBKIT_BROWSER_BLOB_BLOB_URL_REQUEST_JOB_H_ 6 #define WEBKIT_BROWSER_BLOB_BLOB_URL_REQUEST_JOB_H_ 7 8 #include <map> 9 10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/weak_ptr.h" 12 #include "net/http/http_byte_range.h" 13 #include "net/http/http_status_code.h" 14 #include "net/url_request/url_request_job.h" 15 #include "webkit/browser/webkit_storage_browser_export.h" 16 #include "webkit/common/blob/blob_data.h" 17 18 namespace base { 19 class MessageLoopProxy; 20 } 21 22 namespace fileapi { 23 class FileSystemContext; 24 } 25 26 namespace net { 27 class DrainableIOBuffer; 28 class IOBuffer; 29 } 30 31 namespace webkit_blob { 32 33 class FileStreamReader; 34 35 // A request job that handles reading blob URLs. 36 class WEBKIT_STORAGE_BROWSER_EXPORT BlobURLRequestJob 37 : public net::URLRequestJob { 38 public: 39 BlobURLRequestJob(net::URLRequest* request, 40 net::NetworkDelegate* network_delegate, 41 BlobData* blob_data, 42 fileapi::FileSystemContext* file_system_context, 43 base::MessageLoopProxy* resolving_message_loop_proxy); 44 45 // net::URLRequestJob methods. 46 virtual void Start() OVERRIDE; 47 virtual void Kill() OVERRIDE; 48 virtual bool ReadRawData(net::IOBuffer* buf, 49 int buf_size, 50 int* bytes_read) OVERRIDE; 51 virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; 52 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE; 53 virtual int GetResponseCode() const OVERRIDE; 54 virtual void SetExtraRequestHeaders( 55 const net::HttpRequestHeaders& headers) OVERRIDE; 56 57 protected: 58 virtual ~BlobURLRequestJob(); 59 60 private: 61 typedef std::map<size_t, FileStreamReader*> IndexToReaderMap; 62 63 // For preparing for read: get the size, apply the range and perform seek. 64 void DidStart(); 65 bool AddItemLength(size_t index, int64 item_length); 66 void CountSize(); 67 void DidCountSize(int error); 68 void DidGetFileItemLength(size_t index, int64 result); 69 void Seek(int64 offset); 70 71 // For reading the blob. 72 bool ReadLoop(int* bytes_read); 73 bool ReadItem(); 74 void AdvanceItem(); 75 void AdvanceBytesRead(int result); 76 bool ReadBytesItem(const BlobData::Item& item, int bytes_to_read); 77 bool ReadFileItem(FileStreamReader* reader, int bytes_to_read); 78 79 void DidReadFile(int result); 80 void DeleteCurrentFileReader(); 81 82 int ComputeBytesToRead() const; 83 int BytesReadCompleted(); 84 85 // These methods convert the result of blob data reading into response headers 86 // and pass it to URLRequestJob's NotifyDone() or NotifyHeadersComplete(). 87 void NotifySuccess(); 88 void NotifyFailure(int); 89 void HeadersCompleted(net::HttpStatusCode status_code); 90 91 // Returns a FileStreamReader for a blob item at |index|. 92 // If the item at |index| is not of file this returns NULL. 93 FileStreamReader* GetFileStreamReader(size_t index); 94 95 // Creates a FileStreamReader for the item at |index| with additional_offset. 96 void CreateFileStreamReader(size_t index, int64 additional_offset); 97 98 scoped_refptr<BlobData> blob_data_; 99 100 // Variables for controlling read from |blob_data_|. 101 scoped_refptr<fileapi::FileSystemContext> file_system_context_; 102 scoped_refptr<base::MessageLoopProxy> file_thread_proxy_; 103 std::vector<int64> item_length_list_; 104 int64 total_size_; 105 int64 remaining_bytes_; 106 int pending_get_file_info_count_; 107 IndexToReaderMap index_to_reader_; 108 size_t current_item_index_; 109 int64 current_item_offset_; 110 111 // Holds the buffer for read data with the IOBuffer interface. 112 scoped_refptr<net::DrainableIOBuffer> read_buf_; 113 114 // Is set when NotifyFailure() is called and reset when DidStart is called. 115 bool error_; 116 117 bool byte_range_set_; 118 net::HttpByteRange byte_range_; 119 120 scoped_ptr<net::HttpResponseInfo> response_info_; 121 122 base::WeakPtrFactory<BlobURLRequestJob> weak_factory_; 123 124 DISALLOW_COPY_AND_ASSIGN(BlobURLRequestJob); 125 }; 126 127 } // namespace webkit_blob 128 129 #endif // WEBKIT_BROWSER_BLOB_BLOB_URL_REQUEST_JOB_H_ 130