Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Ruby-ize code that doesn't need to be in C. #2

Merged
merged 6 commits into from

1 participant

John Ledbetter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 4, 2013
  1. move straight ruby code back out into ruby.

    John Ledbetter authored
  2. move response out of C into ruby.

    John Ledbetter authored
  3. pull options out of opts hash when constructing request.

    John Ledbetter authored
  4. move more request logic out into ruby.

    John Ledbetter authored
  5. remove unused SELF parameter.

    John Ledbetter authored
  6. add accessors, sort things alphabetically in case of OCD.

    John Ledbetter authored
This page is out of date. Refresh to see the latest.
195 ext/curly/request.c
View
@@ -4,19 +4,12 @@
#include "response.h"
#include "native.h"
-/* Request member functions */
-static VALUE request_get (int argc, VALUE* argv, VALUE self);
-static VALUE request_post (int argc, VALUE* argv, VALUE self);
-static VALUE request_put (int argc, VALUE* argv, VALUE self);
-static VALUE request_delete(int argc, VALUE* argv, VALUE self);
-
-static VALUE request_initialize(int argc, VALUE* argv, VALUE self);
static VALUE request_run(VALUE self);
/* internal helpers */
static VALUE request_alloc(VALUE self);
-static VALUE request_perform(VALUE self, CURL* c, VALUE url, VALUE opts);
-static struct curl_slist* request_build_headers(VALUE self, CURL* c, VALUE opts);
+static VALUE request_perform(VALUE self, CURL* c, VALUE url);
+static struct curl_slist* build_headers(CURL* c, VALUE headers);
static int request_add_header(VALUE key, VALUE val, VALUE in);
static VALUE build_query_string(VALUE params);
@@ -25,11 +18,6 @@ static size_t header_callback(void* buffer, size_t size, size_t count, void* sel
static size_t data_callback (void* buffer, size_t size, size_t count, void* self);
static struct {
- VALUE to_query;
- VALUE params;
- VALUE body;
- VALUE headers;
- VALUE timeout;
VALUE method;
VALUE get, post, put, delete;
} syms;
@@ -38,51 +26,23 @@ void Init_curly_request(VALUE curly_mod)
{
VALUE request = rb_define_class_under(curly_mod, "Request", rb_cObject);
- rb_define_singleton_method(request, "get", request_get, -1);
- rb_define_singleton_method(request, "post", request_post, -1);
- rb_define_singleton_method(request, "put", request_put, -1);
- rb_define_singleton_method(request, "delete", request_delete, -1);
-
- rb_define_method(request, "initialize", request_initialize, -1);
- rb_define_method(request, "run", request_run, 0);
+ rb_define_method(request, "run", request_run, 0);
- syms.to_query = ID2SYM(rb_intern("to_query"));
- syms.params = ID2SYM(rb_intern("params"));
- syms.body = ID2SYM(rb_intern("body"));
- syms.headers = ID2SYM(rb_intern("headers"));
- syms.timeout = ID2SYM(rb_intern("timeout"));
syms.method = ID2SYM(rb_intern("method"));
syms.get = ID2SYM(rb_intern("get"));
syms.post = ID2SYM(rb_intern("post"));
syms.put = ID2SYM(rb_intern("put"));
syms.delete = ID2SYM(rb_intern("delete"));
-
-}
-
-
-static VALUE request_initialize(int argc, VALUE* argv, VALUE self)
-{
- VALUE url, opts;
-
- rb_scan_args(argc, argv, "11", &url, &opts);
- opts = (opts == Qnil ? rb_hash_new() : opts);
-
- rb_iv_set(self, "@url", url);
- rb_iv_set(self, "@options", opts);
-
- return self;
}
static VALUE request_run(VALUE self)
{
VALUE url = rb_iv_get(self, "@url");
- VALUE opts = rb_iv_get(self, "@options");
- VALUE method = rb_hash_aref(opts, syms.method);
+ VALUE method = rb_iv_get(self, "@method");
CURL* c = curl_easy_init();
VALUE body, resp;
-
method = (method == Qnil ? syms.get : rb_funcall(method, rb_intern("to_sym"), 0));
if (method == syms.get) {
@@ -97,30 +57,18 @@ static VALUE request_run(VALUE self)
/* TODO: rb_raise_whatever */
}
- if ((body = rb_hash_aref(opts, syms.body)) != Qnil) {
+ if ((body = rb_iv_get(self, "@body")) != Qnil) {
/* TODO: handle case where `body` is a hash. */
curl_easy_setopt(c, CURLOPT_POSTFIELDS, RSTRING_PTR(StringValue(body)));
}
- resp = request_perform(self, c, url, opts);
+ resp = request_perform(self, c, url);
curl_easy_cleanup(c);
return resp;
}
-static VALUE request_new(VALUE url, VALUE opts)
-{
- VALUE args[2] = { url, opts };
-
- return rb_class_new_instance(2, args,
- rb_const_get(
- rb_const_get(rb_cObject, rb_intern("Curly")),
- rb_intern("Request")
- )
- );
-}
-
static VALUE curl_easy_perform_wrapper(void* args)
{
native_curly* n = (native_curly*)args;
@@ -130,7 +78,7 @@ static VALUE curl_easy_perform_wrapper(void* args)
return Qnil;
}
-static VALUE request_perform(VALUE self, CURL* c, VALUE url, VALUE opts)
+static VALUE request_perform(VALUE self, CURL* c, VALUE url)
{
long code;
VALUE timeout, params, headers;
@@ -146,21 +94,17 @@ static VALUE request_perform(VALUE self, CURL* c, VALUE url, VALUE opts)
curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, data_callback);
curl_easy_setopt(c, CURLOPT_WRITEDATA, &n);
- /* handle headers, query string, timeout, etc. */
- if (TYPE(opts) == T_HASH) {
-
- if ((headers = rb_hash_aref(opts, syms.headers)) != Qnil) {
- header_list = request_build_headers(self, c, headers);
- }
+ if ((headers = rb_iv_get(self, "@headers")) != Qnil) {
+ header_list = build_headers(c, headers);
+ }
- if ((params = rb_hash_aref(opts, syms.params)) != Qnil) {
- url = rb_str_plus(url, rb_str_new2("?"));
- url = rb_str_append(url, build_query_string(params));
- }
+ if ((params = rb_iv_get(self, "@params")) != Qnil) {
+ url = rb_str_plus(url, rb_str_new2("?"));
+ url = rb_str_append(url, build_query_string(params));
+ }
- if ((timeout = rb_hash_aref(opts, syms.timeout)) != Qnil) {
- curl_easy_setopt(c, CURLOPT_TIMEOUT_MS, NUM2LONG(timeout));
- }
+ if ((timeout = rb_iv_get(self, "@timeout")) != Qnil) {
+ curl_easy_setopt(c, CURLOPT_TIMEOUT_MS, NUM2LONG(timeout));
}
curl_easy_setopt(c, CURLOPT_URL, RSTRING_PTR(StringValue(url)));
@@ -170,6 +114,7 @@ static VALUE request_perform(VALUE self, CURL* c, VALUE url, VALUE opts)
rb_thread_blocking_region(curl_easy_perform_wrapper, &n, NULL, NULL);
rb_iv_set(resp, "@body", rb_str_new(n.body.value, n.body.length));
+ rb_iv_set(resp, "@head", rb_str_new(n.head.value, n.head.length));
rb_iv_set(resp, "@curl_code", INT2NUM(n.curl_rc));
if (n.curl_rc == CURLE_OK) {
@@ -185,94 +130,6 @@ static VALUE request_perform(VALUE self, CURL* c, VALUE url, VALUE opts)
return resp;
}
-/*
- * call-seq:
- * Request.get(url, options = {}) -> Response
- *
- * Issues a HTTP GET to the specified +url+ using the provided
- * +options+.
- *
- */
-static VALUE request_get(int argc, VALUE* argv, VALUE self)
-{
- VALUE req, url, opts;
-
- rb_scan_args(argc, argv, "11", &url, &opts);
- opts = (opts == Qnil ? rb_hash_new() : opts);
-
- rb_hash_aset(opts, syms.method, syms.get);
-
- req = request_new(url, opts);
-
- return rb_funcall(req, rb_intern("run"), 0);
-}
-
-/*
- * call-seq:
- * Request.post(url, options = {}) -> Response
- *
- * Issues a HTTP POST to the specified +url+ using the provided
- * +options+.
- *
- */
-static VALUE request_post(int argc, VALUE* argv, VALUE self)
-{
- VALUE req, url, opts;
-
- rb_scan_args(argc, argv, "11", &url, &opts);
- opts = (opts == Qnil ? rb_hash_new() : opts);
-
- rb_hash_aset(opts, syms.method, syms.post);
-
- req = request_new(url, opts);
-
- return rb_funcall(req, rb_intern("run"), 0);
-}
-
-/*
- * call-seq:
- * Request.put(url, options = {}) -> Response
- *
- * Issues a HTTP PUT to the specified +url+ using the provided
- * +options+.
- *
- */
-static VALUE request_put(int argc, VALUE* argv, VALUE self)
-{
- VALUE req, url, opts;
-
- rb_scan_args(argc, argv, "11", &url, &opts);
- opts = (opts == Qnil ? rb_hash_new() : opts);
-
- rb_hash_aset(opts, syms.method, syms.put);
-
- req = request_new(url, opts);
-
- return rb_funcall(req, rb_intern("run"), 0);
-}
-
-/*
- * call-seq:
- * Request.delete(url, options = {}) -> Curly::Response
- *
- * Issues a HTTP DELETE to the specified +url+ using the provided
- * +options+.
- *
- */
-static VALUE request_delete(int argc, VALUE* argv, VALUE self)
-{
- VALUE req, url, opts;
-
- rb_scan_args(argc, argv, "11", &url, &opts);
- opts = (opts == Qnil ? rb_hash_new() : opts);
-
- rb_hash_aset(opts, syms.method, syms.delete);
-
- req = request_new(url, opts);
-
- return rb_funcall(req, rb_intern("run"), 0);
-}
-
static int request_add_header(VALUE key, VALUE val, VALUE in)
{
struct curl_slist** list = (struct curl_slist**)in;
@@ -287,7 +144,7 @@ static int request_add_header(VALUE key, VALUE val, VALUE in)
return ST_CONTINUE;
}
-static struct curl_slist* request_build_headers(VALUE self, CURL* c, VALUE headers)
+static struct curl_slist* build_headers(CURL* c, VALUE headers)
{
struct curl_slist* list = NULL;
@@ -322,17 +179,7 @@ static size_t data_callback(void* buffer, size_t size, size_t count, void* arg)
* our own compatible implementation */
static VALUE build_query_string(VALUE params)
{
- VALUE paramize;
- VALUE has_to_query = rb_funcall(params, rb_intern("respond_to?"), 1,
- syms.to_query);
-
- if (has_to_query == Qtrue) {
- /* use active support */
- return rb_funcall(params, rb_intern("to_query"), 0);
- } else {
- paramize = rb_const_get(rb_const_get(rb_cObject, rb_intern("Curly")),
- rb_intern("Parameterize"));
- /* use our own version */
- return rb_funcall(paramize, rb_intern("query_string"), 1, params);
- }
+ VALUE paramize = rb_const_get(rb_const_get(rb_cObject, rb_intern("Curly")),
+ rb_intern("Parameterize"));
+ return rb_funcall(paramize, rb_intern("query_string"), 1, params);
}
44 ext/curly/response.c
View
@@ -1,30 +1,6 @@
#include "response.h"
#include <curl/curl.h>
-
-/* :nodoc: */
-static VALUE response_init(VALUE self)
-{
- rb_iv_set(self, "@body", rb_str_new2(""));
- rb_iv_set(self, "@headers", rb_hash_new());
- rb_iv_set(self, "@status", INT2NUM(0));
-
- return Qnil;
-}
-
-/*
- * call-seq:
- * success? -> true or false
- *
- * returns +true+ if the HTTP response code returned from the server falls
- * in the +2xx+ range, +false+ otherwise.
- */
-static VALUE response_success(VALUE self)
-{
- int status = NUM2INT(rb_iv_get(self, "@status"));
- return (status >= 200 && status < 300 ? Qtrue : Qfalse);
-}
-
/*
* call-seq:
* timed_out? -> true or false
@@ -52,26 +28,6 @@ void Init_curly_response(VALUE curly_mod)
{
VALUE response = rb_define_class_under(curly_mod, "Response", rb_cObject);
- rb_define_method(response, "initialize", response_init, 0);
- rb_define_method(response, "success?", response_success, 0);
rb_define_method(response, "timed_out?", response_timed_out, 0);
- /*
- * the body (if any) returned by the server in response to the issued request.
- */
- rb_define_attr(response, "body", 1, 0);
- /* Hash of header name/value pairs returned from the server (if any). */
- rb_define_attr(response, "headers", 1, 0);
- /* the HTTP status code returned by the server. */
- rb_define_attr(response, "status", 1, 0);
- /* The error code returned by curl (if any). */
- rb_define_attr(response, "curl_code", 1, 0);
- /* If +curl_code+ is set, contains a string representation the error. */
- rb_define_attr(response, "curl_error", 1, 0);
-
- /* provide some aliases to match Typhoeus */
- rb_alias(response, rb_intern("code"), rb_intern("status"));
- rb_alias(response, rb_intern("curl_return_code"), rb_intern("curl_code"));
- rb_alias(response, rb_intern("curl_error_message"), rb_intern("curl_error"));
-
}
2  lib/curly.rb
View
@@ -7,3 +7,5 @@
require "curly/version"
require "curly/parameterize"
require "curly/curly"
+require "curly/request"
+require "curly/response"
10 lib/curly/parameterize.rb
View
@@ -2,18 +2,22 @@
# This class converts a hash of http request parameters into a query string of
# the form key=value&key2=value2&key3=value3... in a format compatible to the
-# +Object.to_query+ method provided by ActiveSupport. This class will only be
-# used if Curly detects that ActiveSupport's +to_query+ is not present.
+# +Object.to_query+ method provided by ActiveSupport.
+# If ActiveSupport +to_query+ is found that will be used instead.
module Curly::Parameterize
class << self
# Convert the given +params+ hash into a URLencoded query string.
def query_string(params)
- params.collect { |key, value| to_param(key, value) }.sort * '&'
+ params.respond_to?(:to_query) ? params.to_query : build_query_string(params)
end
private
+ def build_query_string(params)
+ params.collect { |key, value| to_param(key, value) }.sort * '&'
+ end
+
def to_param(key, value)
if value.instance_of?(Array)
value.collect{ |v| to_param("#{key}[]", v) }.join('&')
37 lib/curly/request.rb
View
@@ -0,0 +1,37 @@
+class Curly::Request
+ class << self
+
+ def get(url, opts = {})
+ opts[:method] = :get
+ Curly::Request.new(url, opts).run
+ end
+
+ def post(url, opts = {})
+ opts[:method] = :post
+ Curly::Request.new(url, opts).run
+ end
+
+ def put(url, opts = {})
+ opts[:method] = :put
+ Curly::Request.new(url, opts).run
+ end
+
+ def delete(url, opts = {})
+ opts[:method] = :delete
+ Curly::Request.new(url, opts).run
+ end
+
+ end
+
+ attr_accessor :url
+ attr_accessor :body, :headers, :method, :params, :timeout
+
+ def initialize(url, opts = {})
+ @url = url
+ @body = opts[:body]
+ @headers = opts[:headers]
+ @method = opts[:method]
+ @params = opts[:params]
+ @timeout = opts[:timeout]
+ end
+end
26 lib/curly/response.rb
View
@@ -0,0 +1,26 @@
+class Curly::Response
+ attr_reader :body, :head, :status, :curl_code, :curl_error
+
+ alias_method :code, :status
+
+ alias_method :curl_return_code, :curl_code
+ alias_method :curl_error_message, :curl_error
+
+ def initialize
+ @body = ''
+ @head = ''
+ @status = 0
+ end
+
+ def success?
+ @status >= 200 && @status < 300
+ end
+
+ def headers
+ @headers ||= @head.split(/\r\n/).each_with_object({}) do |line, h|
+ key, value = line.split(': ', 2)
+ h[key] = value if value
+ end
+ end
+
+end
Something went wrong with that request. Please try again.