int main(int argc, char **argv) { GlobalInfo g; CURLMcode rc; (void)argc; (void)argv; memset(&g, 0, sizeof(GlobalInfo)); g.loop = ev_default_loop(0); init_fifo(&g); g.multi = curl_multi_init(); ev_timer_init(&g.timer_event, timer_cb, 0., 0.); g.timer_event.data = &g; g.fifo_event.data = &g; curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb); curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g); curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb); curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g); do { rc = curl_multi_socket_all(g.multi, &g.still_running); } while ( CURLM_CALL_MULTI_PERFORM == rc ); ev_loop(g.loop, 0); curl_multi_cleanup(g.multi); return 0; }
int main(int argc, char **argv) { GlobalInfo *g; CURLMcode rc; GMainLoop*gmain; int fd; GIOChannel* ch; g=g_malloc0(sizeof(GlobalInfo)); fd=init_fifo(); ch=g_io_channel_unix_new(fd); g_io_add_watch(ch,G_IO_IN,fifo_cb,g); gmain=g_main_loop_new(NULL,FALSE); g->multi = curl_multi_init(); curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb); curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g); curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb); curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g); do { rc = curl_multi_socket_all(g->multi, &g->still_running); } while (CURLM_CALL_MULTI_PERFORM == rc); g_main_loop_run(gmain); curl_multi_cleanup(g->multi); return 0; }
static void curl_multi_do(void *arg) { BDRVCURLState *s = (BDRVCURLState *)arg; int running; int r; int msgs_in_queue; if (!s->multi) return; do { r = curl_multi_socket_all(s->multi, &running); } while(r == CURLM_CALL_MULTI_PERFORM); /* Try to find done transfers, so we can free the easy * handle again. */ do { CURLMsg *msg; msg = curl_multi_info_read(s->multi, &msgs_in_queue); if (!msg) break; if (msg->msg == CURLMSG_NONE) break; switch (msg->msg) { case CURLMSG_DONE: { CURLState *state = NULL; curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, (char**)&state); /* ACBs for successful messages get completed in curl_read_cb */ if (msg->data.result != CURLE_OK) { int i; for (i = 0; i < CURL_NUM_ACB; i++) { CURLAIOCB *acb = state->acb[i]; if (acb == NULL) { continue; } acb->common.cb(acb->common.opaque, -EIO); qemu_aio_release(acb); state->acb[i] = NULL; } } curl_clean_state(state); break; } default: msgs_in_queue = 0; break; } } while(msgs_in_queue); }
static void curl_multi_do(void *arg) { BDRVCURLState *s = (BDRVCURLState *)arg; int running; int r; if (!s->multi) { return; } do { r = curl_multi_socket_all(s->multi, &running); } while(r == CURLM_CALL_MULTI_PERFORM); curl_multi_read(s); }
/* Create a new easy handle, and add it to the global curl_multi */ static void new_conn(char *url, GlobalInfo *g ) { ConnInfo *conn; CURLMcode rc; conn = g_malloc0(sizeof(ConnInfo)); conn->error[0]='\0'; conn->easy = curl_easy_init(); if (!conn->easy) { MSG_OUT("curl_easy_init() failed, exiting!\n"); exit(2); } conn->global = g; conn->url = g_strdup(url); curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn); curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE); curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0L:1L); curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb); curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn); curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L); MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); rc =curl_multi_add_handle(g->multi, conn->easy); mcode_or_die("new_conn: curl_multi_add_handle", rc); g->requested++; do { rc = curl_multi_socket_all(g->multi, &g->still_running); } while (CURLM_CALL_MULTI_PERFORM == rc); mcode_or_die("new_conn: curl_multi_socket_all", rc); check_run_count(g); }
static PyObject * do_multi_socket_all(CurlMultiObject *self) { CURLMcode res; int running = -1; if (check_multi_state(self, 1 | 2, "socket_all") != 0) { return NULL; } PYCURL_BEGIN_ALLOW_THREADS res = curl_multi_socket_all(self->multi_handle, &running); PYCURL_END_ALLOW_THREADS /* We assume these errors are ok, otherwise raise exception */ if (res != CURLM_OK && res != CURLM_CALL_MULTI_PERFORM) { CURLERROR_MSG("perform failed"); } /* Return a tuple with the result and the number of running handles */ return Py_BuildValue("(ii)", (int)res, running); }
static void curl_multi_do(void *arg) { BDRVCURLState *s = (BDRVCURLState *)arg; int running; int r; int msgs_in_queue; if (!s->multi) return; do { r = curl_multi_socket_all(s->multi, &running); } while(r == CURLM_CALL_MULTI_PERFORM); /* Try to find done transfers, so we can free the easy * handle again. */ do { CURLMsg *msg; msg = curl_multi_info_read(s->multi, &msgs_in_queue); if (!msg) break; if (msg->msg == CURLMSG_NONE) break; switch (msg->msg) { case CURLMSG_DONE: { CURLState *state = NULL; curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, (char**)&state); curl_clean_state(state); break; } default: msgs_in_queue = 0; break; } } while(msgs_in_queue); }
void AsyncLoop::asyncLoop() { // This runs as an asynchronous task. dbgAssert( m_multiCurl ); SocketActions socketActions; while( !m_shutdown ) { try { if( m_hasPending ) { // Add new and remove canceled requests. handlePendingRequests(); dbgAssert( m_runningRequestCount >= m_socketPool.size() ); } size_t socketCount = m_socketPool.size(); if( m_runningRequestCount > socketCount ) { // We have added more requests to the multi-handle than the number of sockets // curl reported back to us yet. Execute 'timeout' action. executeSocketAction( INVALID_SOCKET_HANDLE ); } else { // Wait for any activity. socketActions.reserve( socketCount ); if( m_socketPool.wait( m_socketActionTimeout, c_interruptOnlyTimeout, &socketActions ) ) { // Some activity (or interrupt) has been detected, handle it. for( SocketActions::const_iterator it = socketActions.begin(); it != socketActions.end(); ++it ) { executeSocketAction( it->first, it->second ); } } else { // No activity, go through all sockets and check their status. // Note: curl_multi_socket_all(..) is deprecated but it doesn't seem // there is another way to check all sockets. Without this call some sockets // may stuck for very long. int stillRunning = 0; CURLMcode multiCurlCode = curl_multi_socket_all( m_multiCurl, &stillRunning ); raiseIfError( multiCurlCode ); } } // Remove completed requests. removeCompletedRequests(); dbgAssert( m_runningRequestCount >= m_socketPool.size() ); } catch( ... ) { // Continue to work no matter what. handleBackgroundError(); taskSleep( 3000 ); } } }
static bool curl_new(struct dionaea *d) { g_debug("%s", __PRETTY_FUNCTION__); struct lcfgx_tree_node *node; if( lcfgx_get_string(g_dionaea->config.root, &node, "downloads.dir") != LCFGX_PATH_FOUND_TYPE_OK ) { g_warning("missing downloads.dir in dionaea.conf"); return false; } curl_runtime.download_dir = g_strdup((char *)node->value.string.data); if( curl_global_init(CURL_GLOBAL_ALL) != 0 ) return false; curl_version_info_data *curlinfo; curlinfo = curl_version_info(CURLVERSION_NOW); GString *features = g_string_new(""); GString *protocols = g_string_new(""); if( curlinfo->features ) { struct curl_feature { const char *name; int bitmask; }; static const struct curl_feature feats[] = { {"c-ares", CURL_VERSION_ASYNCHDNS}, {"debug", CURL_VERSION_DEBUG}, #ifdef CURL_VERSION_CURLDEBUG {"debugmemory", CURL_VERSION_CURLDEBUG}, #endif {"gss", CURL_VERSION_GSSNEGOTIATE}, {"idn", CURL_VERSION_IDN}, {"ipv6", CURL_VERSION_IPV6}, {"largefile", CURL_VERSION_LARGEFILE}, {"ntlm", CURL_VERSION_NTLM}, {"spnego", CURL_VERSION_SPNEGO}, {"ssl", CURL_VERSION_SSL}, {"sspi", CURL_VERSION_SSPI}, {"krb4", CURL_VERSION_KERBEROS4}, {"libz", CURL_VERSION_LIBZ}, {"charconv", CURL_VERSION_CONV} }; for( unsigned int i=0; i<sizeof(feats)/sizeof(feats[0]); i++ ) if( curlinfo->features & feats[i].bitmask ) g_string_append_printf(features, ",%s", feats[i].name); } if( curlinfo->protocols ) for( const char * const *proto=curlinfo->protocols; *proto; ++proto ) g_string_append_printf(protocols, ",%s", *proto); g_info("curl version %s features:%s protocols:%s ", curlinfo->version, features->str+1, protocols->str+1); g_string_free(features, TRUE); g_string_free(protocols, TRUE); curl_runtime.multi = curl_multi_init(); ev_timer_init(&curl_runtime.timer_event, timer_cb, 0., 0.); curl_multi_setopt(curl_runtime.multi, CURLMOPT_SOCKETFUNCTION, curl_socketfunction_cb); curl_multi_setopt(curl_runtime.multi, CURLMOPT_SOCKETDATA, NULL); curl_multi_setopt(curl_runtime.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb); curl_multi_setopt(curl_runtime.multi, CURLMOPT_TIMERDATA, NULL); CURLMcode rc; do { rc = curl_multi_socket_all(curl_runtime.multi, &curl_runtime.active); } while( CURLM_CALL_MULTI_PERFORM == rc ); curl_runtime.download_ihandler = ihandler_new("dionaea.download.offer", curl_ihandler_cb, NULL); curl_runtime.upload_ihandler = ihandler_new("dionaea.upload.request", curl_ihandler_cb, NULL); return true; }