Allow returning string in custom protocols.

This commit is contained in:
Cheng Zhao 2013-08-25 12:36:06 +08:00
parent 8464fb4f64
commit 912bac698c
3 changed files with 113 additions and 20 deletions

View file

@ -35,6 +35,38 @@ net::URLRequestJobFactoryImpl* GetRequestJobFactory() {
return job_factory; return job_factory;
} }
class URLRequestStringJob : public net::URLRequestSimpleJob {
public:
URLRequestStringJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& mime_type,
const std::string& charset,
const std::string& data)
: net::URLRequestSimpleJob(request, network_delegate),
mime_type_(mime_type),
charset_(charset),
data_(data) {
}
// URLRequestSimpleJob:
virtual int GetData(std::string* mime_type,
std::string* charset,
std::string* data,
const net::CompletionCallback& callback) const OVERRIDE {
*mime_type = mime_type_;
*charset = charset_;
*data = data_;
return net::OK;
}
private:
std::string mime_type_;
std::string charset_;
std::string data_;
DISALLOW_COPY_AND_ASSIGN(URLRequestStringJob);
};
// Ask JS which type of job it wants, and then delegate corresponding methods. // Ask JS which type of job it wants, and then delegate corresponding methods.
class AdapterRequestJob : public net::URLRequestJob { class AdapterRequestJob : public net::URLRequestJob {
public: public:
@ -45,6 +77,7 @@ class AdapterRequestJob : public net::URLRequestJob {
} }
protected: protected:
// net::URLRequestJob:
virtual void Start() OVERRIDE { virtual void Start() OVERRIDE {
DCHECK(!real_job_); DCHECK(!real_job_);
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
@ -65,8 +98,8 @@ class AdapterRequestJob : public net::URLRequestJob {
DCHECK(real_job_); DCHECK(real_job_);
// The ReadRawData is a protected method. // The ReadRawData is a protected method.
switch (type_) { switch (type_) {
case FILE_JOB: case REQUEST_STRING_JOB:
return static_cast<net::URLRequestFileJob*>(real_job_.get())-> return static_cast<URLRequestStringJob*>(real_job_.get())->
ReadRawData(buf, buf_size, bytes_read); ReadRawData(buf, buf_size, bytes_read);
default: default:
return net::URLRequestJob::ReadRawData(buf, buf_size, bytes_read); return net::URLRequestJob::ReadRawData(buf, buf_size, bytes_read);
@ -96,9 +129,9 @@ class AdapterRequestJob : public net::URLRequestJob {
private: private:
enum JOB_TYPE { enum JOB_TYPE {
ERROR_JOB, REQUEST_ERROR_JOB,
STRING_JOB, REQUEST_STRING_JOB,
FILE_JOB, REQUEST_FILE_JOB,
}; };
void GetJobTypeInUI() { void GetJobTypeInUI() {
@ -115,36 +148,72 @@ class AdapterRequestJob : public net::URLRequestJob {
// Determine the type of the job we are going to create. // Determine the type of the job we are going to create.
if (result->IsString()) { if (result->IsString()) {
type_ = STRING_JOB; std::string data = *v8::String::Utf8Value(result);
data_ = *v8::String::Utf8Value(result); content::BrowserThread::PostTask(
} else { content::BrowserThread::IO,
type_ = ERROR_JOB; FROM_HERE,
error_code_ = net::ERR_NOT_IMPLEMENTED; base::Bind(&AdapterRequestJob::CreateStringJobAndStart,
weak_factory_.GetWeakPtr(),
"text/plain",
"UTF-8",
data));
return;
} else if (result->IsObject()) {
v8::Handle<v8::Object> obj = result->ToObject();
std::string name = *v8::String::Utf8Value(obj->GetConstructorName());
if (name == "RequestStringJob") {
std::string mime_type = *v8::String::Utf8Value(obj->Get(
v8::String::New("mimeType")));
std::string charset = *v8::String::Utf8Value(obj->Get(
v8::String::New("charset")));
std::string data = *v8::String::Utf8Value(obj->Get(
v8::String::New("data")));
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
base::Bind(&AdapterRequestJob::CreateStringJobAndStart,
weak_factory_.GetWeakPtr(),
mime_type,
charset,
data));
return;
}
} }
// Go back to the IO thread. // Fallback to the not implemented error.
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::IO, content::BrowserThread::IO,
FROM_HERE, FROM_HERE,
base::Bind(&AdapterRequestJob::CreateJobAndStart, base::Bind(&AdapterRequestJob::CreateErrorJobAndStart,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr(),
net::ERR_NOT_IMPLEMENTED));
} }
void CreateJobAndStart() { void CreateErrorJobAndStart(int error_code) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
type_ = REQUEST_ERROR_JOB;
real_job_ = new net::URLRequestErrorJob( real_job_ = new net::URLRequestErrorJob(
request(), network_delegate(), net::ERR_NOT_IMPLEMENTED); request(), network_delegate(), error_code);
real_job_->Start();
}
void CreateStringJobAndStart(const std::string& mime_type,
const std::string& charset,
const std::string& data) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
type_ = REQUEST_STRING_JOB;
real_job_ = new URLRequestStringJob(
request(), network_delegate(), mime_type, charset, data);
real_job_->Start(); real_job_->Start();
} }
scoped_refptr<net::URLRequestJob> real_job_; scoped_refptr<net::URLRequestJob> real_job_;
// Type of the delegated url request job.
JOB_TYPE type_; JOB_TYPE type_;
int error_code_;
base::FilePath file_path_;
std::string mime_type_;
std::string charset_;
std::string data_;
base::WeakPtrFactory<AdapterRequestJob> weak_factory_; base::WeakPtrFactory<AdapterRequestJob> weak_factory_;

View file

@ -1,4 +1,5 @@
assert = require 'assert' assert = require 'assert'
ipc = require 'ipc'
protocol = require('remote').require 'protocol' protocol = require('remote').require 'protocol'
describe 'protocol API', -> describe 'protocol API', ->
@ -18,3 +19,13 @@ describe 'protocol API', ->
it 'throws error when scheme does not exist', -> it 'throws error when scheme does not exist', ->
unregister = -> protocol.unregisterProtocol 'test3' unregister = -> protocol.unregisterProtocol 'test3'
assert.throws unregister, /The scheme has not been registered/ assert.throws unregister, /The scheme has not been registered/
describe 'registered protocol callback', ->
it 'returns string should send the string as request content', (done) ->
$.ajax
url: 'atom-string://something'
success: (data) ->
assert.equal data, 'atom-string://something'
done()
error: (xhr, errorType, error) ->
console.log xhr, errorType, error

View file

@ -22,6 +22,10 @@ ipc.on('process.exit', function(pid, rid, code) {
process.exit(code); process.exit(code);
}); });
ipc.on('eval', function(ev, pid, rid, script) {
ev.result = eval(script);
});
process.on('uncaughtException', function() { process.on('uncaughtException', function() {
window.openDevTools(); window.openDevTools();
}); });
@ -30,6 +34,15 @@ app.on('window-all-closed', function() {
app.terminate(); app.terminate();
}); });
app.on('will-finish-launching', function() {
// Reigster some protocols, used by the protocol spec.
// FIXME(zcbenz): move this to somewhere else.
var protocol = require('protocol');
protocol.registerProtocol('atom-string', function(url) {
return url;
});
});
app.on('finish-launching', function() { app.on('finish-launching', function() {
window = new BrowserWindow({ window = new BrowserWindow({
title: 'atom-shell tests', title: 'atom-shell tests',