This source file includes following definitions.
- CreateEntry
- WriteEntry
- CloseEntry
- SafeCreateDirectory
- entry_
- CreateEntry
- GetNormalizedHeaders
- WriteEntry
- CloseEntry
#include "net/tools/dump_cache/cache_dumper.h"
#include "base/file_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/blockfile/entry_impl.h"
#include "net/http/http_cache.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/tools/dump_cache/url_to_filename_encoder.h"
CacheDumper::CacheDumper(disk_cache::Backend* cache)
: cache_(cache) {
}
int CacheDumper::CreateEntry(const std::string& key,
disk_cache::Entry** entry,
const net::CompletionCallback& callback) {
return cache_->CreateEntry(key, entry, callback);
}
int CacheDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset,
net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) {
return entry->WriteData(index, offset, buf, buf_len, callback, false);
}
void CacheDumper::CloseEntry(disk_cache::Entry* entry, base::Time last_used,
base::Time last_modified) {
if (entry) {
static_cast<disk_cache::EntryImpl*>(entry)->SetTimes(last_used,
last_modified);
entry->Close();
}
}
bool SafeCreateDirectory(const base::FilePath& path) {
#ifdef WIN32_LARGE_FILENAME_SUPPORT
bool rv = false;
std::wstring::size_type pos(0);
std::wstring backslash(L"\\");
const std::wstring kLargeFilenamePrefix(L"\\\\?\\");
std::wstring header(kLargeFilenamePrefix);
if (path.value().find(header) == 0)
pos = 4;
while ((pos = path.value().find(backslash, pos)) != std::wstring::npos) {
base::FilePath::StringType subdir = path.value().substr(0, pos);
CreateDirectoryW(subdir.c_str(), NULL);
pos++;
}
return CreateDirectoryW(path.value().c_str(), NULL) == TRUE;
#else
return base::CreateDirectory(path);
#endif
}
DiskDumper::DiskDumper(const base::FilePath& path)
: path_(path), entry_(NULL) {
base::CreateDirectory(path);
}
int DiskDumper::CreateEntry(const std::string& key,
disk_cache::Entry** entry,
const net::CompletionCallback& callback) {
int urlpos = key.find("http");
std::string url = urlpos > 0 ? key.substr(urlpos) : key;
std::string base_path = path_.MaybeAsASCII();
std::string new_path =
net::UrlToFilenameEncoder::Encode(url, base_path, false);
entry_path_ = base::FilePath::FromUTF8Unsafe(new_path);
#ifdef WIN32_LARGE_FILENAME_SUPPORT
const std::wstring kLongFilenamePrefix(L"\\\\?\\");
std::wstring name = kLongFilenamePrefix;
name.append(entry_path_.value());
entry_path_ = base::FilePath(name);
#endif
entry_url_ = key;
SafeCreateDirectory(entry_path_.DirName());
base::FilePath::StringType file = entry_path_.value();
#ifdef WIN32_LARGE_FILENAME_SUPPORT
entry_ = CreateFileW(file.c_str(), GENERIC_WRITE|GENERIC_READ, 0, 0,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (entry_ == INVALID_HANDLE_VALUE)
wprintf(L"CreateFileW (%s) failed: %d\n", file.c_str(), GetLastError());
return (entry_ != INVALID_HANDLE_VALUE) ? net::OK : net::ERR_FAILED;
#else
entry_ = base::OpenFile(entry_path_, "w+");
return (entry_ != NULL) ? net::OK : net::ERR_FAILED;
#endif
}
void GetNormalizedHeaders(const net::HttpResponseInfo& info,
std::string* output) {
output->assign(info.headers->GetStatusLine());
output->append("\r\n");
void* iter = 0;
std::string name, value;
while (info.headers->EnumerateHeaderLines(&iter, &name, &value)) {
output->append(name);
output->append(": ");
output->append(value);
output->append("\r\n");
}
output->append("\r\n");
}
int DiskDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset,
net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) {
if (!entry_)
return 0;
std::string headers;
const char *data;
size_t len;
if (index == 0) {
net::HttpResponseInfo response_info;
bool truncated;
if (!net::HttpCache::ParseResponseInfo(buf->data(), buf_len,
&response_info, &truncated))
return 0;
if (truncated)
return buf_len;
response_info.headers->RemoveHeader("transfer-encoding");
response_info.headers->RemoveHeader("content-length");
response_info.headers->RemoveHeader("x-original-url");
GetNormalizedHeaders(response_info, &headers);
std::string url = entry_url_;
std::string::size_type pos(0);
if ((pos = url.find("http")) != 0) {
if (pos != std::string::npos)
url = url.substr(pos);
}
std::string x_original_url = "X-Original-Url: " + url + "\r\n";
headers.replace(headers.length() - 2, 0, x_original_url);
data = headers.c_str();
len = headers.size();
} else if (index == 1) {
data = buf->data();
len = buf_len;
} else {
return 0;
}
#ifdef WIN32_LARGE_FILENAME_SUPPORT
DWORD bytes;
if (!WriteFile(entry_, data, len, &bytes, 0))
return 0;
return bytes;
#else
return fwrite(data, 1, len, entry_);
#endif
}
void DiskDumper::CloseEntry(disk_cache::Entry* entry, base::Time last_used,
base::Time last_modified) {
#ifdef WIN32_LARGE_FILENAME_SUPPORT
CloseHandle(entry_);
#else
base::CloseFile(entry_);
#endif
}