int zhttp_client_execute (zhttp_client_t *self) { #ifdef HAVE_LIBCURL int response_code; zchunk_t *data; void *arg; zhttp_client_fn *handler; int rc; int events = zsock_events (self); while (zsock_has_in (self)) { rc = zsock_recv (self, "icpp", &response_code, &data, &handler, &arg); if (rc < 0) return rc; handler (arg, response_code, data); events = zsock_events (self); } return 0; #else return -1; #endif }
static void handler (zsock_t *pipe, void *args) { curl_global_init(CURL_GLOBAL_ALL); CURLM *multi = curl_multi_init (); CURLSH *share = curl_share_init (); curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); long verbose = (*(bool *) args) ? 1L : 0L; long timeout = 30; CURLMcode code; SOCKET pipefd = zsock_fd (pipe); struct curl_waitfd waitfd = {pipefd, CURL_WAIT_POLLIN}; // List to hold pending curl handles, in case we are destroy the client // while request are inprogress zlistx_t *pending_handles = zlistx_new (); zlistx_set_destructor (pending_handles, (zlistx_destructor_fn *) curl_destructor); zsock_signal (pipe, 0); bool terminated = false; while (!terminated) { int events = zsock_events (pipe); if ((events & ZMQ_POLLIN) == 0) { code = curl_multi_wait (multi, &waitfd, 1, 1000, NULL); assert (code == CURLM_OK); } events = zsock_events (pipe); if (events & ZMQ_POLLIN) { char* command = zstr_recv (pipe); if (!command) break; // Interrupted // All actors must handle $TERM in this way if (streq (command, "$TERM")) terminated = true; else if (streq (command, "GET")) { char *url; zlistx_t *headers; void *userp; int rc = zsock_recv (pipe, "slp", &url, &headers, &userp); assert (rc == 0); zchunk_t *data = zchunk_new (NULL, 100); assert (data); struct curl_slist *curl_headers = zlistx_to_slist (headers); CURL *curl = curl_easy_init (); zlistx_add_end (pending_handles, curl); http_request *request = (http_request *) zmalloc (sizeof (http_request)); assert (request); request->userp = userp; request->curl = curl; request->data = data; request->headers = curl_headers; curl_easy_setopt (curl, CURLOPT_SHARE, share); curl_easy_setopt (curl, CURLOPT_TIMEOUT, timeout); curl_easy_setopt (curl, CURLOPT_VERBOSE, verbose); curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers); curl_easy_setopt (curl, CURLOPT_URL, url); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt (curl, CURLOPT_WRITEDATA, data); curl_easy_setopt (curl, CURLOPT_PRIVATE, request); code = curl_multi_add_handle (multi, curl); assert (code == CURLM_OK); zlistx_destroy (&headers); zstr_free (&url); } else { puts ("E: invalid message to actor"); assert (false); } zstr_free (&command); } int still_running; code = curl_multi_perform (multi, &still_running); assert (code == CURLM_OK); int msgq = 0; struct CURLMsg *msg = curl_multi_info_read(multi, &msgq); while (msg) { if(msg->msg == CURLMSG_DONE) { CURL *curl = msg->easy_handle; http_request *request; curl_easy_getinfo(curl, CURLINFO_PRIVATE, &request); long response_code_long; curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code_long); int response_code = (int)response_code_long; int rc = zsock_send (pipe, "icp", response_code, request->data, request->userp); assert (rc == 0); curl_multi_remove_handle (multi, curl); // Remove curl from the pending handles and delete it void *handle = zlistx_find (pending_handles, curl); assert (handle); rc = zlistx_delete (pending_handles, handle); assert (rc == 0); } msg = curl_multi_info_read(multi, &msgq); } } zlistx_destroy (&pending_handles); curl_share_cleanup (share); curl_multi_cleanup (multi); curl_global_cleanup (); }
/// // Get socket option `events`. int QZsock::events () { int rv = zsock_events (self); return rv; }
JNIEXPORT jint JNICALL Java_org_zeromq_czmq_Zsock__1_1events (JNIEnv *env, jclass c, jlong self) { jint events_ = (jint) zsock_events ((zsock_t *) (intptr_t) self); return events_; }
/// // Get socket option `events`. int QmlZsock::events () { return zsock_events (self); };