ext/revdispatch/libdispatch-0.1/src/ev_http.cc in evdispatch-0.1.5 vs ext/revdispatch/libdispatch-0.1/src/ev_http.cc in evdispatch-0.2.0

- old
+ new

@@ -168,58 +168,73 @@ size_t HttpRequest::write_cb(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; HttpRequest *req = (HttpRequest *)data; - if( req->response ) { - req->response->body.append((const char*)ptr,realsize); - //fprintf(stderr, "Write: %s (%lu) => (%d)%s\n", req->url.c_str(), realsize, (int)req->response, req->response->body.c_str() ); - } - else if( req->m_fd ) { - write( req->m_fd, ptr, realsize ); - } + req->m_response->write( ptr, realsize, size, nmemb ); return realsize; } +// CURLOPT_HEADERFUNCTION +size_t HttpRequest::header_write_cb(void *ptr, size_t size, size_t nmemb, void *data) +{ + size_t realsize = size * nmemb; + HttpRequest *req = (HttpRequest *)data; + + req->m_response->write_header( ptr, realsize, size, nmemb ); + + return realsize; +} + // CURLOPT_PROGRESSFUNCTION int HttpRequest::prog_cb(void *p, double dltotal, double dlnow, double ult, double uln) { HttpRequest *req = (HttpRequest *)p; //fprintf(stderr, "Progress: %s (%g/%g)\n", req->url.c_str(), dlnow, dltotal); return 0; } -HttpRequest::HttpRequest( Dispatch &dispatch, const std::string &url ) - : Request( 0, url ), response(new Response()), m_handle(curl_easy_init()), m_client(dispatch.getHttpClient()) +void HttpRequest::init_curl() { - memset(error,'\0', CURL_ERROR_SIZE); curl_easy_setopt(m_handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(m_handle, CURLOPT_HEADERFUNCTION, header_write_cb); + curl_easy_setopt(m_handle, CURLOPT_HEADERDATA, this); curl_easy_setopt(m_handle, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(m_handle, CURLOPT_WRITEDATA, this); curl_easy_setopt(m_handle, CURLOPT_VERBOSE, 0); - curl_easy_setopt(m_handle, CURLOPT_ERRORBUFFER, error); + curl_easy_setopt(m_handle, CURLOPT_ERRORBUFFER, m_error); curl_easy_setopt(m_handle, CURLOPT_PRIVATE, this); curl_easy_setopt(m_handle, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(m_handle, CURLOPT_PROGRESSFUNCTION, prog_cb); curl_easy_setopt(m_handle, CURLOPT_PROGRESSDATA, this); - // setup the response object - this->response->name = url; } -void HttpRequest::set_response_fd( int fd ) +HttpRequest::HttpRequest( Dispatch &dispatch, const std::string &url, int fd ) + : Request( 0, url ), + m_response(new HttpResponse(url,fd)), + m_handle(curl_easy_init()), + m_client(dispatch.getHttpClient()) { - if( this->response ){ delete this->response; this->response = NULL; } - m_fd = fd; + init_curl(); } +HttpRequest::HttpRequest( Dispatch &dispatch, const std::string &url ) + : Request( 0, url ), + m_response(new HttpResponse(url)), + m_handle(curl_easy_init()), + m_client(dispatch.getHttpClient()) +{ + init_curl(); +} + HttpRequest::~HttpRequest() { curl_easy_cleanup( m_handle ); #ifdef DEBUG - response = NULL; + m_response = NULL; m_handle = NULL; m_client = NULL; #endif } @@ -237,18 +252,84 @@ void HttpRequest::finish(CURLcode rc) { curl_multi_remove_handle( m_client->m_handle, m_handle ); - if( this->response ) { - // add the response object here to the responses queue in the dispatcher? - // signaling to any waiting clients that their response is available - this->response->response_time = difftime( time(NULL), this->start_time ); - m_client->m_disp->send_response( this->response ); + // add the response object here to the responses queue in the dispatcher? + // signaling to any waiting clients that their response is available + m_response->response_time = Timer::elapsed_time( &(this->start_time) ); + m_response->finish( m_client, rc ); + + //fprintf( stderr, "DONE: (%s/%s) => (%d), body(%d): '%s'\n", url.c_str(), url.c_str(), rc, (int)m_response, m_response->body.c_str() ); +} +void HttpRequest::set_key( request_t key ) +{ + Request::set_key(key); + m_response->id = key; +} + +void HttpRequest::set_opt( const std::string &key, const std::string &value ) +{ + Request::set_opt(key,value); + // convert the key into a curl value + // #define CURLOPTTYPE_LONG 0 + // #define CURLOPTTYPE_OBJECTPOINT 10000 + // #define CURLOPTTYPE_FUNCTIONPOINT 20000 + // #define CURLOPTTYPE_OFF_T 30000 + + std::map<std::string,CURLoption> key_loopup; + // TODO: define this once for each resquest? + key_loopup["port"] = CURLOPT_PORT; + key_loopup["autoreferer"] = CURLOPT_AUTOREFERER; + key_loopup["followlocation"] = CURLOPT_FOLLOWLOCATION; + key_loopup["maxredirs"] = CURLOPT_MAXREDIRS; + key_loopup["referer"] = CURLOPT_REFERER; + key_loopup["useragent"] = CURLOPT_USERAGENT; + key_loopup["cookie"] = CURLOPT_COOKIE; + + std::map<std::string,CURLoption>::iterator loc = key_loopup.find(key); + if( loc != key_loopup.end() ){ + CURLoption val_type = loc->second; + if( val_type >= CURLOPTTYPE_LONG && val_type < CURLOPTTYPE_OBJECTPOINT ) { + long val = atoi(value.c_str()); + printf( "set opt %s : %ld\n", key.c_str(), val ); + curl_easy_setopt( m_handle, val_type, val ); + } + else if( val_type >= CURLOPTTYPE_OBJECTPOINT && val_type < CURLOPTTYPE_FUNCTIONPOINT ) { + printf( "set opt %s : %s\n", key.c_str(), value.c_str() ); + curl_easy_setopt( m_handle, val_type, value.c_str() ); + } } +} + +HttpResponse::HttpResponse( const std::string &url ) + : Response(url), m_fd(-1) +{ +} +HttpResponse::HttpResponse( const std::string &url, int fd ) + : Response(url), m_fd(fd) +{ +} +void HttpResponse::write( void *ptr, size_t realsize, size_t size, size_t nmemb ) +{ + if( m_fd == -1 ) { + body.append((const char*)ptr,realsize); + } else { + ::write( m_fd, ptr, realsize ); + } +} +void HttpResponse::write_header( void *ptr, size_t realsize, size_t size, size_t nmemb ) +{ + m_header.append((const char*)ptr,realsize); +} +void HttpResponse::finish( HttpClient *client, CURLcode rc ) +{ + if( m_fd == -1 ) { + client->m_disp->send_response( this ); + } + else { close( this->m_fd ); } - //fprintf( stderr, "DONE: (%s/%s) => (%d), body(%d): '%s'\n", url.c_str(), url.c_str(), rc, (int)this->response, this->response->body.c_str() ); } }