Hello. libcurl is freezed in multi mode on SSL urls after it updated from 7.38.0 to 7.52.1 version.
Prompt, please, what I am doing wrong. Test code attached to the letter. Linux SMP Debian 4.9.2-2 (2017-01-12) x86_64 GNU/Linux It's output with libcurl 7.38.0 > ./a.out https://www.google.com/ Using libcurl/7.38.0 OpenSSL/1.0.1t zlib/1.2.8 libidn/1.29 libssh2/1.4.3 librtmp/2.3 >>> timerCallback: timeout: 1 ms .>>> timerCallback: timeout: 1 ms .>>> socketCallback: adding fd=5 action=2 >>> timerCallback: timeout: 199 ms .>>> socketCallback: adding fd=5 action=1 ...>>> socketCallback: adding fd=5 action=4 >>> socketCallback: removing fd=5 >>> timerCallback: timeout: 1 ms .>>> socketCallback: adding fd=6 action=2 >>> timerCallback: timeout: 117 ms .>>> socketCallback: adding fd=6 action=1 ..>>> timerCallback: timeout: 77 ms ...........>>> timerCallback: timeout: -1 ms .>>> socketCallback: adding fd=6 action=4 >>> socketCallback: removing fd=6 code=200 url=https://www.google.de/?gfe_rd=cr&ei=RKeJWLedHqri8AfZ-YmQDQ >>> bye bye It's output with libcurl 7.52.1. Libcurl freezed. > ./a.out https://www.google.com/ Using libcurl/7.52.1 OpenSSL/1.0.2j zlib/1.2.8 libidn2/0.14 libpsl/0.16.1 (+libicu/57.1) libssh2/1.7.0 nghttp2/1.17.0 librtmp/2.3 >>> timerCallback: timeout: 0 ms .>>> timerCallback: timeout: 0 ms .>>> timerCallback: timeout: 1 ms .>>> socketCallback: adding fd=4 action=2 >>> timerCallback: timeout: 199 ms .>>> socketCallback: adding fd=4 action=4 >>> socketCallback: removing fd=4 It's output wiht CURLOPT_VERBOSE > ./a.out https://www.google.com/ Using libcurl/7.52.1 OpenSSL/1.0.2j zlib/1.2.8 libidn2/0.14 libpsl/0.16.1 (+libicu/57.1) libssh2/1.7.0 nghttp2/1.17.0 librtmp/2.3 >>> timerCallback: timeout: 0 ms .>>> timerCallback: timeout: 0 ms .>>> timerCallback: timeout: 1 ms .>>> timerCallback: timeout: 1 ms .>>> timerCallback: timeout: 1 ms * Trying 172.217.20.164... * TCP_NODELAY set .>>> socketCallback: adding fd=4 action=2 >>> timerCallback: timeout: 199 ms * Connected to www.google.com (172.217.20.164) port 443 (#0) * ALPN, offering http/1.1 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs .>>> socketCallback: adding fd=4 action=4 >>> socketCallback: removing fd=4
// cc -lcurl curlepoll.c // ./a.out https://www.google.com/ #include <assert.h> #include <curl/curl.h> #include <poll.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <sys/epoll.h> #include <unistd.h> void error(const char* string) { perror(string); exit(1); } int epollFd; int timeout = -1; struct pollfd pollfd; int socketCallback(CURL* easy, curl_socket_t fd, int action, void* u, void* s) { struct epoll_event event; event.events = 0; event.data.fd = fd; pollfd.fd = fd; pollfd.events = 0; pollfd.revents = 0; printf(">>> %s: adding fd=%d action=%d\n", __func__, fd, action); if (action == CURL_POLL_REMOVE) { printf(">>> %s: removing fd=%d\n", __func__, fd); assert(pollfd.fd == fd); pollfd.fd = -1; int res = epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, &event); if (res == -1 && errno != EBADF) error("epoll_ctl(DEL)"); return 0; } if (action == CURL_POLL_IN || action == CURL_POLL_INOUT) { pollfd.events |= POLLIN; event.events |= EPOLLIN; } if (action == CURL_POLL_OUT || action == CURL_POLL_INOUT) { pollfd.events |= POLLOUT; event.events |= EPOLLOUT; } if (event.events != 0) { int res = epoll_ctl(epollFd, EPOLL_CTL_ADD, fd, &event); if (res == -1) res = epoll_ctl(epollFd, EPOLL_CTL_MOD, fd, &event); if (res == -1) error("epoll_ctl(MOD)"); } return 0; } int timerCallback(CURLM* multi, long timeout_ms, void* u) { printf(">>> %s: timeout: %ld ms\n", __func__, timeout_ms); timeout = timeout_ms; return 0; } size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) { return size * nmemb; } size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata) { return size * nitems; } int main(int argc, char** argv) { // argv[1] == URL // argc[2] == proxi pollfd.fd = -1; epollFd = epoll_create(1); if (epollFd == -1) error("epoll_create"); curl_global_init(CURL_GLOBAL_ALL); printf("Using %s\n", curl_version()); CURL* easy = curl_easy_init(); curl_easy_setopt(easy, CURLOPT_URL, argv[1]); curl_easy_setopt(easy, CURLOPT_FOLLOWLOCATION, 1); // curl_easy_setopt(easy, CURLOPT_VERBOSE, 1); curl_easy_setopt(easy, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(easy, CURLOPT_MAXREDIRS, 5); curl_easy_setopt(easy, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(easy, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"); curl_easy_setopt(easy, CURLOPT_ACCEPT_ENCODING, "gzip"); curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(easy, CURLOPT_HEADERFUNCTION, header_callback); if (argv[2]) { curl_easy_setopt(easy, CURLOPT_PROXY, argv[2]); } CURLM* multi = curl_multi_init(); curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, socketCallback); curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, timerCallback); curl_multi_add_handle(multi, easy); int running_handles = 1; while (running_handles > 0) { // printf(">>> calling epoll_wait\n"); printf("."); struct epoll_event event; int res = epoll_wait(epollFd, &event, 1, timeout); if (res == -1) { error("epoll_wait"); } else if (res == 0) { curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0, &running_handles); } else { curl_multi_socket_action(multi, event.data.fd, 0, &running_handles); } } long respcode; curl_easy_getinfo(easy, CURLINFO_RESPONSE_CODE, &respcode); char * urlp; curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &urlp); printf("code=%ld url=%s\n", respcode, urlp); curl_easy_cleanup(easy); curl_multi_cleanup(multi); curl_global_cleanup(); close(epollFd); printf(">>> bye bye\n"); return 0; }
------------------------------------------------------------------- Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library Etiquette: https://curl.haxx.se/mail/etiquette.html
