first commit
This commit is contained in:
commit
f8f934a119
18 changed files with 901 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
raw
|
||||||
|
build
|
2
.npmignore
Normal file
2
.npmignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
raw
|
||||||
|
build
|
36
README.md
Normal file
36
README.md
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
Node Curl Wrap
|
||||||
|
Use select curl multi
|
||||||
|
|
||||||
|
Quick Start
|
||||||
|
===========
|
||||||
|
|
||||||
|
curl = require('node-curl')
|
||||||
|
curl('www.google.com', {VERBOSE: 1}, function(err, res) {
|
||||||
|
console.info(res.status)
|
||||||
|
console.info('-----')
|
||||||
|
console.info(res.body)
|
||||||
|
console.info('-----')
|
||||||
|
console.info(res.info('SIZE_DOWNLOAD'))
|
||||||
|
});
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
Function: curl
|
||||||
|
curl(url, [options = {}], callback)
|
||||||
|
callback includes 2 parameters (error, result)
|
||||||
|
|
||||||
|
Curl Options:
|
||||||
|
options is on the list at http://curl.haxx.se/libcurl/c/curl_easy_setopt.html without CURLOPT_
|
||||||
|
eg: CURLOPT_VERBOSE will be VERBOSE, CURLOPT_HEADER will be HEADER
|
||||||
|
|
||||||
|
Object: result
|
||||||
|
body
|
||||||
|
status
|
||||||
|
info
|
||||||
|
|
||||||
|
Curl Infos:
|
||||||
|
infos is on the list at http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html without CURLINFO_
|
||||||
|
eg: CURLINFO_EFFECTIVE_URL will be EFFETCTIVE_URL
|
||||||
|
|
||||||
|
|
19
examples/quick-start.js
Normal file
19
examples/quick-start.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
curl = require('../index');
|
||||||
|
url = 'www.yahoo.com';
|
||||||
|
curl(url, function(err, res) {
|
||||||
|
console.info("body length: " + res.body.length);
|
||||||
|
console.info('-----');
|
||||||
|
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) {
|
||||||
|
console.info("body length: " + res.body.length);
|
||||||
|
console.info('-----');
|
||||||
|
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");
|
||||||
|
});
|
6
index.js
Normal file
6
index.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// Generated by CoffeeScript 1.1.4-3
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
module.exports = require('./lib/curl');
|
||||||
|
|
||||||
|
}).call(this);
|
1
index.toffee
Normal file
1
index.toffee
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require './lib/curl'
|
120
lib/curl.js
Normal file
120
lib/curl.js
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
// Generated by CoffeeScript 1.1.4-3
|
||||||
|
(function() {
|
||||||
|
var Curl, curl, curl_id,
|
||||||
|
__slice = [].slice,
|
||||||
|
__hasProp = {}.hasOwnProperty;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Curl = require(__dirname + '/../build/Release/node-curl').Curl;
|
||||||
|
} catch (e) {
|
||||||
|
Curl = require(__dirname + '/../build/default/node-curl').Curl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Curl.prototype.setopt = function(ooption, value) {
|
||||||
|
var option, option_id;
|
||||||
|
option = ooption.toUpperCase();
|
||||||
|
if ((option_id = Curl.integer_options[option]) != null) {
|
||||||
|
return this.setopt_int_(option_id, value >> 0);
|
||||||
|
} else if ((option_id = Curl.string_options[option]) != null) {
|
||||||
|
return this.setopt_str_(option_id, value.toString());
|
||||||
|
} else {
|
||||||
|
throw new Error("unsupported option " + option);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Curl.prototype.getinfo = function(oinfo) {
|
||||||
|
var info, info_id;
|
||||||
|
info = oinfo.toUpperCase();
|
||||||
|
if ((info_id = Curl.integer_infos[info]) != null) {
|
||||||
|
return this.getinfo_int_(info_id);
|
||||||
|
} else if ((info_id = Curl.string_infos[info]) != null) {
|
||||||
|
return this.getinfo_str_(info_id);
|
||||||
|
} else if ((info_id = Curl.double_infos[info]) != null) {
|
||||||
|
return this.getinfo_double_(info_id);
|
||||||
|
} else {
|
||||||
|
throw new Error("unsupproted info " + oinfo);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Curl.prototype.perform = function() {
|
||||||
|
this.perform_();
|
||||||
|
return Curl.process();
|
||||||
|
};
|
||||||
|
|
||||||
|
Curl.process = function() {
|
||||||
|
var once;
|
||||||
|
if (Curl.in_process) return;
|
||||||
|
return (once = function() {
|
||||||
|
var num;
|
||||||
|
num = Curl.process_();
|
||||||
|
if (num > 0) {
|
||||||
|
Curl.in_process = true;
|
||||||
|
return setTimeout(once, 80);
|
||||||
|
} else {
|
||||||
|
return Curl.in_process = false;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
curl_id = 0;
|
||||||
|
|
||||||
|
curl = function() {
|
||||||
|
var args, c, cb, chunks, k, length, options, res, url, v;
|
||||||
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
||||||
|
cb = args.pop();
|
||||||
|
url = args[0], options = args[1];
|
||||||
|
if (options == null) options = {};
|
||||||
|
c = new Curl();
|
||||||
|
c.id = ++curl_id;
|
||||||
|
c.setopt('FOLLOWLOCATION', 1);
|
||||||
|
c.setopt('ACCEPT_ENCODING', 'gzip');
|
||||||
|
chunks = [];
|
||||||
|
length = 0;
|
||||||
|
res = {};
|
||||||
|
for (k in options) {
|
||||||
|
if (!__hasProp.call(options, k)) continue;
|
||||||
|
v = options[k];
|
||||||
|
c.setopt(k, v);
|
||||||
|
}
|
||||||
|
c.on_write = function(chunk) {
|
||||||
|
chunks.push(chunk);
|
||||||
|
length += chunk.length;
|
||||||
|
return console.info("on_write " + c.id + " " + chunk.length);
|
||||||
|
};
|
||||||
|
c.on_end = function() {
|
||||||
|
var chunk, data, i, position, st, _i, _len;
|
||||||
|
data = new Buffer(length);
|
||||||
|
position = 0;
|
||||||
|
for (_i = 0, _len = chunks.length; _i < _len; _i++) {
|
||||||
|
chunk = chunks[_i];
|
||||||
|
chunk.copy(data, position);
|
||||||
|
position += chunk.length;
|
||||||
|
}
|
||||||
|
st = Date.now();
|
||||||
|
i = 0;
|
||||||
|
while (Date.now() - st < 500) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
res.body = data;
|
||||||
|
res.status = res.code = c.getinfo('RESPONSE_CODE');
|
||||||
|
res.info = function(info) {
|
||||||
|
return c.getinfo(info);
|
||||||
|
};
|
||||||
|
console.info("id: " + c.id);
|
||||||
|
return cb(null, res);
|
||||||
|
};
|
||||||
|
c.on_error = function(err) {
|
||||||
|
var _this = this;
|
||||||
|
return process.nextTick(function() {
|
||||||
|
return cb(err, null);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
c.setopt('URL', url);
|
||||||
|
return c.perform();
|
||||||
|
};
|
||||||
|
|
||||||
|
curl.Curl = Curl;
|
||||||
|
|
||||||
|
module.exports = curl;
|
||||||
|
|
||||||
|
}).call(this);
|
95
lib/curl.toffee
Normal file
95
lib/curl.toffee
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
try
|
||||||
|
{Curl} = require __dirname + '/../build/Release/node-curl'
|
||||||
|
catch e
|
||||||
|
{Curl} = require __dirname + '/../build/default/node-curl'
|
||||||
|
|
||||||
|
Curl::setopt = (ooption, value) ->
|
||||||
|
option = ooption.toUpperCase()
|
||||||
|
if (option_id = Curl.integer_options[option])?
|
||||||
|
@setopt_int_ option_id, value >> 0
|
||||||
|
else if (option_id = Curl.string_options[option])?
|
||||||
|
@setopt_str_ option_id, value.toString()
|
||||||
|
else
|
||||||
|
throw new Error("unsupported option #{option}")
|
||||||
|
|
||||||
|
Curl::getinfo = (oinfo) ->
|
||||||
|
info = oinfo.toUpperCase()
|
||||||
|
if (info_id = Curl.integer_infos[info])?
|
||||||
|
@getinfo_int_(info_id)
|
||||||
|
else if (info_id = Curl.string_infos[info])?
|
||||||
|
@getinfo_str_(info_id)
|
||||||
|
else if (info_id = Curl.double_infos[info])?
|
||||||
|
@getinfo_double_(info_id)
|
||||||
|
else
|
||||||
|
throw new Error("unsupproted info #{oinfo}")
|
||||||
|
|
||||||
|
Curl::perform = ->
|
||||||
|
@perform_()
|
||||||
|
Curl.process()
|
||||||
|
|
||||||
|
Curl.process = ->
|
||||||
|
if Curl.in_process
|
||||||
|
return
|
||||||
|
do once = ->
|
||||||
|
num = Curl.process_()
|
||||||
|
if num > 0
|
||||||
|
Curl.in_process = true
|
||||||
|
setTimeout once, 80
|
||||||
|
else
|
||||||
|
Curl.in_process = false
|
||||||
|
|
||||||
|
# url, [options], cb
|
||||||
|
curl_id = 0
|
||||||
|
curl = (args...) ->
|
||||||
|
cb = args.pop()
|
||||||
|
[url, options] = args
|
||||||
|
options ?= {}
|
||||||
|
|
||||||
|
c = new Curl()
|
||||||
|
c.id = ++curl_id
|
||||||
|
c.setopt 'FOLLOWLOCATION', 1
|
||||||
|
c.setopt 'ACCEPT_ENCODING', 'gzip'
|
||||||
|
chunks = []
|
||||||
|
length = 0
|
||||||
|
res = {}
|
||||||
|
|
||||||
|
for own k, v of options
|
||||||
|
c.setopt k, v
|
||||||
|
|
||||||
|
c.on_write = (chunk) ->
|
||||||
|
chunks.push chunk
|
||||||
|
length += chunk.length
|
||||||
|
console.info "on_write #{c.id} #{chunk.length}"
|
||||||
|
|
||||||
|
c.on_end = ->
|
||||||
|
data = new Buffer(length)
|
||||||
|
position = 0
|
||||||
|
for chunk in chunks
|
||||||
|
chunk.copy data, position
|
||||||
|
position += chunk.length
|
||||||
|
# Strange Issue
|
||||||
|
# use data.toString() will cause parallel http request terminated? eg yahoo.com
|
||||||
|
st = Date.now()
|
||||||
|
i = 0
|
||||||
|
while Date.now() - st < 500
|
||||||
|
++i
|
||||||
|
|
||||||
|
|
||||||
|
res.body = data #.toString()
|
||||||
|
res.status = res.code = c.getinfo('RESPONSE_CODE')
|
||||||
|
res.info = (info)->
|
||||||
|
c.getinfo(info)
|
||||||
|
# 当curl返回过快,且cb循环调用回导致堆栈溢出
|
||||||
|
# process.nextTick!
|
||||||
|
console.info "id: #{c.id}"
|
||||||
|
cb null, res
|
||||||
|
|
||||||
|
c.on_error = (err)->
|
||||||
|
process.nextTick!
|
||||||
|
cb err, null
|
||||||
|
|
||||||
|
c.setopt('URL', url)
|
||||||
|
c.perform()
|
||||||
|
|
||||||
|
curl.Curl = Curl
|
||||||
|
module.exports = curl
|
17
package.json
Normal file
17
package.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "node-curl",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "node wrapper for multi curl",
|
||||||
|
"keywords" : ["node-curl", "curl", "multi-curl", "mcurl"],
|
||||||
|
"homepage": "http://github.com/jiangmiao/node-curl",
|
||||||
|
"repository" : {
|
||||||
|
"type" : "git",
|
||||||
|
"url" : "git://github.com/jiangmiao/node-curl.git"
|
||||||
|
},
|
||||||
|
"author" : "Jiang Miao <jiangfriend@gmail.com>",
|
||||||
|
"main" : "./lib",
|
||||||
|
"scripts" : {
|
||||||
|
"install" : "node-waf configure build || true"
|
||||||
|
},
|
||||||
|
"engines" : { "node": ">= 0.6.0" }
|
||||||
|
}
|
16
src/double_infos.h
Normal file
16
src/double_infos.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// generated by generate_curl_options_list.sh at Mon, 13 Feb 2012 21:40:10 +0800
|
||||||
|
CurlOption double_infos[] = {
|
||||||
|
{"TOTAL_TIME", CURLINFO_TOTAL_TIME},
|
||||||
|
{"NAMELOOKUP_TIME", CURLINFO_NAMELOOKUP_TIME},
|
||||||
|
{"CONNECT_TIME", CURLINFO_CONNECT_TIME},
|
||||||
|
{"PRETRANSFER_TIME", CURLINFO_PRETRANSFER_TIME},
|
||||||
|
{"SIZE_UPLOAD", CURLINFO_SIZE_UPLOAD},
|
||||||
|
{"SIZE_DOWNLOAD", CURLINFO_SIZE_DOWNLOAD},
|
||||||
|
{"SPEED_DOWNLOAD", CURLINFO_SPEED_DOWNLOAD},
|
||||||
|
{"SPEED_UPLOAD", CURLINFO_SPEED_UPLOAD},
|
||||||
|
{"CONTENT_LENGTH_DOWNLOAD", CURLINFO_CONTENT_LENGTH_DOWNLOAD},
|
||||||
|
{"CONTENT_LENGTH_UPLOAD", CURLINFO_CONTENT_LENGTH_UPLOAD},
|
||||||
|
{"STARTTRANSFER_TIME", CURLINFO_STARTTRANSFER_TIME},
|
||||||
|
{"REDIRECT_TIME", CURLINFO_REDIRECT_TIME},
|
||||||
|
{"APPCONNECT_TIME", CURLINFO_APPCONNECT_TIME},
|
||||||
|
};
|
19
src/generate_curl_options_list.sh
Normal file
19
src/generate_curl_options_list.sh
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
generate() {
|
||||||
|
name=$1
|
||||||
|
pattern=$2
|
||||||
|
prefix=$3
|
||||||
|
(
|
||||||
|
echo "// generated by $0 at $(date -R)"
|
||||||
|
echo "CurlOption $name[] = {"
|
||||||
|
cat /usr/include/curl/curl.h|perl -ne "/$pattern/i && print \"\t{\\\"\$1\\\", CURL${prefix}_\$1},\n\""
|
||||||
|
echo '};'
|
||||||
|
) > $name.h
|
||||||
|
}
|
||||||
|
generate integer_options 'CINIT\((\w+).*LONG' OPT
|
||||||
|
generate string_options 'CINIT\((\w+).*OBJECT' OPT
|
||||||
|
|
||||||
|
generate integer_infos 'CURLINFO_(\w+).*LONG' INFO
|
||||||
|
generate string_infos 'CURLINFO_(\w+).*STRING' INFO
|
||||||
|
generate double_infos 'CURLINFO_(\w+).*DOUBLE' INFO
|
21
src/integer_infos.h
Normal file
21
src/integer_infos.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// generated by generate_curl_options_list.sh at Mon, 13 Feb 2012 21:40:10 +0800
|
||||||
|
CurlOption integer_infos[] = {
|
||||||
|
{"RESPONSE_CODE", CURLINFO_RESPONSE_CODE},
|
||||||
|
{"HEADER_SIZE", CURLINFO_HEADER_SIZE},
|
||||||
|
{"REQUEST_SIZE", CURLINFO_REQUEST_SIZE},
|
||||||
|
{"SSL_VERIFYRESULT", CURLINFO_SSL_VERIFYRESULT},
|
||||||
|
{"FILETIME", CURLINFO_FILETIME},
|
||||||
|
{"REDIRECT_COUNT", CURLINFO_REDIRECT_COUNT},
|
||||||
|
{"HTTP_CONNECTCODE", CURLINFO_HTTP_CONNECTCODE},
|
||||||
|
{"HTTPAUTH_AVAIL", CURLINFO_HTTPAUTH_AVAIL},
|
||||||
|
{"PROXYAUTH_AVAIL", CURLINFO_PROXYAUTH_AVAIL},
|
||||||
|
{"OS_ERRNO", CURLINFO_OS_ERRNO},
|
||||||
|
{"NUM_CONNECTS", CURLINFO_NUM_CONNECTS},
|
||||||
|
{"LASTSOCKET", CURLINFO_LASTSOCKET},
|
||||||
|
{"CONDITION_UNMET", CURLINFO_CONDITION_UNMET},
|
||||||
|
{"RTSP_CLIENT_CSEQ", CURLINFO_RTSP_CLIENT_CSEQ},
|
||||||
|
{"RTSP_SERVER_CSEQ", CURLINFO_RTSP_SERVER_CSEQ},
|
||||||
|
{"RTSP_CSEQ_RECV", CURLINFO_RTSP_CSEQ_RECV},
|
||||||
|
{"PRIMARY_PORT", CURLINFO_PRIMARY_PORT},
|
||||||
|
{"LOCAL_PORT", CURLINFO_LOCAL_PORT},
|
||||||
|
};
|
91
src/integer_options.h
Normal file
91
src/integer_options.h
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// generated by generate_curl_options_list.sh at Mon, 13 Feb 2012 21:40:10 +0800
|
||||||
|
CurlOption integer_options[] = {
|
||||||
|
{"PORT", CURLOPT_PORT},
|
||||||
|
{"TIMEOUT", CURLOPT_TIMEOUT},
|
||||||
|
{"INFILESIZE", CURLOPT_INFILESIZE},
|
||||||
|
{"LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT},
|
||||||
|
{"LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME},
|
||||||
|
{"RESUME_FROM", CURLOPT_RESUME_FROM},
|
||||||
|
{"CRLF", CURLOPT_CRLF},
|
||||||
|
{"SSLVERSION", CURLOPT_SSLVERSION},
|
||||||
|
{"TIMECONDITION", CURLOPT_TIMECONDITION},
|
||||||
|
{"TIMEVALUE", CURLOPT_TIMEVALUE},
|
||||||
|
{"VERBOSE", CURLOPT_VERBOSE},
|
||||||
|
{"HEADER", CURLOPT_HEADER},
|
||||||
|
{"NOPROGRESS", CURLOPT_NOPROGRESS},
|
||||||
|
{"NOBODY", CURLOPT_NOBODY},
|
||||||
|
{"FAILONERROR", CURLOPT_FAILONERROR},
|
||||||
|
{"UPLOAD", CURLOPT_UPLOAD},
|
||||||
|
{"POST", CURLOPT_POST},
|
||||||
|
{"DIRLISTONLY", CURLOPT_DIRLISTONLY},
|
||||||
|
{"APPEND", CURLOPT_APPEND},
|
||||||
|
{"NETRC", CURLOPT_NETRC},
|
||||||
|
{"FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION},
|
||||||
|
{"TRANSFERTEXT", CURLOPT_TRANSFERTEXT},
|
||||||
|
{"PUT", CURLOPT_PUT},
|
||||||
|
{"AUTOREFERER", CURLOPT_AUTOREFERER},
|
||||||
|
{"PROXYPORT", CURLOPT_PROXYPORT},
|
||||||
|
{"POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE},
|
||||||
|
{"HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL},
|
||||||
|
{"SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER},
|
||||||
|
{"MAXREDIRS", CURLOPT_MAXREDIRS},
|
||||||
|
{"FILETIME", CURLOPT_FILETIME},
|
||||||
|
{"MAXCONNECTS", CURLOPT_MAXCONNECTS},
|
||||||
|
{"CLOSEPOLICY", CURLOPT_CLOSEPOLICY},
|
||||||
|
{"FRESH_CONNECT", CURLOPT_FRESH_CONNECT},
|
||||||
|
{"FORBID_REUSE", CURLOPT_FORBID_REUSE},
|
||||||
|
{"CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT},
|
||||||
|
{"HTTPGET", CURLOPT_HTTPGET},
|
||||||
|
{"SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST},
|
||||||
|
{"HTTP_VERSION", CURLOPT_HTTP_VERSION},
|
||||||
|
{"FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV},
|
||||||
|
{"SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT},
|
||||||
|
{"DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE},
|
||||||
|
{"DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT},
|
||||||
|
{"COOKIESESSION", CURLOPT_COOKIESESSION},
|
||||||
|
{"BUFFERSIZE", CURLOPT_BUFFERSIZE},
|
||||||
|
{"NOSIGNAL", CURLOPT_NOSIGNAL},
|
||||||
|
{"PROXYTYPE", CURLOPT_PROXYTYPE},
|
||||||
|
{"UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH},
|
||||||
|
{"FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT},
|
||||||
|
{"HTTPAUTH", CURLOPT_HTTPAUTH},
|
||||||
|
{"FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS},
|
||||||
|
{"PROXYAUTH", CURLOPT_PROXYAUTH},
|
||||||
|
{"FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT},
|
||||||
|
{"IPRESOLVE", CURLOPT_IPRESOLVE},
|
||||||
|
{"MAXFILESIZE", CURLOPT_MAXFILESIZE},
|
||||||
|
{"USE_SSL", CURLOPT_USE_SSL},
|
||||||
|
{"TCP_NODELAY", CURLOPT_TCP_NODELAY},
|
||||||
|
{"FTPSSLAUTH", CURLOPT_FTPSSLAUTH},
|
||||||
|
{"IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH},
|
||||||
|
{"FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP},
|
||||||
|
{"FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD},
|
||||||
|
{"LOCALPORT", CURLOPT_LOCALPORT},
|
||||||
|
{"LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE},
|
||||||
|
{"CONNECT_ONLY", CURLOPT_CONNECT_ONLY},
|
||||||
|
{"SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE},
|
||||||
|
{"SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES},
|
||||||
|
{"FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC},
|
||||||
|
{"TIMEOUT_MS", CURLOPT_TIMEOUT_MS},
|
||||||
|
{"CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS},
|
||||||
|
{"HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING},
|
||||||
|
{"HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING},
|
||||||
|
{"NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS},
|
||||||
|
{"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS},
|
||||||
|
{"POSTREDIR", CURLOPT_POSTREDIR},
|
||||||
|
{"PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE},
|
||||||
|
{"ADDRESS_SCOPE", CURLOPT_ADDRESS_SCOPE},
|
||||||
|
{"CERTINFO", CURLOPT_CERTINFO},
|
||||||
|
{"TFTP_BLKSIZE", CURLOPT_TFTP_BLKSIZE},
|
||||||
|
{"SOCKS5_GSSAPI_NEC", CURLOPT_SOCKS5_GSSAPI_NEC},
|
||||||
|
{"PROTOCOLS", CURLOPT_PROTOCOLS},
|
||||||
|
{"REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS},
|
||||||
|
{"FTP_USE_PRET", CURLOPT_FTP_USE_PRET},
|
||||||
|
{"RTSP_REQUEST", CURLOPT_RTSP_REQUEST},
|
||||||
|
{"RTSP_CLIENT_CSEQ", CURLOPT_RTSP_CLIENT_CSEQ},
|
||||||
|
{"RTSP_SERVER_CSEQ", CURLOPT_RTSP_SERVER_CSEQ},
|
||||||
|
{"WILDCARDMATCH", CURLOPT_WILDCARDMATCH},
|
||||||
|
{"TRANSFER_ENCODING", CURLOPT_TRANSFER_ENCODING},
|
||||||
|
{"GSSAPI_DELEGATION", CURLOPT_GSSAPI_DELEGATION},
|
||||||
|
{"ACCEPTTIMEOUT_MS", CURLOPT_ACCEPTTIMEOUT_MS},
|
||||||
|
};
|
7
src/node-curl.cc
Normal file
7
src/node-curl.cc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include "node-curl.h"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void init(v8::Handle<v8::Object> target)
|
||||||
|
{
|
||||||
|
NodeCurl::Initialize(target);
|
||||||
|
}
|
339
src/node-curl.h
Normal file
339
src/node-curl.h
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
#ifndef NODE_CURL_NOHE_CURL_H
|
||||||
|
#define NODE_CURL_NOHE_CURL_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <v8.h>
|
||||||
|
#include <node.h>
|
||||||
|
#include <node_buffer.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#define NODE_CURL_OPTION_NX(name, value) {#name, value}
|
||||||
|
#define NODE_CURL_OPTION(name) NODE_CURL_OPTION_NX(name , CURLOPT_##name)
|
||||||
|
#define NODE_CURL_EXPORT(name) export_curl_options(t, #name, name, sizeof(name) / sizeof(CurlOption));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class NodeCurl
|
||||||
|
{
|
||||||
|
struct CurlOption {
|
||||||
|
const char *name;
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
static CURLM * curlm;
|
||||||
|
static int running_handles;
|
||||||
|
static bool is_ref;
|
||||||
|
static std::map< CURL*, NodeCurl* > curls;
|
||||||
|
|
||||||
|
CURL * curl;
|
||||||
|
v8::Persistent<v8::Object> handle;
|
||||||
|
NodeCurl(v8::Handle<v8::Object> object)
|
||||||
|
{
|
||||||
|
object->SetPointerInInternalField(0, this);
|
||||||
|
handle = v8::Persistent<v8::Object>::New(object);
|
||||||
|
handle.MakeWeak(this, destructor);
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if (!curl)
|
||||||
|
{
|
||||||
|
raise("curl_easy_init failed");
|
||||||
|
}
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
|
||||||
|
curls[curl] = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~NodeCurl()
|
||||||
|
{
|
||||||
|
if (curl)
|
||||||
|
{
|
||||||
|
curl_multi_remove_handle(curlm, curl);
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curls.erase(curl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destructor(v8::Persistent<v8::Value> object, void *data)
|
||||||
|
{
|
||||||
|
NodeCurl * curl = (NodeCurl*)object->ToObject()->GetPointerFromInternalField(0);
|
||||||
|
delete curl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
handle->SetPointerInInternalField(0, NULL);
|
||||||
|
handle.Dispose();
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NodeCurl * unwrap(v8::Handle<v8::Object> value)
|
||||||
|
{
|
||||||
|
return (NodeCurl*)value->GetPointerFromInternalField(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// curl write function mapping
|
||||||
|
static size_t write_function(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||||
|
{
|
||||||
|
NodeCurl *nodecurl = (NodeCurl*)userdata;
|
||||||
|
return nodecurl->on_write(ptr, size * nmemb);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t on_write(char *data, size_t n)
|
||||||
|
{
|
||||||
|
v8::HandleScope scope;
|
||||||
|
static auto SYM_ON_WRITE = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_write"));
|
||||||
|
auto cb = handle->Get(SYM_ON_WRITE);
|
||||||
|
if (cb->IsFunction())
|
||||||
|
{
|
||||||
|
auto buffer = node::Buffer::New(data, n);
|
||||||
|
v8::Handle<v8::Value> argv[] = { buffer->handle_ };
|
||||||
|
cb->ToObject()->CallAsFunction(handle, 1, argv);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_end(CURLMsg *msg)
|
||||||
|
{
|
||||||
|
static auto SYM_ON_END = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_end"));
|
||||||
|
auto cb = handle->Get(SYM_ON_END);
|
||||||
|
if (cb->IsFunction())
|
||||||
|
{
|
||||||
|
v8::Handle<v8::Value> argv[] = {};
|
||||||
|
cb->ToObject()->CallAsFunction(handle, 0, argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_error(CURLMsg *msg)
|
||||||
|
{
|
||||||
|
static auto SYM_ON_ERROR = v8::Persistent<v8::String>::New(v8::String::NewSymbol("on_error"));
|
||||||
|
auto cb = handle->Get(SYM_ON_ERROR);
|
||||||
|
if (cb->IsFunction())
|
||||||
|
{
|
||||||
|
v8::Handle<v8::Value> argv[] = {v8::Exception::Error(v8::String::New(curl_easy_strerror(msg->data.result)))};
|
||||||
|
cb->ToObject()->CallAsFunction(handle, 1, argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// curl_easy_getinfo
|
||||||
|
template<typename T, typename S>
|
||||||
|
static v8::Handle<v8::Value> getinfo(const v8::Arguments &args)
|
||||||
|
{
|
||||||
|
T result;
|
||||||
|
NodeCurl * node_curl = unwrap(args.This());
|
||||||
|
CURLINFO info = (CURLINFO)args[0]->Int32Value();
|
||||||
|
CURLcode code = curl_easy_getinfo(node_curl->curl, info, &result);
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
return raise("curl_easy_getinfo failed", curl_easy_strerror(code));
|
||||||
|
}
|
||||||
|
return S::New(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> getinfo_int(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
return getinfo<int, v8::Integer>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> getinfo_str(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
return getinfo<char*,v8::String>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> getinfo_double(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
return getinfo<double, v8::Number>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// curl_easy_setopt
|
||||||
|
template<typename T>
|
||||||
|
v8::Handle<v8::Value> setopt(v8::Handle<v8::Value> option, T value)
|
||||||
|
{
|
||||||
|
return v8::Integer::New(
|
||||||
|
curl_easy_setopt(
|
||||||
|
curl,
|
||||||
|
(CURLoption)option->Int32Value(),
|
||||||
|
value
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> setopt_int(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
return unwrap(args.This())->setopt(args[0], args[1]->Int32Value());
|
||||||
|
}
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> setopt_str(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
return unwrap(args.This())->setopt(args[0], *v8::String::Utf8Value(args[1]) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> raise(const char *data, const char *reason = NULL)
|
||||||
|
{
|
||||||
|
static char message[256];
|
||||||
|
const char *what = data;
|
||||||
|
if (reason)
|
||||||
|
{
|
||||||
|
snprintf(message, sizeof(message), "%s: %s", data, reason);
|
||||||
|
what = message;
|
||||||
|
}
|
||||||
|
return v8::ThrowException(v8::Exception::Error(v8::String::New(what)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void export_curl_options(T t, const char *group_name, CurlOption *options, int len)
|
||||||
|
{
|
||||||
|
auto node_options = v8::Object::New();
|
||||||
|
for (int i=0; i<len; ++i)
|
||||||
|
{
|
||||||
|
const auto & option = options[i];
|
||||||
|
node_options->Set(
|
||||||
|
v8::String::NewSymbol(option.name),
|
||||||
|
v8::Integer::New(option.value)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
t->Set(v8::String::NewSymbol(group_name), node_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// node js functions
|
||||||
|
static v8::Handle<v8::Value> New(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
new NodeCurl(args.This());
|
||||||
|
return args.This();
|
||||||
|
}
|
||||||
|
|
||||||
|
// int process()
|
||||||
|
static v8::Handle<v8::Value> process(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
if (running_handles > 0)
|
||||||
|
{
|
||||||
|
CURLMcode code;
|
||||||
|
int max_fd = FD_SETSIZE;
|
||||||
|
fd_set read_fds;
|
||||||
|
fd_set write_fds;
|
||||||
|
fd_set error_fds;
|
||||||
|
FD_ZERO(&read_fds);
|
||||||
|
FD_ZERO(&write_fds);
|
||||||
|
FD_ZERO(&error_fds);
|
||||||
|
// use select because of libuv didn't support sockfd well
|
||||||
|
code = curl_multi_fdset(curlm, &read_fds, &write_fds, &error_fds, &max_fd);
|
||||||
|
if (code != CURLM_OK)
|
||||||
|
{
|
||||||
|
return raise("curl_multi_fdset failed", curl_multi_strerror(code));
|
||||||
|
}
|
||||||
|
printf("maxfd returns %d\n", max_fd);
|
||||||
|
if (max_fd > 0)
|
||||||
|
{
|
||||||
|
timeval tv = {0};
|
||||||
|
int n = select(max_fd+1, &read_fds, &write_fds, &error_fds, &tv);
|
||||||
|
printf("selecting returns %d\n", n);
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return v8::Integer::New(running_handles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
code = curl_multi_perform(curlm, &running_handles);
|
||||||
|
} while ( code == CURLM_CALL_MULTI_PERFORM );
|
||||||
|
|
||||||
|
if (code != CURLM_OK)
|
||||||
|
{
|
||||||
|
return raise("curl_multi_perform failed", curl_multi_strerror(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
int msgs = 0;
|
||||||
|
CURLMsg * msg = NULL;
|
||||||
|
while ( (msg = curl_multi_info_read(curlm, &msgs)) )
|
||||||
|
{
|
||||||
|
printf("msgs: %d, running_handles: %d\n", msgs, running_handles);
|
||||||
|
if (msg->msg == CURLMSG_DONE)
|
||||||
|
{
|
||||||
|
auto curl = curls[msg->easy_handle];
|
||||||
|
if (msg->data.result == CURLE_OK)
|
||||||
|
curl->on_end(msg);
|
||||||
|
else
|
||||||
|
curl->on_error(msg);
|
||||||
|
code = curl_multi_remove_handle(curlm, msg->easy_handle);
|
||||||
|
if (code != CURLM_OK)
|
||||||
|
{
|
||||||
|
return raise("curl_multi_remove_handle failed", curl_multi_strerror(code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts("done.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v8::Integer::New(running_handles);
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform()
|
||||||
|
static v8::Handle<v8::Value> perform(const v8::Arguments & args)
|
||||||
|
{
|
||||||
|
NodeCurl *curl = unwrap(args.This());
|
||||||
|
CURLMcode code = curl_multi_add_handle(curlm, curl->curl);
|
||||||
|
if (code != CURLM_OK)
|
||||||
|
{
|
||||||
|
return raise("curl_multi_add_handle failed", curl_multi_strerror(code));
|
||||||
|
}
|
||||||
|
++running_handles;
|
||||||
|
return args.This();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static v8::Handle<v8::Value> Initialize(v8::Handle<v8::Object> target)
|
||||||
|
{
|
||||||
|
// Initialize curl
|
||||||
|
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
return raise("curl_global_init faield");
|
||||||
|
}
|
||||||
|
|
||||||
|
curlm = curl_multi_init();
|
||||||
|
if (curlm == NULL)
|
||||||
|
{
|
||||||
|
return raise("curl_multi_init failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize node-curl
|
||||||
|
auto t = v8::FunctionTemplate::New(New);
|
||||||
|
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
|
|
||||||
|
// Set prototype methods
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "perform_", perform);
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "setopt_int_", setopt_int);
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "setopt_str_", setopt_str);
|
||||||
|
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_int_", getinfo_int);
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_str_", getinfo_str);
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(t, "getinfo_double_", getinfo_double);
|
||||||
|
|
||||||
|
NODE_SET_METHOD(t, "process_", process);
|
||||||
|
|
||||||
|
// Set curl constants
|
||||||
|
#include "string_options.h"
|
||||||
|
#include "integer_options.h"
|
||||||
|
#include "string_infos.h"
|
||||||
|
#include "integer_infos.h"
|
||||||
|
#include "double_infos.h"
|
||||||
|
|
||||||
|
NODE_CURL_EXPORT(string_options);
|
||||||
|
NODE_CURL_EXPORT(integer_options);
|
||||||
|
NODE_CURL_EXPORT(string_infos);
|
||||||
|
NODE_CURL_EXPORT(integer_infos);
|
||||||
|
NODE_CURL_EXPORT(double_infos);
|
||||||
|
|
||||||
|
target->Set(v8::String::NewSymbol("Curl"), t->GetFunction());
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CURLM * NodeCurl::curlm = NULL;
|
||||||
|
int NodeCurl::running_handles = 0;
|
||||||
|
bool NodeCurl::is_ref = false;
|
||||||
|
std::map< CURL*, NodeCurl* > NodeCurl::curls;
|
||||||
|
|
||||||
|
#endif
|
11
src/string_infos.h
Normal file
11
src/string_infos.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// generated by generate_curl_options_list.sh at Mon, 13 Feb 2012 21:40:10 +0800
|
||||||
|
CurlOption string_infos[] = {
|
||||||
|
{"EFFECTIVE_URL", CURLINFO_EFFECTIVE_URL},
|
||||||
|
{"CONTENT_TYPE", CURLINFO_CONTENT_TYPE},
|
||||||
|
{"PRIVATE", CURLINFO_PRIVATE},
|
||||||
|
{"FTP_ENTRY_PATH", CURLINFO_FTP_ENTRY_PATH},
|
||||||
|
{"REDIRECT_URL", CURLINFO_REDIRECT_URL},
|
||||||
|
{"PRIMARY_IP", CURLINFO_PRIMARY_IP},
|
||||||
|
{"RTSP_SESSION_ID", CURLINFO_RTSP_SESSION_ID},
|
||||||
|
{"LOCAL_IP", CURLINFO_LOCAL_IP},
|
||||||
|
};
|
84
src/string_options.h
Normal file
84
src/string_options.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// generated by generate_curl_options_list.sh at Mon, 13 Feb 2012 21:40:10 +0800
|
||||||
|
CurlOption string_options[] = {
|
||||||
|
{"FILE", CURLOPT_FILE},
|
||||||
|
{"URL", CURLOPT_URL},
|
||||||
|
{"PROXY", CURLOPT_PROXY},
|
||||||
|
{"USERPWD", CURLOPT_USERPWD},
|
||||||
|
{"PROXYUSERPWD", CURLOPT_PROXYUSERPWD},
|
||||||
|
{"RANGE", CURLOPT_RANGE},
|
||||||
|
{"INFILE", CURLOPT_INFILE},
|
||||||
|
{"ERRORBUFFER", CURLOPT_ERRORBUFFER},
|
||||||
|
{"POSTFIELDS", CURLOPT_POSTFIELDS},
|
||||||
|
{"REFERER", CURLOPT_REFERER},
|
||||||
|
{"FTPPORT", CURLOPT_FTPPORT},
|
||||||
|
{"USERAGENT", CURLOPT_USERAGENT},
|
||||||
|
{"COOKIE", CURLOPT_COOKIE},
|
||||||
|
{"HTTPHEADER", CURLOPT_HTTPHEADER},
|
||||||
|
{"HTTPPOST", CURLOPT_HTTPPOST},
|
||||||
|
{"SSLCERT", CURLOPT_SSLCERT},
|
||||||
|
{"KEYPASSWD", CURLOPT_KEYPASSWD},
|
||||||
|
{"QUOTE", CURLOPT_QUOTE},
|
||||||
|
{"WRITEHEADER", CURLOPT_WRITEHEADER},
|
||||||
|
{"COOKIEFILE", CURLOPT_COOKIEFILE},
|
||||||
|
{"CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST},
|
||||||
|
{"STDERR", CURLOPT_STDERR},
|
||||||
|
{"POSTQUOTE", CURLOPT_POSTQUOTE},
|
||||||
|
{"WRITEINFO", CURLOPT_WRITEINFO},
|
||||||
|
{"PROGRESSDATA", CURLOPT_PROGRESSDATA},
|
||||||
|
{"INTERFACE", CURLOPT_INTERFACE},
|
||||||
|
{"KRBLEVEL", CURLOPT_KRBLEVEL},
|
||||||
|
{"CAINFO", CURLOPT_CAINFO},
|
||||||
|
{"TELNETOPTIONS", CURLOPT_TELNETOPTIONS},
|
||||||
|
{"RANDOM_FILE", CURLOPT_RANDOM_FILE},
|
||||||
|
{"EGDSOCKET", CURLOPT_EGDSOCKET},
|
||||||
|
{"COOKIEJAR", CURLOPT_COOKIEJAR},
|
||||||
|
{"SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST},
|
||||||
|
{"SSLCERTTYPE", CURLOPT_SSLCERTTYPE},
|
||||||
|
{"SSLKEY", CURLOPT_SSLKEY},
|
||||||
|
{"SSLKEYTYPE", CURLOPT_SSLKEYTYPE},
|
||||||
|
{"SSLENGINE", CURLOPT_SSLENGINE},
|
||||||
|
{"PREQUOTE", CURLOPT_PREQUOTE},
|
||||||
|
{"DEBUGDATA", CURLOPT_DEBUGDATA},
|
||||||
|
{"CAPATH", CURLOPT_CAPATH},
|
||||||
|
{"SHARE", CURLOPT_SHARE},
|
||||||
|
{"ACCEPT_ENCODING", CURLOPT_ACCEPT_ENCODING},
|
||||||
|
{"PRIVATE", CURLOPT_PRIVATE},
|
||||||
|
{"HTTP200ALIASES", CURLOPT_HTTP200ALIASES},
|
||||||
|
{"SSL_CTX_DATA", CURLOPT_SSL_CTX_DATA},
|
||||||
|
{"NETRC_FILE", CURLOPT_NETRC_FILE},
|
||||||
|
{"IOCTLDATA", CURLOPT_IOCTLDATA},
|
||||||
|
{"FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT},
|
||||||
|
{"COOKIELIST", CURLOPT_COOKIELIST},
|
||||||
|
{"FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER},
|
||||||
|
{"SOCKOPTDATA", CURLOPT_SOCKOPTDATA},
|
||||||
|
{"SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE},
|
||||||
|
{"SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE},
|
||||||
|
{"SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5},
|
||||||
|
{"OPENSOCKETDATA", CURLOPT_OPENSOCKETDATA},
|
||||||
|
{"COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS},
|
||||||
|
{"SEEKDATA", CURLOPT_SEEKDATA},
|
||||||
|
{"CRLFILE", CURLOPT_CRLFILE},
|
||||||
|
{"ISSUERCERT", CURLOPT_ISSUERCERT},
|
||||||
|
{"USERNAME", CURLOPT_USERNAME},
|
||||||
|
{"PASSWORD", CURLOPT_PASSWORD},
|
||||||
|
{"PROXYUSERNAME", CURLOPT_PROXYUSERNAME},
|
||||||
|
{"PROXYPASSWORD", CURLOPT_PROXYPASSWORD},
|
||||||
|
{"NOPROXY", CURLOPT_NOPROXY},
|
||||||
|
{"SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE},
|
||||||
|
{"SSH_KNOWNHOSTS", CURLOPT_SSH_KNOWNHOSTS},
|
||||||
|
{"SSH_KEYDATA", CURLOPT_SSH_KEYDATA},
|
||||||
|
{"MAIL_FROM", CURLOPT_MAIL_FROM},
|
||||||
|
{"MAIL_RCPT", CURLOPT_MAIL_RCPT},
|
||||||
|
{"RTSP_SESSION_ID", CURLOPT_RTSP_SESSION_ID},
|
||||||
|
{"RTSP_STREAM_URI", CURLOPT_RTSP_STREAM_URI},
|
||||||
|
{"RTSP_TRANSPORT", CURLOPT_RTSP_TRANSPORT},
|
||||||
|
{"INTERLEAVEDATA", CURLOPT_INTERLEAVEDATA},
|
||||||
|
{"CHUNK_DATA", CURLOPT_CHUNK_DATA},
|
||||||
|
{"FNMATCH_DATA", CURLOPT_FNMATCH_DATA},
|
||||||
|
{"RESOLVE", CURLOPT_RESOLVE},
|
||||||
|
{"TLSAUTH_USERNAME", CURLOPT_TLSAUTH_USERNAME},
|
||||||
|
{"TLSAUTH_PASSWORD", CURLOPT_TLSAUTH_PASSWORD},
|
||||||
|
{"TLSAUTH_TYPE", CURLOPT_TLSAUTH_TYPE},
|
||||||
|
{"CLOSESOCKETDATA", CURLOPT_CLOSESOCKETDATA},
|
||||||
|
{"DNS_SERVERS", CURLOPT_DNS_SERVERS},
|
||||||
|
};
|
15
wscript
Normal file
15
wscript
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
def set_options(opt):
|
||||||
|
opt.tool_options('compiler_cxx')
|
||||||
|
|
||||||
|
def configure(conf):
|
||||||
|
conf.check_tool('compiler_cxx')
|
||||||
|
conf.check_tool('node_addon')
|
||||||
|
conf.env.append_unique('CXXFLAGS', ['-Wall', '-O2', '-std=c++0x'])
|
||||||
|
conf.env['LIB_CURL'] = 'curl'
|
||||||
|
|
||||||
|
def build(bld):
|
||||||
|
obj = bld.new_task_gen('cxx', 'shlib', 'node_addon', uselib="CURL")
|
||||||
|
obj.target = 'node-curl'
|
||||||
|
obj.source = [
|
||||||
|
'src/node-curl.cc',
|
||||||
|
]
|
Loading…
Add table
Add a link
Reference in a new issue