| // Copyright (c) 2012 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_APPCACHE_APPCACHE_RESPONSE_H_ |
| #define CONTENT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_ |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include "base/compiler_specific.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| #include "content/common/appcache_interfaces.h" |
| #include "content/common/content_export.h" |
| #include "net/base/completion_once_callback.h" |
| #include "net/http/http_response_info.h" |
| #include "url/gurl.h" |
| |
| namespace net { |
| class IOBuffer; |
| } |
| |
| namespace content { |
| class AppCacheDiskCache; |
| class AppCacheDiskCacheEntry; |
| class AppCacheStorage; |
| class MockAppCacheStorage; |
| |
| static const int kUnknownResponseDataSize = -1; |
| |
| using OnceCompletionCallback = base::OnceCallback<void(int)>; |
| |
| // Response info for a particular response id. Instances are tracked in |
| // the working set. |
| class CONTENT_EXPORT AppCacheResponseInfo |
| : public base::RefCounted<AppCacheResponseInfo> { |
| public: |
| AppCacheResponseInfo(base::WeakPtr<AppCacheStorage> storage, |
| const GURL& manifest_url, |
| int64_t response_id, |
| std::unique_ptr<net::HttpResponseInfo> http_info, |
| int64_t response_data_size); |
| |
| const GURL& manifest_url() const { return manifest_url_; } |
| int64_t response_id() const { return response_id_; } |
| const net::HttpResponseInfo& http_response_info() const { |
| return *http_response_info_; |
| } |
| int64_t response_data_size() const { return response_data_size_; } |
| |
| private: |
| friend class base::RefCounted<AppCacheResponseInfo>; |
| ~AppCacheResponseInfo(); |
| |
| const GURL manifest_url_; |
| const int64_t response_id_; |
| const std::unique_ptr<net::HttpResponseInfo> http_response_info_; |
| const int64_t response_data_size_; |
| base::WeakPtr<AppCacheStorage> storage_; |
| }; |
| |
| // A refcounted wrapper for HttpResponseInfo so we can apply the |
| // refcounting semantics used with IOBuffer with these structures too. |
| struct CONTENT_EXPORT HttpResponseInfoIOBuffer |
| : public base::RefCountedThreadSafe<HttpResponseInfoIOBuffer> { |
| std::unique_ptr<net::HttpResponseInfo> http_info; |
| int response_data_size; |
| |
| HttpResponseInfoIOBuffer(); |
| explicit HttpResponseInfoIOBuffer( |
| std::unique_ptr<net::HttpResponseInfo> info); |
| |
| private: |
| friend class base::RefCountedThreadSafe<HttpResponseInfoIOBuffer>; |
| ~HttpResponseInfoIOBuffer(); |
| }; |
| |
| // Common base class for response reader and writer. |
| class CONTENT_EXPORT AppCacheResponseIO { |
| public: |
| virtual ~AppCacheResponseIO(); |
| int64_t response_id() const { return response_id_; } |
| |
| protected: |
| AppCacheResponseIO(int64_t response_id, |
| base::WeakPtr<AppCacheDiskCache> disk_cache); |
| |
| virtual void OnIOComplete(int result) = 0; |
| virtual void OnOpenEntryComplete() {} |
| |
| bool IsIOPending() const { return !callback_.is_null(); } |
| void ScheduleIOCompletionCallback(int result); |
| void InvokeUserCompletionCallback(int result); |
| void ReadRaw(int index, int offset, net::IOBuffer* buf, int buf_len); |
| void WriteRaw(int index, int offset, net::IOBuffer* buf, int buf_len); |
| void OpenEntryIfNeeded(); |
| |
| // Methods in this class use weak pointers. The weak pointer factories must be |
| // defined in the subclasses, to avoid use-after-free situations. |
| virtual base::WeakPtr<AppCacheResponseIO> GetWeakPtr() = 0; |
| |
| const int64_t response_id_; |
| base::WeakPtr<AppCacheDiskCache> disk_cache_; |
| AppCacheDiskCacheEntry* entry_; |
| scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_; |
| scoped_refptr<net::IOBuffer> buffer_; |
| int buffer_len_; |
| OnceCompletionCallback callback_; |
| net::CompletionOnceCallback open_callback_; |
| |
| private: |
| void OnRawIOComplete(int result); |
| static void OpenEntryCallback(base::WeakPtr<AppCacheResponseIO> response, |
| AppCacheDiskCacheEntry** entry, |
| int rv); |
| }; |
| |
| // Reads existing response data from storage. If the object is deleted |
| // and there is a read in progress, the implementation will return |
| // immediately but will take care of any side effect of cancelling the |
| // operation. In other words, instances are safe to delete at will. |
| class CONTENT_EXPORT AppCacheResponseReader : public AppCacheResponseIO { |
| public: |
| ~AppCacheResponseReader() override; |
| |
| // Reads http info from storage. Always returns the result of the read |
| // asynchronously through the 'callback'. Returns the number of bytes read |
| // or a net:: error code. Guaranteed to not perform partial reads of |
| // the info data. The reader acquires a reference to the 'info_buf' until |
| // completion at which time the callback is invoked with either a negative |
| // error code or the number of bytes read. The 'info_buf' argument should |
| // contain a NULL http_info when ReadInfo is called. The 'callback' is a |
| // required parameter. |
| // Should only be called where there is no Read operation in progress. |
| // (virtual for testing) |
| virtual void ReadInfo(HttpResponseInfoIOBuffer* info_buf, |
| OnceCompletionCallback callback); |
| |
| // Reads data from storage. Always returns the result of the read |
| // asynchronously through the 'callback'. Returns the number of bytes read |
| // or a net:: error code. EOF is indicated with a return value of zero. |
| // The reader acquires a reference to the provided 'buf' until completion |
| // at which time the callback is invoked with either a negative error code |
| // or the number of bytes read. The 'callback' is a required parameter. |
| // Should only be called where there is no Read operation in progress. |
| // (virtual for testing) |
| virtual void ReadData(net::IOBuffer* buf, |
| int buf_len, |
| OnceCompletionCallback callback); |
| |
| // Returns true if there is a read operation, for data or info, pending. |
| bool IsReadPending() { return IsIOPending(); } |
| |
| // Used to support range requests. If not called, the reader will |
| // read the entire response body. If called, this must be called prior |
| // to the first call to the ReadData method. |
| void SetReadRange(int offset, int length); |
| |
| protected: |
| friend class AppCacheStorageImpl; |
| friend class content::MockAppCacheStorage; |
| |
| // Use AppCacheStorage::CreateResponse() instead of calling directly. |
| AppCacheResponseReader(int64_t response_id, |
| base::WeakPtr<AppCacheDiskCache> disk_cache); |
| |
| void OnIOComplete(int result) override; |
| void OnOpenEntryComplete() override; |
| base::WeakPtr<AppCacheResponseIO> GetWeakPtr() override; |
| |
| void ContinueReadInfo(); |
| void ContinueReadData(); |
| |
| int range_offset_; |
| int range_length_; |
| int read_position_; |
| int reading_metadata_size_; |
| |
| base::WeakPtrFactory<AppCacheResponseReader> weak_factory_; |
| }; |
| |
| // Writes new response data to storage. If the object is deleted |
| // and there is a write in progress, the implementation will return |
| // immediately but will take care of any side effect of cancelling the |
| // operation. In other words, instances are safe to delete at will. |
| class CONTENT_EXPORT AppCacheResponseWriter : public AppCacheResponseIO { |
| public: |
| ~AppCacheResponseWriter() override; |
| |
| // Writes the http info to storage. Always returns the result of the write |
| // asynchronously through the 'callback'. Returns the number of bytes written |
| // or a net:: error code. The writer acquires a reference to the 'info_buf' |
| // until completion at which time the callback is invoked with either a |
| // negative error code or the number of bytes written. The 'callback' is a |
| // required parameter. The contents of 'info_buf' are not modified. |
| // Should only be called where there is no Write operation in progress. |
| // (virtual for testing) |
| virtual void WriteInfo(HttpResponseInfoIOBuffer* info_buf, |
| OnceCompletionCallback callback); |
| |
| // Writes data to storage. Always returns the result of the write |
| // asynchronously through the 'callback'. Returns the number of bytes written |
| // or a net:: error code. Guaranteed to not perform partial writes. |
| // The writer acquires a reference to the provided 'buf' until completion at |
| // which time the callback is invoked with either a negative error code or |
| // the number of bytes written. The 'callback' is a required parameter. |
| // The contents of 'buf' are not modified. |
| // Should only be called where there is no Write operation in progress. |
| // (virtual for testing) |
| virtual void WriteData(net::IOBuffer* buf, |
| int buf_len, |
| OnceCompletionCallback callback); |
| |
| // Returns true if there is a write pending. |
| bool IsWritePending() { return IsIOPending(); } |
| |
| // Returns the amount written, info and data. |
| int64_t amount_written() { return info_size_ + write_position_; } |
| |
| protected: |
| // Should only be constructed by the storage class and derivatives. |
| AppCacheResponseWriter(int64_t response_id, |
| base::WeakPtr<AppCacheDiskCache> disk_cache); |
| |
| private: |
| friend class AppCacheStorageImpl; |
| friend class content::MockAppCacheStorage; |
| |
| enum CreationPhase { |
| NO_ATTEMPT, |
| INITIAL_ATTEMPT, |
| DOOM_EXISTING, |
| SECOND_ATTEMPT |
| }; |
| |
| void OnIOComplete(int result) override; |
| base::WeakPtr<AppCacheResponseIO> GetWeakPtr() override; |
| |
| void ContinueWriteInfo(); |
| void ContinueWriteData(); |
| void CreateEntryIfNeededAndContinue(); |
| static void OnCreateEntryComplete( |
| base::WeakPtr<AppCacheResponseWriter> writer, |
| AppCacheDiskCacheEntry** entry, |
| int rv); |
| |
| int info_size_; |
| int write_position_; |
| int write_amount_; |
| CreationPhase creation_phase_; |
| base::WeakPtrFactory<AppCacheResponseWriter> weak_factory_; |
| }; |
| |
| // Writes metadata of the existing response to storage. If the object is deleted |
| // and there is a write in progress, the implementation will return |
| // immediately but will take care of any side effect of cancelling the |
| // operation. In other words, instances are safe to delete at will. |
| class CONTENT_EXPORT AppCacheResponseMetadataWriter |
| : public AppCacheResponseIO { |
| public: |
| ~AppCacheResponseMetadataWriter() override; |
| |
| // Writes metadata to storage. Always returns the result of the write |
| // asynchronously through the 'callback'. Returns the number of bytes written |
| // or a net:: error code. Guaranteed to not perform partial writes. |
| // The writer acquires a reference to the provided 'buf' until completion at |
| // which time the callback is invoked with either a negative error code or |
| // the number of bytes written. The 'callback' is a required parameter. |
| // The contents of 'buf' are not modified. |
| // Should only be called where there is no WriteMetadata operation in |
| // progress. |
| void WriteMetadata(net::IOBuffer* buf, |
| int buf_len, |
| net::CompletionOnceCallback callback); |
| |
| // Returns true if there is a write pending. |
| bool IsWritePending() { return IsIOPending(); } |
| |
| protected: |
| friend class AppCacheStorageImpl; |
| friend class content::MockAppCacheStorage; |
| |
| // Should only be constructed by the storage class and derivatives. |
| AppCacheResponseMetadataWriter(int64_t response_id, |
| base::WeakPtr<AppCacheDiskCache> disk_cache); |
| |
| private: |
| void OnIOComplete(int result) override; |
| void OnOpenEntryComplete() override; |
| base::WeakPtr<AppCacheResponseIO> GetWeakPtr() override; |
| |
| int write_amount_; |
| base::WeakPtrFactory<AppCacheResponseMetadataWriter> weak_factory_; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_ |