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