ext/revdispatch/revdispatch.cc in evdispatch-0.3.0 vs ext/revdispatch/revdispatch.cc in evdispatch-0.3.1

- old
+ new

@@ -1,7 +1,8 @@ #include "util.h" #include "rhttp.h" +#include <st.h> /* * * Using ruby dispatch interface: @@ -91,21 +92,50 @@ VALUE obj = rb_hash_aref( options, ID2SYM(rb_intern(name)) ); \ if( !NIL_P(obj) ) {\ req->set_opt(name, RSTRING_PTR(obj));\ }\ } + +static int +build_header_list(VALUE key, VALUE value, struct curl_slist **slist ) +{ + if (key == Qundef) return ST_CONTINUE; + VALUE str = rb_str_new(RSTRING_PTR(key),RSTRING_LEN(key)); + str = rb_str_cat2(str,":"); + *slist = curl_slist_append(*slist, RSTRING_PTR(rb_str_append(str,value)) ); + return ST_CONTINUE; +} + +static struct curl_slist *build_headers( VALUE hash ) +{ + struct curl_slist *slist = NULL; + rb_hash_foreach( hash, (int (*)(...))build_header_list, (VALUE)&slist ); + return slist; +} + +static void set_headers( VALUE options, EVD::HttpRequest *req ) +{ + VALUE hash = rb_hash_aref( options, ID2SYM(rb_intern("headers")) ); + if( !NIL_P(hash) && TYPE(hash) == T_HASH ) { + struct curl_slist *headers = build_headers( hash ); + req->set_opt( "headers", headers ); + } +} + // set options -#define SET_REQ_OPTS \ +#define SET_REQ_OPTS(options,req) \ 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"); \ - SET_STR_VAL("post"); + SET_STR_VAL("post"); \ + set_headers(options, req) + /** * call-seq: * loop.request( url, options ) -> request_id * * Notify the background of a new request. Can send a few options to influence the request: @@ -121,10 +151,11 @@ * :useragent: (String) Pass a pointer to a zero terminated string as parameter. It will be used to set the User-Agent: header in the http request sent to the remote server. This can be used to fool servers or scripts. You can also set any custom header with CURLOPT_HTTPHEADER. * :cookie: (String) Pass a pointer to a zero terminated string as parameter. It will be used to set a cookie in the http request. The format of the string should be NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie should contain. * If you need to set multiple cookies, you need to set them all using a single option and thus you need to concatenate them all in one single string. Set multiple cookies in one string like this: "name1=content1; name2=content2;" etc. * Note that this option sets the cookie header explictly in the outgoing request(s). If multiple requests are done due to authentication, followed redirections or similar, they will all get this cookie passed on. * Using this option multiple times will only make the latest string override the previous ones. + * :headers: (Hash) An arbitrary list of HTTP Headers. Set any HTTP header or override the defaults. see libcurl's documentation for more details. * * :post: (String) Pass a string and sets CURLOPT_POST, CURLOPT_POSTFIELDSIZE, and CURLOPT_COPYPOSTFIELDS * * :stream: (Evdispatch::Response) Send the response to the IO object. Ignore the response id returned it'd invalid */ @@ -156,19 +187,20 @@ rb_raise(rb_eIOError, "Failed to create new pipe"); } EVD::HttpRequest *req = new EVD::HttpRequest( *d, RSTRING_PTR(url), res->m_pipe[1] ); - SET_REQ_OPTS - + SET_REQ_OPTS(options,req); + res->m_response = req->m_response; d->request(req); return response_object; } else { EVD::HttpRequest *req = new EVD::HttpRequest( *d, RSTRING_PTR(url) ); - SET_REQ_OPTS + + SET_REQ_OPTS(options,req); return rb_int_new( d->request(req) ); } }