Send file content in asar://
This commit is contained in:
parent
6d712da7e3
commit
b01db4aa09
4 changed files with 122 additions and 9 deletions
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
#include "atom/browser/net/asar/url_request_asar_job.h"
|
#include "atom/browser/net/asar/url_request_asar_job.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "net/base/file_stream.h"
|
||||||
|
#include "net/base/io_buffer.h"
|
||||||
#include "net/base/mime_util.h"
|
#include "net/base/mime_util.h"
|
||||||
#include "net/base/net_errors.h"
|
#include "net/base/net_errors.h"
|
||||||
#include "net/url_request/url_request_status.h"
|
#include "net/url_request/url_request_status.h"
|
||||||
|
@ -19,20 +23,30 @@ URLRequestAsarJob::URLRequestAsarJob(
|
||||||
: net::URLRequestJob(request, network_delegate),
|
: net::URLRequestJob(request, network_delegate),
|
||||||
archive_(asar_path),
|
archive_(asar_path),
|
||||||
file_path_(file_path),
|
file_path_(file_path),
|
||||||
|
stream_(new net::FileStream(file_task_runner)),
|
||||||
|
remaining_bytes_(0),
|
||||||
file_task_runner_(file_task_runner),
|
file_task_runner_(file_task_runner),
|
||||||
weak_ptr_factory_(this) {}
|
weak_ptr_factory_(this) {}
|
||||||
|
|
||||||
URLRequestAsarJob::~URLRequestAsarJob() {}
|
URLRequestAsarJob::~URLRequestAsarJob() {}
|
||||||
|
|
||||||
void URLRequestAsarJob::Start() {
|
void URLRequestAsarJob::Start() {
|
||||||
Archive::FileInfo info;
|
if (!archive_.Init() || !archive_.GetFileInfo(file_path_, &file_info_)) {
|
||||||
if (!archive_.Init() || !archive_.GetFileInfo(file_path_, &info)) {
|
|
||||||
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
||||||
net::ERR_FILE_NOT_FOUND));
|
net::ERR_FILE_NOT_FOUND));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyHeadersComplete();
|
remaining_bytes_ = static_cast<int64>(file_info_.size);
|
||||||
|
|
||||||
|
int flags = base::File::FLAG_OPEN |
|
||||||
|
base::File::FLAG_READ |
|
||||||
|
base::File::FLAG_ASYNC;
|
||||||
|
int rv = stream_->Open(archive_.path(), flags,
|
||||||
|
base::Bind(&URLRequestAsarJob::DidOpen,
|
||||||
|
weak_ptr_factory_.GetWeakPtr()));
|
||||||
|
if (rv != net::ERR_IO_PENDING)
|
||||||
|
DidOpen(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void URLRequestAsarJob::Kill() {
|
void URLRequestAsarJob::Kill() {
|
||||||
|
@ -40,15 +54,89 @@ void URLRequestAsarJob::Kill() {
|
||||||
URLRequestJob::Kill();
|
URLRequestJob::Kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool URLRequestAsarJob::ReadRawData(net::IOBuffer* buf,
|
bool URLRequestAsarJob::ReadRawData(net::IOBuffer* dest,
|
||||||
int buf_size,
|
int dest_size,
|
||||||
int* bytes_read) {
|
int* bytes_read) {
|
||||||
|
if (remaining_bytes_ < dest_size)
|
||||||
|
dest_size = static_cast<int>(remaining_bytes_);
|
||||||
|
|
||||||
|
// If we should copy zero bytes because |remaining_bytes_| is zero, short
|
||||||
|
// circuit here.
|
||||||
|
if (!dest_size) {
|
||||||
*bytes_read = 0;
|
*bytes_read = 0;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rv = stream_->Read(dest,
|
||||||
|
dest_size,
|
||||||
|
base::Bind(&URLRequestAsarJob::DidRead,
|
||||||
|
weak_ptr_factory_.GetWeakPtr(),
|
||||||
|
make_scoped_refptr(dest)));
|
||||||
|
if (rv >= 0) {
|
||||||
|
// Data is immediately available.
|
||||||
|
*bytes_read = rv;
|
||||||
|
remaining_bytes_ -= rv;
|
||||||
|
DCHECK_GE(remaining_bytes_, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, a read error occured. We may just need to wait...
|
||||||
|
if (rv == net::ERR_IO_PENDING) {
|
||||||
|
SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
|
||||||
|
} else {
|
||||||
|
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, rv));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool URLRequestAsarJob::GetMimeType(std::string* mime_type) const {
|
bool URLRequestAsarJob::GetMimeType(std::string* mime_type) const {
|
||||||
return net::GetMimeTypeFromFile(file_path_, mime_type);
|
return net::GetMimeTypeFromFile(file_path_, mime_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void URLRequestAsarJob::DidOpen(int result) {
|
||||||
|
if (result != net::OK) {
|
||||||
|
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rv = stream_->Seek(net::FROM_BEGIN,
|
||||||
|
file_info_.offset,
|
||||||
|
base::Bind(&URLRequestAsarJob::DidSeek,
|
||||||
|
weak_ptr_factory_.GetWeakPtr()));
|
||||||
|
if (rv != net::ERR_IO_PENDING) {
|
||||||
|
// stream_->Seek() failed, so pass an intentionally erroneous value
|
||||||
|
// into DidSeek().
|
||||||
|
DidSeek(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void URLRequestAsarJob::DidSeek(int64 result) {
|
||||||
|
if (result != static_cast<int64>(file_info_.offset)) {
|
||||||
|
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
||||||
|
net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_expected_content_size(remaining_bytes_);
|
||||||
|
NotifyHeadersComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
void URLRequestAsarJob::DidRead(scoped_refptr<net::IOBuffer> buf, int result) {
|
||||||
|
if (result > 0) {
|
||||||
|
SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status
|
||||||
|
remaining_bytes_ -= result;
|
||||||
|
DCHECK_GE(remaining_bytes_, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
NotifyDone(net::URLRequestStatus());
|
||||||
|
} else if (result < 0) {
|
||||||
|
NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
|
||||||
|
}
|
||||||
|
|
||||||
|
NotifyReadComplete(result);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace asar
|
} // namespace asar
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#ifndef ATOM_BROWSER_NET_ASAR_URL_REQUEST_ASAR_JOB_H_
|
#ifndef ATOM_BROWSER_NET_ASAR_URL_REQUEST_ASAR_JOB_H_
|
||||||
#define ATOM_BROWSER_NET_ASAR_URL_REQUEST_ASAR_JOB_H_
|
#define ATOM_BROWSER_NET_ASAR_URL_REQUEST_ASAR_JOB_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "atom/common/asar/archive.h"
|
#include "atom/common/asar/archive.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
|
@ -15,6 +17,10 @@ namespace base {
|
||||||
class TaskRunner;
|
class TaskRunner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace net {
|
||||||
|
class FileStream;
|
||||||
|
}
|
||||||
|
|
||||||
namespace asar {
|
namespace asar {
|
||||||
|
|
||||||
class URLRequestAsarJob : public net::URLRequestJob {
|
class URLRequestAsarJob : public net::URLRequestJob {
|
||||||
|
@ -37,8 +43,22 @@ class URLRequestAsarJob : public net::URLRequestJob {
|
||||||
virtual ~URLRequestAsarJob();
|
virtual ~URLRequestAsarJob();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Callback after opening file on a background thread.
|
||||||
|
void DidOpen(int result);
|
||||||
|
|
||||||
|
// Callback after seeking to the beginning of |byte_range_| in the file
|
||||||
|
// on a background thread.
|
||||||
|
void DidSeek(int64 result);
|
||||||
|
|
||||||
|
// Callback after data is asynchronously read from the file into |buf|.
|
||||||
|
void DidRead(scoped_refptr<net::IOBuffer> buf, int result);
|
||||||
|
|
||||||
Archive archive_;
|
Archive archive_;
|
||||||
|
Archive::FileInfo file_info_;
|
||||||
base::FilePath file_path_;
|
base::FilePath file_path_;
|
||||||
|
|
||||||
|
scoped_ptr<net::FileStream> stream_;
|
||||||
|
int64 remaining_bytes_;
|
||||||
const scoped_refptr<base::TaskRunner> file_task_runner_;
|
const scoped_refptr<base::TaskRunner> file_task_runner_;
|
||||||
|
|
||||||
base::WeakPtrFactory<URLRequestAsarJob> weak_ptr_factory_;
|
base::WeakPtrFactory<URLRequestAsarJob> weak_ptr_factory_;
|
||||||
|
|
|
@ -44,7 +44,9 @@ bool GetNodeFromPath(std::string path,
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Archive::Archive(const base::FilePath& path) : path_(path) {
|
Archive::Archive(const base::FilePath& path)
|
||||||
|
: path_(path),
|
||||||
|
header_size_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Archive::~Archive() {
|
Archive::~Archive() {
|
||||||
|
@ -94,6 +96,7 @@ bool Archive::Init() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header_size_ = 8 + size;
|
||||||
header_.reset(static_cast<base::DictionaryValue*>(value));
|
header_.reset(static_cast<base::DictionaryValue*>(value));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -119,8 +122,9 @@ bool Archive::GetFileInfo(const base::FilePath& path, FileInfo* info) {
|
||||||
int size;
|
int size;
|
||||||
if (!node->GetInteger("size", &size))
|
if (!node->GetInteger("size", &size))
|
||||||
return false;
|
return false;
|
||||||
info->size = static_cast<uint32>(size);
|
|
||||||
|
|
||||||
|
info->offset += header_size_;
|
||||||
|
info->size = static_cast<uint32>(size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ class Archive {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
base::FilePath path_;
|
base::FilePath path_;
|
||||||
|
uint32 header_size_;
|
||||||
scoped_ptr<base::DictionaryValue> header_;
|
scoped_ptr<base::DictionaryValue> header_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Archive);
|
DISALLOW_COPY_AND_ASSIGN(Archive);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue