blob: 0578c10202ade2178be37e3b9ec8cf06fe5be9df [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_CACHE_COPIER_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_CACHE_COPIER_H_
#include <stdint.h>
#include <memory>
#include "content/browser/appcache/appcache_storage.h"
#include "content/browser/appcache/appcache_update_job.h"
#include "net/base/io_buffer.h"
#include "url/gurl.h"
namespace net {
class IOBuffer;
class HttpResponseInfo;
} // namespace net
namespace content {
class AppCacheResponseInfo;
class AppCacheResponseReader;
class AppCacheResponseWriter;
// Helper class to read cache info from and write cache info to disk.
class AppCacheUpdateJob::CacheCopier : public AppCacheStorage::Delegate {
public:
CacheCopier(AppCacheUpdateJob* job,
const GURL& url,
const GURL& manifest_url,
std::unique_ptr<AppCacheUpdateJob::URLFetcher> incoming_fetcher,
std::unique_ptr<AppCacheResponseWriter> response_writer);
~CacheCopier() override;
void Run();
AppCacheResponseWriter* response_writer() { return response_writer_.get(); }
private:
// Cache copies follow this flow:
//
// 1. Run() is called, state is kIdle, basic objects are set up to support
// reading and writing. State moves to kAwaitReadInfoComplete and
// ResponseInfoLoad() is triggered.
//
// 2. ResponseInfoLoad() completes async and calls OnResponseInfoLoaded(),
// which verifies state is kAwaitReadInfoComplete. The cached response
// info is updated with the incoming 304 response. Basic objects are
// prepared to write the new response info to a new response id. State
// moves to kAwaitWriteInfoComplete and WriteInfo() is triggered.
//
// 3. WriteInfo() completes async and calls OnWriteInfoComplete(), which
// verifies state kAwaitWriteComplete, that result (ie. number of
// bytes written) is greater than 0, sets state kReadData and async calls
// ReadData().
//
// 4. ReadData() handles state kReadData, which verifies that basic objects
// exist to read a chunk of data from the cached response id's data,
// state moves to kAwaitReadDataComplete, and ReadData() is triggered.
//
// 5. ReadData() completes async and calls OnReadDataComplete(), which detects
// state kAwaitReadDataComplete.
//
// If result (ie. the number of bytes read) is 0, state becomes
// kFinalize and a task is posted to trigger CopyComplete().
//
// If result is greater than 0, state becomes kAwaitWriteDataComplete
// and WriteData() is called.
//
// 6. WriteData() completes async and calls OnWriteDataComplete(), which
// verifies state kAwaitWriteDataComplete. State becomes kReadData and we
// post a task to call ReadData() again to repeat from step 4.
//
// 7. CopyComplete() can be called which verifies state kCopyComplete. From
// here, we post a task to let the update job know we've completed the copy
// and the resource fetch completed handling can continue.
//
// 8. The posted task in update job deletes the cache copy instance.
//
// 9. If the update job has been canceled, then we exit handling our copy
// and set state to kCanceled.
enum class State {
kIdle,
kAwaitReadInfoComplete,
kAwaitWriteInfoComplete,
kReadData,
kAwaitReadDataComplete,
kAwaitWriteDataComplete,
kCopyComplete,
kCanceled,
};
// Methods for AppCacheStorage::Delegate.
void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
int64_t response_id) override;
void Cancel();
void OnWriteInfoComplete(int result);
void ReadData();
void OnReadDataComplete(int result);
void OnWriteDataComplete(int result);
void CopyComplete();
AppCacheUpdateJob* const job_;
const GURL url_;
const GURL manifest_url_;
std::unique_ptr<AppCacheUpdateJob::URLFetcher> incoming_fetcher_;
std::unique_ptr<AppCacheResponseWriter> response_writer_;
State state_;
std::unique_ptr<net::HttpResponseInfo> incoming_http_info_;
scoped_refptr<AppCacheResponseInfo> existing_appcache_response_info_;
std::unique_ptr<net::HttpResponseInfo> merged_http_info_;
std::unique_ptr<AppCacheResponseReader> read_data_response_reader_;
scoped_refptr<net::IOBuffer> read_data_buffer_;
int read_data_size_;
};
} // namespace content
#endif // CONTENT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_CACHE_COPIER_H_