Implementing authentication callback.

This commit is contained in:
ali.ibrahim 2016-09-21 17:35:03 +02:00
parent 2d9d4af98d
commit 2b3b41d5f9
5 changed files with 312 additions and 129 deletions

View file

@ -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,
atom_url_request->set_method(method); 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; 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;

View file

@ -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;

View file

@ -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;
@ -18,19 +19,20 @@ const int kBufferSize = 4096;
namespace atom { 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();
} }

View file

@ -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_;

View file

@ -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