Created
October 3, 2009 02:07
-
-
Save slyphon/200346 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
# gem 'ffi', '= 0.3.5' | |
require 'ffi' | |
require 'fileutils' | |
if defined?(JRUBY_VERSION) | |
jsys = java.lang.System | |
$stderr.puts "#{jsys.get_property('java.vm.name')} #{jsys.get_property('java.version')}" | |
end | |
module CurlFfi | |
module Easy | |
extend FFI::Library | |
class CurlFfiError < StandardError | |
end | |
COTYPE_LONG = 0 | |
COTYPE_OBJECTPOINT = 10_000 | |
COTYPE_FUNCTIONPOINT = 20_000 | |
COTYPE_OFF_T = 30_000 | |
# constants defined in curl.h | |
CURL_GLOBAL_SSL = (1 << 0) | |
CURL_GLOBAL_WIN32 = (1 << 1) | |
CURL_GLOBAL_ALL = (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) | |
CURL_GLOBAL_NOTHING = 0 | |
CURL_GLOBAL_DEFAULT = CURL_GLOBAL_ALL | |
# options | |
CURLOPT_FILE = COTYPE_OBJECTPOINT + 1 | |
CURLOPT_URL = COTYPE_OBJECTPOINT + 2 | |
CURLOPT_ERRORBUFFER = COTYPE_OBJECTPOINT + 10 | |
CURLOPT_WRITEFUNCTION = COTYPE_FUNCTIONPOINT + 11 | |
# status | |
CURLE_OK = 0 | |
ffi_lib "curl" | |
attach_function :_global_init, :curl_global_init, [:long], :int | |
attach_function :_init, :curl_easy_init, [], :pointer | |
attach_function :_cleanup, :curl_easy_cleanup, [:pointer], :void | |
attach_function :_setopt, :curl_easy_setopt, [:pointer, :int, :pointer], :int | |
attach_function :_setoptstr, :curl_easy_setopt, [:pointer, :int, :string], :int | |
attach_function :_setoptva, :curl_easy_setopt, [:pointer, :int, :varargs], :int | |
attach_function :_perform, :curl_easy_perform, [:pointer], :int | |
attach_function :_strerror, :curl_easy_strerror, [:int], :string | |
@@global_init_done = false unless defined?(@@global_init_done) | |
@@mutex = Mutex.new unless defined?(@@mutex) | |
attr_reader :url | |
def self.global_init! | |
@@mutex.synchronize do | |
return if @@global_init_done | |
@@global_init_done = true | |
_global_init(CURL_GLOBAL_DEFAULT) | |
end | |
end | |
class StdIO | |
extend FFI::Library | |
ffi_lib 'c' | |
attach_function :_fopen, :fopen, [:string, :string], :pointer | |
attach_function :_fdopen, :fdopen, [:int, :string], :pointer | |
attach_function :_fclose, :fclose, [:pointer], :int | |
attach_function :_fflush, :fflush, [:pointer], :int | |
attach_function :_strerror, :strerror, [:int], :string | |
attach_function :_printf, :printf, [:varargs], :int | |
class << self | |
def fopen(path, mode) | |
_fopen(path, mode) or raise_errno! | |
end | |
def fdopen(int, str) | |
_fdopen(int, str) or raise_errno! | |
end | |
def fclose(ptr) | |
raise_errno! unless _fclose(ptr) == 0 | |
end | |
def fflush(ptr) | |
raise_errno! unless _fflush(ptr) == 0 | |
end | |
private | |
def raise_errno! | |
raise SystemCallError.new(nil, FFI.errno) | |
end | |
end | |
end | |
class << self | |
def download(url, path) | |
fp = nil | |
handle = self._init | |
$stderr.puts "printing url from stdlib printf" | |
StdIO._printf(:string, url) | |
self._setoptstr(handle, CURLOPT_URL, url) | |
self._setopt(handle, CURLOPT_WRITEFUNCTION, nil) | |
fpointer = StdIO.fopen(path, 'w') | |
p fpointer | |
self._setopt(handle, CURLOPT_FILE, fpointer) | |
if (code = self._perform(handle)) > CURLE_OK | |
raise CurlFfiError, self._strerror(code) | |
end | |
StdIO.fflush(fpointer) | |
true | |
rescue Exception => e | |
FileUtils.rm_f(path) rescue nil | |
raise e | |
ensure | |
StdIO.fclose(fpointer) if fpointer | |
self._cleanup(handle) if handle | |
end | |
private | |
def raise_curl_errno! | |
raise CurlFfiError, self._strerror | |
end | |
end | |
end | |
end | |
def main | |
if ARGV.empty? | |
$stderr.puts "Usage: #{File.basename($0)} http://example.com/ /tmp/blah.out" | |
exit 1 | |
end | |
CurlFfi::Easy.global_init! | |
url = ARGV.first | |
outpath = ARGV[1] | |
CurlFfi::Easy.download(url, outpath) | |
end | |
main if __FILE__ == $0 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[20091003-02.14.14]$ jruby curlffi.rb http://www.google.com/ /tmp/blah.html | |
Java HotSpot(TM) 64-Bit Server VM 1.6.0_07 | |
printing url from stdlib printf | |
#<Pointer address=0x7fff700d0440> | |
curlffi.rb:119:in `download': couldn't resolve host name (CurlFfi::Easy::CurlFfiError) | |
from curlffi.rb:152:in `main' | |
from curlffi.rb:155 | |
http://www.google.com/ | |
[20091003-02.15.30]$ uname -a | |
Darwin hackett 9.6.0 Darwin Kernel Version 9.6.0: Mon Nov 24 17:37:00 PST 2008; root:xnu-1228.9.59~1/RELEASE_I386 i386 | |
slyphon@hackett:~ | |
[20091003-02.15.33]$ jruby --version | |
jruby 1.3.1 (ruby 1.8.6p287) (2009-09-21 6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java] | |
slyphon@hackett:~ | |
[20091003-02.16.15]$ $JAVA_HOME/bin/java -version | |
java version "1.6.0_07" | |
Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153) | |
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_07-b06-57, mixed mode) | |
slyphon@hackett:~ | |
[20091003-02.16.28]$ curl --version | |
curl 7.19.6 (i386-apple-darwin9.6.0) libcurl/7.19.6 OpenSSL/0.9.8k zlib/1.2.3 | |
Protocols: tftp ftp telnet dict http file https ftps | |
Features: Largefile NTLM SSL libz |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment