ext/revdispatch/revdispatch.cc in evdispatch-0.1.5 vs ext/revdispatch/revdispatch.cc in evdispatch-0.2.0

- old
+ new

@@ -17,35 +17,38 @@ * Using ruby dispatch interface: * * require 'rev_dispatch' * * # create a new dispatch loop - * d = Rev::Dispatch::Loop.new + * d = Evdispatch::Loop.new * * # start the event loop thread * * # send a dispatch http request and store a handle to the request - * google_id = d.request("get", "http://www.google.com/") + * google_id = d.request_http("http://www.google.com/") * * # do some processing and later on check for the response * while d.wait_for_response( google_id, 1, 0 ) * res = d.response_for( google_id ) * break if res * end * res = d.response_for( google_id ) unless res * - * puts res.inspect # array of response values + * puts res[:body] * * # sometime later you can stop the event loop * d.stop * * * You only get 1 background event loop, calling start multiple times will have no effect. * You typically don't need or want to stop the event loop after it's active. It will sit in the * background and happily wait for new requests using a minimal amount of cpu while waiting. * Everything in the background thread is written in C++ and has absolutely no hooks back into ruby. * The results of the work being processed in the background can be retrieved by ruby but that is it. + * + * the request method can be used passing it options will set specific libcurl options + * */ static VALUE rb_Evdispatch; static VALUE rb_Loop; static @@ -68,10 +71,50 @@ EVD::request_t id = d->request( new EVD::HttpRequest( *d, RSTRING_PTR(url) ) ); return rb_int_new(id); } +#define SET_LONG_VAL(name)\ +{\ + VALUE obj = rb_hash_aref( options, ID2SYM(rb_intern(name)) ); \ + if( !NIL_P(obj) ) {\ + snprintf( VALUE_BUFFER, VALUE_BUFFER_SIZE, "%d", FIX2LONG(obj) );\ + req->set_opt(name, VALUE_BUFFER);\ + }\ +} + +#define SET_STR_VAL(name)\ +{\ + VALUE obj = rb_hash_aref( options, ID2SYM(rb_intern(name)) ); \ + if( !NIL_P(obj) ) {\ + req->set_opt(name, RSTRING_PTR(obj));\ + }\ +} + +static +VALUE Loop_request( VALUE self, VALUE url, VALUE options ) +{ + EVD::Dispatch *d; + const int VALUE_BUFFER_SIZE = 1024; + char VALUE_BUFFER[VALUE_BUFFER_SIZE]; + Data_Get_Struct( self, EVD::Dispatch, d ); + + + EVD::HttpRequest *req = new EVD::HttpRequest( *d, RSTRING_PTR(url) ); + + // check for some specific options + SET_LONG_VAL("port"); + SET_STR_VAL("autoreferer"); + SET_LONG_VAL("followlocation"); + SET_LONG_VAL("maxredirs"); + SET_STR_VAL("referer"); + SET_STR_VAL("useragent"); + SET_STR_VAL("cookie"); + + return rb_int_new( d->request(req) ); +} + static VALUE Loop_wait_for_response( VALUE self, VALUE id, VALUE timeout_seconds, VALUE timeout_mseconds ) { EVD::Dispatch *d; EVD::Queue<EVD::Response>::POP_STATE rstate; @@ -88,22 +131,23 @@ VALUE Loop_response_for( VALUE self, VALUE id ) { EVD::Dispatch *d; Data_Get_Struct( self, EVD::Dispatch, d ); - EVD::Response *res = NULL; + EVD::HttpResponse *res = NULL; EVD::request_t rid = FIX2LONG(id); - res = d->response_for( rid ); + res = (EVD::HttpResponse*)d->response_for( rid ); if( res ){ VALUE result = rb_hash_new(); rb_hash_aset( result, ID2SYM(rb_intern("name")), rb_str_new( res->name.c_str(), res->name.length() ) ); rb_hash_aset( result, ID2SYM(rb_intern("body")), rb_str_new( res->body.c_str(), res->body.length() ) ); rb_hash_aset( result, ID2SYM(rb_intern("id")), rb_int_new( res->id ) ); rb_hash_aset( result, ID2SYM(rb_intern("response_time")), rb_float_new( res->response_time ) ); + rb_hash_aset( result, ID2SYM(rb_intern("header")), rb_str_new( res->m_header.c_str(), res->m_header.length() ) ); delete res; return result; } @@ -140,13 +184,15 @@ extern "C" void Init_revdispatch() { rb_Evdispatch = rb_define_module( "Evdispatch" ); rb_Loop = rb_define_class_under( rb_Evdispatch, "Loop", rb_cObject ); + // setup the Loop object rb_define_alloc_func( rb_Loop, Loop_alloc ); rb_define_method( rb_Loop, "start", (VALUE (*)(...))Loop_start, 0 ); rb_define_method( rb_Loop, "request_http", (VALUE (*)(...))Loop_request_http, 1 ); + rb_define_method( rb_Loop, "request", (VALUE (*)(...))Loop_request, 2 ); rb_define_method( rb_Loop, "response_for", (VALUE (*)(...))Loop_response_for, 1 ); rb_define_method( rb_Loop, "wait_for_response", (VALUE (*)(...))Loop_wait_for_response, 3 ); rb_define_method( rb_Loop, "stop", (VALUE (*)(...))Loop_stop, 0 ); }