Implementing authentication callback.
This commit is contained in:
parent
2d9d4af98d
commit
2b3b41d5f9
5 changed files with 312 additions and 129 deletions
|
@ -8,6 +8,9 @@
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "atom/browser/net/atom_url_request.h"
|
#include "atom/browser/net/atom_url_request.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
#include "atom/common/native_mate_converters/net_converter.h"
|
||||||
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -19,9 +22,9 @@ const char* const kEnd = "end";
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Converter<scoped_refptr<net::HttpResponseHeaders>> {
|
struct Converter<scoped_refptr<const net::HttpResponseHeaders>> {
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
scoped_refptr<net::HttpResponseHeaders> val) {
|
scoped_refptr<const net::HttpResponseHeaders> val) {
|
||||||
|
|
||||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||||
if (val) {
|
if (val) {
|
||||||
|
@ -37,10 +40,10 @@ struct Converter<scoped_refptr<net::HttpResponseHeaders>> {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Converter<scoped_refptr<net::IOBufferWithSize>> {
|
struct Converter<scoped_refptr<const net::IOBufferWithSize>> {
|
||||||
static v8::Local<v8::Value> ToV8(
|
static v8::Local<v8::Value> ToV8(
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
scoped_refptr<net::IOBufferWithSize> buffer) {
|
scoped_refptr<const net::IOBufferWithSize> buffer) {
|
||||||
return node::Buffer::Copy(isolate, buffer->data(), buffer->size()).ToLocalChecked();
|
return node::Buffer::Copy(isolate, buffer->data(), buffer->size()).ToLocalChecked();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -79,11 +82,13 @@ mate::WrappableBase* URLRequest::New(mate::Arguments* args) {
|
||||||
|
|
||||||
auto api_url_request = new URLRequest(args->isolate(), args->GetThis());
|
auto api_url_request = new URLRequest(args->isolate(), args->GetThis());
|
||||||
auto weak_ptr = api_url_request->weak_ptr_factory_.GetWeakPtr();
|
auto weak_ptr = api_url_request->weak_ptr_factory_.GetWeakPtr();
|
||||||
auto atom_url_request = AtomURLRequest::create(browser_context, url, weak_ptr);
|
auto atom_url_request = AtomURLRequest::Create(
|
||||||
|
browser_context,
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
weak_ptr);
|
||||||
|
|
||||||
atom_url_request->set_method(method);
|
api_url_request->atom_request_ = atom_url_request;
|
||||||
|
|
||||||
api_url_request->atom_url_request_ = atom_url_request;
|
|
||||||
|
|
||||||
|
|
||||||
return api_url_request;
|
return api_url_request;
|
||||||
|
@ -97,12 +102,12 @@ void URLRequest::BuildPrototype(v8::Isolate* isolate,
|
||||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||||
// Request API
|
// Request API
|
||||||
.MakeDestroyable()
|
.MakeDestroyable()
|
||||||
.SetMethod("write", &URLRequest::Write)
|
.SetMethod("_write", &URLRequest::Write)
|
||||||
.SetMethod("end", &URLRequest::End)
|
.SetMethod("_end", &URLRequest::End)
|
||||||
.SetMethod("abort", &URLRequest::Abort)
|
.SetMethod("abort", &URLRequest::Abort)
|
||||||
.SetMethod("setHeader", &URLRequest::SetHeader)
|
.SetMethod("_setHeader", &URLRequest::SetHeader)
|
||||||
.SetMethod("getHeader", &URLRequest::GetHeader)
|
.SetMethod("_getHeader", &URLRequest::GetHeader)
|
||||||
.SetMethod("removaHeader", &URLRequest::RemoveHeader)
|
.SetMethod("_removaHeader", &URLRequest::RemoveHeader)
|
||||||
// Response APi
|
// Response APi
|
||||||
.SetProperty("statusCode", &URLRequest::StatusCode)
|
.SetProperty("statusCode", &URLRequest::StatusCode)
|
||||||
.SetProperty("statusMessage", &URLRequest::StatusMessage)
|
.SetProperty("statusMessage", &URLRequest::StatusMessage)
|
||||||
|
@ -114,92 +119,83 @@ void URLRequest::BuildPrototype(v8::Isolate* isolate,
|
||||||
}
|
}
|
||||||
|
|
||||||
void URLRequest::Write() {
|
void URLRequest::Write() {
|
||||||
atom_url_request_->Write();
|
atom_request_->Write();
|
||||||
}
|
}
|
||||||
|
|
||||||
void URLRequest::End() {
|
void URLRequest::End() {
|
||||||
pin();
|
pin();
|
||||||
atom_url_request_->End();
|
atom_request_->End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void URLRequest::Abort() {
|
void URLRequest::Abort() {
|
||||||
atom_url_request_->Abort();
|
atom_request_->Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void URLRequest::SetHeader() {
|
void URLRequest::SetHeader(const std::string& name, const std::string& value) {
|
||||||
atom_url_request_->SetHeader();
|
atom_request_->SetHeader(name, value);
|
||||||
}
|
}
|
||||||
void URLRequest::GetHeader() {
|
std::string URLRequest::GetHeader(const std::string& name) {
|
||||||
atom_url_request_->GetHeader();
|
return atom_request_->GetHeader(name);
|
||||||
}
|
}
|
||||||
void URLRequest::RemoveHeader() {
|
void URLRequest::RemoveHeader(const std::string& name) {
|
||||||
atom_url_request_->RemoveHeader();
|
atom_request_->RemoveHeader(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void URLRequest::OnAuthenticationRequired(
|
||||||
|
scoped_refptr<const net::AuthChallengeInfo> auth_info) {
|
||||||
|
EmitRequestEvent(
|
||||||
|
"login",
|
||||||
|
auth_info.get(),
|
||||||
|
base::Bind(&AtomURLRequest::PassLoginInformation, atom_request_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void URLRequest::OnResponseStarted() {
|
void URLRequest::OnResponseStarted() {
|
||||||
//v8::Local<v8::Function> _emitResponse;
|
|
||||||
|
|
||||||
//auto wrapper = GetWrapper();
|
|
||||||
//if (mate::Dictionary(isolate(), wrapper).Get("_emitResponse", &_emitResponse))
|
|
||||||
// _emitResponse->Call(wrapper, 0, nullptr);
|
|
||||||
EmitRequestEvent("response");
|
EmitRequestEvent("response");
|
||||||
}
|
}
|
||||||
|
|
||||||
void URLRequest::OnResponseData(scoped_refptr<net::IOBufferWithSize> buffer) {
|
void URLRequest::OnResponseData(
|
||||||
|
scoped_refptr<const net::IOBufferWithSize> buffer) {
|
||||||
if (!buffer || !buffer->data() || !buffer->size()) {
|
if (!buffer || !buffer->data() || !buffer->size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitResponseEvent("data", buffer);
|
EmitResponseEvent("data", buffer);
|
||||||
//v8::Local<v8::Function> _emitData;
|
|
||||||
//auto data = mate::ConvertToV8(isolate(), buffer);
|
|
||||||
|
|
||||||
//auto wrapper = GetWrapper();
|
|
||||||
//if (mate::Dictionary(isolate(), wrapper).Get("_emitData", &_emitData))
|
|
||||||
// _emitData->Call(wrapper, 1, &data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void URLRequest::OnResponseCompleted() {
|
void URLRequest::OnResponseCompleted() {
|
||||||
|
|
||||||
//v8::Local<v8::Function> _emitEnd;
|
|
||||||
|
|
||||||
//auto wrapper = GetWrapper();
|
|
||||||
//if (mate::Dictionary(isolate(), wrapper).Get("_emitEnd", &_emitEnd))
|
|
||||||
// _emitEnd->Call(wrapper, 0, nullptr);
|
|
||||||
|
|
||||||
EmitResponseEvent("end");
|
EmitResponseEvent("end");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int URLRequest::StatusCode() {
|
int URLRequest::StatusCode() const {
|
||||||
if (auto response_headers = atom_url_request_->GetResponseHeaders()) {
|
if (auto response_headers = atom_request_->GetResponseHeaders()) {
|
||||||
return response_headers->response_code();
|
return response_headers->response_code();
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string URLRequest::StatusMessage() {
|
std::string URLRequest::StatusMessage() const {
|
||||||
std::string result;
|
std::string result;
|
||||||
if (auto response_headers = atom_url_request_->GetResponseHeaders()) {
|
if (auto response_headers = atom_request_->GetResponseHeaders()) {
|
||||||
result = response_headers->GetStatusText();
|
result = response_headers->GetStatusText();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_refptr<net::HttpResponseHeaders> URLRequest::RawResponseHeaders() {
|
scoped_refptr<const net::HttpResponseHeaders> URLRequest::RawResponseHeaders() const {
|
||||||
return atom_url_request_->GetResponseHeaders();
|
return atom_request_->GetResponseHeaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t URLRequest::ResponseHttpVersionMajor() {
|
uint32_t URLRequest::ResponseHttpVersionMajor() const {
|
||||||
if (auto response_headers = atom_url_request_->GetResponseHeaders()) {
|
if (auto response_headers = atom_request_->GetResponseHeaders()) {
|
||||||
return response_headers->GetHttpVersion().major_value();
|
return response_headers->GetHttpVersion().major_value();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t URLRequest::ResponseHttpVersionMinor() {
|
uint32_t URLRequest::ResponseHttpVersionMinor() const {
|
||||||
if (auto response_headers = atom_url_request_->GetResponseHeaders()) {
|
if (auto response_headers = atom_request_->GetResponseHeaders()) {
|
||||||
return response_headers->GetHttpVersion().minor_value();
|
return response_headers->GetHttpVersion().minor_value();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,25 +35,27 @@ private:
|
||||||
void Write();
|
void Write();
|
||||||
void End();
|
void End();
|
||||||
void Abort();
|
void Abort();
|
||||||
void SetHeader();
|
void SetHeader(const std::string& name, const std::string& value);
|
||||||
void GetHeader();
|
std::string GetHeader(const std::string& name);
|
||||||
void RemoveHeader();
|
void RemoveHeader(const std::string& name);
|
||||||
|
|
||||||
friend class AtomURLRequest;
|
friend class AtomURLRequest;
|
||||||
|
void OnAuthenticationRequired(
|
||||||
|
scoped_refptr<const net::AuthChallengeInfo> auth_info);
|
||||||
void OnResponseStarted();
|
void OnResponseStarted();
|
||||||
void OnResponseData(scoped_refptr<net::IOBufferWithSize> data);
|
void OnResponseData(scoped_refptr<const net::IOBufferWithSize> data);
|
||||||
void OnResponseCompleted();
|
void OnResponseCompleted();
|
||||||
|
|
||||||
int StatusCode();
|
int StatusCode() const;
|
||||||
std::string StatusMessage();
|
std::string StatusMessage() const;
|
||||||
scoped_refptr<net::HttpResponseHeaders> RawResponseHeaders();
|
scoped_refptr<const net::HttpResponseHeaders> RawResponseHeaders() const;
|
||||||
uint32_t ResponseHttpVersionMajor();
|
uint32_t ResponseHttpVersionMajor() const;
|
||||||
uint32_t ResponseHttpVersionMinor();
|
uint32_t ResponseHttpVersionMinor() const;
|
||||||
|
|
||||||
|
|
||||||
template <typename ... ArgTypes>
|
template <typename ... ArgTypes>
|
||||||
std::array<v8::Local<v8::Value>, sizeof...(ArgTypes)>
|
std::array<v8::Local<v8::Value>, sizeof...(ArgTypes)>
|
||||||
BuildArgsArray(ArgTypes... args);
|
BuildArgsArray(ArgTypes... args) const;
|
||||||
|
|
||||||
template <typename ... ArgTypes>
|
template <typename ... ArgTypes>
|
||||||
void EmitRequestEvent(ArgTypes... args);
|
void EmitRequestEvent(ArgTypes... args);
|
||||||
|
@ -61,12 +63,10 @@ private:
|
||||||
template <typename ... ArgTypes>
|
template <typename ... ArgTypes>
|
||||||
void EmitResponseEvent(ArgTypes... args);
|
void EmitResponseEvent(ArgTypes... args);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void pin();
|
void pin();
|
||||||
void unpin();
|
void unpin();
|
||||||
|
|
||||||
scoped_refptr<AtomURLRequest> atom_url_request_;
|
scoped_refptr<const AtomURLRequest> atom_request_;
|
||||||
v8::Global<v8::Object> wrapper_;
|
v8::Global<v8::Object> wrapper_;
|
||||||
base::WeakPtrFactory<URLRequest> weak_ptr_factory_;
|
base::WeakPtrFactory<URLRequest> weak_ptr_factory_;
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ private:
|
||||||
|
|
||||||
template <typename ... ArgTypes>
|
template <typename ... ArgTypes>
|
||||||
std::array<v8::Local<v8::Value>, sizeof...(ArgTypes)>
|
std::array<v8::Local<v8::Value>, sizeof...(ArgTypes)>
|
||||||
URLRequest::BuildArgsArray(ArgTypes... args) {
|
URLRequest::BuildArgsArray(ArgTypes... args) const {
|
||||||
std::array<v8::Local<v8::Value>, sizeof...(ArgTypes)> result
|
std::array<v8::Local<v8::Value>, sizeof...(ArgTypes)> result
|
||||||
= { mate::ConvertToV8(isolate(), args)... };
|
= { mate::ConvertToV8(isolate(), args)... };
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "net/base/io_buffer.h"
|
#include "net/base/io_buffer.h"
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const int kBufferSize = 4096;
|
const int kBufferSize = 4096;
|
||||||
|
@ -20,17 +21,18 @@ namespace atom {
|
||||||
|
|
||||||
AtomURLRequest::AtomURLRequest(base::WeakPtr<api::URLRequest> delegate)
|
AtomURLRequest::AtomURLRequest(base::WeakPtr<api::URLRequest> delegate)
|
||||||
: delegate_(delegate)
|
: delegate_(delegate)
|
||||||
, buffer_( new net::IOBuffer(kBufferSize)) {
|
, buffer_(new net::IOBuffer(kBufferSize)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomURLRequest::~AtomURLRequest() {
|
AtomURLRequest::~AtomURLRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_refptr<AtomURLRequest> AtomURLRequest::create(
|
scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
|
||||||
AtomBrowserContext* browser_context,
|
AtomBrowserContext* browser_context,
|
||||||
|
const std::string& method,
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
base::WeakPtr<api::URLRequest> delegate) {
|
base::WeakPtr<api::URLRequest> delegate) {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
DCHECK(browser_context);
|
DCHECK(browser_context);
|
||||||
DCHECK(!url.empty());
|
DCHECK(!url.empty());
|
||||||
|
|
||||||
|
@ -44,69 +46,117 @@ scoped_refptr<AtomURLRequest> AtomURLRequest::create(
|
||||||
|
|
||||||
scoped_refptr<AtomURLRequest> atom_url_request = new AtomURLRequest(delegate);
|
scoped_refptr<AtomURLRequest> atom_url_request = new AtomURLRequest(delegate);
|
||||||
|
|
||||||
atom_url_request->url_request_ = context->CreateRequest(GURL(url),
|
atom_url_request->request_ = context->CreateRequest(GURL(url),
|
||||||
net::RequestPriority::DEFAULT_PRIORITY,
|
net::RequestPriority::DEFAULT_PRIORITY,
|
||||||
atom_url_request.get());
|
atom_url_request.get());
|
||||||
|
|
||||||
|
atom_url_request->request_->set_method(method);
|
||||||
return atom_url_request;
|
return atom_url_request;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::Write() {
|
void AtomURLRequest::Write() const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::End() {
|
void AtomURLRequest::End() const {
|
||||||
// Called on content::BrowserThread::UI
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&AtomURLRequest::StartOnIOThread, this));
|
base::Bind(&AtomURLRequest::DoStart, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::Abort() {
|
void AtomURLRequest::Abort() const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::SetHeader() {
|
void AtomURLRequest::SetHeader(const std::string& name,
|
||||||
|
const std::string& value) const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
request_->SetExtraRequestHeaderByName(name, value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::GetHeader() {
|
std::string AtomURLRequest::GetHeader(const std::string& name) const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
std::string result;
|
||||||
|
const auto& extra_headers = request_->extra_request_headers();
|
||||||
|
if (!extra_headers.GetHeader(name, &result)) {
|
||||||
|
net::HttpRequestHeaders* request_headers = nullptr;
|
||||||
|
if (request_->GetFullRequestHeaders(request_headers) && request_headers) {
|
||||||
|
request_headers->GetHeader(name, &result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::RemoveHeader() {
|
void AtomURLRequest::RemoveHeader(const std::string& name) const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
request_->RemoveRequestHeaderByName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
scoped_refptr<net::HttpResponseHeaders> AtomURLRequest::GetResponseHeaders() {
|
scoped_refptr<const net::HttpResponseHeaders>
|
||||||
return url_request_->response_headers();
|
AtomURLRequest::GetResponseHeaders() const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
return request_->response_headers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AtomURLRequest::PassLoginInformation(const base::string16& username,
|
||||||
void AtomURLRequest::StartOnIOThread() {
|
const base::string16& password) const {
|
||||||
// Called on content::BrowserThread::IO
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
if (username.empty() || password.empty()) {
|
||||||
url_request_->Start();
|
content::BrowserThread::PostTask(
|
||||||
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
|
base::Bind(&AtomURLRequest::DoCancelAuth, this));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
content::BrowserThread::PostTask(
|
||||||
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
|
base::Bind(&AtomURLRequest::DoSetAuth, this, username, password));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AtomURLRequest::set_method(const std::string& method) {
|
void AtomURLRequest::DoStart() const {
|
||||||
url_request_->set_method(method);
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
|
||||||
|
request_->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomURLRequest::DoSetAuth(const base::string16& username,
|
||||||
|
const base::string16& password) const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
request_->SetAuth(net::AuthCredentials(username, password));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomURLRequest::DoCancelAuth() const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
request_->CancelAuth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomURLRequest::OnAuthRequired(net::URLRequest* request,
|
||||||
|
net::AuthChallengeInfo* auth_info) {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
|
||||||
|
content::BrowserThread::PostTask(
|
||||||
|
content::BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&AtomURLRequest::InformDelegateAuthenticationRequired,
|
||||||
|
this,
|
||||||
|
scoped_refptr<net::AuthChallengeInfo>(auth_info)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::OnResponseStarted(net::URLRequest* request) {
|
void AtomURLRequest::OnResponseStarted(net::URLRequest* request) {
|
||||||
// Called on content::BrowserThread::IO
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
DCHECK_EQ(request, request_.get());
|
||||||
|
|
||||||
DCHECK_EQ(request, url_request_.get());
|
if (request_->status().is_success()) {
|
||||||
|
|
||||||
if (url_request_->status().is_success()) {
|
|
||||||
// Cache net::HttpResponseHeaders instance, a read-only objects
|
// Cache net::HttpResponseHeaders instance, a read-only objects
|
||||||
// so that headers and other http metainformation can be simultaneously
|
// so that headers and other http metainformation can be simultaneously
|
||||||
// read from UI thread while request data is simulataneously streaming
|
// read from UI thread while request data is simulataneously streaming
|
||||||
// on IO thread.
|
// on IO thread.
|
||||||
response_headers_ = url_request_->response_headers();
|
response_headers_ = request_->response_headers();
|
||||||
}
|
}
|
||||||
|
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
|
@ -117,29 +167,28 @@ void AtomURLRequest::OnResponseStarted(net::URLRequest* request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::ReadResponse() {
|
void AtomURLRequest::ReadResponse() {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
// Called on content::BrowserThread::IO
|
|
||||||
|
|
||||||
// Some servers may treat HEAD requests as GET requests. To free up the
|
// Some servers may treat HEAD requests as GET requests. To free up the
|
||||||
// network connection as soon as possible, signal that the request has
|
// network connection as soon as possible, signal that the request has
|
||||||
// completed immediately, without trying to read any data back (all we care
|
// completed immediately, without trying to read any data back (all we care
|
||||||
// about is the response code and headers, which we already have).
|
// about is the response code and headers, which we already have).
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
if (url_request_->status().is_success() /* TODO && (request_type_ != URLFetcher::HEAD)*/) {
|
if (request_->status().is_success() /* TODO && (request_type_ != URLFetcher::HEAD)*/) {
|
||||||
if (!url_request_->Read(buffer_.get(), kBufferSize, &bytes_read))
|
if (!request_->Read(buffer_.get(), kBufferSize, &bytes_read))
|
||||||
bytes_read = -1;
|
bytes_read = -1;
|
||||||
}
|
}
|
||||||
OnReadCompleted(url_request_.get(), bytes_read);
|
OnReadCompleted(request_.get(), bytes_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AtomURLRequest::OnReadCompleted(net::URLRequest* request, int bytes_read) {
|
void AtomURLRequest::OnReadCompleted(net::URLRequest* request, int bytes_read) {
|
||||||
// Called on content::BrowserThread::IO
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
|
||||||
DCHECK_EQ(request, url_request_.get());
|
DCHECK_EQ(request, request_.get());
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!url_request_->status().is_success() || bytes_read <= 0)
|
if (!request_->status().is_success() || bytes_read <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,9 +197,9 @@ void AtomURLRequest::OnReadCompleted(net::URLRequest* request, int bytes_read) {
|
||||||
// Failed to transfer data to UI thread.
|
// Failed to transfer data to UI thread.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} while (url_request_->Read(buffer_.get(), kBufferSize, &bytes_read));
|
} while (request_->Read(buffer_.get(), kBufferSize, &bytes_read));
|
||||||
|
|
||||||
const auto status = url_request_->status();
|
const auto status = request_->status();
|
||||||
|
|
||||||
if (!status.is_io_pending() /* TODO || request_type_ == URLFetcher::HEAD*/ ) {
|
if (!status.is_io_pending() /* TODO || request_type_ == URLFetcher::HEAD*/ ) {
|
||||||
|
|
||||||
|
@ -161,9 +210,8 @@ void AtomURLRequest::OnReadCompleted(net::URLRequest* request, int bytes_read) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool AtomURLRequest::CopyAndPostBuffer(int bytes_read) {
|
bool AtomURLRequest::CopyAndPostBuffer(int bytes_read) {
|
||||||
// Called on content::BrowserThread::IO.
|
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||||
|
|
||||||
// data is only a wrapper for the async buffer_.
|
// data is only a wrapper for the async buffer_.
|
||||||
// Make a deep copy of payload and transfer ownership to the UI thread.
|
// Make a deep copy of payload and transfer ownership to the UI thread.
|
||||||
|
@ -176,16 +224,25 @@ bool AtomURLRequest::CopyAndPostBuffer(int bytes_read) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AtomURLRequest::InformDelegateResponseStarted() {
|
void AtomURLRequest::InformDelegateAuthenticationRequired(
|
||||||
// Called on content::BrowserThread::UI.
|
scoped_refptr<net::AuthChallengeInfo> auth_info) const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
if (delegate_) {
|
||||||
|
delegate_->OnAuthenticationRequired(auth_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomURLRequest::InformDelegateResponseStarted() const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
|
||||||
if (delegate_) {
|
if (delegate_) {
|
||||||
delegate_->OnResponseStarted();
|
delegate_->OnResponseStarted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::InformDelegateResponseData(scoped_refptr<net::IOBufferWithSize> data) {
|
void AtomURLRequest::InformDelegateResponseData(
|
||||||
// Called on content::BrowserThread::IO.
|
scoped_refptr<net::IOBufferWithSize> data) const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
|
||||||
// Transfer ownership of the data buffer, data will be released
|
// Transfer ownership of the data buffer, data will be released
|
||||||
// by the delegate's OnResponseData.
|
// by the delegate's OnResponseData.
|
||||||
|
@ -194,7 +251,9 @@ void AtomURLRequest::InformDelegateResponseData(scoped_refptr<net::IOBufferWithS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomURLRequest::InformDelegateResponseCompleted() {
|
void AtomURLRequest::InformDelegateResponseCompleted() const {
|
||||||
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||||
|
|
||||||
if (delegate_) {
|
if (delegate_) {
|
||||||
delegate_->OnResponseCompleted();
|
delegate_->OnResponseCompleted();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,43 +27,52 @@ namespace api {
|
||||||
class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
|
class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
|
||||||
public net::URLRequest::Delegate {
|
public net::URLRequest::Delegate {
|
||||||
public:
|
public:
|
||||||
static scoped_refptr<AtomURLRequest> create(
|
static scoped_refptr<AtomURLRequest> Create(
|
||||||
AtomBrowserContext* browser_context,
|
AtomBrowserContext* browser_context,
|
||||||
|
const std::string& method,
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
base::WeakPtr<api::URLRequest> delegate);
|
base::WeakPtr<api::URLRequest> delegate);
|
||||||
|
|
||||||
void set_method(const std::string& method);
|
void Write() const;
|
||||||
|
void End() const;
|
||||||
void Write();
|
void Abort() const;
|
||||||
void End();
|
void SetHeader(const std::string& name, const std::string& value) const;
|
||||||
void Abort();
|
std::string GetHeader(const std::string& name) const;
|
||||||
void SetHeader();
|
void RemoveHeader(const std::string& name) const;
|
||||||
void GetHeader();
|
void PassLoginInformation(const base::string16& username,
|
||||||
void RemoveHeader();
|
const base::string16& password) const;
|
||||||
|
scoped_refptr<const net::HttpResponseHeaders> GetResponseHeaders() const;
|
||||||
scoped_refptr<net::HttpResponseHeaders> GetResponseHeaders();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Overrides of net::URLRequest::Delegate
|
// Overrides of net::URLRequest::Delegate
|
||||||
|
virtual void OnAuthRequired(net::URLRequest* request,
|
||||||
|
net::AuthChallengeInfo* auth_info) override;
|
||||||
virtual void OnResponseStarted(net::URLRequest* request) override;
|
virtual void OnResponseStarted(net::URLRequest* request) override;
|
||||||
virtual void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
|
virtual void OnReadCompleted(net::URLRequest* request,
|
||||||
|
int bytes_read) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class base::RefCountedThreadSafe<AtomURLRequest>;
|
friend class base::RefCountedThreadSafe<AtomURLRequest>;
|
||||||
void StartOnIOThread();
|
void DoStart() const;
|
||||||
|
void DoSetAuth(const base::string16& username,
|
||||||
|
const base::string16& password) const;
|
||||||
|
void DoCancelAuth() const;
|
||||||
|
|
||||||
void ReadResponse();
|
void ReadResponse();
|
||||||
bool CopyAndPostBuffer(int bytes_read);
|
bool CopyAndPostBuffer(int bytes_read);
|
||||||
|
|
||||||
void InformDelegateResponseStarted();
|
void InformDelegateAuthenticationRequired(
|
||||||
void InformDelegateResponseData(scoped_refptr<net::IOBufferWithSize> data);
|
scoped_refptr<net::AuthChallengeInfo> auth_info) const;
|
||||||
void InformDelegateResponseCompleted();
|
void InformDelegateResponseStarted() const;
|
||||||
|
void InformDelegateResponseData(
|
||||||
|
scoped_refptr<net::IOBufferWithSize> data) const;
|
||||||
|
void InformDelegateResponseCompleted() const;
|
||||||
|
|
||||||
AtomURLRequest(base::WeakPtr<api::URLRequest> delegate);
|
AtomURLRequest(base::WeakPtr<api::URLRequest> delegate);
|
||||||
virtual ~AtomURLRequest();
|
virtual ~AtomURLRequest();
|
||||||
|
|
||||||
base::WeakPtr<api::URLRequest> delegate_;
|
base::WeakPtr<api::URLRequest> delegate_;
|
||||||
std::unique_ptr<net::URLRequest> url_request_;
|
std::unique_ptr<net::URLRequest> request_;
|
||||||
scoped_refptr<net::IOBuffer> buffer_;
|
scoped_refptr<net::IOBuffer> buffer_;
|
||||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,48 @@ Net.prototype.request = function(options, callback) {
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
|
||||||
|
URLRequest.prototype._init = function() {
|
||||||
|
this._finished = false;
|
||||||
|
this._hasBody = true;
|
||||||
|
this._chunkedEncoding = false;
|
||||||
|
this._headersSent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
URLRequest.prototype.setHeader = function(name, value) {
|
||||||
|
if (typeof name !== 'string')
|
||||||
|
throw new TypeError('`name` should be a string in setHeader(name, value).');
|
||||||
|
if (value === undefined)
|
||||||
|
throw new Error('`value` required in setHeader("' + name + '", value).');
|
||||||
|
if (this._headersSent)
|
||||||
|
throw new Error('Can\'t set headers after they are sent.');
|
||||||
|
|
||||||
|
this._setHeader(name, value)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
URLRequest.prototype.getHeader = function(name) {
|
||||||
|
if (arguments.length < 1) {
|
||||||
|
throw new Error('`name` is required for getHeader(name).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._getHeader(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
URLRequest.prototype.removeHeader = function(name) {
|
||||||
|
if (arguments.length < 1) {
|
||||||
|
throw new Error('`name` is required for removeHeader(name).');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._headersSent) {
|
||||||
|
throw new Error('Can\'t remove headers after they are sent.');
|
||||||
|
}
|
||||||
|
|
||||||
|
this._removeHeader(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
URLRequest.prototype._emitRequestEvent = function(name) {
|
URLRequest.prototype._emitRequestEvent = function(name) {
|
||||||
if (name === 'response') {
|
if (name === 'response') {
|
||||||
this.response = new URLResponse(this);
|
this.response = new URLResponse(this);
|
||||||
|
@ -69,5 +111,82 @@ URLRequest.prototype._emitResponseEvent = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
URLRequest.prototype.write = function(chunk, encoding, callback) {
|
||||||
|
|
||||||
|
if (this.finished) {
|
||||||
|
var err = new Error('write after end');
|
||||||
|
process.nextTick(writeAfterEndNT, this, err, callback);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO
|
||||||
|
if (!this._header) {
|
||||||
|
this._implicitHeader();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!this._hasBody) {
|
||||||
|
//debug('This type of response MUST NOT have a body. ' +
|
||||||
|
// 'Ignoring write() calls.');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (typeof chunk !== 'string' && !(chunk instanceof Buffer)) {
|
||||||
|
throw new TypeError('First argument must be a string or Buffer');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If we get an empty string or buffer, then just do nothing, and
|
||||||
|
// signal the user to keep writing.
|
||||||
|
if (chunk.length === 0) return true;
|
||||||
|
|
||||||
|
var len, ret;
|
||||||
|
if (this.chunkedEncoding) {
|
||||||
|
if (typeof chunk === 'string' &&
|
||||||
|
encoding !== 'hex' &&
|
||||||
|
encoding !== 'base64' &&
|
||||||
|
encoding !== 'binary') {
|
||||||
|
len = Buffer.byteLength(chunk, encoding);
|
||||||
|
chunk = len.toString(16) + CRLF + chunk + CRLF;
|
||||||
|
ret = this._send(chunk, encoding, callback);
|
||||||
|
} else {
|
||||||
|
// buffer, or a non-toString-friendly encoding
|
||||||
|
if (typeof chunk === 'string')
|
||||||
|
len = Buffer.byteLength(chunk, encoding);
|
||||||
|
else
|
||||||
|
len = chunk.length;
|
||||||
|
|
||||||
|
if (this.connection && !this.connection.corked) {
|
||||||
|
this.connection.cork();
|
||||||
|
process.nextTick(connectionCorkNT, this.connection);
|
||||||
|
}
|
||||||
|
this._send(len.toString(16), 'binary', null);
|
||||||
|
this._send(crlf_buf, null, null);
|
||||||
|
this._send(chunk, encoding, null);
|
||||||
|
ret = this._send(crlf_buf, null, callback);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = this._send(chunk, encoding, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//debug('write ret = ' + ret);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
URLRequest.prototype.end = function() {
|
||||||
|
this._end();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function writeAfterEndNT(self, err, callback) {
|
||||||
|
self.emit('error', err);
|
||||||
|
if (callback) callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = net
|
module.exports = net
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue