1e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block/* 2e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * Copyright (C) 2010 Google Inc. All rights reserved. 3e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 4e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * Redistribution and use in source and binary forms, with or without 5e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * modification, are permitted provided that the following conditions are 6e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * met: 7e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 8e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * * Redistributions of source code must retain the above copyright 9e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * notice, this list of conditions and the following disclaimer. 10e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * * Redistributions in binary form must reproduce the above 11e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * copyright notice, this list of conditions and the following disclaimer 12e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * in the documentation and/or other materials provided with the 13e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * distribution. 14e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * * Neither the name of Google Inc. nor the names of its 15e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * contributors may be used to endorse or promote products derived from 16e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * this software without specific prior written permission. 17e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 18e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block */ 30e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 31e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "config.h" 32e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 33e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#if ENABLE(BLOB) 34e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 35e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "BlobResourceHandle.h" 36e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 37e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "AsyncFileStream.h" 38e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "BlobRegistryImpl.h" 39e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "FileStream.h" 40e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "FileSystem.h" 41e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "HTTPParsers.h" 42e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "KURL.h" 43e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "ResourceError.h" 44e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "ResourceLoader.h" 45e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "ResourceRequest.h" 46e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "ResourceResponse.h" 47e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 48e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blocknamespace WebCore { 49e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 50e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const unsigned bufferSize = 1024; 51e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int maxVectorLength = 0x7fffffff; 52e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const long long positionNotSpecified = -1; 53e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 54e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int httpOK = 200; 55e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int httpPartialContent = 206; 56e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int httpNotAllowed = 403; 57e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int httpNotFound = 404; 58e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int httpRequestedRangeNotSatisfiable = 416; 59e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int httpInternalError = 500; 60e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const char* httpOKText = "OK"; 61e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const char* httpPartialContentText = "Partial Content"; 62e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const char* httpNotAllowedText = "Not Allowed"; 63e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const char* httpNotFoundText = "Not Found"; 64e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const char* httpRequestedRangeNotSatisfiableText = "Requested Range Not Satisfiable"; 65e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const char* httpInternalErrorText = "Internal Server Error"; 66e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 67e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int notFoundError = 1; 68e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int securityError = 2; 69e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int rangeError = 3; 70e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic const int notReadableError = 4; 71e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 72e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block/////////////////////////////////////////////////////////////////////////////// 73e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block// BlobResourceSynchronousLoader 74e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 75e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blocknamespace { 76e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 77e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockclass BlobResourceSynchronousLoader : public ResourceHandleClient { 78e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockpublic: 79e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block BlobResourceSynchronousLoader(ResourceError&, ResourceResponse&, Vector<char>&); 80e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 81e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); 822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch virtual void didReceiveData(ResourceHandle*, const char*, int, int /*encodedDataLength*/); 8368513a70bcd92384395513322f1b801e7bf9c729Steve Block virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); 84e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block virtual void didFail(ResourceHandle*, const ResourceError&); 85e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 86e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockprivate: 87e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ResourceError& m_error; 88e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ResourceResponse& m_response; 89e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block Vector<char>& m_data; 90e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}; 91e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 92e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockBlobResourceSynchronousLoader::BlobResourceSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data) 93e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block : m_error(error) 94e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_response(response) 95e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_data(data) 96e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 97e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 98e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 99e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceSynchronousLoader::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response) 100e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 101e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // We cannot handle the size that is more than maximum integer. 102e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block const int intMaxForLength = 0x7fffffff; 103e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (response.expectedContentLength() > intMaxForLength) { 104e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_error = ResourceError(String(), notReadableError, response.url(), String()); 105e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 106e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 107e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 108e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_response = response; 109e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 110e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Read all the data. 111e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_data.resize(static_cast<size_t>(response.expectedContentLength())); 112e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block static_cast<BlobResourceHandle*>(handle)->readSync(m_data.data(), static_cast<int>(m_data.size())); 113e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 114e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 115e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceSynchronousLoader::didReceiveData(ResourceHandle*, const char*, int, int) 116e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 117e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 118e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 11968513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid BlobResourceSynchronousLoader::didFinishLoading(ResourceHandle*, double) 120e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 121e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 122e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 123e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error) 124e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 125e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_error = error; 126e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 127e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 128e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 129e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 130e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block/////////////////////////////////////////////////////////////////////////////// 131e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block// BlobResourceHandle 132e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 133e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block// static 134e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::loadResourceSynchronously(PassRefPtr<BlobStorageData> blobData, const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data) 135e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 136e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block BlobResourceSynchronousLoader loader(error, response, data); 137e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block RefPtr<BlobResourceHandle> handle = BlobResourceHandle::create(blobData, request, &loader, false); 138e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block handle->start(); 139e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 140e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 141e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockBlobResourceHandle::BlobResourceHandle(PassRefPtr<BlobStorageData> blobData, const ResourceRequest& request, ResourceHandleClient* client, bool async) 142e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block : ResourceHandle(request, client, false, false) 143e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_blobData(blobData) 144e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_async(async) 145e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_errorCode(0) 146e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_aborted(false) 147e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_rangeOffset(positionNotSpecified) 148e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_rangeEnd(positionNotSpecified) 149e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_rangeSuffixLength(positionNotSpecified) 150e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_totalRemainingSize(0) 151e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_currentItemReadSize(0) 152e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_sizeItemCount(0) 153e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_readItemCount(0) 154e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_fileOpened(false) 155e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_async) 1575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_asyncStream = client->createAsyncFileStream(this); 1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else 159e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_stream = FileStream::create(); 160e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 161e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 162e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockBlobResourceHandle::~BlobResourceHandle() 163e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 164e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_async) { 165e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_asyncStream) 166e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_asyncStream->stop(); 167e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } else { 168e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_stream) 169e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_stream->stop(); 170e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 171e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 172e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 173e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::cancel() 174e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 175e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_async) { 176e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_asyncStream) { 177e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_asyncStream->stop(); 178e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_asyncStream = 0; 179e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 180e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 181e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 182e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_aborted = true; 1832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ResourceHandle::cancel(); 1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid delayedStartBlobResourceHandle(void* context) 1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RefPtr<BlobResourceHandle> handle = adoptRef(static_cast<BlobResourceHandle*>(context)); 1902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block handle->doStart(); 191e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 192e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 193e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::start() 194e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 1952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_async) { 1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Keep BlobResourceHandle alive until delayedStartBlobResourceHandle runs. 1972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ref(); 1982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Finish this async call quickly and return. 2002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block callOnMainThread(delayedStartBlobResourceHandle, this); 2012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 2022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 2032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block doStart(); 2052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 2062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2072fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid BlobResourceHandle::doStart() 2082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 209e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Do not continue if the request is aborted or an error occurs. 210e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_aborted || m_errorCode) 211e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 212e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 213e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // If the blob data is not found, fail now. 214e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_blobData) { 215e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_errorCode = notFoundError; 216e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyResponse(); 217e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 218e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 219e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 220e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Parse the "Range" header we care about. 221e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block String range = firstRequest().httpHeaderField("Range"); 222e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!range.isEmpty() && !parseRange(range, m_rangeOffset, m_rangeEnd, m_rangeSuffixLength)) { 223e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_errorCode = rangeError; 224e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyResponse(); 225e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 226e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 227e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 228e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_async) 229e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block getSizeForNext(); 230e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else { 231e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block for (size_t i = 0; i < m_blobData->items().size() && !m_aborted && !m_errorCode; ++i) 232e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block getSizeForNext(); 233e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyResponse(); 234e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 235e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 236e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 237e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::getSizeForNext() 238e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 239e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Do we finish validating and counting size for all items? 240e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_sizeItemCount >= m_blobData->items().size()) { 241e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block seek(); 242e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 243e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Start reading if in asynchronous mode. 244e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_async) { 245e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyResponse(); 246e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_buffer.resize(bufferSize); 247e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block readAsync(); 248e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 249e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 250e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 251e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 252e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block const BlobDataItem& item = m_blobData->items().at(m_sizeItemCount); 253e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block switch (item.type) { 254e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case BlobDataItem::Data: 255e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block didGetSize(item.length); 256e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 257e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case BlobDataItem::File: 258e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_async) 259e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_asyncStream->getSize(item.path, item.expectedModificationTime); 260e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else 261e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block didGetSize(m_stream->getSize(item.path, item.expectedModificationTime)); 262e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 263e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block default: 264e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT_NOT_REACHED(); 265e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 266e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 267e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 268e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::didGetSize(long long size) 269e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 270e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Do not continue if the request is aborted or an error occurs. 271e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_aborted || m_errorCode) 272e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 273e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 274e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // If the size is -1, it means the file has been moved or changed. Fail now. 275e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (size == -1) { 276e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_errorCode = notFoundError; 277e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyResponse(); 278e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 279e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 280e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 281e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // The size passed back is the size of the whole file. If the underlying item is a sliced file, we need to use the slice length. 282e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block const BlobDataItem& item = m_blobData->items().at(m_sizeItemCount); 283e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (item.type == BlobDataItem::File && item.length != BlobDataItem::toEndOfFile) 284e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block size = item.length; 285e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 286e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Cache the size. 287e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_itemLengthList.append(size); 288e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 289e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Count the size. 290e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_totalRemainingSize += size; 291e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_sizeItemCount++; 292e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 293e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Continue with the next item. 294e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block getSizeForNext(); 295e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 296e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 297e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::seek() 298e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 299e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Convert from the suffix length to the range. 300e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_rangeSuffixLength != positionNotSpecified) { 301e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_rangeOffset = m_totalRemainingSize - m_rangeSuffixLength; 302e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_rangeEnd = m_rangeOffset + m_rangeSuffixLength - 1; 303e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 304e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 305e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Bail out if the range is not provided. 306e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_rangeOffset == positionNotSpecified) 307e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 308e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 309e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Skip the initial items that are not in the range. 310e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block long long offset = m_rangeOffset; 311e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block for (m_readItemCount = 0; m_readItemCount < m_blobData->items().size() && offset >= m_itemLengthList[m_readItemCount]; ++m_readItemCount) 312e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block offset -= m_itemLengthList[m_readItemCount]; 313e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 314e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Set the offset that need to jump to for the first item in the range. 315e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_currentItemReadSize = offset; 316e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 317e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Adjust the total remaining size in order not to go beyond the range. 318e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_rangeEnd != positionNotSpecified) { 319e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block long long rangeSize = m_rangeEnd - m_rangeOffset + 1; 320e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_totalRemainingSize > rangeSize) 321e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_totalRemainingSize = rangeSize; 322e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } else 323e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_totalRemainingSize -= m_rangeOffset; 324e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 325e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 326e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockint BlobResourceHandle::readSync(char* buf, int length) 327e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 328e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(!m_async); 329e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 330e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int offset = 0; 331e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int remaining = length; 332e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block while (remaining) { 333e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Do not continue if the request is aborted or an error occurs. 334e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_aborted || m_errorCode) 335e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 336e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 337e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // If there is no more remaining data to read, we are done. 338e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_totalRemainingSize || m_readItemCount >= m_blobData->items().size()) 339e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 340e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 341e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block const BlobDataItem& item = m_blobData->items().at(m_readItemCount); 342e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int bytesRead = 0; 343e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (item.type == BlobDataItem::Data) 344e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block bytesRead = readDataSync(item, buf + offset, remaining); 345e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else if (item.type == BlobDataItem::File) 346e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block bytesRead = readFileSync(item, buf + offset, remaining); 347e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else 348e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT_NOT_REACHED(); 349e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 350e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (bytesRead > 0) { 351e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block offset += bytesRead; 352e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block remaining -= bytesRead; 353e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 354e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 355e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 356e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int result; 357e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_aborted || m_errorCode) 358e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block result = -1; 359e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else 360e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block result = length - remaining; 361e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 362e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyReceiveData(buf, result); 363e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!result) 364e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyFinish(); 365e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 366e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return result; 367e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 368e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 369e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockint BlobResourceHandle::readDataSync(const BlobDataItem& item, char* buf, int length) 370e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 371e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(!m_async); 372e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 373e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block long long remaining = item.length - m_currentItemReadSize; 374e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int bytesToRead = (length > remaining) ? static_cast<int>(remaining) : length; 375e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (bytesToRead > m_totalRemainingSize) 376e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block bytesToRead = static_cast<int>(m_totalRemainingSize); 377a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch memcpy(buf, item.data->data() + item.offset + m_currentItemReadSize, bytesToRead); 378e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_totalRemainingSize -= bytesToRead; 379e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 380e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_currentItemReadSize += bytesToRead; 381e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_currentItemReadSize == item.length) { 382e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_readItemCount++; 383e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_currentItemReadSize = 0; 384e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 385e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 386e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return bytesToRead; 387e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 388e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 389e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockint BlobResourceHandle::readFileSync(const BlobDataItem& item, char* buf, int length) 390e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 391e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(!m_async); 392e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 393e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_fileOpened) { 394e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block long long bytesToRead = m_itemLengthList[m_readItemCount] - m_currentItemReadSize; 395e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (bytesToRead > m_totalRemainingSize) 396e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block bytesToRead = m_totalRemainingSize; 397e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block bool success = m_stream->openForRead(item.path, item.offset + m_currentItemReadSize, bytesToRead); 398e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_currentItemReadSize = 0; 399e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!success) { 400e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_errorCode = notReadableError; 401e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return 0; 402e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 403e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 404e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_fileOpened = true; 405e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 406e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 407e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int bytesRead = m_stream->read(buf, length); 408e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (bytesRead < 0) { 409e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_errorCode = notReadableError; 410e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return 0; 411e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 412e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!bytesRead) { 413e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_stream->close(); 414e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_fileOpened = false; 415e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_readItemCount++; 416e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } else 417e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_totalRemainingSize -= bytesRead; 418e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 419e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return bytesRead; 420e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 421e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 422e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::readAsync() 423e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 424e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(m_async); 425e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 426e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Do not continue if the request is aborted or an error occurs. 427e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_aborted || m_errorCode) 428e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 429e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 430e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // If there is no more remaining data to read, we are done. 431e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_totalRemainingSize || m_readItemCount >= m_blobData->items().size()) { 432e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyFinish(); 433e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 434e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 435e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 436e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block const BlobDataItem& item = m_blobData->items().at(m_readItemCount); 437e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (item.type == BlobDataItem::Data) 438e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block readDataAsync(item); 439e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else if (item.type == BlobDataItem::File) 440e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block readFileAsync(item); 441e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else 442e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT_NOT_REACHED(); 443e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 444e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 445e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::readDataAsync(const BlobDataItem& item) 446e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 447e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(m_async); 448e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 449e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block long long bytesToRead = item.length - m_currentItemReadSize; 450e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (bytesToRead > m_totalRemainingSize) 451e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block bytesToRead = m_totalRemainingSize; 452a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch consumeData(item.data->data() + item.offset + m_currentItemReadSize, static_cast<int>(bytesToRead)); 453e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_currentItemReadSize = 0; 454e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 455e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 456e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::readFileAsync(const BlobDataItem& item) 457e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 458e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(m_async); 459e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 460e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_fileOpened) { 461e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_asyncStream->read(m_buffer.data(), m_buffer.size()); 462e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 463e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 464e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 465e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block long long bytesToRead = m_itemLengthList[m_readItemCount] - m_currentItemReadSize; 466e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (bytesToRead > m_totalRemainingSize) 467e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block bytesToRead = static_cast<int>(m_totalRemainingSize); 468e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_asyncStream->openForRead(item.path, item.offset + m_currentItemReadSize, bytesToRead); 469e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_fileOpened = true; 470e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_currentItemReadSize = 0; 471e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 472e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 473e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::didOpen(bool success) 474e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 475e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(m_async); 476e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 477e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!success) { 478e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block failed(notReadableError); 479e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 480e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 481e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 482e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Continue the reading. 483e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block readAsync(); 484e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 485e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 486e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::didRead(int bytesRead) 487e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 488e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block consumeData(m_buffer.data(), bytesRead); 489e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 490e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 491e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::consumeData(const char* data, int bytesRead) 492e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 493e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(m_async); 494e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 495e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_totalRemainingSize -= bytesRead; 496e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 497e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Notify the client. 498e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (bytesRead) 499e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyReceiveData(data, bytesRead); 500e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 501e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_fileOpened) { 502e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // When the current item is a file item, the reading is completed only if bytesRead is 0. 503e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!bytesRead) { 504e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Close the file. 505e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_fileOpened = false; 506e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_asyncStream->close(); 507e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 508e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Move to the next item. 509e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_readItemCount++; 510e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 511e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } else { 512e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Otherwise, we read the current text item as a whole and move to the next item. 513e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_readItemCount++; 514e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 515e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 516e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Continue the reading. 517e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block readAsync(); 518e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 519e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 520e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::failed(int errorCode) 521e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 522e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(m_async); 523e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 524e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Notify the client. 525e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyFail(errorCode); 526e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 527e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Close the file if needed. 528e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_fileOpened) { 529e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_fileOpened = false; 530e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_asyncStream->close(); 531e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 532e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 533e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 534e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::notifyResponse() 535e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 536e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!client()) 537e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 538e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 539e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_errorCode) { 540e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyResponseOnError(); 541e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyFinish(); 542e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } else 543e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifyResponseOnSuccess(); 544e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 545e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 546e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::notifyResponseOnSuccess() 547e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 548e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block bool isRangeRequest = m_rangeOffset != positionNotSpecified; 549e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ResourceResponse response(firstRequest().url(), m_blobData->contentType(), m_totalRemainingSize, String(), String()); 550e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setExpectedContentLength(m_totalRemainingSize); 551e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusCode(isRangeRequest ? httpPartialContent : httpOK); 552e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusText(isRangeRequest ? httpPartialContentText : httpOKText); 553e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_blobData->contentDisposition().isEmpty()) 554e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPHeaderField("Content-Disposition", m_blobData->contentDisposition()); 555e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block client()->didReceiveResponse(this, response); 556e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 557e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 558e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::notifyResponseOnError() 559e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 560e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(m_errorCode); 561e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 562e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ResourceResponse response(firstRequest().url(), String(), 0, String(), String()); 563e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block switch (m_errorCode) { 564e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case rangeError: 565e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusCode(httpRequestedRangeNotSatisfiable); 566e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusText(httpRequestedRangeNotSatisfiableText); 567e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 568e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case notFoundError: 569e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusCode(httpNotFound); 570e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusText(httpNotFoundText); 571e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 572e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case securityError: 573e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusCode(httpNotAllowed); 574e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusText(httpNotAllowedText); 575e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 576e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block default: 577e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusCode(httpInternalError); 578e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block response.setHTTPStatusText(httpInternalErrorText); 579e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 580e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 581e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block client()->didReceiveResponse(this, response); 582e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 583e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 584e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::notifyReceiveData(const char* data, int bytesRead) 585e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 586e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (client()) 587e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block client()->didReceiveData(this, data, bytesRead, bytesRead); 588e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 589e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 590e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::notifyFail(int errorCode) 591e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 592e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (client()) 593e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block client()->didFail(this, ResourceError(String(), errorCode, firstRequest().url(), String())); 594e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 595e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 5962fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic void doNotifyFinish(void* context) 5972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 5982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block BlobResourceHandle* handle = static_cast<BlobResourceHandle*>(context); 5992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (handle->client()) 6002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block handle->client()->didFinishLoading(handle, 0); 6012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 6022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 603e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid BlobResourceHandle::notifyFinish() 604e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 6052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_async) { 6062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Schedule to notify the client from a standalone function because the client might dispose the handle immediately from the callback function 6072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // while we still have BlobResourceHandle calls in the stack. 6082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block callOnMainThread(doNotifyFinish, this); 6092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 6102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 6112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 6122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block doNotifyFinish(this); 613e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 614e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 615e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} // namespace WebCore 616e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 617e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif // ENABLE(BLOB) 618e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 619