13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_HTTP_PARTIAL_DATA_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_HTTP_PARTIAL_DATA_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/completion_callback.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_byte_range.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_request_headers.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace disk_cache { 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass Entry; 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass HttpResponseHeaders; 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass IOBuffer; 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class provides support for dealing with range requests and the 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// subsequent partial-content responses. We use sparse cache entries to store 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// these requests. This class is tightly integrated with HttpCache::Transaction 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and it is intended to allow a cleaner implementation of that class. 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// In order to fulfill range requests, we may have to perform a sequence of 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// reads from the cache, interleaved with reads from the network / writes to the 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cache. This class basically keeps track of the data required to perform each 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// of those individual network / cache requests. 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass PartialData { 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PartialData(); 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~PartialData(); 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Performs initialization of the object by examining the request |headers| 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and verifying that we can process the requested range. Returns true if 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we can process the requested range, and false otherwise. 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool Init(const HttpRequestHeaders& headers); 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sets the headers that we should use to make byte range requests. This is a 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // subset of the request extra headers, with byte-range related headers 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // removed. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void SetHeaders(const HttpRequestHeaders& headers); 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Restores the byte-range headers, by appending the byte range to the headers 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // provided to SetHeaders(). 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RestoreHeaders(HttpRequestHeaders* headers) const; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Starts the checks to perform a cache validation. Returns 0 when there is no 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // need to perform more operations because we reached the end of the request 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (so 0 bytes should be actually returned to the user), a positive number to 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // indicate that PrepareCacheValidation should be called, or an appropriate 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // error code. If this method returns ERR_IO_PENDING, the |callback| will be 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // notified when the result is ready. 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int ShouldValidateCache(disk_cache::Entry* entry, 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback); 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Builds the required |headers| to perform the proper cache validation for 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the next range to be fetched. 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void PrepareCacheValidation(disk_cache::Entry* entry, 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestHeaders* headers); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the current range is stored in the cache. 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsCurrentRangeCached() const; 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the current range is the last one needed to fulfill the 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // user's request. 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsLastRange() const; 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Extracts info from headers already stored in the cache. Returns false if 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // there is any problem with the headers. |truncated| should be true if we 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // have an incomplete 200 entry. 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool UpdateFromStoredHeaders(const HttpResponseHeaders* headers, 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disk_cache::Entry* entry, bool truncated); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Sets the byte current range to start again at zero (for a truncated entry). 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void SetRangeToStartDownload(); 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the requested range is valid given the stored data. 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsRequestedRangeOK(); 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true if the response headers match what we expect, false otherwise. 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ResponseHeadersOK(const HttpResponseHeaders* headers); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Fixes the response headers to include the right content length and range. 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // |success| is the result of the whole request so if it's false, we'll change 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the result code to be 416. 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void FixResponseHeaders(HttpResponseHeaders* headers, bool success); 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Fixes the content length that we want to store in the cache. 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void FixContentLength(HttpResponseHeaders* headers); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Reads up to |data_len| bytes from the cache and stores them in the provided 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // buffer (|data|). Basically, this is just a wrapper around the API of the 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cache that provides the right arguments for the current range. When the IO 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // operation completes, OnCacheReadCompleted() must be called with the result 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of the operation. 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int CacheRead(disk_cache::Entry* entry, IOBuffer* data, int data_len, 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Writes |data_len| bytes to cache. This is basically a wrapper around the 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // API of the cache that provides the right arguments for the current range. 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int CacheWrite(disk_cache::Entry* entry, IOBuffer* data, int data_len, 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback); 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This method should be called when CacheRead() finishes the read, to update 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the internal state about the current range. 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void OnCacheReadCompleted(int result); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This method should be called after receiving data from the network, to 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // update the internal state about the current range. 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void OnNetworkReadCompleted(int result); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool initial_validation() const { return initial_validation_; } 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class Core; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the length to use when scanning the cache. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int GetNextRangeLen(); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Completion routine for our callback. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void GetAvailableRangeCompleted(int result, int64 start); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 current_range_start_; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 cached_start_; 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 resource_size_; 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int cached_min_len_; 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HttpByteRange byte_range_; // The range requested by the user. 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The clean set of extra headers (no ranges). 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestHeaders extra_headers_; 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool range_present_; // True if next range entry is already stored. 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool final_range_; 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool sparse_entry_; 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool truncated_; // We have an incomplete 200 stored. 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool initial_validation_; // Only used for truncated entries. 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Core* core_; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback_; 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(PartialData); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_HTTP_PARTIAL_DATA_H_ 147