chore: bump chromium to 32e0bab929213da1019992bf31d29 (master) (#19488)
This commit is contained in:
parent
d0800aa200
commit
e959137a4b
112 changed files with 524 additions and 5639 deletions
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/about_protocol_handler.h"
|
||||
|
||||
#include "shell/browser/net/url_request_about_job.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
AboutProtocolHandler::AboutProtocolHandler() {}
|
||||
|
||||
AboutProtocolHandler::~AboutProtocolHandler() {}
|
||||
|
||||
net::URLRequestJob* AboutProtocolHandler::MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const {
|
||||
return new URLRequestAboutJob(request, network_delegate);
|
||||
}
|
||||
|
||||
bool AboutProtocolHandler::IsSafeRedirectTarget(const GURL& location) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_ABOUT_PROTOCOL_HANDLER_H_
|
||||
#define SHELL_BROWSER_NET_ABOUT_PROTOCOL_HANDLER_H_
|
||||
|
||||
#include "net/url_request/url_request_job_factory.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class AboutProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
|
||||
public:
|
||||
AboutProtocolHandler();
|
||||
~AboutProtocolHandler() override;
|
||||
|
||||
// net::URLRequestJobFactory::ProtocolHandler:
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override;
|
||||
bool IsSafeRedirectTarget(const GURL& location) const override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AboutProtocolHandler);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_ABOUT_PROTOCOL_HANDLER_H_
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/asar/asar_protocol_handler.h"
|
||||
|
||||
#include "base/task_runner.h"
|
||||
#include "net/base/filename_util.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "shell/browser/net/asar/url_request_asar_job.h"
|
||||
|
||||
namespace asar {
|
||||
|
||||
AsarProtocolHandler::AsarProtocolHandler(
|
||||
const scoped_refptr<base::TaskRunner>& file_task_runner)
|
||||
: file_task_runner_(file_task_runner) {}
|
||||
|
||||
AsarProtocolHandler::~AsarProtocolHandler() {}
|
||||
|
||||
net::URLRequestJob* AsarProtocolHandler::MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const {
|
||||
base::FilePath full_path;
|
||||
net::FileURLToFilePath(request->url(), &full_path);
|
||||
auto* job = new URLRequestAsarJob(request, network_delegate);
|
||||
job->Initialize(file_task_runner_, full_path);
|
||||
return job;
|
||||
}
|
||||
|
||||
bool AsarProtocolHandler::IsSafeRedirectTarget(const GURL& location) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace asar
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_ASAR_ASAR_PROTOCOL_HANDLER_H_
|
||||
#define SHELL_BROWSER_NET_ASAR_ASAR_PROTOCOL_HANDLER_H_
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "net/url_request/url_request_job_factory.h"
|
||||
|
||||
namespace base {
|
||||
class TaskRunner;
|
||||
}
|
||||
|
||||
namespace asar {
|
||||
|
||||
class AsarProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
|
||||
public:
|
||||
explicit AsarProtocolHandler(
|
||||
const scoped_refptr<base::TaskRunner>& file_task_runner);
|
||||
~AsarProtocolHandler() override;
|
||||
|
||||
// net::URLRequestJobFactory::ProtocolHandler:
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override;
|
||||
bool IsSafeRedirectTarget(const GURL& location) const override;
|
||||
|
||||
private:
|
||||
const scoped_refptr<base::TaskRunner> file_task_runner_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AsarProtocolHandler);
|
||||
};
|
||||
|
||||
} // namespace asar
|
||||
|
||||
#endif // SHELL_BROWSER_NET_ASAR_ASAR_PROTOCOL_HANDLER_H_
|
|
@ -27,6 +27,23 @@ namespace asar {
|
|||
|
||||
namespace {
|
||||
|
||||
net::Error ConvertMojoResultToNetError(MojoResult result) {
|
||||
switch (result) {
|
||||
case MOJO_RESULT_OK:
|
||||
return net::OK;
|
||||
case MOJO_RESULT_NOT_FOUND:
|
||||
return net::ERR_FILE_NOT_FOUND;
|
||||
case MOJO_RESULT_PERMISSION_DENIED:
|
||||
return net::ERR_ACCESS_DENIED;
|
||||
case MOJO_RESULT_RESOURCE_EXHAUSTED:
|
||||
return net::ERR_INSUFFICIENT_RESOURCES;
|
||||
case MOJO_RESULT_ABORTED:
|
||||
return net::ERR_ABORTED;
|
||||
default:
|
||||
return net::ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr size_t kDefaultFileUrlPipeSize = 65536;
|
||||
|
||||
// Because this makes things simpler.
|
||||
|
@ -55,7 +72,6 @@ class AsarURLLoader : public network::mojom::URLLoader {
|
|||
void FollowRedirect(const std::vector<std::string>& removed_headers,
|
||||
const net::HttpRequestHeaders& modified_headers,
|
||||
const base::Optional<GURL>& new_url) override {}
|
||||
void ProceedWithResponse() override {}
|
||||
void SetPriority(net::RequestPriority priority,
|
||||
int32_t intra_priority_value) override {}
|
||||
void PauseReadingBodyFromNet() override {}
|
||||
|
@ -121,24 +137,17 @@ class AsarURLLoader : public network::mojom::URLLoader {
|
|||
// requests at the same time.
|
||||
base::File file(info.unpacked ? real_path : archive->path(),
|
||||
base::File::FLAG_OPEN | base::File::FLAG_READ);
|
||||
// Move cursor to sub-file.
|
||||
file.Seek(base::File::FROM_BEGIN, info.offset);
|
||||
auto file_data_source =
|
||||
std::make_unique<mojo::FileDataSource>(std::move(file));
|
||||
mojo::DataPipeProducer::DataSource* data_source = file_data_source.get();
|
||||
|
||||
// File reading logics are copied from FileURLLoader.
|
||||
if (!file.IsValid()) {
|
||||
OnClientComplete(net::FileErrorToNetError(file.error_details()));
|
||||
std::vector<char> initial_read_buffer(net::kMaxBytesToSniff);
|
||||
auto read_result =
|
||||
data_source->Read(info.offset, base::span<char>(initial_read_buffer));
|
||||
if (read_result.result != MOJO_RESULT_OK) {
|
||||
OnClientComplete(ConvertMojoResultToNetError(read_result.result));
|
||||
return;
|
||||
}
|
||||
char initial_read_buffer[net::kMaxBytesToSniff];
|
||||
int initial_read_result =
|
||||
file.ReadAtCurrentPos(initial_read_buffer, net::kMaxBytesToSniff);
|
||||
if (initial_read_result < 0) {
|
||||
base::File::Error read_error = base::File::GetLastFileError();
|
||||
DCHECK_NE(base::File::FILE_OK, read_error);
|
||||
OnClientComplete(net::FileErrorToNetError(read_error));
|
||||
return;
|
||||
}
|
||||
size_t initial_read_size = static_cast<size_t>(initial_read_result);
|
||||
|
||||
std::string range_header;
|
||||
net::HttpByteRange byte_range;
|
||||
|
@ -162,27 +171,25 @@ class AsarURLLoader : public network::mojom::URLLoader {
|
|||
}
|
||||
}
|
||||
|
||||
size_t first_byte_to_send = 0;
|
||||
size_t total_bytes_to_send = static_cast<size_t>(info.size);
|
||||
uint64_t first_byte_to_send = 0;
|
||||
uint64_t total_bytes_to_send = info.size;
|
||||
|
||||
if (byte_range.IsValid()) {
|
||||
first_byte_to_send =
|
||||
static_cast<size_t>(byte_range.first_byte_position());
|
||||
first_byte_to_send = byte_range.first_byte_position();
|
||||
total_bytes_to_send =
|
||||
static_cast<size_t>(byte_range.last_byte_position()) -
|
||||
first_byte_to_send + 1;
|
||||
byte_range.last_byte_position() - first_byte_to_send + 1;
|
||||
}
|
||||
|
||||
total_bytes_written_ = static_cast<size_t>(total_bytes_to_send);
|
||||
total_bytes_written_ = total_bytes_to_send;
|
||||
|
||||
head.content_length = base::saturated_cast<int64_t>(total_bytes_to_send);
|
||||
|
||||
if (first_byte_to_send < initial_read_size) {
|
||||
if (first_byte_to_send < read_result.bytes_read) {
|
||||
// Write any data we read for MIME sniffing, constraining by range where
|
||||
// applicable. This will always fit in the pipe (see assertion near
|
||||
// |kDefaultFileUrlPipeSize| definition).
|
||||
uint32_t write_size = std::min(
|
||||
static_cast<uint32_t>(initial_read_size - first_byte_to_send),
|
||||
static_cast<uint32_t>(read_result.bytes_read - first_byte_to_send),
|
||||
static_cast<uint32_t>(total_bytes_to_send));
|
||||
const uint32_t expected_write_size = write_size;
|
||||
MojoResult result = pipe.producer_handle->WriteData(
|
||||
|
@ -194,14 +201,14 @@ class AsarURLLoader : public network::mojom::URLLoader {
|
|||
}
|
||||
|
||||
// Discount the bytes we just sent from the total range.
|
||||
first_byte_to_send = initial_read_size;
|
||||
first_byte_to_send = read_result.bytes_read;
|
||||
total_bytes_to_send -= write_size;
|
||||
}
|
||||
|
||||
if (!net::GetMimeTypeFromFile(path, &head.mime_type)) {
|
||||
std::string new_type;
|
||||
net::SniffMimeType(initial_read_buffer, initial_read_result, request.url,
|
||||
head.mime_type,
|
||||
net::SniffMimeType(initial_read_buffer.data(), read_result.bytes_read,
|
||||
request.url, head.mime_type,
|
||||
net::ForceSniffFileUrlsForHtml::kDisabled, &new_type);
|
||||
head.mime_type.assign(new_type);
|
||||
head.did_mime_sniff = true;
|
||||
|
@ -225,14 +232,14 @@ class AsarURLLoader : public network::mojom::URLLoader {
|
|||
// (i.e., no range request) this Seek is effectively a no-op.
|
||||
//
|
||||
// Note that in Electron we also need to add file offset.
|
||||
file.Seek(base::File::FROM_BEGIN,
|
||||
static_cast<int64_t>(first_byte_to_send) + info.offset);
|
||||
file_data_source->SetRange(
|
||||
first_byte_to_send + info.offset,
|
||||
first_byte_to_send + info.offset + total_bytes_to_send);
|
||||
|
||||
data_producer_ = std::make_unique<mojo::DataPipeProducer>(
|
||||
std::move(pipe.producer_handle));
|
||||
data_producer_->Write(
|
||||
std::make_unique<mojo::FileDataSource>(std::move(file),
|
||||
total_bytes_to_send),
|
||||
std::move(file_data_source),
|
||||
base::BindOnce(&AsarURLLoader::OnFileWritten, base::Unretained(this)));
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ bool ResponseMustBeObject(ProtocolType type) {
|
|||
|
||||
// Helper to convert value to Dictionary.
|
||||
mate::Dictionary ToDict(v8::Isolate* isolate, v8::Local<v8::Value> value) {
|
||||
if (value->IsObject())
|
||||
if (!value->IsFunction() && value->IsObject())
|
||||
return mate::Dictionary(
|
||||
isolate,
|
||||
value->ToObject(isolate->GetCurrentContext()).ToLocalChecked());
|
||||
|
@ -322,10 +322,14 @@ void AtomURLLoaderFactory::StartLoadingString(
|
|||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> response) {
|
||||
std::string contents;
|
||||
if (response->IsString())
|
||||
if (response->IsString()) {
|
||||
contents = gin::V8ToString(isolate, response);
|
||||
else if (!dict.IsEmpty())
|
||||
} else if (!dict.IsEmpty()) {
|
||||
dict.Get("data", &contents);
|
||||
} else {
|
||||
client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
|
||||
return;
|
||||
}
|
||||
|
||||
SendContents(std::move(client), std::move(head), std::move(contents));
|
||||
}
|
||||
|
|
|
@ -1,522 +0,0 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/atom_url_request.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/elements_upload_data_stream.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/base/upload_bytes_element_reader.h"
|
||||
#include "net/url_request/redirect_info.h"
|
||||
#include "shell/browser/api/atom_api_url_request.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
#include "shell/browser/net/atom_url_request_job_factory.h"
|
||||
|
||||
namespace {
|
||||
const int kBufferSize = 4096;
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace internal {
|
||||
|
||||
class UploadOwnedIOBufferElementReader : public net::UploadBytesElementReader {
|
||||
public:
|
||||
explicit UploadOwnedIOBufferElementReader(
|
||||
scoped_refptr<const net::IOBufferWithSize> buffer)
|
||||
: net::UploadBytesElementReader(buffer->data(), buffer->size()),
|
||||
buffer_(buffer) {}
|
||||
|
||||
~UploadOwnedIOBufferElementReader() override {}
|
||||
|
||||
static UploadOwnedIOBufferElementReader* CreateWithBuffer(
|
||||
scoped_refptr<const net::IOBufferWithSize> buffer) {
|
||||
return new UploadOwnedIOBufferElementReader(std::move(buffer));
|
||||
}
|
||||
|
||||
private:
|
||||
scoped_refptr<const net::IOBuffer> buffer_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UploadOwnedIOBufferElementReader);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
AtomURLRequest::AtomURLRequest(api::URLRequest* delegate)
|
||||
: delegate_(delegate),
|
||||
response_read_buffer_(new net::IOBuffer(kBufferSize)) {}
|
||||
|
||||
AtomURLRequest::~AtomURLRequest() {
|
||||
DCHECK(!request_context_getter_);
|
||||
DCHECK(!request_);
|
||||
}
|
||||
|
||||
scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
|
||||
AtomBrowserContext* browser_context,
|
||||
const std::string& method,
|
||||
const std::string& url,
|
||||
const std::string& redirect_policy,
|
||||
api::URLRequest* delegate) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
DCHECK(browser_context);
|
||||
DCHECK(!url.empty());
|
||||
DCHECK(delegate);
|
||||
if (!browser_context || url.empty() || !delegate) {
|
||||
return nullptr;
|
||||
}
|
||||
scoped_refptr<net::URLRequestContextGetter> request_context_getter(
|
||||
browser_context->GetRequestContext());
|
||||
DCHECK(request_context_getter);
|
||||
scoped_refptr<AtomURLRequest> atom_url_request(new AtomURLRequest(delegate));
|
||||
if (base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoInitialize, atom_url_request,
|
||||
request_context_getter, method, url,
|
||||
redirect_policy))) {
|
||||
return atom_url_request;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AtomURLRequest::Terminate() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
delegate_ = nullptr;
|
||||
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoTerminate, this));
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoInitialize(
|
||||
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
|
||||
const std::string& method,
|
||||
const std::string& url,
|
||||
const std::string& redirect_policy) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
DCHECK(request_context_getter);
|
||||
|
||||
redirect_policy_ = redirect_policy;
|
||||
request_context_getter_ = request_context_getter;
|
||||
request_context_getter_->AddObserver(this);
|
||||
auto* context = request_context_getter_->GetURLRequestContext();
|
||||
if (!context) {
|
||||
// Called after shutdown.
|
||||
DoCancelWithError("Cannot start a request after shutdown.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(context);
|
||||
request_ =
|
||||
context->CreateRequest(GURL(url), net::RequestPriority::DEFAULT_PRIORITY,
|
||||
this, MISSING_TRAFFIC_ANNOTATION);
|
||||
if (!request_) {
|
||||
DoCancelWithError("Failed to create a net::URLRequest.", true);
|
||||
return;
|
||||
}
|
||||
request_->set_method(method);
|
||||
// Do not send cookies from the cookie store.
|
||||
DoSetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES);
|
||||
// Set a flag to stop custom protocol from intercepting this request.
|
||||
request_->SetUserData(DisableProtocolInterceptFlagKey(),
|
||||
base::WrapUnique(new base::SupportsUserData::Data()));
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoTerminate() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
request_.reset();
|
||||
if (request_context_getter_) {
|
||||
request_context_getter_->RemoveObserver(this);
|
||||
request_context_getter_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool AtomURLRequest::Write(scoped_refptr<const net::IOBufferWithSize> buffer,
|
||||
bool is_last) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
return base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoWriteBuffer, this, buffer, is_last));
|
||||
}
|
||||
|
||||
void AtomURLRequest::SetChunkedUpload(bool is_chunked_upload) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
// The method can be called only before switching to multi-threaded mode,
|
||||
// i.e. before the first call to write.
|
||||
// So it is safe to change the object in the UI thread.
|
||||
is_chunked_upload_ = is_chunked_upload;
|
||||
}
|
||||
|
||||
void AtomURLRequest::Cancel() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoCancel, this));
|
||||
}
|
||||
|
||||
void AtomURLRequest::FollowRedirect() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoFollowRedirect, this));
|
||||
}
|
||||
|
||||
void AtomURLRequest::SetExtraHeader(const std::string& name,
|
||||
const std::string& value) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoSetExtraHeader, this, name, value));
|
||||
}
|
||||
|
||||
void AtomURLRequest::RemoveExtraHeader(const std::string& name) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoRemoveExtraHeader, this, name));
|
||||
}
|
||||
|
||||
void AtomURLRequest::PassLoginInformation(
|
||||
const base::string16& username,
|
||||
const base::string16& password) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
if (username.empty() || password.empty()) {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoCancelAuth, this));
|
||||
} else {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoSetAuth, this, username, password));
|
||||
}
|
||||
}
|
||||
|
||||
void AtomURLRequest::SetLoadFlags(int flags) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&AtomURLRequest::DoSetLoadFlags, this, flags));
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoWriteBuffer(
|
||||
scoped_refptr<const net::IOBufferWithSize> buffer,
|
||||
bool is_last) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_chunked_upload_) {
|
||||
// Chunked encoding case.
|
||||
|
||||
bool first_call = false;
|
||||
if (!chunked_stream_writer_) {
|
||||
std::unique_ptr<net::ChunkedUploadDataStream> chunked_stream(
|
||||
new net::ChunkedUploadDataStream(0));
|
||||
chunked_stream_writer_ = chunked_stream->CreateWriter();
|
||||
request_->set_upload(std::move(chunked_stream));
|
||||
first_call = true;
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
// Non-empty buffer.
|
||||
chunked_stream_writer_->AppendData(buffer->data(), buffer->size(),
|
||||
is_last);
|
||||
else if (is_last)
|
||||
// Empty buffer and last chunk, i.e. request.end().
|
||||
chunked_stream_writer_->AppendData(nullptr, 0, true);
|
||||
|
||||
if (first_call) {
|
||||
request_->Start();
|
||||
}
|
||||
} else {
|
||||
if (buffer) {
|
||||
// Handling potential empty buffers.
|
||||
using internal::UploadOwnedIOBufferElementReader;
|
||||
auto* element_reader =
|
||||
UploadOwnedIOBufferElementReader::CreateWithBuffer(std::move(buffer));
|
||||
upload_element_readers_.push_back(
|
||||
std::unique_ptr<net::UploadElementReader>(element_reader));
|
||||
}
|
||||
|
||||
if (is_last) {
|
||||
auto* elements_upload_data_stream = new net::ElementsUploadDataStream(
|
||||
std::move(upload_element_readers_), 0);
|
||||
request_->set_upload(
|
||||
std::unique_ptr<net::UploadDataStream>(elements_upload_data_stream));
|
||||
request_->Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoCancel() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (request_) {
|
||||
request_->Cancel();
|
||||
}
|
||||
DoTerminate();
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoFollowRedirect() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (request_ && request_->is_redirecting() && redirect_policy_ == "manual") {
|
||||
request_->FollowDeferredRedirect(base::nullopt /* removed_headers */,
|
||||
base::nullopt /* modified_headers */);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoSetExtraHeader(const std::string& name,
|
||||
const std::string& value) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_) {
|
||||
return;
|
||||
}
|
||||
request_->SetExtraRequestHeaderByName(name, value, true);
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoRemoveExtraHeader(const std::string& name) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_) {
|
||||
return;
|
||||
}
|
||||
request_->RemoveRequestHeaderByName(name);
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoSetAuth(const base::string16& username,
|
||||
const base::string16& password) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_) {
|
||||
return;
|
||||
}
|
||||
request_->SetAuth(net::AuthCredentials(username, password));
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoCancelAuth() const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_) {
|
||||
return;
|
||||
}
|
||||
request_->CancelAuth();
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoCancelWithError(const std::string& error,
|
||||
bool isRequestError) {
|
||||
DoCancel();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&AtomURLRequest::InformDelegateErrorOccured, this, error,
|
||||
isRequestError));
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoSetLoadFlags(int flags) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_) {
|
||||
return;
|
||||
}
|
||||
request_->SetLoadFlags(request_->load_flags() | flags);
|
||||
}
|
||||
|
||||
void AtomURLRequest::OnReceivedRedirect(net::URLRequest* request,
|
||||
const net::RedirectInfo& info,
|
||||
bool* defer_redirect) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_ || redirect_policy_ == "follow")
|
||||
return;
|
||||
|
||||
if (redirect_policy_ == "error") {
|
||||
request->Cancel();
|
||||
DoCancelWithError(
|
||||
"Request cannot follow redirect with the current redirect mode", true);
|
||||
} else if (redirect_policy_ == "manual") {
|
||||
*defer_redirect = true;
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers =
|
||||
request->response_headers();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&AtomURLRequest::InformDelegateReceivedRedirect, this,
|
||||
info.status_code, info.new_method, info.new_url,
|
||||
response_headers));
|
||||
}
|
||||
}
|
||||
|
||||
void AtomURLRequest::OnAuthRequired(net::URLRequest* request,
|
||||
const net::AuthChallengeInfo& auth_info) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&AtomURLRequest::InformDelegateAuthenticationRequired,
|
||||
this, auth_info));
|
||||
}
|
||||
|
||||
void AtomURLRequest::OnResponseStarted(net::URLRequest* request,
|
||||
int net_error) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_) {
|
||||
return;
|
||||
}
|
||||
DCHECK_EQ(request, request_.get());
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers =
|
||||
request->response_headers();
|
||||
const auto& status = request_->status();
|
||||
if (status.is_success()) {
|
||||
// Success or pending trigger a Read.
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&AtomURLRequest::InformDelegateResponseStarted, this,
|
||||
response_headers));
|
||||
ReadResponse();
|
||||
} else if (status.status() == net::URLRequestStatus::Status::FAILED) {
|
||||
// Report error on Start.
|
||||
DoCancelWithError(net::ErrorToString(net_error), true);
|
||||
}
|
||||
// We don't report an error is the request is canceled.
|
||||
}
|
||||
|
||||
void AtomURLRequest::ReadResponse() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
int bytes_read = -1;
|
||||
if (request_->Read(response_read_buffer_.get(), kBufferSize, &bytes_read)) {
|
||||
OnReadCompleted(request_.get(), bytes_read);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomURLRequest::OnReadCompleted(net::URLRequest* request, int bytes_read) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!request_) {
|
||||
return;
|
||||
}
|
||||
DCHECK_EQ(request, request_.get());
|
||||
|
||||
const auto status = request_->status();
|
||||
if (status.error() == bytes_read &&
|
||||
bytes_read == net::ERR_CONTENT_DECODING_INIT_FAILED) {
|
||||
// When the request job is unable to create a source stream for the
|
||||
// content encoding, we fail the request.
|
||||
DoCancelWithError(net::ErrorToString(net::ERR_CONTENT_DECODING_INIT_FAILED),
|
||||
true);
|
||||
return;
|
||||
}
|
||||
|
||||
bool response_error = false;
|
||||
bool data_ended = false;
|
||||
bool data_transfer_error = false;
|
||||
do {
|
||||
if (!status.is_success()) {
|
||||
response_error = true;
|
||||
break;
|
||||
}
|
||||
if (bytes_read == 0) {
|
||||
data_ended = true;
|
||||
break;
|
||||
}
|
||||
if (bytes_read < 0 || !CopyAndPostBuffer(bytes_read)) {
|
||||
data_transfer_error = true;
|
||||
break;
|
||||
}
|
||||
} while (
|
||||
request_->Read(response_read_buffer_.get(), kBufferSize, &bytes_read));
|
||||
if (response_error) {
|
||||
DoCancelWithError(net::ErrorToString(status.ToNetError()), false);
|
||||
} else if (data_ended) {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&AtomURLRequest::InformDelegateResponseCompleted, this));
|
||||
DoTerminate();
|
||||
} else if (data_transfer_error) {
|
||||
// We abort the request on corrupted data transfer.
|
||||
DoCancelWithError("Failed to transfer data from IO to UI thread.", false);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomURLRequest::OnContextShuttingDown() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
DoCancel();
|
||||
}
|
||||
|
||||
bool AtomURLRequest::CopyAndPostBuffer(int bytes_read) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
// data is only a wrapper for the asynchronous response_read_buffer_.
|
||||
// Make a deep copy of payload and transfer ownership to the UI thread.
|
||||
auto buffer_copy = WrapRefCounted(new net::IOBufferWithSize(bytes_read));
|
||||
memcpy(buffer_copy->data(), response_read_buffer_->data(), bytes_read);
|
||||
|
||||
return base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&AtomURLRequest::InformDelegateResponseData, this,
|
||||
buffer_copy));
|
||||
}
|
||||
|
||||
void AtomURLRequest::InformDelegateReceivedRedirect(
|
||||
int status_code,
|
||||
const std::string& method,
|
||||
const GURL& url,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
if (delegate_)
|
||||
delegate_->OnReceivedRedirect(status_code, method, url, response_headers);
|
||||
}
|
||||
|
||||
void AtomURLRequest::InformDelegateAuthenticationRequired(
|
||||
const net::AuthChallengeInfo& auth_info) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
if (delegate_)
|
||||
delegate_->OnAuthenticationRequired(auth_info);
|
||||
}
|
||||
|
||||
void AtomURLRequest::InformDelegateResponseStarted(
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
if (delegate_)
|
||||
delegate_->OnResponseStarted(response_headers);
|
||||
}
|
||||
|
||||
void AtomURLRequest::InformDelegateResponseData(
|
||||
scoped_refptr<net::IOBufferWithSize> data) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
// Transfer ownership of the data buffer, data will be released
|
||||
// by the delegate's OnResponseData.
|
||||
if (delegate_)
|
||||
delegate_->OnResponseData(data);
|
||||
}
|
||||
|
||||
void AtomURLRequest::InformDelegateResponseCompleted() const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnResponseCompleted();
|
||||
}
|
||||
|
||||
void AtomURLRequest::InformDelegateErrorOccured(const std::string& error,
|
||||
bool isRequestError) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnError(error, isRequestError);
|
||||
}
|
||||
|
||||
void AtomURLRequest::GetUploadProgress(mate::Dictionary* progress) const {
|
||||
net::UploadProgress upload_progress;
|
||||
if (request_) {
|
||||
progress->Set("started", true);
|
||||
upload_progress = request_->GetUploadProgress();
|
||||
} else {
|
||||
progress->Set("started", false);
|
||||
}
|
||||
progress->Set("current", upload_progress.position());
|
||||
progress->Set("total", upload_progress.size());
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,122 +0,0 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_ATOM_URL_REQUEST_H_
|
||||
#define SHELL_BROWSER_NET_ATOM_URL_REQUEST_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "net/base/auth.h"
|
||||
#include "net/base/chunked_upload_data_stream.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/base/upload_element_reader.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
#include "net/url_request/url_request_context_getter_observer.h"
|
||||
#include "shell/browser/api/atom_api_url_request.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
|
||||
public net::URLRequest::Delegate,
|
||||
public net::URLRequestContextGetterObserver {
|
||||
public:
|
||||
static scoped_refptr<AtomURLRequest> Create(
|
||||
AtomBrowserContext* browser_context,
|
||||
const std::string& method,
|
||||
const std::string& url,
|
||||
const std::string& redirect_policy,
|
||||
api::URLRequest* delegate);
|
||||
void Terminate();
|
||||
|
||||
bool Write(scoped_refptr<const net::IOBufferWithSize> buffer, bool is_last);
|
||||
void SetChunkedUpload(bool is_chunked_upload);
|
||||
void Cancel();
|
||||
void FollowRedirect();
|
||||
void SetExtraHeader(const std::string& name, const std::string& value) const;
|
||||
void RemoveExtraHeader(const std::string& name) const;
|
||||
void PassLoginInformation(const base::string16& username,
|
||||
const base::string16& password) const;
|
||||
void SetLoadFlags(int flags) const;
|
||||
void GetUploadProgress(mate::Dictionary* progress) const;
|
||||
|
||||
protected:
|
||||
// Overrides of net::URLRequest::Delegate
|
||||
void OnReceivedRedirect(net::URLRequest* request,
|
||||
const net::RedirectInfo& info,
|
||||
bool* defer_redirect) override;
|
||||
void OnAuthRequired(net::URLRequest* request,
|
||||
const net::AuthChallengeInfo& auth_info) override;
|
||||
void OnResponseStarted(net::URLRequest* request, int net_error) override;
|
||||
void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
|
||||
|
||||
// Overrides of net::URLRequestContextGetterObserver
|
||||
void OnContextShuttingDown() override;
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<AtomURLRequest>;
|
||||
|
||||
explicit AtomURLRequest(api::URLRequest* delegate);
|
||||
~AtomURLRequest() override;
|
||||
|
||||
void DoInitialize(scoped_refptr<net::URLRequestContextGetter>,
|
||||
const std::string& method,
|
||||
const std::string& url,
|
||||
const std::string& redirect_policy);
|
||||
void DoTerminate();
|
||||
void DoWriteBuffer(scoped_refptr<const net::IOBufferWithSize> buffer,
|
||||
bool is_last);
|
||||
void DoCancel();
|
||||
void DoFollowRedirect();
|
||||
void DoSetExtraHeader(const std::string& name,
|
||||
const std::string& value) const;
|
||||
void DoRemoveExtraHeader(const std::string& name) const;
|
||||
void DoSetAuth(const base::string16& username,
|
||||
const base::string16& password) const;
|
||||
void DoCancelAuth() const;
|
||||
void DoCancelWithError(const std::string& error, bool isRequestError);
|
||||
void DoSetLoadFlags(int flags) const;
|
||||
|
||||
void ReadResponse();
|
||||
bool CopyAndPostBuffer(int bytes_read);
|
||||
|
||||
void InformDelegateReceivedRedirect(
|
||||
int status_code,
|
||||
const std::string& method,
|
||||
const GURL& url,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers) const;
|
||||
void InformDelegateAuthenticationRequired(
|
||||
const net::AuthChallengeInfo& auth_info) const;
|
||||
void InformDelegateResponseStarted(
|
||||
scoped_refptr<net::HttpResponseHeaders>) const;
|
||||
void InformDelegateResponseData(
|
||||
scoped_refptr<net::IOBufferWithSize> data) const;
|
||||
void InformDelegateResponseCompleted() const;
|
||||
void InformDelegateErrorOccured(const std::string& error,
|
||||
bool isRequestError) const;
|
||||
|
||||
api::URLRequest* delegate_;
|
||||
std::unique_ptr<net::URLRequest> request_;
|
||||
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
|
||||
|
||||
bool is_chunked_upload_ = false;
|
||||
std::string redirect_policy_;
|
||||
std::unique_ptr<net::ChunkedUploadDataStream> chunked_stream_;
|
||||
std::unique_ptr<net::ChunkedUploadDataStream::Writer> chunked_stream_writer_;
|
||||
std::vector<std::unique_ptr<net::UploadElementReader>>
|
||||
upload_element_readers_;
|
||||
scoped_refptr<net::IOBuffer> response_read_buffer_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomURLRequest);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_ATOM_URL_REQUEST_H_
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/http_protocol_handler.h"
|
||||
|
||||
#include "net/url_request/url_request_http_job.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
HttpProtocolHandler::HttpProtocolHandler(const std::string& scheme)
|
||||
: scheme_(scheme) {}
|
||||
|
||||
HttpProtocolHandler::~HttpProtocolHandler() {}
|
||||
|
||||
net::URLRequestJob* HttpProtocolHandler::MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const {
|
||||
return net::URLRequestHttpJob::Factory(request, network_delegate, scheme_);
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_HTTP_PROTOCOL_HANDLER_H_
|
||||
#define SHELL_BROWSER_NET_HTTP_PROTOCOL_HANDLER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "net/url_request/url_request_job_factory.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class HttpProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
|
||||
public:
|
||||
explicit HttpProtocolHandler(const std::string&);
|
||||
~HttpProtocolHandler() override;
|
||||
|
||||
// net::URLRequestJobFactory::ProtocolHandler:
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override;
|
||||
|
||||
private:
|
||||
std::string scheme_;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_HTTP_PROTOCOL_HANDLER_H_
|
|
@ -50,7 +50,6 @@ class NodeStreamLoader : public network::mojom::URLLoader {
|
|||
void FollowRedirect(const std::vector<std::string>& removed_headers,
|
||||
const net::HttpRequestHeaders& modified_headers,
|
||||
const base::Optional<GURL>& new_url) override {}
|
||||
void ProceedWithResponse() override {}
|
||||
void SetPriority(net::RequestPriority priority,
|
||||
int32_t intra_priority_value) override {}
|
||||
void PauseReadingBodyFromNet() override {}
|
||||
|
|
|
@ -145,11 +145,6 @@ void ProxyingURLLoaderFactory::InProgressRequest::FollowRedirect(
|
|||
RestartInternal();
|
||||
}
|
||||
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::ProceedWithResponse() {
|
||||
if (target_loader_.is_bound())
|
||||
target_loader_->ProceedWithResponse();
|
||||
}
|
||||
|
||||
void ProxyingURLLoaderFactory::InProgressRequest::SetPriority(
|
||||
net::RequestPriority priority,
|
||||
int32_t intra_priority_value) {
|
||||
|
|
|
@ -50,7 +50,6 @@ class ProxyingURLLoaderFactory
|
|||
void FollowRedirect(const std::vector<std::string>& removed_headers,
|
||||
const net::HttpRequestHeaders& modified_headers,
|
||||
const base::Optional<GURL>& new_url) override;
|
||||
void ProceedWithResponse() override;
|
||||
void SetPriority(net::RequestPriority priority,
|
||||
int32_t intra_priority_value) override;
|
||||
void PauseReadingBodyFromNet() override;
|
||||
|
|
|
@ -50,9 +50,9 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams() {
|
|||
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params =
|
||||
network::mojom::HttpAuthDynamicParams::New();
|
||||
|
||||
auth_dynamic_params->server_whitelist = command_line->GetSwitchValueASCII(
|
||||
auth_dynamic_params->server_allowlist = command_line->GetSwitchValueASCII(
|
||||
electron::switches::kAuthServerWhitelist);
|
||||
auth_dynamic_params->delegate_whitelist = command_line->GetSwitchValueASCII(
|
||||
auth_dynamic_params->delegate_allowlist = command_line->GetSwitchValueASCII(
|
||||
electron::switches::kAuthNegotiateDelegateWhitelist);
|
||||
auth_dynamic_params->enable_negotiate_port =
|
||||
command_line->HasSwitch(electron::switches::kEnableAuthNegotiatePort);
|
||||
|
|
|
@ -60,7 +60,6 @@ class URLPipeLoader : public network::mojom::URLLoader,
|
|||
void FollowRedirect(const std::vector<std::string>& removed_headers,
|
||||
const net::HttpRequestHeaders& modified_headers,
|
||||
const base::Optional<GURL>& new_url) override {}
|
||||
void ProceedWithResponse() override {}
|
||||
void SetPriority(net::RequestPriority priority,
|
||||
int32_t intra_priority_value) override {}
|
||||
void PauseReadingBodyFromNet() override {}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/url_request_about_job.h"
|
||||
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
URLRequestAboutJob::URLRequestAboutJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate)
|
||||
: net::URLRequestJob(request, network_delegate), weak_ptr_factory_(this) {}
|
||||
|
||||
void URLRequestAboutJob::Start() {
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&URLRequestAboutJob::StartAsync,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void URLRequestAboutJob::Kill() {
|
||||
weak_ptr_factory_.InvalidateWeakPtrs();
|
||||
URLRequestJob::Kill();
|
||||
}
|
||||
|
||||
bool URLRequestAboutJob::GetMimeType(std::string* mime_type) const {
|
||||
*mime_type = "text/html";
|
||||
return true;
|
||||
}
|
||||
|
||||
URLRequestAboutJob::~URLRequestAboutJob() {}
|
||||
|
||||
void URLRequestAboutJob::StartAsync() {
|
||||
NotifyHeadersComplete();
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_URL_REQUEST_ABOUT_JOB_H_
|
||||
#define SHELL_BROWSER_NET_URL_REQUEST_ABOUT_JOB_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "net/url_request/url_request_job.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class URLRequestAboutJob : public net::URLRequestJob {
|
||||
public:
|
||||
URLRequestAboutJob(net::URLRequest*, net::NetworkDelegate*);
|
||||
|
||||
// URLRequestJob:
|
||||
void Start() override;
|
||||
void Kill() override;
|
||||
bool GetMimeType(std::string* mime_type) const override;
|
||||
|
||||
private:
|
||||
~URLRequestAboutJob() override;
|
||||
void StartAsync();
|
||||
|
||||
base::WeakPtrFactory<URLRequestAboutJob> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestAboutJob);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_URL_REQUEST_ABOUT_JOB_H_
|
|
@ -1,138 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/url_request_async_asar_job.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "shell/common/atom_constants.h"
|
||||
#include "shell/common/native_mate_converters/net_converter.h"
|
||||
#include "shell/common/native_mate_converters/v8_value_converter.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
void BeforeStartInUI(base::WeakPtr<URLRequestAsyncAsarJob> job,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> value;
|
||||
int error = net::OK;
|
||||
std::unique_ptr<base::Value> request_options = nullptr;
|
||||
|
||||
if (args->GetNext(&value)) {
|
||||
V8ValueConverter converter;
|
||||
v8::Local<v8::Context> context = args->isolate()->GetCurrentContext();
|
||||
request_options = converter.FromV8Value(value, context);
|
||||
}
|
||||
|
||||
if (request_options) {
|
||||
JsAsker::IsErrorOptions(request_options.get(), &error);
|
||||
} else {
|
||||
error = net::ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// sanitize custom headers
|
||||
if (request_options && request_options->is_dict()) {
|
||||
const base::Value* headersDict = request_options->FindDictKey("headers");
|
||||
if (headersDict) {
|
||||
for (const auto& iter : headersDict->DictItems()) {
|
||||
if (!iter.second.is_string()) {
|
||||
args->ThrowError("Value of '" + iter.first +
|
||||
"' header has to be a string");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestAsyncAsarJob::StartAsync, job,
|
||||
std::move(request_options), error));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
URLRequestAsyncAsarJob::URLRequestAsyncAsarJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate)
|
||||
: asar::URLRequestAsarJob(request, network_delegate), weak_factory_(this) {}
|
||||
|
||||
URLRequestAsyncAsarJob::~URLRequestAsyncAsarJob() = default;
|
||||
|
||||
void URLRequestAsyncAsarJob::Start() {
|
||||
auto request_details = std::make_unique<base::DictionaryValue>();
|
||||
FillRequestDetails(request_details.get(), request());
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(
|
||||
&JsAsker::AskForOptions, base::Unretained(isolate()), handler(),
|
||||
std::move(request_details),
|
||||
base::BindOnce(&BeforeStartInUI, weak_factory_.GetWeakPtr())));
|
||||
}
|
||||
|
||||
void URLRequestAsyncAsarJob::StartAsync(std::unique_ptr<base::Value> options,
|
||||
int error) {
|
||||
if (error != net::OK) {
|
||||
NotifyStartError(
|
||||
net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string file_path;
|
||||
response_headers_ = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
|
||||
if (options->is_dict()) {
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(options.get());
|
||||
base::Value* pathValue =
|
||||
dict->FindKeyOfType("path", base::Value::Type::STRING);
|
||||
if (pathValue) {
|
||||
file_path = pathValue->GetString();
|
||||
}
|
||||
base::Value* headersValue =
|
||||
dict->FindKeyOfType("headers", base::Value::Type::DICTIONARY);
|
||||
if (headersValue) {
|
||||
for (const auto& iter : headersValue->DictItems()) {
|
||||
response_headers_->AddHeader(iter.first + ": " +
|
||||
iter.second.GetString());
|
||||
}
|
||||
}
|
||||
} else if (options->is_string()) {
|
||||
file_path = options->GetString();
|
||||
}
|
||||
response_headers_->AddHeader(kCORSHeader);
|
||||
|
||||
if (file_path.empty()) {
|
||||
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
||||
net::ERR_NOT_IMPLEMENTED));
|
||||
} else {
|
||||
asar::URLRequestAsarJob::Initialize(
|
||||
base::CreateSequencedTaskRunnerWithTraits(
|
||||
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
|
||||
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}),
|
||||
#if defined(OS_WIN)
|
||||
base::FilePath(base::UTF8ToWide(file_path)));
|
||||
#else
|
||||
base::FilePath(file_path));
|
||||
#endif
|
||||
asar::URLRequestAsarJob::Start();
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequestAsyncAsarJob::Kill() {
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
URLRequestAsarJob::Kill();
|
||||
}
|
||||
|
||||
void URLRequestAsyncAsarJob::GetResponseInfo(net::HttpResponseInfo* info) {
|
||||
info->headers = response_headers_;
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_URL_REQUEST_ASYNC_ASAR_JOB_H_
|
||||
#define SHELL_BROWSER_NET_URL_REQUEST_ASYNC_ASAR_JOB_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "shell/browser/net/asar/url_request_asar_job.h"
|
||||
#include "shell/browser/net/js_asker.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
// Like URLRequestAsarJob, but asks the JavaScript handler for file path.
|
||||
class URLRequestAsyncAsarJob : public asar::URLRequestAsarJob, public JsAsker {
|
||||
public:
|
||||
URLRequestAsyncAsarJob(net::URLRequest*, net::NetworkDelegate*);
|
||||
~URLRequestAsyncAsarJob() override;
|
||||
|
||||
void StartAsync(std::unique_ptr<base::Value> options, int error);
|
||||
|
||||
// URLRequestJob:
|
||||
void Start() override;
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override;
|
||||
void Kill() override;
|
||||
|
||||
private:
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||
base::WeakPtrFactory<URLRequestAsyncAsarJob> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestAsyncAsarJob);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_URL_REQUEST_ASYNC_ASAR_JOB_H_
|
|
@ -1,155 +0,0 @@
|
|||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/url_request_buffer_job.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/mime_util.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "shell/common/atom_constants.h"
|
||||
#include "shell/common/native_mate_converters/net_converter.h"
|
||||
#include "shell/common/native_mate_converters/v8_value_converter.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string GetExtFromURL(const GURL& url) {
|
||||
std::string spec = url.spec();
|
||||
size_t index = spec.find_last_of('.');
|
||||
if (index == std::string::npos || index == spec.size())
|
||||
return std::string();
|
||||
return spec.substr(index + 1, spec.size() - index - 1);
|
||||
}
|
||||
|
||||
void BeforeStartInUI(base::WeakPtr<URLRequestBufferJob> job,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> value;
|
||||
int error = net::OK;
|
||||
std::unique_ptr<base::Value> request_options = nullptr;
|
||||
|
||||
if (args->GetNext(&value)) {
|
||||
V8ValueConverter converter;
|
||||
v8::Local<v8::Context> context = args->isolate()->GetCurrentContext();
|
||||
request_options = converter.FromV8Value(value, context);
|
||||
}
|
||||
|
||||
if (request_options) {
|
||||
JsAsker::IsErrorOptions(request_options.get(), &error);
|
||||
} else {
|
||||
error = net::ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestBufferJob::StartAsync, job,
|
||||
std::move(request_options), error));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
URLRequestBufferJob::URLRequestBufferJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate)
|
||||
: net::URLRequestSimpleJob(request, network_delegate),
|
||||
status_code_(net::HTTP_NOT_IMPLEMENTED),
|
||||
weak_factory_(this) {}
|
||||
|
||||
URLRequestBufferJob::~URLRequestBufferJob() = default;
|
||||
|
||||
void URLRequestBufferJob::Start() {
|
||||
auto request_details = std::make_unique<base::DictionaryValue>();
|
||||
FillRequestDetails(request_details.get(), request());
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(
|
||||
&JsAsker::AskForOptions, base::Unretained(isolate()), handler(),
|
||||
std::move(request_details),
|
||||
base::BindOnce(&BeforeStartInUI, weak_factory_.GetWeakPtr())));
|
||||
}
|
||||
|
||||
void URLRequestBufferJob::StartAsync(std::unique_ptr<base::Value> options,
|
||||
int error) {
|
||||
if (error != net::OK) {
|
||||
NotifyStartError(
|
||||
net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
|
||||
return;
|
||||
}
|
||||
|
||||
const base::Value* binary = nullptr;
|
||||
if (options->is_dict()) {
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(options.get());
|
||||
dict->GetString("mimeType", &mime_type_);
|
||||
dict->GetString("charset", &charset_);
|
||||
dict->GetBinary("data", &binary);
|
||||
} else if (options->is_blob()) {
|
||||
binary = options.get();
|
||||
}
|
||||
|
||||
if (mime_type_.empty()) {
|
||||
std::string ext = GetExtFromURL(request()->url());
|
||||
#if defined(OS_WIN)
|
||||
net::GetWellKnownMimeTypeFromExtension(base::UTF8ToUTF16(ext), &mime_type_);
|
||||
#else
|
||||
net::GetWellKnownMimeTypeFromExtension(ext, &mime_type_);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!binary) {
|
||||
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
||||
net::ERR_NOT_IMPLEMENTED));
|
||||
return;
|
||||
}
|
||||
|
||||
data_ = new base::RefCountedBytes(
|
||||
reinterpret_cast<const unsigned char*>(binary->GetBlob().data()),
|
||||
binary->GetBlob().size());
|
||||
status_code_ = net::HTTP_OK;
|
||||
net::URLRequestSimpleJob::Start();
|
||||
}
|
||||
|
||||
void URLRequestBufferJob::Kill() {
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
net::URLRequestSimpleJob::Kill();
|
||||
}
|
||||
|
||||
void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) {
|
||||
std::string status("HTTP/1.1 ");
|
||||
status.append(base::NumberToString(status_code_));
|
||||
status.append(" ");
|
||||
status.append(net::GetHttpReasonPhrase(status_code_));
|
||||
status.append("\0\0", 2);
|
||||
auto* headers = new net::HttpResponseHeaders(status);
|
||||
|
||||
headers->AddHeader(kCORSHeader);
|
||||
|
||||
if (!mime_type_.empty()) {
|
||||
std::string content_type_header(net::HttpRequestHeaders::kContentType);
|
||||
content_type_header.append(": ");
|
||||
content_type_header.append(mime_type_);
|
||||
headers->AddHeader(content_type_header);
|
||||
}
|
||||
|
||||
info->headers = headers;
|
||||
}
|
||||
|
||||
int URLRequestBufferJob::GetRefCountedData(
|
||||
std::string* mime_type,
|
||||
std::string* charset,
|
||||
scoped_refptr<base::RefCountedMemory>* data,
|
||||
net::CompletionOnceCallback callback) const {
|
||||
*mime_type = mime_type_;
|
||||
*charset = charset_;
|
||||
*data = data_;
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_URL_REQUEST_BUFFER_JOB_H_
|
||||
#define SHELL_BROWSER_NET_URL_REQUEST_BUFFER_JOB_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/ref_counted_memory.h"
|
||||
#include "net/http/http_status_code.h"
|
||||
#include "net/url_request/url_request_simple_job.h"
|
||||
#include "shell/browser/net/js_asker.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class URLRequestBufferJob : public JsAsker, public net::URLRequestSimpleJob {
|
||||
public:
|
||||
URLRequestBufferJob(net::URLRequest*, net::NetworkDelegate*);
|
||||
~URLRequestBufferJob() override;
|
||||
|
||||
void StartAsync(std::unique_ptr<base::Value> options, int error);
|
||||
|
||||
// URLRequestJob:
|
||||
void Start() override;
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override;
|
||||
void Kill() override;
|
||||
|
||||
// URLRequestSimpleJob:
|
||||
int GetRefCountedData(std::string* mime_type,
|
||||
std::string* charset,
|
||||
scoped_refptr<base::RefCountedMemory>* data,
|
||||
net::CompletionOnceCallback callback) const override;
|
||||
|
||||
private:
|
||||
std::string mime_type_;
|
||||
std::string charset_;
|
||||
scoped_refptr<base::RefCountedBytes> data_;
|
||||
net::HttpStatusCode status_code_;
|
||||
|
||||
base::WeakPtrFactory<URLRequestBufferJob> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestBufferJob);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_URL_REQUEST_BUFFER_JOB_H_
|
|
@ -1,365 +0,0 @@
|
|||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/url_request_context_getter.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/network_session_configurator/common/network_switches.h"
|
||||
#include "components/prefs/value_map_pref_store.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/devtools_network_transaction_factory.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "net/base/host_mapping_rules.h"
|
||||
#include "net/cert/multi_log_ct_verifier.h"
|
||||
#include "net/cookies/cookie_monster.h"
|
||||
#include "net/dns/mapped_host_resolver.h" // nogncheck
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/http/http_auth_scheme.h"
|
||||
#include "net/http/http_transaction_factory.h"
|
||||
#include "net/log/net_log.h"
|
||||
#include "net/traffic_annotation/network_traffic_annotation.h"
|
||||
#include "net/url_request/data_protocol_handler.h"
|
||||
#include "net/url_request/static_http_user_agent_settings.h"
|
||||
#include "net/url_request/url_request_intercepting_job_factory.h"
|
||||
#include "net/url_request/url_request_job_factory_impl.h"
|
||||
#include "services/network/ignore_errors_cert_verifier.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/cpp/network_switches.h"
|
||||
#include "services/network/url_request_context_builder_mojo.h"
|
||||
#include "shell/browser/api/atom_api_protocol.h"
|
||||
#include "shell/browser/atom_browser_client.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
#include "shell/browser/atom_browser_main_parts.h"
|
||||
#include "shell/browser/browser_process_impl.h"
|
||||
#include "shell/browser/net/about_protocol_handler.h"
|
||||
#include "shell/browser/net/asar/asar_protocol_handler.h"
|
||||
#include "shell/browser/net/atom_cert_verifier.h"
|
||||
#include "shell/browser/net/atom_network_delegate.h"
|
||||
#include "shell/browser/net/atom_url_request_job_factory.h"
|
||||
#include "shell/browser/net/http_protocol_handler.h"
|
||||
#include "shell/browser/net/require_ct_delegate.h"
|
||||
#include "shell/browser/net/system_network_context_manager.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
|
||||
#include "net/url_request/ftp_protocol_handler.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_REPORTING)
|
||||
#include "net/reporting/reporting_policy.h"
|
||||
#include "net/reporting/reporting_service.h"
|
||||
#endif // BUILDFLAG(ENABLE_REPORTING)
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
void SetupAtomURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
net::URLRequestContext* url_request_context,
|
||||
AtomURLRequestJobFactory* job_factory) {
|
||||
for (auto& protocol_handler : *protocol_handlers) {
|
||||
job_factory->SetProtocolHandler(protocol_handler.first,
|
||||
std::move(protocol_handler.second));
|
||||
}
|
||||
protocol_handlers->clear();
|
||||
|
||||
job_factory->SetProtocolHandler(url::kAboutScheme,
|
||||
std::make_unique<AboutProtocolHandler>());
|
||||
job_factory->SetProtocolHandler(url::kDataScheme,
|
||||
std::make_unique<net::DataProtocolHandler>());
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFileScheme,
|
||||
std::make_unique<asar::AsarProtocolHandler>(
|
||||
base::CreateTaskRunnerWithTraits(
|
||||
{base::MayBlock(), base::TaskPriority::USER_BLOCKING,
|
||||
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpScheme,
|
||||
std::make_unique<HttpProtocolHandler>(url::kHttpScheme));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kHttpsScheme,
|
||||
std::make_unique<HttpProtocolHandler>(url::kHttpsScheme));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWsScheme, std::make_unique<HttpProtocolHandler>(url::kWsScheme));
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kWssScheme, std::make_unique<HttpProtocolHandler>(url::kWssScheme));
|
||||
|
||||
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
|
||||
auto* host_resolver = url_request_context->host_resolver();
|
||||
auto* ftp_auth_cache = url_request_context->ftp_auth_cache();
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFtpScheme,
|
||||
net::FtpProtocolHandler::Create(host_resolver, ftp_auth_cache));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
URLRequestContextGetter::Handle::Handle(
|
||||
base::WeakPtr<AtomBrowserContext> browser_context)
|
||||
: resource_context_(new content::ResourceContext),
|
||||
browser_context_(browser_context),
|
||||
initialized_(false) {}
|
||||
|
||||
URLRequestContextGetter::Handle::~Handle() {}
|
||||
|
||||
content::ResourceContext*
|
||||
URLRequestContextGetter::Handle::GetResourceContext() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
LazyInitialize();
|
||||
return resource_context_.get();
|
||||
}
|
||||
|
||||
scoped_refptr<URLRequestContextGetter>
|
||||
URLRequestContextGetter::Handle::CreateMainRequestContextGetter(
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
DCHECK(!main_request_context_getter_.get());
|
||||
DCHECK(AtomBrowserMainParts::Get()->browser_process()->io_thread());
|
||||
|
||||
LazyInitialize();
|
||||
main_request_context_getter_ = new URLRequestContextGetter(
|
||||
this, protocol_handlers, std::move(protocol_interceptors));
|
||||
AtomBrowserMainParts::Get()
|
||||
->browser_process()
|
||||
->io_thread()
|
||||
->RegisterURLRequestContextGetter(main_request_context_getter_.get());
|
||||
return main_request_context_getter_;
|
||||
}
|
||||
|
||||
scoped_refptr<URLRequestContextGetter>
|
||||
URLRequestContextGetter::Handle::GetMainRequestContextGetter() {
|
||||
return main_request_context_getter_;
|
||||
}
|
||||
|
||||
network::mojom::NetworkContextPtr
|
||||
URLRequestContextGetter::Handle::GetNetworkContext() {
|
||||
if (!main_network_context_) {
|
||||
main_network_context_request_ = mojo::MakeRequest(&main_network_context_);
|
||||
}
|
||||
return std::move(main_network_context_);
|
||||
}
|
||||
|
||||
network::mojom::NetworkContextParamsPtr
|
||||
URLRequestContextGetter::Handle::CreateNetworkContextParams() {
|
||||
network::mojom::NetworkContextParamsPtr network_context_params =
|
||||
SystemNetworkContextManager::GetInstance()
|
||||
->CreateDefaultNetworkContextParams();
|
||||
|
||||
network_context_params->user_agent = browser_context_->GetUserAgent();
|
||||
|
||||
network_context_params->http_cache_enabled =
|
||||
browser_context_->CanUseHttpCache();
|
||||
|
||||
network_context_params->accept_language =
|
||||
net::HttpUtil::GenerateAcceptLanguageHeader(
|
||||
AtomBrowserClient::Get()->GetApplicationLocale());
|
||||
|
||||
if (!browser_context_->IsOffTheRecord()) {
|
||||
auto base_path = browser_context_->GetPath();
|
||||
network_context_params->http_cache_path =
|
||||
base_path.Append(chrome::kCacheDirname);
|
||||
network_context_params->http_cache_max_size =
|
||||
browser_context_->GetMaxCacheSize();
|
||||
network_context_params->http_server_properties_path =
|
||||
base_path.Append(chrome::kNetworkPersistentStateFilename);
|
||||
network_context_params->cookie_path =
|
||||
base_path.Append(chrome::kCookieFilename);
|
||||
network_context_params->restore_old_session_cookies = false;
|
||||
network_context_params->persist_session_cookies = false;
|
||||
// TODO(deepak1556): Matches the existing behavior https://git.io/fxHMl,
|
||||
// enable encryption as a followup.
|
||||
network_context_params->enable_encrypted_cookies = false;
|
||||
}
|
||||
|
||||
// TODO(deepak1556): Decide the stand on chrome ct policy and
|
||||
// enable it.
|
||||
// See //net/docs/certificate-transparency.md
|
||||
// network_context_params->enforce_chrome_ct_policy = true;
|
||||
return network_context_params;
|
||||
}
|
||||
|
||||
void URLRequestContextGetter::Handle::LazyInitialize() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
if (initialized_)
|
||||
return;
|
||||
|
||||
initialized_ = true;
|
||||
main_network_context_params_ = CreateNetworkContextParams();
|
||||
|
||||
browser_context_->proxy_config_monitor()->AddToNetworkContextParams(
|
||||
main_network_context_params_.get());
|
||||
|
||||
BrowserProcessImpl::ApplyProxyModeFromCommandLine(
|
||||
browser_context_->in_memory_pref_store());
|
||||
|
||||
if (!main_network_context_request_.is_pending()) {
|
||||
main_network_context_request_ = mojo::MakeRequest(&main_network_context_);
|
||||
}
|
||||
content::BrowserContext::EnsureResourceContextInitialized(
|
||||
browser_context_.get());
|
||||
}
|
||||
|
||||
void URLRequestContextGetter::Handle::ShutdownOnUIThread() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
if (main_request_context_getter_) {
|
||||
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestContextGetter::NotifyContextShuttingDown,
|
||||
base::RetainedRef(main_request_context_getter_)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this))
|
||||
delete this;
|
||||
}
|
||||
|
||||
URLRequestContextGetter::URLRequestContextGetter(
|
||||
URLRequestContextGetter::Handle* context_handle,
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors)
|
||||
: context_handle_(context_handle),
|
||||
url_request_context_(nullptr),
|
||||
protocol_interceptors_(std::move(protocol_interceptors)),
|
||||
context_shutting_down_(false) {
|
||||
// Must first be created on the UI thread.
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
if (protocol_handlers)
|
||||
std::swap(protocol_handlers_, *protocol_handlers);
|
||||
}
|
||||
|
||||
URLRequestContextGetter::~URLRequestContextGetter() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
// NotifyContextShuttingDown should have been called.
|
||||
DCHECK(context_shutting_down_);
|
||||
}
|
||||
|
||||
void URLRequestContextGetter::NotifyContextShuttingDown() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
DCHECK(AtomBrowserMainParts::Get()->browser_process()->io_thread());
|
||||
DCHECK(context_handle_);
|
||||
|
||||
if (context_shutting_down_)
|
||||
return;
|
||||
|
||||
AtomBrowserMainParts::Get()
|
||||
->browser_process()
|
||||
->io_thread()
|
||||
->DeregisterURLRequestContextGetter(this);
|
||||
|
||||
context_shutting_down_ = true;
|
||||
context_handle_->resource_context_.reset();
|
||||
net::URLRequestContextGetter::NotifyContextShuttingDown();
|
||||
network_context_.reset();
|
||||
}
|
||||
|
||||
net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
if (context_shutting_down_)
|
||||
return nullptr;
|
||||
|
||||
if (!url_request_context_) {
|
||||
std::unique_ptr<network::URLRequestContextBuilderMojo> builder =
|
||||
std::make_unique<network::URLRequestContextBuilderMojo>();
|
||||
|
||||
// Enable file:// support.
|
||||
builder->set_file_enabled(true);
|
||||
|
||||
#if BUILDFLAG(ENABLE_REPORTING)
|
||||
if (base::FeatureList::IsEnabled(network::features::kReporting)) {
|
||||
auto reporting_policy = net::ReportingPolicy::Create();
|
||||
builder->set_reporting_policy(std::move(reporting_policy));
|
||||
} else {
|
||||
builder->set_reporting_policy(nullptr);
|
||||
}
|
||||
|
||||
builder->set_network_error_logging_enabled(
|
||||
base::FeatureList::IsEnabled(network::features::kNetworkErrorLogging));
|
||||
#endif // BUILDFLAG(ENABLE_REPORTING)
|
||||
|
||||
auto network_delegate = std::make_unique<AtomNetworkDelegate>();
|
||||
network_delegate_ = network_delegate.get();
|
||||
builder->set_network_delegate(std::move(network_delegate));
|
||||
|
||||
ct_delegate_.reset(new RequireCTDelegate);
|
||||
auto cert_verifier = std::make_unique<AtomCertVerifier>(ct_delegate_.get());
|
||||
builder->SetCertVerifier(std::move(cert_verifier));
|
||||
|
||||
builder->SetCreateHttpTransactionFactoryCallback(
|
||||
base::BindOnce(&content::CreateDevToolsNetworkTransactionFactory));
|
||||
|
||||
builder->set_ct_verifier(std::make_unique<net::MultiLogCTVerifier>());
|
||||
|
||||
// Enable FTP, we override it later in SetupAtomURLRequestJobFactory
|
||||
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
|
||||
builder->set_ftp_enabled(true);
|
||||
#endif
|
||||
|
||||
auto* network_service = content::GetNetworkServiceImpl();
|
||||
network_context_ = network_service->CreateNetworkContextWithBuilder(
|
||||
std::move(context_handle_->main_network_context_request_),
|
||||
std::move(context_handle_->main_network_context_params_),
|
||||
std::move(builder), &url_request_context_);
|
||||
|
||||
net::TransportSecurityState* transport_security_state =
|
||||
url_request_context_->transport_security_state();
|
||||
transport_security_state->SetRequireCTDelegate(ct_delegate_.get());
|
||||
|
||||
// Add custom standard schemes to cookie schemes.
|
||||
auto* cookie_monster =
|
||||
static_cast<net::CookieMonster*>(url_request_context_->cookie_store());
|
||||
std::vector<std::string> cookie_schemes(
|
||||
{url::kHttpScheme, url::kHttpsScheme, url::kWsScheme, url::kWssScheme});
|
||||
const auto& custom_standard_schemes = electron::api::GetStandardSchemes();
|
||||
cookie_schemes.insert(cookie_schemes.end(), custom_standard_schemes.begin(),
|
||||
custom_standard_schemes.end());
|
||||
cookie_monster->SetCookieableSchemes(cookie_schemes, base::NullCallback());
|
||||
|
||||
// Setup handlers for custom job factory.
|
||||
top_job_factory_.reset(new AtomURLRequestJobFactory);
|
||||
SetupAtomURLRequestJobFactory(&protocol_handlers_, url_request_context_,
|
||||
top_job_factory_.get());
|
||||
std::unique_ptr<net::URLRequestJobFactory> inner_job_factory(
|
||||
new net::URLRequestJobFactoryImpl);
|
||||
if (!protocol_interceptors_.empty()) {
|
||||
// Set up interceptors in the reverse order.
|
||||
for (auto it = protocol_interceptors_.rbegin();
|
||||
it != protocol_interceptors_.rend(); ++it) {
|
||||
inner_job_factory.reset(new net::URLRequestInterceptingJobFactory(
|
||||
std::move(inner_job_factory), std::move(*it)));
|
||||
}
|
||||
protocol_interceptors_.clear();
|
||||
}
|
||||
top_job_factory_->Chain(std::move(inner_job_factory));
|
||||
url_request_context_->set_job_factory(top_job_factory_.get());
|
||||
}
|
||||
|
||||
return url_request_context_;
|
||||
}
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner>
|
||||
URLRequestContextGetter::GetNetworkTaskRunner() const {
|
||||
return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,114 +0,0 @@
|
|||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_
|
||||
#define SHELL_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
#include "base/debug/leak_tracker.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
class AtomBrowserContext;
|
||||
class AtomNetworkDelegate;
|
||||
class AtomURLRequestJobFactory;
|
||||
class RequireCTDelegate;
|
||||
class ResourceContext;
|
||||
|
||||
class URLRequestContextGetter : public net::URLRequestContextGetter {
|
||||
public:
|
||||
// net::URLRequestContextGetter:
|
||||
net::URLRequestContext* GetURLRequestContext() override;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
|
||||
const override;
|
||||
|
||||
// Discard reference to URLRequestContext and inform observers to
|
||||
// shutdown. Must be called only on IO thread.
|
||||
void NotifyContextShuttingDown();
|
||||
|
||||
AtomURLRequestJobFactory* job_factory() const {
|
||||
return top_job_factory_.get();
|
||||
}
|
||||
|
||||
AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
|
||||
|
||||
private:
|
||||
friend class AtomBrowserContext;
|
||||
|
||||
// Responsible for destroying URLRequestContextGetter
|
||||
// on the IO thread.
|
||||
class Handle {
|
||||
public:
|
||||
explicit Handle(base::WeakPtr<AtomBrowserContext> browser_context);
|
||||
~Handle();
|
||||
|
||||
scoped_refptr<URLRequestContextGetter> CreateMainRequestContextGetter(
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors);
|
||||
content::ResourceContext* GetResourceContext();
|
||||
scoped_refptr<URLRequestContextGetter> GetMainRequestContextGetter();
|
||||
network::mojom::NetworkContextPtr GetNetworkContext();
|
||||
network::mojom::NetworkContextParamsPtr CreateNetworkContextParams();
|
||||
|
||||
void ShutdownOnUIThread();
|
||||
|
||||
private:
|
||||
friend class URLRequestContextGetter;
|
||||
void LazyInitialize();
|
||||
|
||||
scoped_refptr<URLRequestContextGetter> main_request_context_getter_;
|
||||
std::unique_ptr<content::ResourceContext> resource_context_;
|
||||
base::WeakPtr<AtomBrowserContext> browser_context_;
|
||||
// This is a NetworkContext interface that uses URLRequestContextGetter
|
||||
// NetworkContext, ownership is passed to StoragePartition when
|
||||
// CreateMainNetworkContext is called.
|
||||
network::mojom::NetworkContextPtr main_network_context_;
|
||||
// Request corresponding to |main_network_context_|. Ownership
|
||||
// is passed to network service.
|
||||
network::mojom::NetworkContextRequest main_network_context_request_;
|
||||
network::mojom::NetworkContextParamsPtr main_network_context_params_;
|
||||
bool initialized_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Handle);
|
||||
};
|
||||
|
||||
URLRequestContextGetter(
|
||||
URLRequestContextGetter::Handle* context_handle,
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors);
|
||||
~URLRequestContextGetter() override;
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
base::debug::LeakTracker<URLRequestContextGetter> leak_tracker_;
|
||||
#endif
|
||||
|
||||
std::unique_ptr<RequireCTDelegate> ct_delegate_;
|
||||
std::unique_ptr<AtomURLRequestJobFactory> top_job_factory_;
|
||||
std::unique_ptr<network::mojom::NetworkContext> network_context_;
|
||||
|
||||
URLRequestContextGetter::Handle* context_handle_;
|
||||
net::URLRequestContext* url_request_context_;
|
||||
AtomNetworkDelegate* network_delegate_;
|
||||
content::ProtocolHandlerMap protocol_handlers_;
|
||||
content::URLRequestInterceptorScopedVector protocol_interceptors_;
|
||||
bool context_shutting_down_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_
|
|
@ -1,344 +0,0 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/url_request_fetch_job.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/guid.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_fetcher.h"
|
||||
#include "net/url_request/url_fetcher_response_writer.h"
|
||||
#include "shell/browser/api/atom_api_session.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
#include "shell/common/native_mate_converters/net_converter.h"
|
||||
#include "shell/common/native_mate_converters/v8_value_converter.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
// Convert string to RequestType.
|
||||
net::URLFetcher::RequestType GetRequestType(const std::string& raw) {
|
||||
std::string method = base::ToUpperASCII(raw);
|
||||
if (method.empty() || method == "GET")
|
||||
return net::URLFetcher::GET;
|
||||
else if (method == "POST")
|
||||
return net::URLFetcher::POST;
|
||||
else if (method == "HEAD")
|
||||
return net::URLFetcher::HEAD;
|
||||
else if (method == "DELETE")
|
||||
return net::URLFetcher::DELETE_REQUEST;
|
||||
else if (method == "PUT")
|
||||
return net::URLFetcher::PUT;
|
||||
else if (method == "PATCH")
|
||||
return net::URLFetcher::PATCH;
|
||||
else // Use "GET" as fallback.
|
||||
return net::URLFetcher::GET;
|
||||
}
|
||||
|
||||
// Pipe the response writer back to URLRequestFetchJob.
|
||||
class ResponsePiper : public net::URLFetcherResponseWriter {
|
||||
public:
|
||||
explicit ResponsePiper(URLRequestFetchJob* job) : job_(job) {}
|
||||
|
||||
// net::URLFetcherResponseWriter:
|
||||
int Initialize(net::CompletionOnceCallback callback) override {
|
||||
return net::OK;
|
||||
}
|
||||
int Write(net::IOBuffer* buffer,
|
||||
int num_bytes,
|
||||
net::CompletionOnceCallback callback) override {
|
||||
if (first_write_) {
|
||||
// The URLFetcherResponseWriter doesn't have an event when headers have
|
||||
// been read, so we have to emulate by hooking to first write event.
|
||||
job_->HeadersCompleted();
|
||||
first_write_ = false;
|
||||
}
|
||||
return job_->DataAvailable(buffer, num_bytes, std::move(callback));
|
||||
}
|
||||
int Finish(int net_error, net::CompletionOnceCallback callback) override {
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
private:
|
||||
bool first_write_ = true;
|
||||
URLRequestFetchJob* job_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ResponsePiper);
|
||||
};
|
||||
|
||||
void BeforeStartInUI(base::WeakPtr<URLRequestFetchJob> job,
|
||||
mate::Arguments* args) {
|
||||
// Pass whatever user passed to the actaul request job.
|
||||
v8::Local<v8::Value> value;
|
||||
mate::Dictionary options;
|
||||
if (!args->GetNext(&value) ||
|
||||
!mate::ConvertFromV8(args->isolate(), value, &options)) {
|
||||
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestFetchJob::OnError, job,
|
||||
net::ERR_NOT_IMPLEMENTED));
|
||||
return;
|
||||
}
|
||||
|
||||
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter;
|
||||
scoped_refptr<AtomBrowserContext> custom_browser_context;
|
||||
// When |session| is set to |null| we use a new request context for fetch
|
||||
// job.
|
||||
if (options.Get("session", &value)) {
|
||||
if (value->IsNull()) {
|
||||
// We have to create the URLRequestContextGetter on UI thread.
|
||||
custom_browser_context =
|
||||
AtomBrowserContext::From(base::GenerateGUID(), true);
|
||||
url_request_context_getter = custom_browser_context->GetRequestContext();
|
||||
} else {
|
||||
mate::Handle<api::Session> session;
|
||||
if (mate::ConvertFromV8(args->isolate(), value, &session) &&
|
||||
!session.IsEmpty()) {
|
||||
AtomBrowserContext* browser_context = session->browser_context();
|
||||
url_request_context_getter = browser_context->GetRequestContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
V8ValueConverter converter;
|
||||
v8::Local<v8::Context> context = args->isolate()->GetCurrentContext();
|
||||
std::unique_ptr<base::Value> request_options(
|
||||
converter.FromV8Value(value, context));
|
||||
|
||||
int error = net::OK;
|
||||
if (!request_options || !request_options->is_dict())
|
||||
error = net::ERR_NOT_IMPLEMENTED;
|
||||
|
||||
JsAsker::IsErrorOptions(request_options.get(), &error);
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestFetchJob::StartAsync, job,
|
||||
base::RetainedRef(url_request_context_getter),
|
||||
base::RetainedRef(custom_browser_context),
|
||||
std::move(request_options), error));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
URLRequestFetchJob::URLRequestFetchJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate)
|
||||
: net::URLRequestJob(request, network_delegate), weak_factory_(this) {}
|
||||
|
||||
URLRequestFetchJob::~URLRequestFetchJob() = default;
|
||||
|
||||
void URLRequestFetchJob::Start() {
|
||||
auto request_details = std::make_unique<base::DictionaryValue>();
|
||||
FillRequestDetails(request_details.get(), request());
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(
|
||||
&JsAsker::AskForOptions, base::Unretained(isolate()), handler(),
|
||||
std::move(request_details),
|
||||
base::BindOnce(&BeforeStartInUI, weak_factory_.GetWeakPtr())));
|
||||
}
|
||||
|
||||
void URLRequestFetchJob::StartAsync(
|
||||
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
|
||||
scoped_refptr<AtomBrowserContext> browser_context,
|
||||
std::unique_ptr<base::Value> options,
|
||||
int error) {
|
||||
if (error != net::OK) {
|
||||
NotifyStartError(
|
||||
net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url, method, referrer;
|
||||
base::DictionaryValue* upload_data = nullptr;
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(options.get());
|
||||
dict->GetString("url", &url);
|
||||
dict->GetString("method", &method);
|
||||
dict->GetString("referrer", &referrer);
|
||||
dict->GetDictionary("uploadData", &upload_data);
|
||||
|
||||
// Check if URL is valid.
|
||||
GURL formated_url(url);
|
||||
if (!formated_url.is_valid()) {
|
||||
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
||||
net::ERR_INVALID_URL));
|
||||
return;
|
||||
}
|
||||
|
||||
// Use |request|'s method if |method| is not specified.
|
||||
net::URLFetcher::RequestType request_type;
|
||||
if (method.empty())
|
||||
request_type = GetRequestType(request()->method());
|
||||
else
|
||||
request_type = GetRequestType(method);
|
||||
|
||||
fetcher_ = net::URLFetcher::Create(formated_url, request_type, this,
|
||||
MISSING_TRAFFIC_ANNOTATION);
|
||||
fetcher_->SaveResponseWithWriter(base::WrapUnique(new ResponsePiper(this)));
|
||||
|
||||
// A request context getter is passed by the user.
|
||||
if (url_request_context_getter)
|
||||
fetcher_->SetRequestContext(url_request_context_getter.get());
|
||||
else
|
||||
fetcher_->SetRequestContext(request_context_getter());
|
||||
|
||||
// Use |request|'s referrer if |referrer| is not specified.
|
||||
if (referrer.empty())
|
||||
fetcher_->SetReferrer(request()->referrer());
|
||||
else
|
||||
fetcher_->SetReferrer(referrer);
|
||||
|
||||
// Set the data needed for POSTs.
|
||||
if (upload_data && request_type == net::URLFetcher::POST) {
|
||||
std::string content_type, data;
|
||||
upload_data->GetString("contentType", &content_type);
|
||||
upload_data->GetString("data", &data);
|
||||
fetcher_->SetUploadData(content_type, data);
|
||||
}
|
||||
|
||||
// Use |request|'s headers.
|
||||
fetcher_->SetExtraRequestHeaders(
|
||||
request()->extra_request_headers().ToString());
|
||||
|
||||
fetcher_->Start();
|
||||
|
||||
if (browser_context)
|
||||
custom_browser_context_ = browser_context;
|
||||
}
|
||||
|
||||
void URLRequestFetchJob::OnError(int error) {
|
||||
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
|
||||
}
|
||||
|
||||
void URLRequestFetchJob::HeadersCompleted() {
|
||||
response_info_.reset(new net::HttpResponseInfo);
|
||||
response_info_->headers = fetcher_->GetResponseHeaders();
|
||||
NotifyHeadersComplete();
|
||||
}
|
||||
|
||||
int URLRequestFetchJob::DataAvailable(net::IOBuffer* buffer,
|
||||
int num_bytes,
|
||||
net::CompletionOnceCallback callback) {
|
||||
// When pending_buffer_ is empty, there's no ReadRawData() operation waiting
|
||||
// for IO completion, we have to save the parameters until the request is
|
||||
// ready to read data.
|
||||
if (!pending_buffer_.get()) {
|
||||
write_buffer_ = buffer;
|
||||
write_num_bytes_ = num_bytes;
|
||||
write_callback_ = std::move(callback);
|
||||
return net::ERR_IO_PENDING;
|
||||
}
|
||||
|
||||
// Write data to the pending buffer and clear them after the writing.
|
||||
int bytes_read = BufferCopy(buffer, num_bytes, pending_buffer_.get(),
|
||||
pending_buffer_size_);
|
||||
ClearPendingBuffer();
|
||||
ReadRawDataComplete(bytes_read);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
void URLRequestFetchJob::Kill() {
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
net::URLRequestJob::Kill();
|
||||
fetcher_.reset();
|
||||
custom_browser_context_ = nullptr;
|
||||
}
|
||||
|
||||
int URLRequestFetchJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
|
||||
if (GetResponseCode() == 204) {
|
||||
request()->set_received_response_content_length(prefilter_bytes_read());
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
// When write_buffer_ is empty, there is no data valable yet, we have to save
|
||||
// the dest buffer util DataAvailable.
|
||||
if (!write_buffer_.get()) {
|
||||
pending_buffer_ = dest;
|
||||
pending_buffer_size_ = dest_size;
|
||||
return net::ERR_IO_PENDING;
|
||||
}
|
||||
|
||||
// Read from the write buffer and clear them after reading.
|
||||
int bytes_read =
|
||||
BufferCopy(write_buffer_.get(), write_num_bytes_, dest, dest_size);
|
||||
ClearWriteBuffer();
|
||||
if (!write_callback_.is_null())
|
||||
std::move(write_callback_).Run(bytes_read);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
bool URLRequestFetchJob::GetMimeType(std::string* mime_type) const {
|
||||
if (!response_info_ || !response_info_->headers)
|
||||
return false;
|
||||
|
||||
return response_info_->headers->GetMimeType(mime_type);
|
||||
}
|
||||
|
||||
void URLRequestFetchJob::GetResponseInfo(net::HttpResponseInfo* info) {
|
||||
if (response_info_)
|
||||
*info = *response_info_;
|
||||
}
|
||||
|
||||
int URLRequestFetchJob::GetResponseCode() const {
|
||||
if (!response_info_ || !response_info_->headers)
|
||||
return -1;
|
||||
|
||||
return response_info_->headers->response_code();
|
||||
}
|
||||
|
||||
void URLRequestFetchJob::OnURLFetchComplete(const net::URLFetcher* source) {
|
||||
ClearPendingBuffer();
|
||||
ClearWriteBuffer();
|
||||
|
||||
if (fetcher_->GetStatus().is_success()) {
|
||||
if (!response_info_) {
|
||||
// Since we notify header completion only after first write there will be
|
||||
// no response object constructed for http respones with no content 204.
|
||||
// We notify header completion here.
|
||||
HeadersCompleted();
|
||||
return;
|
||||
}
|
||||
if (request_->status().is_io_pending()) {
|
||||
ReadRawDataComplete(0);
|
||||
}
|
||||
} else {
|
||||
NotifyStartError(fetcher_->GetStatus());
|
||||
}
|
||||
}
|
||||
|
||||
int URLRequestFetchJob::BufferCopy(net::IOBuffer* source,
|
||||
int num_bytes,
|
||||
net::IOBuffer* target,
|
||||
int target_size) {
|
||||
int bytes_written = std::min(num_bytes, target_size);
|
||||
memcpy(target->data(), source->data(), bytes_written);
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
void URLRequestFetchJob::ClearPendingBuffer() {
|
||||
pending_buffer_ = nullptr;
|
||||
pending_buffer_size_ = 0;
|
||||
}
|
||||
|
||||
void URLRequestFetchJob::ClearWriteBuffer() {
|
||||
write_buffer_ = nullptr;
|
||||
write_num_bytes_ = 0;
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_URL_REQUEST_FETCH_JOB_H_
|
||||
#define SHELL_BROWSER_NET_URL_REQUEST_FETCH_JOB_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "net/url_request/url_fetcher_delegate.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
#include "net/url_request/url_request_job.h"
|
||||
#include "shell/browser/net/js_asker.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
class URLRequestFetchJob : public JsAsker,
|
||||
public net::URLRequestJob,
|
||||
public net::URLFetcherDelegate {
|
||||
public:
|
||||
URLRequestFetchJob(net::URLRequest*, net::NetworkDelegate*);
|
||||
~URLRequestFetchJob() override;
|
||||
|
||||
void StartAsync(
|
||||
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
|
||||
scoped_refptr<AtomBrowserContext> browser_context,
|
||||
std::unique_ptr<base::Value> options,
|
||||
int error);
|
||||
void OnError(int error);
|
||||
|
||||
// Called by response writer.
|
||||
void HeadersCompleted();
|
||||
int DataAvailable(net::IOBuffer* buffer,
|
||||
int num_bytes,
|
||||
net::CompletionOnceCallback callback);
|
||||
|
||||
protected:
|
||||
// net::URLRequestJob:
|
||||
void Start() override;
|
||||
void Kill() override;
|
||||
int ReadRawData(net::IOBuffer* buf, int buf_size) override;
|
||||
bool GetMimeType(std::string* mime_type) const override;
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override;
|
||||
int GetResponseCode() const override;
|
||||
|
||||
// net::URLFetcherDelegate:
|
||||
void OnURLFetchComplete(const net::URLFetcher* source) override;
|
||||
|
||||
private:
|
||||
int BufferCopy(net::IOBuffer* source,
|
||||
int num_bytes,
|
||||
net::IOBuffer* target,
|
||||
int target_size);
|
||||
void ClearPendingBuffer();
|
||||
void ClearWriteBuffer();
|
||||
|
||||
scoped_refptr<AtomBrowserContext> custom_browser_context_;
|
||||
std::unique_ptr<net::URLFetcher> fetcher_;
|
||||
std::unique_ptr<net::HttpResponseInfo> response_info_;
|
||||
|
||||
// Saved arguments passed to ReadRawData.
|
||||
scoped_refptr<net::IOBuffer> pending_buffer_;
|
||||
int pending_buffer_size_ = 0;
|
||||
|
||||
// Saved arguments passed to DataAvailable.
|
||||
scoped_refptr<net::IOBuffer> write_buffer_;
|
||||
int write_num_bytes_ = 0;
|
||||
net::CompletionOnceCallback write_callback_;
|
||||
|
||||
base::WeakPtrFactory<URLRequestFetchJob> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestFetchJob);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_URL_REQUEST_FETCH_JOB_H_
|
|
@ -1,258 +0,0 @@
|
|||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/url_request_stream_job.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "base/time/time.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/filter/gzip_source_stream.h"
|
||||
#include "shell/common/api/event_emitter_caller.h"
|
||||
#include "shell/common/atom_constants.h"
|
||||
#include "shell/common/native_mate_converters/net_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
void BeforeStartInUI(base::WeakPtr<URLRequestStreamJob> job,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> value;
|
||||
int error = net::OK;
|
||||
bool ended = false;
|
||||
if (!args->GetNext(&value) || !value->IsObject()) {
|
||||
// Invalid opts.
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestStreamJob::OnError, job, net::ERR_FAILED));
|
||||
return;
|
||||
}
|
||||
|
||||
mate::Dictionary opts(args->isolate(), v8::Local<v8::Object>::Cast(value));
|
||||
int status_code;
|
||||
if (!opts.Get("statusCode", &status_code)) {
|
||||
// assume HTTP OK if statusCode is not passed.
|
||||
status_code = 200;
|
||||
}
|
||||
std::string status("HTTP/1.1 ");
|
||||
status.append(base::NumberToString(status_code));
|
||||
status.append(" ");
|
||||
status.append(
|
||||
net::GetHttpReasonPhrase(static_cast<net::HttpStatusCode>(status_code)));
|
||||
status.append("\0\0", 2);
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers(
|
||||
new net::HttpResponseHeaders(status));
|
||||
|
||||
if (opts.Get("headers", &value)) {
|
||||
mate::Converter<net::HttpResponseHeaders*>::FromV8(args->isolate(), value,
|
||||
response_headers.get());
|
||||
}
|
||||
|
||||
if (!opts.Get("data", &value)) {
|
||||
// Assume the opts is already a stream
|
||||
value = opts.GetHandle();
|
||||
} else if (value->IsNullOrUndefined()) {
|
||||
// "data" was explicitly passed as null or undefined, assume the user wants
|
||||
// to send an empty body.
|
||||
ended = true;
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestStreamJob::StartAsync, job, nullptr,
|
||||
base::RetainedRef(response_headers), ended, error));
|
||||
return;
|
||||
}
|
||||
|
||||
mate::Dictionary data(args->isolate(), v8::Local<v8::Object>::Cast(value));
|
||||
if (!data.Get("on", &value) || !value->IsFunction() ||
|
||||
!data.Get("removeListener", &value) || !value->IsFunction()) {
|
||||
// If data is passed but it is not a stream, signal an error.
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestStreamJob::OnError, job, net::ERR_FAILED));
|
||||
return;
|
||||
}
|
||||
|
||||
auto subscriber = base::MakeRefCounted<mate::StreamSubscriber>(
|
||||
args->isolate(), data.GetHandle(), job,
|
||||
base::ThreadTaskRunnerHandle::Get());
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestStreamJob::StartAsync, job, subscriber,
|
||||
base::RetainedRef(response_headers), ended, error));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
URLRequestStreamJob::URLRequestStreamJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate)
|
||||
: net::URLRequestJob(request, network_delegate),
|
||||
pending_buf_(nullptr),
|
||||
pending_buf_size_(0),
|
||||
ended_(false),
|
||||
response_headers_(nullptr),
|
||||
weak_factory_(this) {}
|
||||
|
||||
URLRequestStreamJob::~URLRequestStreamJob() {
|
||||
DCHECK(!subscriber_ || subscriber_->HasOneRef());
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::Start() {
|
||||
auto request_details = std::make_unique<base::DictionaryValue>();
|
||||
FillRequestDetails(request_details.get(), request());
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(
|
||||
&JsAsker::AskForOptions, base::Unretained(isolate()), handler(),
|
||||
std::move(request_details),
|
||||
base::BindOnce(&BeforeStartInUI, weak_factory_.GetWeakPtr())));
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::StartAsync(
|
||||
scoped_refptr<mate::StreamSubscriber> subscriber,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
||||
bool ended,
|
||||
int error) {
|
||||
if (error != net::OK) {
|
||||
NotifyStartError(
|
||||
net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
|
||||
return;
|
||||
}
|
||||
|
||||
ended_ = ended;
|
||||
response_headers_ = response_headers;
|
||||
subscriber_ = subscriber;
|
||||
request_start_time_ = base::TimeTicks::Now();
|
||||
NotifyHeadersComplete();
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::OnData(std::vector<char>&& buffer) { // NOLINT
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (write_buffer_.empty()) {
|
||||
// Quick branch without copying.
|
||||
write_buffer_ = std::move(buffer);
|
||||
} else {
|
||||
// write_buffer_ += buffer
|
||||
size_t len = write_buffer_.size();
|
||||
write_buffer_.resize(len + buffer.size());
|
||||
std::copy(buffer.begin(), buffer.end(), write_buffer_.begin() + len);
|
||||
}
|
||||
|
||||
// Copy to output.
|
||||
if (pending_buf_) {
|
||||
int len = BufferCopy(&write_buffer_, pending_buf_.get(), pending_buf_size_);
|
||||
write_buffer_.erase(write_buffer_.begin(), write_buffer_.begin() + len);
|
||||
pending_buf_ = nullptr;
|
||||
pending_buf_size_ = 0;
|
||||
ReadRawDataComplete(len);
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::OnEnd() {
|
||||
ended_ = true;
|
||||
if (pending_buf_) {
|
||||
ReadRawDataComplete(0);
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::OnError(int error) {
|
||||
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
|
||||
}
|
||||
|
||||
int URLRequestStreamJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
|
||||
response_start_time_ = base::TimeTicks::Now();
|
||||
|
||||
if (ended_ && write_buffer_.empty())
|
||||
return 0;
|
||||
|
||||
// When write_buffer_ is empty, there is no data valable yet, we have to save
|
||||
// the dest buffer util DataAvailable.
|
||||
if (write_buffer_.empty()) {
|
||||
pending_buf_ = dest;
|
||||
pending_buf_size_ = dest_size;
|
||||
return net::ERR_IO_PENDING;
|
||||
}
|
||||
|
||||
// Read from the write buffer and clear them after reading.
|
||||
int len = BufferCopy(&write_buffer_, dest, dest_size);
|
||||
write_buffer_.erase(write_buffer_.begin(), write_buffer_.begin() + len);
|
||||
return len;
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::DoneReading() {
|
||||
write_buffer_.clear();
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::DoneReadingRedirectResponse() {
|
||||
if (subscriber_) {
|
||||
DCHECK(subscriber_->HasAtLeastOneRef());
|
||||
subscriber_ = nullptr;
|
||||
}
|
||||
DoneReading();
|
||||
}
|
||||
|
||||
std::unique_ptr<net::SourceStream> URLRequestStreamJob::SetUpSourceStream() {
|
||||
std::unique_ptr<net::SourceStream> source =
|
||||
net::URLRequestJob::SetUpSourceStream();
|
||||
size_t i = 0;
|
||||
std::string type;
|
||||
while (response_headers_->EnumerateHeader(&i, "Content-Encoding", &type)) {
|
||||
if (base::LowerCaseEqualsASCII(type, "gzip") ||
|
||||
base::LowerCaseEqualsASCII(type, "x-gzip")) {
|
||||
return net::GzipSourceStream::Create(std::move(source),
|
||||
net::SourceStream::TYPE_GZIP);
|
||||
} else if (base::LowerCaseEqualsASCII(type, "deflate")) {
|
||||
return net::GzipSourceStream::Create(std::move(source),
|
||||
net::SourceStream::TYPE_DEFLATE);
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
bool URLRequestStreamJob::GetMimeType(std::string* mime_type) const {
|
||||
return response_headers_->GetMimeType(mime_type);
|
||||
}
|
||||
|
||||
int URLRequestStreamJob::GetResponseCode() const {
|
||||
return response_headers_->response_code();
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::GetResponseInfo(net::HttpResponseInfo* info) {
|
||||
info->headers = response_headers_;
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::GetLoadTimingInfo(
|
||||
net::LoadTimingInfo* load_timing_info) const {
|
||||
load_timing_info->send_start = request_start_time_;
|
||||
load_timing_info->send_end = request_start_time_;
|
||||
load_timing_info->request_start = request_start_time_;
|
||||
load_timing_info->receive_headers_end = response_start_time_;
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::Kill() {
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
net::URLRequestJob::Kill();
|
||||
}
|
||||
|
||||
int URLRequestStreamJob::BufferCopy(std::vector<char>* source,
|
||||
net::IOBuffer* target,
|
||||
int target_size) {
|
||||
int bytes_written = std::min(static_cast<int>(source->size()), target_size);
|
||||
memcpy(target->data(), source->data(), bytes_written);
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_URL_REQUEST_STREAM_JOB_H_
|
||||
#define SHELL_BROWSER_NET_URL_REQUEST_STREAM_JOB_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/http/http_status_code.h"
|
||||
#include "net/url_request/url_request_job.h"
|
||||
#include "shell/browser/api/stream_subscriber.h"
|
||||
#include "shell/browser/net/js_asker.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class URLRequestStreamJob : public JsAsker, public net::URLRequestJob {
|
||||
public:
|
||||
URLRequestStreamJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate);
|
||||
~URLRequestStreamJob() override;
|
||||
|
||||
void StartAsync(scoped_refptr<mate::StreamSubscriber> subscriber,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
||||
bool ended,
|
||||
int error);
|
||||
|
||||
void OnData(std::vector<char>&& buffer); // NOLINT
|
||||
void OnEnd();
|
||||
void OnError(int error);
|
||||
|
||||
protected:
|
||||
// URLRequestJob
|
||||
void Start() override;
|
||||
int ReadRawData(net::IOBuffer* buf, int buf_size) override;
|
||||
void DoneReading() override;
|
||||
void DoneReadingRedirectResponse() override;
|
||||
std::unique_ptr<net::SourceStream> SetUpSourceStream() override;
|
||||
bool GetMimeType(std::string* mime_type) const override;
|
||||
int GetResponseCode() const override;
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override;
|
||||
void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override;
|
||||
void Kill() override;
|
||||
|
||||
private:
|
||||
int BufferCopy(std::vector<char>* source,
|
||||
net::IOBuffer* target,
|
||||
int target_size);
|
||||
|
||||
// Saved arguments passed to ReadRawData.
|
||||
scoped_refptr<net::IOBuffer> pending_buf_;
|
||||
int pending_buf_size_;
|
||||
|
||||
// Saved arguments passed to OnData.
|
||||
std::vector<char> write_buffer_;
|
||||
|
||||
bool ended_;
|
||||
base::TimeTicks request_start_time_;
|
||||
base::TimeTicks response_start_time_;
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||
scoped_refptr<mate::StreamSubscriber> subscriber_;
|
||||
|
||||
base::WeakPtrFactory<URLRequestStreamJob> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestStreamJob);
|
||||
};
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_URL_REQUEST_STREAM_JOB_H_
|
|
@ -1,117 +0,0 @@
|
|||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/net/url_request_string_job.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "shell/common/atom_constants.h"
|
||||
#include "shell/common/native_mate_converters/net_converter.h"
|
||||
#include "shell/common/native_mate_converters/v8_value_converter.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
void BeforeStartInUI(base::WeakPtr<URLRequestStringJob> job,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> value;
|
||||
int error = net::OK;
|
||||
std::unique_ptr<base::Value> request_options = nullptr;
|
||||
|
||||
if (args->GetNext(&value)) {
|
||||
V8ValueConverter converter;
|
||||
v8::Local<v8::Context> context = args->isolate()->GetCurrentContext();
|
||||
request_options = converter.FromV8Value(value, context);
|
||||
}
|
||||
|
||||
if (request_options) {
|
||||
JsAsker::IsErrorOptions(request_options.get(), &error);
|
||||
} else {
|
||||
error = net::ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestStringJob::StartAsync, job,
|
||||
std::move(request_options), error));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
URLRequestStringJob::URLRequestStringJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate)
|
||||
: net::URLRequestSimpleJob(request, network_delegate),
|
||||
weak_factory_(this) {}
|
||||
|
||||
URLRequestStringJob::~URLRequestStringJob() = default;
|
||||
|
||||
void URLRequestStringJob::Start() {
|
||||
auto request_details = std::make_unique<base::DictionaryValue>();
|
||||
FillRequestDetails(request_details.get(), request());
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(
|
||||
&JsAsker::AskForOptions, base::Unretained(isolate()), handler(),
|
||||
std::move(request_details),
|
||||
base::BindOnce(&BeforeStartInUI, weak_factory_.GetWeakPtr())));
|
||||
}
|
||||
|
||||
void URLRequestStringJob::StartAsync(std::unique_ptr<base::Value> options,
|
||||
int error) {
|
||||
if (error != net::OK) {
|
||||
NotifyStartError(
|
||||
net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (options->is_dict()) {
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(options.get());
|
||||
dict->GetString("mimeType", &mime_type_);
|
||||
dict->GetString("charset", &charset_);
|
||||
dict->GetString("data", &data_);
|
||||
} else if (options->is_string()) {
|
||||
data_ = options->GetString();
|
||||
}
|
||||
net::URLRequestSimpleJob::Start();
|
||||
}
|
||||
|
||||
void URLRequestStringJob::Kill() {
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
net::URLRequestSimpleJob::Kill();
|
||||
}
|
||||
|
||||
void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) {
|
||||
std::string status("HTTP/1.1 200 OK");
|
||||
auto* headers = new net::HttpResponseHeaders(status);
|
||||
|
||||
headers->AddHeader(kCORSHeader);
|
||||
|
||||
if (!mime_type_.empty()) {
|
||||
std::string content_type_header(net::HttpRequestHeaders::kContentType);
|
||||
content_type_header.append(": ");
|
||||
content_type_header.append(mime_type_);
|
||||
headers->AddHeader(content_type_header);
|
||||
}
|
||||
|
||||
info->headers = headers;
|
||||
}
|
||||
|
||||
int URLRequestStringJob::GetData(std::string* mime_type,
|
||||
std::string* charset,
|
||||
std::string* data,
|
||||
net::CompletionOnceCallback callback) const {
|
||||
*mime_type = mime_type_;
|
||||
*charset = charset_;
|
||||
*data = data_;
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_NET_URL_REQUEST_STRING_JOB_H_
|
||||
#define SHELL_BROWSER_NET_URL_REQUEST_STRING_JOB_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "net/url_request/url_request_simple_job.h"
|
||||
#include "shell/browser/net/js_asker.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class URLRequestStringJob : public JsAsker, public net::URLRequestSimpleJob {
|
||||
public:
|
||||
URLRequestStringJob(net::URLRequest*, net::NetworkDelegate*);
|
||||
~URLRequestStringJob() override;
|
||||
|
||||
void StartAsync(std::unique_ptr<base::Value> options, int error);
|
||||
|
||||
// URLRequestJob:
|
||||
void Start() override;
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override;
|
||||
void Kill() override;
|
||||
|
||||
// URLRequestSimpleJob:
|
||||
int GetData(std::string* mime_type,
|
||||
std::string* charset,
|
||||
std::string* data,
|
||||
net::CompletionOnceCallback callback) const override;
|
||||
|
||||
private:
|
||||
std::string mime_type_;
|
||||
std::string charset_;
|
||||
std::string data_;
|
||||
|
||||
base::WeakPtrFactory<URLRequestStringJob> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestStringJob);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_NET_URL_REQUEST_STRING_JOB_H_
|
Loading…
Add table
Add a link
Reference in a new issue