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 "atom/browser/net/atom_url_request.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 {
|
||||
|
||||
|
@ -19,9 +22,9 @@ const char* const kEnd = "end";
|
|||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<scoped_refptr<net::HttpResponseHeaders>> {
|
||||
struct Converter<scoped_refptr<const net::HttpResponseHeaders>> {
|
||||
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);
|
||||
if (val) {
|
||||
|
@ -37,10 +40,10 @@ struct Converter<scoped_refptr<net::HttpResponseHeaders>> {
|
|||
};
|
||||
|
||||
template<>
|
||||
struct Converter<scoped_refptr<net::IOBufferWithSize>> {
|
||||
struct Converter<scoped_refptr<const net::IOBufferWithSize>> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
scoped_refptr<net::IOBufferWithSize> buffer) {
|
||||
scoped_refptr<const net::IOBufferWithSize> buffer) {
|
||||
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 weak_ptr = api_url_request->weak_ptr_factory_.GetWeakPtr();
|
||||
auto atom_url_request = AtomURLRequest::create(browser_context, url, weak_ptr);
|
||||
|
||||
atom_url_request->set_method(method);
|
||||
auto atom_url_request = AtomURLRequest::Create(
|
||||
browser_context,
|
||||
method,
|
||||
url,
|
||||
weak_ptr);
|
||||
|
||||
api_url_request->atom_url_request_ = atom_url_request;
|
||||
api_url_request->atom_request_ = atom_url_request;
|
||||
|
||||
|
||||
return api_url_request;
|
||||
|
@ -97,12 +102,12 @@ void URLRequest::BuildPrototype(v8::Isolate* isolate,
|
|||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
// Request API
|
||||
.MakeDestroyable()
|
||||
.SetMethod("write", &URLRequest::Write)
|
||||
.SetMethod("end", &URLRequest::End)
|
||||
.SetMethod("_write", &URLRequest::Write)
|
||||
.SetMethod("_end", &URLRequest::End)
|
||||
.SetMethod("abort", &URLRequest::Abort)
|
||||
.SetMethod("setHeader", &URLRequest::SetHeader)
|
||||
.SetMethod("getHeader", &URLRequest::GetHeader)
|
||||
.SetMethod("removaHeader", &URLRequest::RemoveHeader)
|
||||
.SetMethod("_setHeader", &URLRequest::SetHeader)
|
||||
.SetMethod("_getHeader", &URLRequest::GetHeader)
|
||||
.SetMethod("_removaHeader", &URLRequest::RemoveHeader)
|
||||
// Response APi
|
||||
.SetProperty("statusCode", &URLRequest::StatusCode)
|
||||
.SetProperty("statusMessage", &URLRequest::StatusMessage)
|
||||
|
@ -114,92 +119,83 @@ void URLRequest::BuildPrototype(v8::Isolate* isolate,
|
|||
}
|
||||
|
||||
void URLRequest::Write() {
|
||||
atom_url_request_->Write();
|
||||
atom_request_->Write();
|
||||
}
|
||||
|
||||
void URLRequest::End() {
|
||||
pin();
|
||||
atom_url_request_->End();
|
||||
atom_request_->End();
|
||||
}
|
||||
|
||||
void URLRequest::Abort() {
|
||||
atom_url_request_->Abort();
|
||||
atom_request_->Abort();
|
||||
}
|
||||
|
||||
void URLRequest::SetHeader() {
|
||||
atom_url_request_->SetHeader();
|
||||
void URLRequest::SetHeader(const std::string& name, const std::string& value) {
|
||||
atom_request_->SetHeader(name, value);
|
||||
}
|
||||
void URLRequest::GetHeader() {
|
||||
atom_url_request_->GetHeader();
|
||||
std::string URLRequest::GetHeader(const std::string& name) {
|
||||
return atom_request_->GetHeader(name);
|
||||
}
|
||||
void URLRequest::RemoveHeader() {
|
||||
atom_url_request_->RemoveHeader();
|
||||
void URLRequest::RemoveHeader(const std::string& name) {
|
||||
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() {
|
||||
//v8::Local<v8::Function> _emitResponse;
|
||||
|
||||
//auto wrapper = GetWrapper();
|
||||
//if (mate::Dictionary(isolate(), wrapper).Get("_emitResponse", &_emitResponse))
|
||||
// _emitResponse->Call(wrapper, 0, nullptr);
|
||||
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()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
//v8::Local<v8::Function> _emitEnd;
|
||||
|
||||
//auto wrapper = GetWrapper();
|
||||
//if (mate::Dictionary(isolate(), wrapper).Get("_emitEnd", &_emitEnd))
|
||||
// _emitEnd->Call(wrapper, 0, nullptr);
|
||||
|
||||
EmitResponseEvent("end");
|
||||
}
|
||||
|
||||
|
||||
int URLRequest::StatusCode() {
|
||||
if (auto response_headers = atom_url_request_->GetResponseHeaders()) {
|
||||
int URLRequest::StatusCode() const {
|
||||
if (auto response_headers = atom_request_->GetResponseHeaders()) {
|
||||
return response_headers->response_code();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string URLRequest::StatusMessage() {
|
||||
std::string URLRequest::StatusMessage() const {
|
||||
std::string result;
|
||||
if (auto response_headers = atom_url_request_->GetResponseHeaders()) {
|
||||
if (auto response_headers = atom_request_->GetResponseHeaders()) {
|
||||
result = response_headers->GetStatusText();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> URLRequest::RawResponseHeaders() {
|
||||
return atom_url_request_->GetResponseHeaders();
|
||||
scoped_refptr<const net::HttpResponseHeaders> URLRequest::RawResponseHeaders() const {
|
||||
return atom_request_->GetResponseHeaders();
|
||||
}
|
||||
|
||||
uint32_t URLRequest::ResponseHttpVersionMajor() {
|
||||
if (auto response_headers = atom_url_request_->GetResponseHeaders()) {
|
||||
uint32_t URLRequest::ResponseHttpVersionMajor() const {
|
||||
if (auto response_headers = atom_request_->GetResponseHeaders()) {
|
||||
return response_headers->GetHttpVersion().major_value();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t URLRequest::ResponseHttpVersionMinor() {
|
||||
if (auto response_headers = atom_url_request_->GetResponseHeaders()) {
|
||||
uint32_t URLRequest::ResponseHttpVersionMinor() const {
|
||||
if (auto response_headers = atom_request_->GetResponseHeaders()) {
|
||||
return response_headers->GetHttpVersion().minor_value();
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -35,25 +35,27 @@ private:
|
|||
void Write();
|
||||
void End();
|
||||
void Abort();
|
||||
void SetHeader();
|
||||
void GetHeader();
|
||||
void RemoveHeader();
|
||||
void SetHeader(const std::string& name, const std::string& value);
|
||||
std::string GetHeader(const std::string& name);
|
||||
void RemoveHeader(const std::string& name);
|
||||
|
||||
friend class AtomURLRequest;
|
||||
void OnAuthenticationRequired(
|
||||
scoped_refptr<const net::AuthChallengeInfo> auth_info);
|
||||
void OnResponseStarted();
|
||||
void OnResponseData(scoped_refptr<net::IOBufferWithSize> data);
|
||||
void OnResponseData(scoped_refptr<const net::IOBufferWithSize> data);
|
||||
void OnResponseCompleted();
|
||||
|
||||
int StatusCode();
|
||||
std::string StatusMessage();
|
||||
scoped_refptr<net::HttpResponseHeaders> RawResponseHeaders();
|
||||
uint32_t ResponseHttpVersionMajor();
|
||||
uint32_t ResponseHttpVersionMinor();
|
||||
int StatusCode() const;
|
||||
std::string StatusMessage() const;
|
||||
scoped_refptr<const net::HttpResponseHeaders> RawResponseHeaders() const;
|
||||
uint32_t ResponseHttpVersionMajor() const;
|
||||
uint32_t ResponseHttpVersionMinor() const;
|
||||
|
||||
|
||||
template <typename ... ArgTypes>
|
||||
std::array<v8::Local<v8::Value>, sizeof...(ArgTypes)>
|
||||
BuildArgsArray(ArgTypes... args);
|
||||
BuildArgsArray(ArgTypes... args) const;
|
||||
|
||||
template <typename ... ArgTypes>
|
||||
void EmitRequestEvent(ArgTypes... args);
|
||||
|
@ -61,12 +63,10 @@ private:
|
|||
template <typename ... ArgTypes>
|
||||
void EmitResponseEvent(ArgTypes... args);
|
||||
|
||||
|
||||
|
||||
void pin();
|
||||
void unpin();
|
||||
|
||||
scoped_refptr<AtomURLRequest> atom_url_request_;
|
||||
scoped_refptr<const AtomURLRequest> atom_request_;
|
||||
v8::Global<v8::Object> wrapper_;
|
||||
base::WeakPtrFactory<URLRequest> weak_ptr_factory_;
|
||||
|
||||
|
@ -76,7 +76,7 @@ private:
|
|||
|
||||
template <typename ... 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
|
||||
= { mate::ConvertToV8(isolate(), args)... };
|
||||
return result;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
const int kBufferSize = 4096;
|
||||
|
@ -18,19 +19,20 @@ const int kBufferSize = 4096;
|
|||
|
||||
namespace atom {
|
||||
|
||||
AtomURLRequest::AtomURLRequest(base::WeakPtr<api::URLRequest> delegate)
|
||||
AtomURLRequest::AtomURLRequest(base::WeakPtr<api::URLRequest> delegate)
|
||||
: delegate_(delegate)
|
||||
, buffer_( new net::IOBuffer(kBufferSize)) {
|
||||
, buffer_(new net::IOBuffer(kBufferSize)) {
|
||||
}
|
||||
|
||||
AtomURLRequest::~AtomURLRequest() {
|
||||
}
|
||||
|
||||
scoped_refptr<AtomURLRequest> AtomURLRequest::create(
|
||||
scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
|
||||
AtomBrowserContext* browser_context,
|
||||
const std::string& method,
|
||||
const std::string& url,
|
||||
base::WeakPtr<api::URLRequest> delegate) {
|
||||
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(browser_context);
|
||||
DCHECK(!url.empty());
|
||||
|
||||
|
@ -44,69 +46,117 @@ scoped_refptr<AtomURLRequest> AtomURLRequest::create(
|
|||
|
||||
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,
|
||||
atom_url_request.get());
|
||||
|
||||
atom_url_request->request_->set_method(method);
|
||||
return atom_url_request;
|
||||
|
||||
}
|
||||
|
||||
void AtomURLRequest::Write() {
|
||||
void AtomURLRequest::Write() const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
}
|
||||
|
||||
void AtomURLRequest::End() {
|
||||
// Called on content::BrowserThread::UI
|
||||
void AtomURLRequest::End() const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
content::BrowserThread::PostTask(
|
||||
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() {
|
||||
return url_request_->response_headers();
|
||||
scoped_refptr<const net::HttpResponseHeaders>
|
||||
AtomURLRequest::GetResponseHeaders() const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
return request_->response_headers();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AtomURLRequest::StartOnIOThread() {
|
||||
// Called on content::BrowserThread::IO
|
||||
|
||||
url_request_->Start();
|
||||
void AtomURLRequest::PassLoginInformation(const base::string16& username,
|
||||
const base::string16& password) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
if (username.empty() || password.empty()) {
|
||||
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) {
|
||||
url_request_->set_method(method);
|
||||
void AtomURLRequest::DoStart() const {
|
||||
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) {
|
||||
// Called on content::BrowserThread::IO
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
DCHECK_EQ(request, request_.get());
|
||||
|
||||
DCHECK_EQ(request, url_request_.get());
|
||||
|
||||
if (url_request_->status().is_success()) {
|
||||
if (request_->status().is_success()) {
|
||||
// Cache net::HttpResponseHeaders instance, a read-only objects
|
||||
// so that headers and other http metainformation can be simultaneously
|
||||
// read from UI thread while request data is simulataneously streaming
|
||||
// on IO thread.
|
||||
response_headers_ = url_request_->response_headers();
|
||||
response_headers_ = request_->response_headers();
|
||||
}
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
|
@ -117,29 +167,28 @@ void AtomURLRequest::OnResponseStarted(net::URLRequest* request) {
|
|||
}
|
||||
|
||||
void AtomURLRequest::ReadResponse() {
|
||||
|
||||
// Called on content::BrowserThread::IO
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
// Some servers may treat HEAD requests as GET requests. To free up the
|
||||
// network connection as soon as possible, signal that the request has
|
||||
// completed immediately, without trying to read any data back (all we care
|
||||
// about is the response code and headers, which we already have).
|
||||
int bytes_read = 0;
|
||||
if (url_request_->status().is_success() /* TODO && (request_type_ != URLFetcher::HEAD)*/) {
|
||||
if (!url_request_->Read(buffer_.get(), kBufferSize, &bytes_read))
|
||||
if (request_->status().is_success() /* TODO && (request_type_ != URLFetcher::HEAD)*/) {
|
||||
if (!request_->Read(buffer_.get(), kBufferSize, &bytes_read))
|
||||
bytes_read = -1;
|
||||
}
|
||||
OnReadCompleted(url_request_.get(), bytes_read);
|
||||
OnReadCompleted(request_.get(), 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 {
|
||||
if (!url_request_->status().is_success() || bytes_read <= 0)
|
||||
if (!request_->status().is_success() || bytes_read <= 0)
|
||||
break;
|
||||
|
||||
|
||||
|
@ -148,9 +197,9 @@ void AtomURLRequest::OnReadCompleted(net::URLRequest* request, int bytes_read) {
|
|||
// Failed to transfer data to UI thread.
|
||||
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*/ ) {
|
||||
|
||||
|
@ -161,9 +210,8 @@ void AtomURLRequest::OnReadCompleted(net::URLRequest* request, 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_.
|
||||
// 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() {
|
||||
// Called on content::BrowserThread::UI.
|
||||
void AtomURLRequest::InformDelegateAuthenticationRequired(
|
||||
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_) {
|
||||
delegate_->OnResponseStarted();
|
||||
}
|
||||
}
|
||||
|
||||
void AtomURLRequest::InformDelegateResponseData(scoped_refptr<net::IOBufferWithSize> data) {
|
||||
// Called on content::BrowserThread::IO.
|
||||
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.
|
||||
|
@ -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_) {
|
||||
delegate_->OnResponseCompleted();
|
||||
}
|
||||
|
|
|
@ -27,43 +27,52 @@ namespace api {
|
|||
class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
|
||||
public net::URLRequest::Delegate {
|
||||
public:
|
||||
static scoped_refptr<AtomURLRequest> create(
|
||||
static scoped_refptr<AtomURLRequest> Create(
|
||||
AtomBrowserContext* browser_context,
|
||||
const std::string& method,
|
||||
const std::string& url,
|
||||
base::WeakPtr<api::URLRequest> delegate);
|
||||
|
||||
void set_method(const std::string& method);
|
||||
|
||||
void Write();
|
||||
void End();
|
||||
void Abort();
|
||||
void SetHeader();
|
||||
void GetHeader();
|
||||
void RemoveHeader();
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> GetResponseHeaders();
|
||||
void Write() const;
|
||||
void End() const;
|
||||
void Abort() const;
|
||||
void SetHeader(const std::string& name, const std::string& value) const;
|
||||
std::string GetHeader(const std::string& name) const;
|
||||
void RemoveHeader(const std::string& name) const;
|
||||
void PassLoginInformation(const base::string16& username,
|
||||
const base::string16& password) const;
|
||||
scoped_refptr<const net::HttpResponseHeaders> GetResponseHeaders() const;
|
||||
|
||||
protected:
|
||||
// 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 OnReadCompleted(net::URLRequest* request, int bytes_read) override;
|
||||
virtual void OnReadCompleted(net::URLRequest* request,
|
||||
int bytes_read) override;
|
||||
|
||||
private:
|
||||
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();
|
||||
bool CopyAndPostBuffer(int bytes_read);
|
||||
|
||||
void InformDelegateResponseStarted();
|
||||
void InformDelegateResponseData(scoped_refptr<net::IOBufferWithSize> data);
|
||||
void InformDelegateResponseCompleted();
|
||||
void InformDelegateAuthenticationRequired(
|
||||
scoped_refptr<net::AuthChallengeInfo> auth_info) const;
|
||||
void InformDelegateResponseStarted() const;
|
||||
void InformDelegateResponseData(
|
||||
scoped_refptr<net::IOBufferWithSize> data) const;
|
||||
void InformDelegateResponseCompleted() const;
|
||||
|
||||
AtomURLRequest(base::WeakPtr<api::URLRequest> delegate);
|
||||
virtual ~AtomURLRequest();
|
||||
|
||||
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::HttpResponseHeaders> response_headers_;
|
||||
|
||||
|
|
|
@ -55,6 +55,48 @@ Net.prototype.request = function(options, callback) {
|
|||
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) {
|
||||
if (name === 'response') {
|
||||
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
|
||||
|
Loading…
Add table
Reference in a new issue