use c++ instead of c++0x to compatible with old compiler
This commit is contained in:
parent
f8f934a119
commit
314d43203f
11 changed files with 454 additions and 106 deletions
102
README.md
102
README.md
|
@ -1,36 +1,88 @@
|
||||||
Node Curl Wrap
|
node-curl
|
||||||
Use select curl multi
|
=========
|
||||||
|
|
||||||
|
node cURL wrapper, support all options and infos.
|
||||||
|
|
||||||
Quick Start
|
Quick Start
|
||||||
===========
|
-----------
|
||||||
|
|
||||||
curl = require('node-curl')
|
* quick start
|
||||||
curl('www.google.com', {VERBOSE: 1}, function(err, res) {
|
|
||||||
console.info(res.status)
|
curl = require('node-curl');
|
||||||
console.info('-----')
|
curl('www.google.com', function(err, res) {
|
||||||
console.info(res.body)
|
console.info(res.status);
|
||||||
console.info('-----')
|
console.info('-----');
|
||||||
console.info(res.info('SIZE_DOWNLOAD'))
|
console.info(res.body);
|
||||||
});
|
console.info('-----');
|
||||||
|
console.info(res.info('SIZE_DOWNLOAD'));
|
||||||
|
res.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
* with options
|
||||||
|
|
||||||
|
curl = require('node-curl')
|
||||||
|
curl('www.google.com', {VERBOSE: 1, RAW: 1}, function(err, res) {
|
||||||
|
console.info(res);
|
||||||
|
res.close();
|
||||||
|
});
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
=====
|
-----
|
||||||
|
|
||||||
Function: curl
|
* curl
|
||||||
curl(url, [options = {}], callback)
|
|
||||||
callback includes 2 parameters (error, result)
|
|
||||||
|
|
||||||
Curl Options:
|
curl(url, [options = {}], callback)
|
||||||
options is on the list at http://curl.haxx.se/libcurl/c/curl_easy_setopt.html without CURLOPT_
|
callback includes 2 parameters (error, result)
|
||||||
eg: CURLOPT_VERBOSE will be VERBOSE, CURLOPT_HEADER will be HEADER
|
|
||||||
|
|
||||||
Object: result
|
* result in callback
|
||||||
body
|
|
||||||
status
|
|
||||||
info
|
|
||||||
|
|
||||||
Curl Infos:
|
members:
|
||||||
infos is on the list at http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html without CURLINFO_
|
status - Http Response code
|
||||||
eg: CURLINFO_EFFECTIVE_URL will be EFFETCTIVE_URL
|
body - Http body
|
||||||
|
|
||||||
|
methods:
|
||||||
|
info(name) - Get information of result, see 'info' section
|
||||||
|
|
||||||
|
Options
|
||||||
|
-------
|
||||||
|
* Any Curl Easy Options
|
||||||
|
|
||||||
|
eg: CURLOPT_VERBOSE will be VERBOSE, CURLOPT_HEADER will be HEADER
|
||||||
|
|
||||||
|
Full list at http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
|
||||||
|
|
||||||
|
* node-curl Extra Options
|
||||||
|
|
||||||
|
RAW - Returns Buffer instead of String in result.body
|
||||||
|
|
||||||
|
* About slist parameters
|
||||||
|
|
||||||
|
node-curl support slist which map to Javascript Array
|
||||||
|
|
||||||
|
eg:
|
||||||
|
HTTP_HEADER: ['FOO', 'BAR']
|
||||||
|
HTTP_HEADER: 'FOO'
|
||||||
|
|
||||||
|
any non-array parameter will convert to [ parameter.toString() ]
|
||||||
|
|
||||||
|
Infos
|
||||||
|
-----
|
||||||
|
* Any Curl Info options
|
||||||
|
|
||||||
|
eg: CURLINFO_EFFECTIVE_URL will be EFFETCTIVE_URL
|
||||||
|
|
||||||
|
full list at http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html
|
||||||
|
|
||||||
|
|
||||||
|
* About slist
|
||||||
|
|
||||||
|
slist will be returns in Array
|
||||||
|
eg: CURLINFO_COOKIELIST
|
||||||
|
|
||||||
|
|
||||||
|
Hints
|
||||||
|
-----
|
||||||
|
close the result to release resource of curl immediately.
|
||||||
|
|
||||||
|
or the resource will not release until gc performed.
|
||||||
|
|
30
examples/pressure.js
Normal file
30
examples/pressure.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Generated by ToffeeScript 1.1.4-4
|
||||||
|
(function() {
|
||||||
|
var assert, curl, i, j, next, once, _i;
|
||||||
|
|
||||||
|
curl = require('../index');
|
||||||
|
|
||||||
|
assert = require('assert');
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
(next = function() {
|
||||||
|
console.info("curl instances: ", curl.get_count());
|
||||||
|
return setTimeout(next, 1000);
|
||||||
|
})();
|
||||||
|
|
||||||
|
for (i = _i = 1; _i <= 100; i = ++_i) {
|
||||||
|
(once = function() {
|
||||||
|
var _this = this;
|
||||||
|
return curl('localhost/test.html', function(_$$_err, _$$_res) {
|
||||||
|
var err, res;
|
||||||
|
err = _$$_err;
|
||||||
|
res = _$$_res;
|
||||||
|
assert.equal(res.body.length, 1468);
|
||||||
|
if (++j % 100 === 0) console.info(j);
|
||||||
|
if (j < 20000) return once();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
}).call(this);
|
16
examples/pressure.toffee
Normal file
16
examples/pressure.toffee
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
curl = require '../index'
|
||||||
|
assert = require 'assert'
|
||||||
|
j = 0;
|
||||||
|
do next = ->
|
||||||
|
console.info "curl instances: ", curl.get_count()
|
||||||
|
setTimeout next, 1000
|
||||||
|
|
||||||
|
for i in [1..100]
|
||||||
|
do once = ->
|
||||||
|
err, res = curl! 'localhost/test.html'
|
||||||
|
assert.equal res.body.length, 1468
|
||||||
|
if ++j % 100 == 0
|
||||||
|
console.info j
|
||||||
|
if j < 20000
|
||||||
|
once()
|
||||||
|
# res.close()
|
|
@ -1,19 +1,27 @@
|
||||||
curl = require('../index');
|
curl = require('../index');
|
||||||
url = 'www.yahoo.com';
|
url = 'www.nodejs.org';
|
||||||
curl(url, function(err, res) {
|
options = {CONNECTTIMEOUT: 2, VERBOSE: 1};
|
||||||
|
curl(url, options, function(err, res) {
|
||||||
|
console.info("\x1b[33meffetcive url: " + res.info('EFFECTIVE_URL') + "\x1b[0m");
|
||||||
console.info("body length: " + res.body.length);
|
console.info("body length: " + res.body.length);
|
||||||
console.info('-----');
|
res.close();
|
||||||
console.info("status: " + res.status);
|
|
||||||
console.info('-----');
|
|
||||||
console.info("size download: " + res.info('SIZE_DOWNLOAD'));
|
|
||||||
console.info("\033[33meffetcive url: " + res.info('EFFECTIVE_URL') + "\033[0m");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
curl(url, function(err, res) {
|
url = 'www.yahoo.com'
|
||||||
|
curl(url, options, function(err, res) {
|
||||||
|
console.info("\x1b[33meffetcive url: " + res.info('EFFECTIVE_URL') + "\x1b[0m");
|
||||||
console.info("body length: " + res.body.length);
|
console.info("body length: " + res.body.length);
|
||||||
console.info('-----');
|
res.close();
|
||||||
console.info("status: " + res.status);
|
|
||||||
console.info('-----');
|
|
||||||
console.info("size download: " + res.info('SIZE_DOWNLOAD'));
|
|
||||||
console.info("\033[33meffetcive url: " + res.info('EFFECTIVE_URL') + "\033[0m");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
curl('www.google.com', {VERBOSE: 1, RAW: 1}, function(err, res) {
|
||||||
|
console.info(res);
|
||||||
|
res.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
console.info('-----');
|
||||||
|
console.info("status: " + res.status);
|
||||||
|
console.info('-----');
|
||||||
|
console.info("size download: " + res.info('SIZE_DOWNLOAD'));
|
||||||
|
*/
|
||||||
|
|
40
examples/test.js
Normal file
40
examples/test.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Generated by ToffeeScript 1.1.4-4
|
||||||
|
(function() {
|
||||||
|
var curl, fs, p, url, util,
|
||||||
|
_this = this;
|
||||||
|
|
||||||
|
curl = require('../index');
|
||||||
|
|
||||||
|
fs = require('fs');
|
||||||
|
|
||||||
|
util = require('util');
|
||||||
|
|
||||||
|
p = console.info;
|
||||||
|
|
||||||
|
url = 'www.google.com';
|
||||||
|
|
||||||
|
curl(url, {
|
||||||
|
HTTPHEADER: 'BAR',
|
||||||
|
VERBOSE: 1,
|
||||||
|
COOKIEFILE: 'node-curl-cookie.txt'
|
||||||
|
}, function(_$$_err, _$$_res) {
|
||||||
|
var err, res;
|
||||||
|
err = _$$_err;
|
||||||
|
res = _$$_res;
|
||||||
|
p("\x1b[33m" + util.inspect(res.info('COOKIELIST')) + "\x1b[0m");
|
||||||
|
url = 'www.yahoo.com';
|
||||||
|
return curl(url, {
|
||||||
|
HTTPHEADER: ['foo', 'bar'],
|
||||||
|
VERBOSE: 1,
|
||||||
|
COOKIEFILE: 'node-curl-cookie.txt',
|
||||||
|
RAW: 1
|
||||||
|
}, function(_$$_err, _$$_res) {
|
||||||
|
err = _$$_err;
|
||||||
|
res = _$$_res;
|
||||||
|
p("\x1b[33m" + util.inspect(res.info('COOKIELIST')) + "\x1b[0m");
|
||||||
|
p(res.body);
|
||||||
|
return fs.unlink('node-curl-cookie.txt');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}).call(this);
|
22
examples/test.toffee
Normal file
22
examples/test.toffee
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
curl = require '../index'
|
||||||
|
fs = require 'fs'
|
||||||
|
util = require 'util'
|
||||||
|
p = console.info
|
||||||
|
|
||||||
|
url = 'www.google.com'
|
||||||
|
err, res = curl! url,
|
||||||
|
HTTPHEADER: 'BAR'
|
||||||
|
VERBOSE: 1
|
||||||
|
COOKIEFILE: 'node-curl-cookie.txt'
|
||||||
|
|
||||||
|
p "\x1b[33m" + util.inspect(res.info('COOKIELIST')) + "\x1b[0m"
|
||||||
|
url = 'www.yahoo.com'
|
||||||
|
err, res = curl! url,
|
||||||
|
HTTPHEADER: ['foo', 'bar']
|
||||||
|
VERBOSE: 1
|
||||||
|
COOKIEFILE: 'node-curl-cookie.txt'
|
||||||
|
RAW: 1
|
||||||
|
|
||||||
|
p "\x1b[33m" + util.inspect(res.info('COOKIELIST')) + "\x1b[0m"
|
||||||
|
p res.body
|
||||||
|
fs.unlink 'node-curl-cookie.txt'
|
81
lib/curl.js
81
lib/curl.js
|
@ -1,6 +1,6 @@
|
||||||
// Generated by CoffeeScript 1.1.4-3
|
// Generated by ToffeeScript 1.1.4-4
|
||||||
(function() {
|
(function() {
|
||||||
var Curl, curl, curl_id,
|
var Curl, curl, curl_id, curls,
|
||||||
__slice = [].slice,
|
__slice = [].slice,
|
||||||
__hasProp = {}.hasOwnProperty;
|
__hasProp = {}.hasOwnProperty;
|
||||||
|
|
||||||
|
@ -10,10 +10,18 @@
|
||||||
Curl = require(__dirname + '/../build/default/node-curl').Curl;
|
Curl = require(__dirname + '/../build/default/node-curl').Curl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl.prototype.setopt_user_ = function(option_id, value) {
|
||||||
|
return this.options[option_id] = value;
|
||||||
|
};
|
||||||
|
|
||||||
Curl.prototype.setopt = function(ooption, value) {
|
Curl.prototype.setopt = function(ooption, value) {
|
||||||
var option, option_id;
|
var option, option_id;
|
||||||
option = ooption.toUpperCase();
|
option = ooption.toUpperCase();
|
||||||
if ((option_id = Curl.integer_options[option]) != null) {
|
if ((option_id = Curl.user_options[option]) != null) {
|
||||||
|
return this.setopt_user_(option_id, value);
|
||||||
|
} else if ((option_id = Curl.slist_options[option]) != null) {
|
||||||
|
return this.setopt_slist_(option_id, value);
|
||||||
|
} else if ((option_id = Curl.integer_options[option]) != null) {
|
||||||
return this.setopt_int_(option_id, value >> 0);
|
return this.setopt_int_(option_id, value >> 0);
|
||||||
} else if ((option_id = Curl.string_options[option]) != null) {
|
} else if ((option_id = Curl.string_options[option]) != null) {
|
||||||
return this.setopt_str_(option_id, value.toString());
|
return this.setopt_str_(option_id, value.toString());
|
||||||
|
@ -25,14 +33,16 @@
|
||||||
Curl.prototype.getinfo = function(oinfo) {
|
Curl.prototype.getinfo = function(oinfo) {
|
||||||
var info, info_id;
|
var info, info_id;
|
||||||
info = oinfo.toUpperCase();
|
info = oinfo.toUpperCase();
|
||||||
if ((info_id = Curl.integer_infos[info]) != null) {
|
if ((info_id = Curl.slist_infos[info]) != null) {
|
||||||
|
return this.getinfo_slist_(info_id);
|
||||||
|
} else if ((info_id = Curl.integer_infos[info]) != null) {
|
||||||
return this.getinfo_int_(info_id);
|
return this.getinfo_int_(info_id);
|
||||||
} else if ((info_id = Curl.string_infos[info]) != null) {
|
} else if ((info_id = Curl.string_infos[info]) != null) {
|
||||||
return this.getinfo_str_(info_id);
|
return this.getinfo_str_(info_id);
|
||||||
} else if ((info_id = Curl.double_infos[info]) != null) {
|
} else if ((info_id = Curl.double_infos[info]) != null) {
|
||||||
return this.getinfo_double_(info_id);
|
return this.getinfo_double_(info_id);
|
||||||
} else {
|
} else {
|
||||||
throw new Error("unsupproted info " + oinfo);
|
throw new Error("unsupported info " + oinfo);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,6 +51,10 @@
|
||||||
return Curl.process();
|
return Curl.process();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Curl.user_options = {
|
||||||
|
RAW: 'RAW'
|
||||||
|
};
|
||||||
|
|
||||||
Curl.process = function() {
|
Curl.process = function() {
|
||||||
var once;
|
var once;
|
||||||
if (Curl.in_process) return;
|
if (Curl.in_process) return;
|
||||||
|
@ -58,63 +72,84 @@
|
||||||
|
|
||||||
curl_id = 0;
|
curl_id = 0;
|
||||||
|
|
||||||
|
curls = {};
|
||||||
|
|
||||||
curl = function() {
|
curl = function() {
|
||||||
var args, c, cb, chunks, k, length, options, res, url, v;
|
var args, c, cb, k, length, options, url, v;
|
||||||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
||||||
cb = args.pop();
|
cb = args.pop();
|
||||||
url = args[0], options = args[1];
|
url = args[0], options = args[1];
|
||||||
if (options == null) options = {};
|
if (options == null) options = {};
|
||||||
c = new Curl();
|
c = new Curl();
|
||||||
|
c.options = {};
|
||||||
c.id = ++curl_id;
|
c.id = ++curl_id;
|
||||||
|
curls[c.id] = c;
|
||||||
c.setopt('FOLLOWLOCATION', 1);
|
c.setopt('FOLLOWLOCATION', 1);
|
||||||
c.setopt('ACCEPT_ENCODING', 'gzip');
|
c.setopt('ACCEPT_ENCODING', 'gzip');
|
||||||
chunks = [];
|
c.chunks = [];
|
||||||
length = 0;
|
length = 0;
|
||||||
res = {};
|
|
||||||
for (k in options) {
|
for (k in options) {
|
||||||
if (!__hasProp.call(options, k)) continue;
|
if (!__hasProp.call(options, k)) continue;
|
||||||
v = options[k];
|
v = options[k];
|
||||||
c.setopt(k, v);
|
c.setopt(k, v);
|
||||||
}
|
}
|
||||||
c.on_write = function(chunk) {
|
c.on_write = function(chunk) {
|
||||||
chunks.push(chunk);
|
c.chunks.push(chunk);
|
||||||
length += chunk.length;
|
return length += chunk.length;
|
||||||
return console.info("on_write " + c.id + " " + chunk.length);
|
|
||||||
};
|
};
|
||||||
c.on_end = function() {
|
c.on_end = function() {
|
||||||
var chunk, data, i, position, st, _i, _len;
|
var chunk, data, position, res, _i, _len, _ref,
|
||||||
|
_this = this;
|
||||||
data = new Buffer(length);
|
data = new Buffer(length);
|
||||||
position = 0;
|
position = 0;
|
||||||
for (_i = 0, _len = chunks.length; _i < _len; _i++) {
|
_ref = c.chunks;
|
||||||
chunk = chunks[_i];
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
chunk = _ref[_i];
|
||||||
chunk.copy(data, position);
|
chunk.copy(data, position);
|
||||||
position += chunk.length;
|
position += chunk.length;
|
||||||
}
|
}
|
||||||
st = Date.now();
|
c.chunks = [];
|
||||||
i = 0;
|
res = {};
|
||||||
while (Date.now() - st < 500) {
|
res.curl_ = c;
|
||||||
++i;
|
delete curls[c.id];
|
||||||
|
if (c.options.RAW) {
|
||||||
|
res.body = data;
|
||||||
|
} else {
|
||||||
|
res.body = data.toString();
|
||||||
}
|
}
|
||||||
res.body = data;
|
|
||||||
res.status = res.code = c.getinfo('RESPONSE_CODE');
|
res.status = res.code = c.getinfo('RESPONSE_CODE');
|
||||||
res.info = function(info) {
|
res.info = function(info) {
|
||||||
return c.getinfo(info);
|
if (this.curl_ == null) throw new Error('curl is closed');
|
||||||
|
return this.curl_.getinfo(info);
|
||||||
};
|
};
|
||||||
console.info("id: " + c.id);
|
res.close = function() {
|
||||||
return cb(null, res);
|
if (this.curl_ != null) this.curl_.close();
|
||||||
|
this.curl_ = null;
|
||||||
|
return this.body = null;
|
||||||
|
};
|
||||||
|
return process.nextTick(function() {
|
||||||
|
return cb(null, res);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
c.on_error = function(err) {
|
c.on_error = function(err) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
curls[c.id].close();
|
||||||
|
delete curls[c.id];
|
||||||
return process.nextTick(function() {
|
return process.nextTick(function() {
|
||||||
return cb(err, null);
|
return cb(err, null);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
c.setopt('URL', url);
|
c.setopt('URL', url);
|
||||||
return c.perform();
|
c.perform();
|
||||||
|
return c;
|
||||||
};
|
};
|
||||||
|
|
||||||
curl.Curl = Curl;
|
curl.Curl = Curl;
|
||||||
|
|
||||||
|
curl.get_count = function() {
|
||||||
|
return Curl.get_count();
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = curl;
|
module.exports = curl;
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
|
@ -3,9 +3,19 @@ try
|
||||||
catch e
|
catch e
|
||||||
{Curl} = require __dirname + '/../build/default/node-curl'
|
{Curl} = require __dirname + '/../build/default/node-curl'
|
||||||
|
|
||||||
|
Curl::setopt_user_ = (option_id, value) ->
|
||||||
|
@options[option_id] = value
|
||||||
|
|
||||||
Curl::setopt = (ooption, value) ->
|
Curl::setopt = (ooption, value) ->
|
||||||
option = ooption.toUpperCase()
|
option = ooption.toUpperCase()
|
||||||
if (option_id = Curl.integer_options[option])?
|
|
||||||
|
# slist must be at the top of condition
|
||||||
|
# the option exists in string_options too
|
||||||
|
if (option_id = Curl.user_options[option])?
|
||||||
|
@setopt_user_ option_id, value
|
||||||
|
else if (option_id = Curl.slist_options[option])?
|
||||||
|
@setopt_slist_ option_id, value
|
||||||
|
else if (option_id = Curl.integer_options[option])?
|
||||||
@setopt_int_ option_id, value >> 0
|
@setopt_int_ option_id, value >> 0
|
||||||
else if (option_id = Curl.string_options[option])?
|
else if (option_id = Curl.string_options[option])?
|
||||||
@setopt_str_ option_id, value.toString()
|
@setopt_str_ option_id, value.toString()
|
||||||
|
@ -14,19 +24,24 @@ Curl::setopt = (ooption, value) ->
|
||||||
|
|
||||||
Curl::getinfo = (oinfo) ->
|
Curl::getinfo = (oinfo) ->
|
||||||
info = oinfo.toUpperCase()
|
info = oinfo.toUpperCase()
|
||||||
if (info_id = Curl.integer_infos[info])?
|
if (info_id = Curl.slist_infos[info])?
|
||||||
|
@getinfo_slist_(info_id)
|
||||||
|
else if (info_id = Curl.integer_infos[info])?
|
||||||
@getinfo_int_(info_id)
|
@getinfo_int_(info_id)
|
||||||
else if (info_id = Curl.string_infos[info])?
|
else if (info_id = Curl.string_infos[info])?
|
||||||
@getinfo_str_(info_id)
|
@getinfo_str_(info_id)
|
||||||
else if (info_id = Curl.double_infos[info])?
|
else if (info_id = Curl.double_infos[info])?
|
||||||
@getinfo_double_(info_id)
|
@getinfo_double_(info_id)
|
||||||
else
|
else
|
||||||
throw new Error("unsupproted info #{oinfo}")
|
throw new Error("unsupported info #{oinfo}")
|
||||||
|
|
||||||
Curl::perform = ->
|
Curl::perform = ->
|
||||||
@perform_()
|
@perform_()
|
||||||
Curl.process()
|
Curl.process()
|
||||||
|
|
||||||
|
Curl.user_options =
|
||||||
|
RAW: 'RAW'
|
||||||
|
|
||||||
Curl.process = ->
|
Curl.process = ->
|
||||||
if Curl.in_process
|
if Curl.in_process
|
||||||
return
|
return
|
||||||
|
@ -40,56 +55,75 @@ Curl.process = ->
|
||||||
|
|
||||||
# url, [options], cb
|
# url, [options], cb
|
||||||
curl_id = 0
|
curl_id = 0
|
||||||
|
curls = {}
|
||||||
curl = (args...) ->
|
curl = (args...) ->
|
||||||
cb = args.pop()
|
cb = args.pop()
|
||||||
[url, options] = args
|
[url, options] = args
|
||||||
options ?= {}
|
options ?= {}
|
||||||
|
|
||||||
c = new Curl()
|
c = new Curl()
|
||||||
|
c.options = {}
|
||||||
c.id = ++curl_id
|
c.id = ++curl_id
|
||||||
|
# after the scope c will not valid any more, so add to curls to keep c alive
|
||||||
|
curls[c.id] = c
|
||||||
|
|
||||||
c.setopt 'FOLLOWLOCATION', 1
|
c.setopt 'FOLLOWLOCATION', 1
|
||||||
c.setopt 'ACCEPT_ENCODING', 'gzip'
|
c.setopt 'ACCEPT_ENCODING', 'gzip'
|
||||||
chunks = []
|
c.chunks = []
|
||||||
length = 0
|
length = 0
|
||||||
res = {}
|
|
||||||
|
|
||||||
for own k, v of options
|
for own k, v of options
|
||||||
c.setopt k, v
|
c.setopt k, v
|
||||||
|
|
||||||
c.on_write = (chunk) ->
|
c.on_write = (chunk) ->
|
||||||
chunks.push chunk
|
c.chunks.push chunk
|
||||||
length += chunk.length
|
length += chunk.length
|
||||||
console.info "on_write #{c.id} #{chunk.length}"
|
|
||||||
|
|
||||||
c.on_end = ->
|
c.on_end = ->
|
||||||
data = new Buffer(length)
|
data = new Buffer(length)
|
||||||
position = 0
|
position = 0
|
||||||
for chunk in chunks
|
for chunk in c.chunks
|
||||||
chunk.copy data, position
|
chunk.copy data, position
|
||||||
position += chunk.length
|
position += chunk.length
|
||||||
# Strange Issue
|
c.chunks = []
|
||||||
# use data.toString() will cause parallel http request terminated? eg yahoo.com
|
|
||||||
st = Date.now()
|
|
||||||
i = 0
|
|
||||||
while Date.now() - st < 500
|
|
||||||
++i
|
|
||||||
|
|
||||||
|
res = {}
|
||||||
|
# now the c is in res.curl, delete curl in curls
|
||||||
|
# if res destruct, curl will be destruct after gc
|
||||||
|
res.curl_ = c
|
||||||
|
delete curls[c.id]
|
||||||
|
|
||||||
res.body = data #.toString()
|
if c.options.RAW
|
||||||
|
res.body = data
|
||||||
|
else
|
||||||
|
res.body = data.toString() #.toString()
|
||||||
res.status = res.code = c.getinfo('RESPONSE_CODE')
|
res.status = res.code = c.getinfo('RESPONSE_CODE')
|
||||||
|
|
||||||
res.info = (info)->
|
res.info = (info)->
|
||||||
c.getinfo(info)
|
unless @curl_?
|
||||||
# 当curl返回过快,且cb循环调用回导致堆栈溢出
|
throw new Error('curl is closed')
|
||||||
# process.nextTick!
|
@curl_.getinfo(info)
|
||||||
console.info "id: #{c.id}"
|
|
||||||
|
res.close = ->
|
||||||
|
@curl_.close() if @curl_?
|
||||||
|
@curl_ = null
|
||||||
|
@body = null
|
||||||
|
|
||||||
|
# if curl returns to fast, avoid cb recursive call
|
||||||
|
process.nextTick!
|
||||||
cb null, res
|
cb null, res
|
||||||
|
|
||||||
c.on_error = (err)->
|
c.on_error = (err)->
|
||||||
|
curls[c.id].close()
|
||||||
|
delete curls[c.id]
|
||||||
process.nextTick!
|
process.nextTick!
|
||||||
cb err, null
|
cb err, null
|
||||||
|
|
||||||
c.setopt('URL', url)
|
c.setopt('URL', url)
|
||||||
c.perform()
|
c.perform()
|
||||||
|
c
|
||||||
|
|
||||||
curl.Curl = Curl
|
curl.Curl = Curl
|
||||||
|
curl.get_count = ->
|
||||||
|
Curl.get_count()
|
||||||
module.exports = curl
|
module.exports = curl
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
{
|
{
|
||||||
"name": "node-curl",
|
"name": "node-curl",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "node wrapper for multi curl",
|
"author" : "Jiang Miao <jiangfriend@gmail.com>",
|
||||||
|
"description": "node wrapper for multi curl, full implemented.",
|
||||||
"keywords" : ["node-curl", "curl", "multi-curl", "mcurl"],
|
"keywords" : ["node-curl", "curl", "multi-curl", "mcurl"],
|
||||||
"homepage": "http://github.com/jiangmiao/node-curl",
|
"homepage": "http://github.com/jiangmiao/node-curl",
|
||||||
"repository" : {
|
"repository" : {
|
||||||
"type" : "git",
|
"type" : "git",
|
||||||
"url" : "git://github.com/jiangmiao/node-curl.git"
|
"url" : "git://github.com/jiangmiao/node-curl.git"
|
||||||
},
|
},
|
||||||
"author" : "Jiang Miao <jiangfriend@gmail.com>",
|
|
||||||
"main" : "./lib",
|
"main" : "./lib",
|
||||||
"scripts" : {
|
"scripts" : {
|
||||||
"install" : "node-waf configure build || true"
|
"install" : "node-waf configure build || true"
|
||||||
|
|
157
src/node-curl.h
157
src/node-curl.h
|
@ -8,6 +8,7 @@
|
||||||
#include <node_buffer.h>
|
#include <node_buffer.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#define NODE_CURL_OPTION_NX(name, value) {#name, value}
|
#define NODE_CURL_OPTION_NX(name, value) {#name, value}
|
||||||
#define NODE_CURL_OPTION(name) NODE_CURL_OPTION_NX(name , CURLOPT_##name)
|
#define NODE_CURL_OPTION(name) NODE_CURL_OPTION_NX(name , CURLOPT_##name)
|
||||||
|
@ -26,11 +27,17 @@ class NodeCurl
|
||||||
static int running_handles;
|
static int running_handles;
|
||||||
static bool is_ref;
|
static bool is_ref;
|
||||||
static std::map< CURL*, NodeCurl* > curls;
|
static std::map< CURL*, NodeCurl* > curls;
|
||||||
|
static int count;
|
||||||
|
|
||||||
CURL * curl;
|
CURL * curl;
|
||||||
v8::Persistent<v8::Object> handle;
|
v8::Persistent<v8::Object> handle;
|
||||||
|
bool in_curlm;
|
||||||
|
std::vector<curl_slist*> slists;
|
||||||
NodeCurl(v8::Handle<v8::Object> object)
|
NodeCurl(v8::Handle<v8::Object> object)
|
||||||
|
: in_curlm(false)
|
||||||
{
|
{
|
||||||
|
++count;
|
||||||
|
v8::V8::AdjustAmountOfExternalAllocatedMemory(2*4096);
|
||||||
object->SetPointerInInternalField(0, this);
|
object->SetPointerInInternalField(0, this);
|
||||||
handle = v8::Persistent<v8::Object>::New(object);
|
handle = v8::Persistent<v8::Object>::New(object);
|
||||||
handle.MakeWeak(this, destructor);
|
handle.MakeWeak(this, destructor);
|
||||||
|
@ -39,6 +46,7 @@ class NodeCurl
|
||||||
if (!curl)
|
if (!curl)
|
||||||
{
|
{
|
||||||
raise("curl_easy_init failed");
|
raise("curl_easy_init failed");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
|
||||||
|
@ -47,18 +55,31 @@ class NodeCurl
|
||||||
|
|
||||||
~NodeCurl()
|
~NodeCurl()
|
||||||
{
|
{
|
||||||
|
--count;
|
||||||
|
v8::V8::AdjustAmountOfExternalAllocatedMemory(-2*4096);
|
||||||
if (curl)
|
if (curl)
|
||||||
{
|
{
|
||||||
curl_multi_remove_handle(curlm, curl);
|
if (in_curlm)
|
||||||
|
curl_multi_remove_handle(curlm, curl);
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
curls.erase(curl);
|
curls.erase(curl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::vector<curl_slist*>::iterator i = slists.begin(), e = slists.end(); i != e; ++i)
|
||||||
|
{
|
||||||
|
curl_slist * slist = *i;
|
||||||
|
if (slist)
|
||||||
|
{
|
||||||
|
curl_slist_free_all(slist);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destructor(v8::Persistent<v8::Value> object, void *data)
|
static void destructor(v8::Persistent<v8::Value> value, void *data)
|
||||||
{
|
{
|
||||||
NodeCurl * curl = (NodeCurl*)object->ToObject()->GetPointerFromInternalField(0);
|
v8::Handle<v8::Object> object = value->ToObject();
|
||||||
delete curl;
|
NodeCurl * curl = (NodeCurl*)object->GetPointerFromInternalField(0);
|
||||||
|
curl->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void close()
|
void close()
|
||||||
|
@ -68,6 +89,15 @@ class NodeCurl
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> close(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
NodeCurl * node_curl = unwrap(args.This());
|
||||||
|
if (node_curl)
|
||||||
|
node_curl->close();
|
||||||
|
return args.This();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static NodeCurl * unwrap(v8::Handle<v8::Object> value)
|
static NodeCurl * unwrap(v8::Handle<v8::Object> value)
|
||||||
{
|
{
|
||||||
return (NodeCurl*)value->GetPointerFromInternalField(0);
|
return (NodeCurl*)value->GetPointerFromInternalField(0);
|
||||||
|
@ -82,12 +112,11 @@ class NodeCurl
|
||||||
|
|
||||||
size_t on_write(char *data, size_t n)
|
size_t on_write(char *data, size_t n)
|
||||||
{
|
{
|
||||||
v8::HandleScope scope;
|
static v8::Persistent<v8::String> SYM_ON_WRITE = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_write"));
|
||||||
static auto SYM_ON_WRITE = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_write"));
|
v8::Handle<v8::Value> cb = handle->Get(SYM_ON_WRITE);
|
||||||
auto cb = handle->Get(SYM_ON_WRITE);
|
|
||||||
if (cb->IsFunction())
|
if (cb->IsFunction())
|
||||||
{
|
{
|
||||||
auto buffer = node::Buffer::New(data, n);
|
node::Buffer * buffer = node::Buffer::New(data, n);
|
||||||
v8::Handle<v8::Value> argv[] = { buffer->handle_ };
|
v8::Handle<v8::Value> argv[] = { buffer->handle_ };
|
||||||
cb->ToObject()->CallAsFunction(handle, 1, argv);
|
cb->ToObject()->CallAsFunction(handle, 1, argv);
|
||||||
}
|
}
|
||||||
|
@ -96,8 +125,8 @@ class NodeCurl
|
||||||
|
|
||||||
void on_end(CURLMsg *msg)
|
void on_end(CURLMsg *msg)
|
||||||
{
|
{
|
||||||
static auto SYM_ON_END = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_end"));
|
static v8::Persistent<v8::String> SYM_ON_END = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_end"));
|
||||||
auto cb = handle->Get(SYM_ON_END);
|
v8::Handle<v8::Value> cb = handle->Get(SYM_ON_END);
|
||||||
if (cb->IsFunction())
|
if (cb->IsFunction())
|
||||||
{
|
{
|
||||||
v8::Handle<v8::Value> argv[] = {};
|
v8::Handle<v8::Value> argv[] = {};
|
||||||
|
@ -107,8 +136,8 @@ class NodeCurl
|
||||||
|
|
||||||
void on_error(CURLMsg *msg)
|
void on_error(CURLMsg *msg)
|
||||||
{
|
{
|
||||||
static auto SYM_ON_ERROR = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_error"));
|
static v8::Persistent<v8::String> SYM_ON_ERROR = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_error"));
|
||||||
auto cb = handle->Get(SYM_ON_ERROR);
|
v8::Handle<v8::Value> cb = handle->Get(SYM_ON_ERROR);
|
||||||
if (cb->IsFunction())
|
if (cb->IsFunction())
|
||||||
{
|
{
|
||||||
v8::Handle<v8::Value> argv[] = {v8::Exception::Error(v8::String::New(curl_easy_strerror(msg->data.result)))};
|
v8::Handle<v8::Value> argv[] = {v8::Exception::Error(v8::String::New(curl_easy_strerror(msg->data.result)))};
|
||||||
|
@ -117,10 +146,10 @@ class NodeCurl
|
||||||
}
|
}
|
||||||
|
|
||||||
// curl_easy_getinfo
|
// curl_easy_getinfo
|
||||||
template<typename T, typename S>
|
template<typename CType, typename JsClass>
|
||||||
static v8::Handle<v8::Value> getinfo(const v8::Arguments &args)
|
static v8::Handle<v8::Value> getinfo(const v8::Arguments &args)
|
||||||
{
|
{
|
||||||
T result;
|
CType result;
|
||||||
NodeCurl * node_curl = unwrap(args.This());
|
NodeCurl * node_curl = unwrap(args.This());
|
||||||
CURLINFO info = (CURLINFO)args[0]->Int32Value();
|
CURLINFO info = (CURLINFO)args[0]->Int32Value();
|
||||||
CURLcode code = curl_easy_getinfo(node_curl->curl, info, &result);
|
CURLcode code = curl_easy_getinfo(node_curl->curl, info, &result);
|
||||||
|
@ -128,7 +157,7 @@ class NodeCurl
|
||||||
{
|
{
|
||||||
return raise("curl_easy_getinfo failed", curl_easy_strerror(code));
|
return raise("curl_easy_getinfo failed", curl_easy_strerror(code));
|
||||||
}
|
}
|
||||||
return S::New(result);
|
return JsClass::New(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static v8::Handle<v8::Value> getinfo_int(const v8::Arguments & args)
|
static v8::Handle<v8::Value> getinfo_int(const v8::Arguments & args)
|
||||||
|
@ -146,6 +175,30 @@ class NodeCurl
|
||||||
return getinfo<double, v8::Number>(args);
|
return getinfo<double, v8::Number>(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> getinfo_slist(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
curl_slist * slist, * cur;
|
||||||
|
NodeCurl* node_curl = unwrap(args.This());
|
||||||
|
CURLINFO info = (CURLINFO)args[0]->Int32Value();
|
||||||
|
CURLcode code = curl_easy_getinfo(node_curl->curl, info, &slist);
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
return raise("curl_easy_getinfo failed", curl_easy_strerror(code));
|
||||||
|
}
|
||||||
|
v8::Handle<v8::Array> array = v8::Array::New();
|
||||||
|
if (slist)
|
||||||
|
{
|
||||||
|
cur = slist;
|
||||||
|
while (cur)
|
||||||
|
{
|
||||||
|
array->Set(array->Length(), v8::String::New(slist->data));
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
curl_slist_free_all(slist);
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
// curl_easy_setopt
|
// curl_easy_setopt
|
||||||
template<typename T>
|
template<typename T>
|
||||||
v8::Handle<v8::Value> setopt(v8::Handle<v8::Value> option, T value)
|
v8::Handle<v8::Value> setopt(v8::Handle<v8::Value> option, T value)
|
||||||
|
@ -169,6 +222,32 @@ class NodeCurl
|
||||||
return unwrap(args.This())->setopt(args[0], *v8::String::Utf8Value(args[1]) );
|
return unwrap(args.This())->setopt(args[0], *v8::String::Utf8Value(args[1]) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> setopt_slist(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
NodeCurl * node_curl = unwrap(args.This());
|
||||||
|
curl_slist * slist = value_to_slist(args[1]);
|
||||||
|
node_curl->slists.push_back(slist);
|
||||||
|
return node_curl->setopt(args[0], slist);
|
||||||
|
}
|
||||||
|
|
||||||
|
static curl_slist * value_to_slist(v8::Handle<v8::Value> value)
|
||||||
|
{
|
||||||
|
curl_slist * slist = NULL;
|
||||||
|
if (!value->IsArray())
|
||||||
|
{
|
||||||
|
slist = curl_slist_append(slist, *v8::String::Utf8Value(value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
|
||||||
|
for (uint32_t i=0, len = array->Length(); i<len; ++i)
|
||||||
|
{
|
||||||
|
slist = curl_slist_append(slist, *v8::String::Utf8Value(array->Get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return slist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static v8::Handle<v8::Value> raise(const char *data, const char *reason = NULL)
|
static v8::Handle<v8::Value> raise(const char *data, const char *reason = NULL)
|
||||||
{
|
{
|
||||||
|
@ -185,10 +264,10 @@ class NodeCurl
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void export_curl_options(T t, const char *group_name, CurlOption *options, int len)
|
static void export_curl_options(T t, const char *group_name, CurlOption *options, int len)
|
||||||
{
|
{
|
||||||
auto node_options = v8::Object::New();
|
v8::Handle<v8::Object> node_options = v8::Object::New();
|
||||||
for (int i=0; i<len; ++i)
|
for (int i=0; i<len; ++i)
|
||||||
{
|
{
|
||||||
const auto & option = options[i];
|
const CurlOption & option = options[i];
|
||||||
node_options->Set(
|
node_options->Set(
|
||||||
v8::String::NewSymbol(option.name),
|
v8::String::NewSymbol(option.name),
|
||||||
v8::Integer::New(option.value)
|
v8::Integer::New(option.value)
|
||||||
|
@ -223,12 +302,10 @@ class NodeCurl
|
||||||
{
|
{
|
||||||
return raise("curl_multi_fdset failed", curl_multi_strerror(code));
|
return raise("curl_multi_fdset failed", curl_multi_strerror(code));
|
||||||
}
|
}
|
||||||
printf("maxfd returns %d\n", max_fd);
|
|
||||||
if (max_fd > 0)
|
if (max_fd > 0)
|
||||||
{
|
{
|
||||||
timeval tv = {0};
|
timeval tv = {0};
|
||||||
int n = select(max_fd+1, &read_fds, &write_fds, &error_fds, &tv);
|
int n = select(max_fd+1, &read_fds, &write_fds, &error_fds, &tv);
|
||||||
printf("selecting returns %d\n", n);
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
return v8::Integer::New(running_handles);
|
return v8::Integer::New(running_handles);
|
||||||
|
@ -249,21 +326,20 @@ class NodeCurl
|
||||||
CURLMsg * msg = NULL;
|
CURLMsg * msg = NULL;
|
||||||
while ( (msg = curl_multi_info_read(curlm, &msgs)) )
|
while ( (msg = curl_multi_info_read(curlm, &msgs)) )
|
||||||
{
|
{
|
||||||
printf("msgs: %d, running_handles: %d\n", msgs, running_handles);
|
|
||||||
if (msg->msg == CURLMSG_DONE)
|
if (msg->msg == CURLMSG_DONE)
|
||||||
{
|
{
|
||||||
auto curl = curls[msg->easy_handle];
|
NodeCurl * curl = curls[msg->easy_handle];
|
||||||
if (msg->data.result == CURLE_OK)
|
if (msg->data.result == CURLE_OK)
|
||||||
curl->on_end(msg);
|
curl->on_end(msg);
|
||||||
else
|
else
|
||||||
curl->on_error(msg);
|
curl->on_error(msg);
|
||||||
code = curl_multi_remove_handle(curlm, msg->easy_handle);
|
code = curl_multi_remove_handle(curlm, msg->easy_handle);
|
||||||
|
curl->in_curlm = false;
|
||||||
if (code != CURLM_OK)
|
if (code != CURLM_OK)
|
||||||
{
|
{
|
||||||
return raise("curl_multi_remove_handle failed", curl_multi_strerror(code));
|
return raise("curl_multi_remove_handle failed", curl_multi_strerror(code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
puts("done.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v8::Integer::New(running_handles);
|
return v8::Integer::New(running_handles);
|
||||||
|
@ -274,6 +350,7 @@ class NodeCurl
|
||||||
{
|
{
|
||||||
NodeCurl *curl = unwrap(args.This());
|
NodeCurl *curl = unwrap(args.This());
|
||||||
CURLMcode code = curl_multi_add_handle(curlm, curl->curl);
|
CURLMcode code = curl_multi_add_handle(curlm, curl->curl);
|
||||||
|
curl->in_curlm = true;
|
||||||
if (code != CURLM_OK)
|
if (code != CURLM_OK)
|
||||||
{
|
{
|
||||||
return raise("curl_multi_add_handle failed", curl_multi_strerror(code));
|
return raise("curl_multi_add_handle failed", curl_multi_strerror(code));
|
||||||
|
@ -282,6 +359,11 @@ class NodeCurl
|
||||||
return args.This();
|
return args.This();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> get_count(const v8::Arguments & args )
|
||||||
|
{
|
||||||
|
return v8::Integer::New(count);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static v8::Handle<v8::Value> Initialize(v8::Handle<v8::Object> target)
|
static v8::Handle<v8::Value> Initialize(v8::Handle<v8::Object> target)
|
||||||
{
|
{
|
||||||
|
@ -299,19 +381,24 @@ class NodeCurl
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize node-curl
|
// Initialize node-curl
|
||||||
auto t = v8::FunctionTemplate::New(New);
|
v8::Handle<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New);
|
||||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
|
|
||||||
// Set prototype methods
|
// Set prototype methods
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "perform_", perform);
|
NODE_SET_PROTOTYPE_METHOD(t, "perform_", perform);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "setopt_int_", setopt_int);
|
NODE_SET_PROTOTYPE_METHOD(t, "setopt_int_", setopt_int);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "setopt_str_", setopt_str);
|
NODE_SET_PROTOTYPE_METHOD(t, "setopt_str_", setopt_str);
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "setopt_slist_", setopt_slist);
|
||||||
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_int_", getinfo_int);
|
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_int_", getinfo_int);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_str_", getinfo_str);
|
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_str_", getinfo_str);
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_double_", getinfo_double);
|
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_double_", getinfo_double);
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_slist_", getinfo_slist);
|
||||||
|
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "close", close);
|
||||||
|
|
||||||
NODE_SET_METHOD(t, "process_", process);
|
NODE_SET_METHOD(t, "process_", process);
|
||||||
|
NODE_SET_METHOD(t, "get_count", get_count);
|
||||||
|
|
||||||
// Set curl constants
|
// Set curl constants
|
||||||
#include "string_options.h"
|
#include "string_options.h"
|
||||||
|
@ -320,11 +407,34 @@ class NodeCurl
|
||||||
#include "integer_infos.h"
|
#include "integer_infos.h"
|
||||||
#include "double_infos.h"
|
#include "double_infos.h"
|
||||||
|
|
||||||
|
#define X(name) {#name, CURLOPT_##name}
|
||||||
|
CurlOption slist_options[] = {
|
||||||
|
X(HTTPHEADER),
|
||||||
|
X(HTTP200ALIASES),
|
||||||
|
X(MAIL_RCPT),
|
||||||
|
X(QUOTE),
|
||||||
|
X(POSTQUOTE),
|
||||||
|
X(PREQUOTE),
|
||||||
|
X(RESOLVE),
|
||||||
|
X(TELNETOPTIONS)
|
||||||
|
};
|
||||||
|
#undef X
|
||||||
|
|
||||||
|
#define X(name) {#name, CURLINFO_##name}
|
||||||
|
CurlOption slist_infos[] = {
|
||||||
|
X(SSL_ENGINES),
|
||||||
|
X(COOKIELIST)
|
||||||
|
};
|
||||||
|
#undef X
|
||||||
|
|
||||||
NODE_CURL_EXPORT(string_options);
|
NODE_CURL_EXPORT(string_options);
|
||||||
NODE_CURL_EXPORT(integer_options);
|
NODE_CURL_EXPORT(integer_options);
|
||||||
|
NODE_CURL_EXPORT(slist_options);
|
||||||
|
|
||||||
NODE_CURL_EXPORT(string_infos);
|
NODE_CURL_EXPORT(string_infos);
|
||||||
NODE_CURL_EXPORT(integer_infos);
|
NODE_CURL_EXPORT(integer_infos);
|
||||||
NODE_CURL_EXPORT(double_infos);
|
NODE_CURL_EXPORT(double_infos);
|
||||||
|
NODE_CURL_EXPORT(slist_infos);
|
||||||
|
|
||||||
target->Set(v8::String::NewSymbol("Curl"), t->GetFunction());
|
target->Set(v8::String::NewSymbol("Curl"), t->GetFunction());
|
||||||
return target;
|
return target;
|
||||||
|
@ -335,5 +445,6 @@ CURLM * NodeCurl::curlm = NULL;
|
||||||
int NodeCurl::running_handles = 0;
|
int NodeCurl::running_handles = 0;
|
||||||
bool NodeCurl::is_ref = false;
|
bool NodeCurl::is_ref = false;
|
||||||
std::map< CURL*, NodeCurl* > NodeCurl::curls;
|
std::map< CURL*, NodeCurl* > NodeCurl::curls;
|
||||||
|
int NodeCurl::count = 0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2
wscript
2
wscript
|
@ -4,7 +4,7 @@ def set_options(opt):
|
||||||
def configure(conf):
|
def configure(conf):
|
||||||
conf.check_tool('compiler_cxx')
|
conf.check_tool('compiler_cxx')
|
||||||
conf.check_tool('node_addon')
|
conf.check_tool('node_addon')
|
||||||
conf.env.append_unique('CXXFLAGS', ['-Wall', '-O2', '-std=c++0x'])
|
conf.env.append_unique('CXXFLAGS', ['-Wall', '-O2'])
|
||||||
conf.env['LIB_CURL'] = 'curl'
|
conf.env['LIB_CURL'] = 'curl'
|
||||||
|
|
||||||
def build(bld):
|
def build(bld):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue