From e7c9640ce195283929879282e1371f1345e81e14 Mon Sep 17 00:00:00 2001 From: Enrico Bianco Date: Sat, 14 May 2011 00:34:46 -0400 Subject: [PATCH] Support CURLOPT_IPRESOLVE with Curl::Easy#resolve_mode. :auto is CURL_IPRESOLVE_WHATEVER, :ipv4 is CURL_IPRESOLVE_V4, :ipv6 is CURL_IPRESOLVE_V6 --- ext/curb_easy.c | 63 +++++++++++++++++++++++++++++++++++++++++++ ext/curb_easy.h | 1 + ext/curb_macros.h | 1 + tests/tc_curl_easy.rb | 11 ++++++++ 4 files changed, 76 insertions(+) diff --git a/ext/curb_easy.c b/ext/curb_easy.c index 4976f9d1..4ac958cd 100644 --- a/ext/curb_easy.c +++ b/ext/curb_easy.c @@ -1570,6 +1570,65 @@ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) { CURB_BOOLEAN_GETTER(ruby_curl_easy, ignore_content_length); } +/* + * call-seq: + * easy.resolve_mode => symbol + * + * Determines what type of IP address this Curl::Easy instance + * resolves DNS names to. + */ +static VALUE ruby_curl_easy_resolve_mode(VALUE self) { + ruby_curl_easy *rbce; + Data_Get_Struct(self, ruby_curl_easy, rbce); + + unsigned short rm = rbce->resolve_mode; + + switch(rm) { + case CURL_IPRESOLVE_V4: + return rb_easy_sym("ipv4"); + case CURL_IPRESOLVE_V6: + return rb_easy_sym("ipv6"); + default: + return rb_easy_sym("auto"); + } +} + +/* + * call-seq: + * easy.resolve_mode = symbol => symbol + * + * Configures what type of IP address this Curl::Easy instance + * resolves DNS names to. Valid options are: + * + * [:auto] resolves DNS names to all IP versions your system allows + * [:ipv4] resolves DNS names to IPv4 only + * [:ipv6] resolves DNS names to IPv6 only + */ +static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) { + if (TYPE(resolve_mode) != T_SYMBOL) { + rb_raise(rb_eTypeError, "Must pass a symbol"); + return Qnil; + } else { + ruby_curl_easy *rbce; + Data_Get_Struct(self, ruby_curl_easy, rbce); + + ID resolve_mode_id = rb_to_id(resolve_mode); + + if (resolve_mode_id == rb_intern("auto")) { + rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER; + return resolve_mode; + } else if (resolve_mode_id == rb_intern("ipv4")) { + rbce->resolve_mode = CURL_IPRESOLVE_V4; + return resolve_mode; + } else if (resolve_mode_id == rb_intern("ipv6")) { + rbce->resolve_mode = CURL_IPRESOLVE_V6; + return resolve_mode; + } else { + rb_raise(rb_eArgError, "Must set to one of :auto, :ipv4, :ipv6"); + return Qnil; + } + } +} /* ================= EVENT PROCS ================== */ @@ -1877,6 +1936,8 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce ) { curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length); + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, rbce->resolve_mode); + #if LIBCURL_VERSION_NUM >= 0x070a08 curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, rbce->ftp_response_timeout); @@ -3193,6 +3254,8 @@ void init_curb_easy() { rb_define_method(cCurlEasy, "enable_cookies?", ruby_curl_easy_enable_cookies_q, 0); rb_define_method(cCurlEasy, "ignore_content_length=", ruby_curl_easy_ignore_content_length_set, 1); rb_define_method(cCurlEasy, "ignore_content_length?", ruby_curl_easy_ignore_content_length_q, 0); + rb_define_method(cCurlEasy, "resolve_mode", ruby_curl_easy_resolve_mode, 0); + rb_define_method(cCurlEasy, "resolve_mode=", ruby_curl_easy_resolve_mode_set, 1); rb_define_method(cCurlEasy, "on_body", ruby_curl_easy_on_body_set, -1); rb_define_method(cCurlEasy, "on_header", ruby_curl_easy_on_header_set, -1); diff --git a/ext/curb_easy.h b/ext/curb_easy.h index 97b931ca..97423474 100644 --- a/ext/curb_easy.h +++ b/ext/curb_easy.h @@ -56,6 +56,7 @@ typedef struct { long ssl_version; long use_ssl; long ftp_filemethod; + unsigned short resolve_mode; /* bool flags */ char proxy_tunnel; diff --git a/ext/curb_macros.h b/ext/curb_macros.h index 98333a9f..67f3f157 100644 --- a/ext/curb_macros.h +++ b/ext/curb_macros.h @@ -8,6 +8,7 @@ #ifndef __CURB_MACROS_H #define __CURB_MACROS_H +#define rb_easy_sym(sym) ID2SYM(rb_intern(sym)) #define rb_easy_hkey(key) ID2SYM(rb_intern(key)) #define rb_easy_set(key,val) rb_hash_aset(rbce->opts, rb_easy_hkey(key) , val) #define rb_easy_get(key) rb_hash_aref(rbce->opts, rb_easy_hkey(key)) diff --git a/tests/tc_curl_easy.rb b/tests/tc_curl_easy.rb index fcf8c878..47f55a1d 100644 --- a/tests/tc_curl_easy.rb +++ b/tests/tc_curl_easy.rb @@ -507,6 +507,17 @@ def test_ignore_content_length assert c.ignore_content_length? end + def test_resolve_mode + c = Curl::Easy.new + assert c.resolve_mode == :auto + c.resolve_mode = :ipv4 + assert c.resolve_mode == :ipv4 + c.resolve_mode = :ipv6 + assert c.resolve_mode == :ipv6 + + assert_raises(ArgumentError) { c.resolve_mode = :bad } + end + def test_enable_cookies c = Curl::Easy.new assert !c.enable_cookies?