15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 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) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_HTTP_PARTIAL_DATA_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_HTTP_PARTIAL_DATA_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_byte_range.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace disk_cache { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Entry; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpResponseHeaders; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IOBuffer; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides support for dealing with range requests and the 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subsequent partial-content responses. We use sparse cache entries to store 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// these requests. This class is tightly integrated with HttpCache::Transaction 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and it is intended to allow a cleaner implementation of that class. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In order to fulfill range requests, we may have to perform a sequence of 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reads from the cache, interleaved with reads from the network / writes to the 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache. This class basically keeps track of the data required to perform each 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of those individual network / cache requests. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PartialData { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PartialData(); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PartialData(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs initialization of the object by examining the request |headers| 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and verifying that we can process the requested range. Returns true if 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we can process the requested range, and false otherwise. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Init(const HttpRequestHeaders& headers); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the headers that we should use to make byte range requests. This is a 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subset of the request extra headers, with byte-range related headers 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // removed. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetHeaders(const HttpRequestHeaders& headers); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restores the byte-range headers, by appending the byte range to the headers 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provided to SetHeaders(). 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RestoreHeaders(HttpRequestHeaders* headers) const; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts the checks to perform a cache validation. Returns 0 when there is no 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // need to perform more operations because we reached the end of the request 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (so 0 bytes should be actually returned to the user), a positive number to 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indicate that PrepareCacheValidation should be called, or an appropriate 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error code. If this method returns ERR_IO_PENDING, the |callback| will be 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notified when the result is ready. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ShouldValidateCache(disk_cache::Entry* entry, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Builds the required |headers| to perform the proper cache validation for 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the next range to be fetched. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PrepareCacheValidation(disk_cache::Entry* entry, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders* headers); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the current range is stored in the cache. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsCurrentRangeCached() const; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the current range is the last one needed to fulfill the 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user's request. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsLastRange() const; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extracts info from headers already stored in the cache. Returns false if 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there is any problem with the headers. |truncated| should be true if we 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have an incomplete 200 entry. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool UpdateFromStoredHeaders(const HttpResponseHeaders* headers, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disk_cache::Entry* entry, bool truncated); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the byte current range to start again at zero (for a truncated entry). 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetRangeToStartDownload(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the requested range is valid given the stored data. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsRequestedRangeOK(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the response headers match what we expect, false otherwise. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ResponseHeadersOK(const HttpResponseHeaders* headers); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fixes the response headers to include the right content length and range. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |success| is the result of the whole request so if it's false, we'll change 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the result code to be 416. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FixResponseHeaders(HttpResponseHeaders* headers, bool success); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fixes the content length that we want to store in the cache. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FixContentLength(HttpResponseHeaders* headers); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads up to |data_len| bytes from the cache and stores them in the provided 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffer (|data|). Basically, this is just a wrapper around the API of the 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cache that provides the right arguments for the current range. When the IO 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operation completes, OnCacheReadCompleted() must be called with the result 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the operation. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int CacheRead(disk_cache::Entry* entry, IOBuffer* data, int data_len, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Writes |data_len| bytes to cache. This is basically a wrapper around the 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // API of the cache that provides the right arguments for the current range. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int CacheWrite(disk_cache::Entry* entry, IOBuffer* data, int data_len, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method should be called when CacheRead() finishes the read, to update 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the internal state about the current range. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnCacheReadCompleted(int result); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method should be called after receiving data from the network, to 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // update the internal state about the current range. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnNetworkReadCompleted(int result); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initial_validation() const { return initial_validation_; } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Core; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the length to use when scanning the cache. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetNextRangeLen(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Completion routine for our callback. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetAvailableRangeCompleted(int result, int64 start); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 current_range_start_; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 cached_start_; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 resource_size_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cached_min_len_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpByteRange byte_range_; // The range requested by the user. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The clean set of extra headers (no ranges). 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpRequestHeaders extra_headers_; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool range_present_; // True if next range entry is already stored. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool final_range_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool sparse_entry_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool truncated_; // We have an incomplete 200 stored. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initial_validation_; // Only used for truncated entries. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Core* core_; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback callback_; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PartialData); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_HTTP_PARTIAL_DATA_H_ 146