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;
}
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.
class AdapterRequestJob : public net::URLRequestJob {
public:
@ -45,6 +77,7 @@ class AdapterRequestJob : public net::URLRequestJob {
}
protected:
// net::URLRequestJob:
virtual void Start() OVERRIDE {
DCHECK(!real_job_);
content::BrowserThread::PostTask(
@ -65,8 +98,8 @@ class AdapterRequestJob : public net::URLRequestJob {
DCHECK(real_job_);
// The ReadRawData is a protected method.
switch (type_) {
case FILE_JOB:
return static_cast<net::URLRequestFileJob*>(real_job_.get())->
case REQUEST_STRING_JOB:
return static_cast<URLRequestStringJob*>(real_job_.get())->
ReadRawData(buf, buf_size, bytes_read);
default:
return net::URLRequestJob::ReadRawData(buf, buf_size, bytes_read);
@ -96,9 +129,9 @@ class AdapterRequestJob : public net::URLRequestJob {
private:
enum JOB_TYPE {
ERROR_JOB,
STRING_JOB,
FILE_JOB,
REQUEST_ERROR_JOB,
REQUEST_STRING_JOB,
REQUEST_FILE_JOB,
};
void GetJobTypeInUI() {
@ -115,36 +148,72 @@ class AdapterRequestJob : public net::URLRequestJob {
// Determine the type of the job we are going to create.
if (result->IsString()) {
type_ = STRING_JOB;
data_ = *v8::String::Utf8Value(result);
} else {
type_ = ERROR_JOB;
error_code_ = net::ERR_NOT_IMPLEMENTED;
}
// Go back to the IO thread.
std::string data = *v8::String::Utf8Value(result);
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
base::Bind(&AdapterRequestJob::CreateJobAndStart,
weak_factory_.GetWeakPtr()));
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;
}
}
void CreateJobAndStart() {
// Fallback to the not implemented error.
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
base::Bind(&AdapterRequestJob::CreateErrorJobAndStart,
weak_factory_.GetWeakPtr(),
net::ERR_NOT_IMPLEMENTED));
}
void CreateErrorJobAndStart(int error_code) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
type_ = REQUEST_ERROR_JOB;
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();
}
scoped_refptr<net::URLRequestJob> real_job_;
// Type of the delegated url request job.
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_;

View file

@ -1,4 +1,5 @@
assert = require 'assert'
ipc = require 'ipc'
protocol = require('remote').require 'protocol'
describe 'protocol API', ->
@ -18,3 +19,13 @@ describe 'protocol API', ->
it 'throws error when scheme does not exist', ->
unregister = -> protocol.unregisterProtocol 'test3'
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);
});
ipc.on('eval', function(ev, pid, rid, script) {
ev.result = eval(script);
});
process.on('uncaughtException', function() {
window.openDevTools();
});
@ -30,6 +34,15 @@ app.on('window-all-closed', function() {
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() {
window = new BrowserWindow({
title: 'atom-shell tests',