refactor: ginify net.request (#22779)
This commit is contained in:
parent
d3d7b3eb54
commit
decbca734f
4 changed files with 52 additions and 50 deletions
|
@ -5,10 +5,7 @@ const { EventEmitter } = require('events');
|
||||||
const { Readable, Writable } = require('stream');
|
const { Readable, Writable } = require('stream');
|
||||||
const { app } = require('electron');
|
const { app } = require('electron');
|
||||||
const { Session } = process.electronBinding('session');
|
const { Session } = process.electronBinding('session');
|
||||||
const { net, Net, _isValidHeaderName, _isValidHeaderValue } = process.electronBinding('net');
|
const { net, Net, isValidHeaderName, isValidHeaderValue, createURLLoader } = process.electronBinding('net');
|
||||||
const { URLLoader } = net;
|
|
||||||
|
|
||||||
Object.setPrototypeOf(URLLoader.prototype, EventEmitter.prototype);
|
|
||||||
|
|
||||||
const kSupportedProtocols = new Set(['http:', 'https:']);
|
const kSupportedProtocols = new Set(['http:', 'https:']);
|
||||||
|
|
||||||
|
@ -240,10 +237,10 @@ function parseOptions (options) {
|
||||||
useSessionCookies: options.useSessionCookies || false
|
useSessionCookies: options.useSessionCookies || false
|
||||||
};
|
};
|
||||||
for (const [name, value] of Object.entries(urlLoaderOptions.extraHeaders)) {
|
for (const [name, value] of Object.entries(urlLoaderOptions.extraHeaders)) {
|
||||||
if (!_isValidHeaderName(name)) {
|
if (!isValidHeaderName(name)) {
|
||||||
throw new Error(`Invalid header name: '${name}'`);
|
throw new Error(`Invalid header name: '${name}'`);
|
||||||
}
|
}
|
||||||
if (!_isValidHeaderValue(value.toString())) {
|
if (!isValidHeaderValue(value.toString())) {
|
||||||
throw new Error(`Invalid value for header '${name}': '${value}'`);
|
throw new Error(`Invalid value for header '${name}': '${value}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,10 +304,10 @@ class ClientRequest extends Writable {
|
||||||
if (this._started || this._firstWrite) {
|
if (this._started || this._firstWrite) {
|
||||||
throw new Error('Can\'t set headers after they are sent');
|
throw new Error('Can\'t set headers after they are sent');
|
||||||
}
|
}
|
||||||
if (!_isValidHeaderName(name)) {
|
if (!isValidHeaderName(name)) {
|
||||||
throw new Error(`Invalid header name: '${name}'`);
|
throw new Error(`Invalid header name: '${name}'`);
|
||||||
}
|
}
|
||||||
if (!_isValidHeaderValue(value.toString())) {
|
if (!isValidHeaderValue(value.toString())) {
|
||||||
throw new Error(`Invalid value for header '${name}': '${value}'`);
|
throw new Error(`Invalid value for header '${name}': '${value}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +371,7 @@ class ClientRequest extends Writable {
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.extraHeaders) };
|
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.extraHeaders) };
|
||||||
this._urlLoader = new URLLoader(opts);
|
this._urlLoader = createURLLoader(opts);
|
||||||
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {
|
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {
|
||||||
const response = this._response = new IncomingMessage(responseHead);
|
const response = this._response = new IncomingMessage(responseHead);
|
||||||
this.emit('response', response);
|
this.emit('response', response);
|
||||||
|
|
|
@ -33,15 +33,6 @@ v8::Local<v8::Value> Net::Create(v8::Isolate* isolate) {
|
||||||
void Net::BuildPrototype(v8::Isolate* isolate,
|
void Net::BuildPrototype(v8::Isolate* isolate,
|
||||||
v8::Local<v8::FunctionTemplate> prototype) {
|
v8::Local<v8::FunctionTemplate> prototype) {
|
||||||
prototype->SetClassName(gin::StringToV8(isolate, "Net"));
|
prototype->SetClassName(gin::StringToV8(isolate, "Net"));
|
||||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
|
||||||
.SetProperty("URLLoader", &Net::URLLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
v8::Local<v8::Value> Net::URLLoader(v8::Isolate* isolate) {
|
|
||||||
v8::Local<v8::FunctionTemplate> constructor;
|
|
||||||
constructor = SimpleURLLoaderWrapper::GetConstructor(isolate);
|
|
||||||
return constructor->GetFunction(isolate->GetCurrentContext())
|
|
||||||
.ToLocalChecked();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
@ -67,15 +58,13 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||||
void* priv) {
|
void* priv) {
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
|
|
||||||
SimpleURLLoaderWrapper::SetConstructor(
|
|
||||||
isolate, base::BindRepeating(SimpleURLLoaderWrapper::New));
|
|
||||||
|
|
||||||
gin_helper::Dictionary dict(isolate, exports);
|
gin_helper::Dictionary dict(isolate, exports);
|
||||||
dict.Set("net", Net::Create(isolate));
|
dict.Set("net", Net::Create(isolate));
|
||||||
dict.Set("Net",
|
dict.Set("Net",
|
||||||
Net::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
Net::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||||
dict.SetMethod("_isValidHeaderName", &IsValidHeaderName);
|
dict.SetMethod("isValidHeaderName", &IsValidHeaderName);
|
||||||
dict.SetMethod("_isValidHeaderValue", &IsValidHeaderValue);
|
dict.SetMethod("isValidHeaderValue", &IsValidHeaderValue);
|
||||||
|
dict.SetMethod("createURLLoader", &SimpleURLLoaderWrapper::Create);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -247,6 +247,9 @@ base::IDMap<SimpleURLLoaderWrapper*>& GetAllRequests() {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
gin::WrapperInfo SimpleURLLoaderWrapper::kWrapperInfo = {
|
||||||
|
gin::kEmbedderNativeGin};
|
||||||
|
|
||||||
SimpleURLLoaderWrapper::SimpleURLLoaderWrapper(
|
SimpleURLLoaderWrapper::SimpleURLLoaderWrapper(
|
||||||
std::unique_ptr<network::ResourceRequest> request,
|
std::unique_ptr<network::ResourceRequest> request,
|
||||||
network::mojom::URLLoaderFactory* url_loader_factory)
|
network::mojom::URLLoaderFactory* url_loader_factory)
|
||||||
|
@ -279,14 +282,14 @@ SimpleURLLoaderWrapper::SimpleURLLoaderWrapper(
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleURLLoaderWrapper::Pin() {
|
void SimpleURLLoaderWrapper::Pin() {
|
||||||
// Prevent ourselves from being GC'd until the request is complete.
|
// Prevent ourselves from being GC'd until the request is complete. Must be
|
||||||
// Must be called after InitWithArgs(), otherwise GetWrapper() isn't
|
// called after gin::CreateHandle, otherwise the wrapper isn't initialized.
|
||||||
// initialized.
|
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||||
pinned_wrapper_.Reset(isolate(), GetWrapper());
|
pinned_wrapper_.Reset(isolate, GetWrapper(isolate).ToLocalChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleURLLoaderWrapper::PinBodyGetter(v8::Local<v8::Value> body_getter) {
|
void SimpleURLLoaderWrapper::PinBodyGetter(v8::Local<v8::Value> body_getter) {
|
||||||
pinned_chunk_pipe_getter_.Reset(isolate(), body_getter);
|
pinned_chunk_pipe_getter_.Reset(v8::Isolate::GetCurrent(), body_getter);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleURLLoaderWrapper::~SimpleURLLoaderWrapper() {
|
SimpleURLLoaderWrapper::~SimpleURLLoaderWrapper() {
|
||||||
|
@ -338,11 +341,12 @@ void SimpleURLLoaderWrapper::Cancel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
gin_helper::WrappableBase* SimpleURLLoaderWrapper::New(gin::Arguments* args) {
|
gin::Handle<SimpleURLLoaderWrapper> SimpleURLLoaderWrapper::Create(
|
||||||
|
gin::Arguments* args) {
|
||||||
gin_helper::Dictionary opts;
|
gin_helper::Dictionary opts;
|
||||||
if (!args->GetNext(&opts)) {
|
if (!args->GetNext(&opts)) {
|
||||||
args->ThrowTypeError("Expected a dictionary");
|
args->ThrowTypeError("Expected a dictionary");
|
||||||
return nullptr;
|
return gin::Handle<SimpleURLLoaderWrapper>();
|
||||||
}
|
}
|
||||||
auto request = std::make_unique<network::ResourceRequest>();
|
auto request = std::make_unique<network::ResourceRequest>();
|
||||||
request->attach_same_site_cookies = true;
|
request->attach_same_site_cookies = true;
|
||||||
|
@ -354,7 +358,7 @@ gin_helper::WrappableBase* SimpleURLLoaderWrapper::New(gin::Arguments* args) {
|
||||||
if (!net::HttpUtil::IsValidHeaderName(it.first) ||
|
if (!net::HttpUtil::IsValidHeaderName(it.first) ||
|
||||||
!net::HttpUtil::IsValidHeaderValue(it.second)) {
|
!net::HttpUtil::IsValidHeaderValue(it.second)) {
|
||||||
args->ThrowTypeError("Invalid header name or value");
|
args->ThrowTypeError("Invalid header name or value");
|
||||||
return nullptr;
|
return gin::Handle<SimpleURLLoaderWrapper>();
|
||||||
}
|
}
|
||||||
request->headers.SetHeader(it.first, it.second);
|
request->headers.SetHeader(it.first, it.second);
|
||||||
}
|
}
|
||||||
|
@ -404,9 +408,9 @@ gin_helper::WrappableBase* SimpleURLLoaderWrapper::New(gin::Arguments* args) {
|
||||||
|
|
||||||
auto url_loader_factory = session->browser_context()->GetURLLoaderFactory();
|
auto url_loader_factory = session->browser_context()->GetURLLoaderFactory();
|
||||||
|
|
||||||
auto* ret =
|
auto ret = gin::CreateHandle(
|
||||||
new SimpleURLLoaderWrapper(std::move(request), url_loader_factory.get());
|
args->isolate(),
|
||||||
ret->InitWithArgs(args);
|
new SimpleURLLoaderWrapper(std::move(request), url_loader_factory.get()));
|
||||||
ret->Pin();
|
ret->Pin();
|
||||||
if (!chunk_pipe_getter.IsEmpty()) {
|
if (!chunk_pipe_getter.IsEmpty()) {
|
||||||
ret->PinBodyGetter(chunk_pipe_getter);
|
ret->PinBodyGetter(chunk_pipe_getter);
|
||||||
|
@ -417,8 +421,9 @@ gin_helper::WrappableBase* SimpleURLLoaderWrapper::New(gin::Arguments* args) {
|
||||||
void SimpleURLLoaderWrapper::OnDataReceived(base::StringPiece string_piece,
|
void SimpleURLLoaderWrapper::OnDataReceived(base::StringPiece string_piece,
|
||||||
base::OnceClosure resume) {
|
base::OnceClosure resume) {
|
||||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
v8::HandleScope handle_scope(isolate());
|
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||||
auto array_buffer = v8::ArrayBuffer::New(isolate(), string_piece.size());
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
auto array_buffer = v8::ArrayBuffer::New(isolate, string_piece.size());
|
||||||
auto backing_store = array_buffer->GetBackingStore();
|
auto backing_store = array_buffer->GetBackingStore();
|
||||||
memcpy(backing_store->Data(), string_piece.data(), string_piece.size());
|
memcpy(backing_store->Data(), string_piece.data(), string_piece.size());
|
||||||
Emit("data", array_buffer);
|
Emit("data", array_buffer);
|
||||||
|
@ -441,8 +446,9 @@ void SimpleURLLoaderWrapper::OnRetry(base::OnceClosure start_retry) {}
|
||||||
void SimpleURLLoaderWrapper::OnResponseStarted(
|
void SimpleURLLoaderWrapper::OnResponseStarted(
|
||||||
const GURL& final_url,
|
const GURL& final_url,
|
||||||
const network::mojom::URLResponseHead& response_head) {
|
const network::mojom::URLResponseHead& response_head) {
|
||||||
v8::HandleScope scope(isolate());
|
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(isolate());
|
v8::HandleScope scope(isolate);
|
||||||
|
gin::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||||
dict.Set("statusCode", response_head.headers->response_code());
|
dict.Set("statusCode", response_head.headers->response_code());
|
||||||
dict.Set("statusMessage", response_head.headers->GetStatusText());
|
dict.Set("statusMessage", response_head.headers->GetStatusText());
|
||||||
dict.Set("httpVersion", response_head.headers->GetHttpVersion());
|
dict.Set("httpVersion", response_head.headers->GetHttpVersion());
|
||||||
|
@ -471,14 +477,17 @@ void SimpleURLLoaderWrapper::OnDownloadProgress(uint64_t current) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void SimpleURLLoaderWrapper::BuildPrototype(
|
gin::ObjectTemplateBuilder SimpleURLLoaderWrapper::GetObjectTemplateBuilder(
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate) {
|
||||||
v8::Local<v8::FunctionTemplate> prototype) {
|
return gin_helper::EventEmitterMixin<
|
||||||
prototype->SetClassName(gin::StringToV8(isolate, "SimpleURLLoaderWrapper"));
|
SimpleURLLoaderWrapper>::GetObjectTemplateBuilder(isolate)
|
||||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
|
||||||
.SetMethod("cancel", &SimpleURLLoaderWrapper::Cancel);
|
.SetMethod("cancel", &SimpleURLLoaderWrapper::Cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* SimpleURLLoaderWrapper::GetTypeName() {
|
||||||
|
return "SimpleURLLoaderWrapper";
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -10,18 +10,21 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
|
#include "gin/wrappable.h"
|
||||||
#include "net/base/auth.h"
|
#include "net/base/auth.h"
|
||||||
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
|
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
|
||||||
#include "services/network/public/mojom/network_context.mojom.h"
|
#include "services/network/public/mojom/network_context.mojom.h"
|
||||||
#include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
|
#include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
|
||||||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||||||
#include "shell/common/gin_helper/event_emitter.h"
|
#include "shell/browser/event_emitter_mixin.h"
|
||||||
#include "url/gurl.h"
|
#include "url/gurl.h"
|
||||||
#include "v8/include/v8.h"
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
namespace gin {
|
namespace gin {
|
||||||
class Arguments;
|
class Arguments;
|
||||||
}
|
template <typename T>
|
||||||
|
class Handle;
|
||||||
|
} // namespace gin
|
||||||
|
|
||||||
namespace network {
|
namespace network {
|
||||||
class SimpleURLLoader;
|
class SimpleURLLoader;
|
||||||
|
@ -34,14 +37,12 @@ namespace api {
|
||||||
|
|
||||||
/** Wraps a SimpleURLLoader to make it usable from JavaScript */
|
/** Wraps a SimpleURLLoader to make it usable from JavaScript */
|
||||||
class SimpleURLLoaderWrapper
|
class SimpleURLLoaderWrapper
|
||||||
: public gin_helper::EventEmitter<SimpleURLLoaderWrapper>,
|
: public gin::Wrappable<SimpleURLLoaderWrapper>,
|
||||||
|
public gin_helper::EventEmitterMixin<SimpleURLLoaderWrapper>,
|
||||||
public network::SimpleURLLoaderStreamConsumer {
|
public network::SimpleURLLoaderStreamConsumer {
|
||||||
public:
|
public:
|
||||||
~SimpleURLLoaderWrapper() override;
|
~SimpleURLLoaderWrapper() override;
|
||||||
static gin_helper::WrappableBase* New(gin::Arguments* args);
|
static gin::Handle<SimpleURLLoaderWrapper> Create(gin::Arguments* args);
|
||||||
|
|
||||||
static void BuildPrototype(v8::Isolate* isolate,
|
|
||||||
v8::Local<v8::FunctionTemplate> prototype);
|
|
||||||
|
|
||||||
static SimpleURLLoaderWrapper* FromID(uint32_t id);
|
static SimpleURLLoaderWrapper* FromID(uint32_t id);
|
||||||
|
|
||||||
|
@ -55,6 +56,12 @@ class SimpleURLLoaderWrapper
|
||||||
|
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
|
// gin::Wrappable
|
||||||
|
static gin::WrapperInfo kWrapperInfo;
|
||||||
|
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||||
|
v8::Isolate* isolate) override;
|
||||||
|
const char* GetTypeName() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SimpleURLLoaderWrapper(std::unique_ptr<network::ResourceRequest> loader,
|
SimpleURLLoaderWrapper(std::unique_ptr<network::ResourceRequest> loader,
|
||||||
network::mojom::URLLoaderFactory* url_loader_factory);
|
network::mojom::URLLoaderFactory* url_loader_factory);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue