Created
February 16, 2011 00:37
-
-
Save bnoordhuis/828613 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include <sys/select.h> | |
#include <curl/curl.h> | |
#define IMAP_URL "imap://testuser:testuser@localhost/Drafts" | |
#define IMAPS_URL "imaps://testuser:testuser@localhost/Drafts" | |
static long timeout_ = -1; | |
static int sockfd_ = -1; | |
static int events_ = -1; | |
static int socket_callback(CURL *c, curl_socket_t sockfd, int events, void *userp, void *socketp) { | |
sockfd_ = sockfd; | |
events_ = events; | |
return CURLM_OK; | |
} | |
static int multi_timer_callback(CURLM *m, long timeout, void *userp) { | |
timeout_ = timeout; | |
return CURLM_OK; | |
} | |
static void test_multi(const char *url, int use_ssl) { | |
struct timeval tv; | |
fd_set readfds; | |
fd_set writefds; | |
CURLMcode status; | |
CURLM *m; | |
CURL *c; | |
int n_fds; | |
if (curl_global_init(CURL_GLOBAL_ALL)) { | |
abort(); | |
} | |
atexit(curl_global_cleanup); | |
m = curl_multi_init(); | |
c = curl_easy_init(); | |
assert(m != NULL); | |
assert(c != NULL); | |
curl_multi_setopt(m, CURLMOPT_TIMERFUNCTION, multi_timer_callback); | |
curl_multi_setopt(m, CURLMOPT_SOCKETFUNCTION, socket_callback); | |
curl_easy_setopt(c, CURLOPT_URL, url); | |
curl_easy_setopt(c, CURLOPT_USE_SSL, use_ssl); | |
curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0); | |
status = curl_multi_add_handle(m, c); | |
assert(status == CURLM_OK); | |
status = curl_multi_socket_all(m, &n_fds); | |
assert(status == CURLM_OK); | |
assert(n_fds > 0); | |
assert(sockfd_ != -1); | |
assert(events_ != -1); | |
assert(timeout_ != -1); | |
do { | |
FD_ZERO(&readfds); | |
FD_ZERO(&writefds); | |
if (events_ & CURL_POLL_IN) { | |
FD_SET(sockfd_, &readfds); | |
} | |
if (events_ & CURL_POLL_OUT) { | |
FD_SET(sockfd_, &writefds); | |
} | |
if (timeout_ == -1) { | |
// 100 ms timeout | |
tv.tv_sec = 0; | |
tv.tv_usec = 100 * 1000; | |
} | |
else { | |
tv.tv_sec = timeout_ / 1000; | |
tv.tv_usec = (timeout_ % 1000) * 1000; | |
} | |
if (-1 == select(sockfd_ + 1, &readfds, &writefds, NULL, &tv)) { | |
perror("select"); | |
abort(); | |
} | |
status = curl_multi_socket_all(m, &n_fds); | |
assert(status == CURLM_OK); | |
} | |
while (n_fds > 0); | |
assert(events_ == CURL_POLL_REMOVE); | |
curl_multi_remove_handle(m, c); | |
curl_multi_cleanup(m); | |
curl_easy_cleanup(c); | |
} | |
static void test_easy(const char *url, int use_ssl) { | |
CURLcode status; | |
CURL *c; | |
c = curl_easy_init(); | |
assert(c != NULL); | |
curl_easy_setopt(c, CURLOPT_URL, url); | |
curl_easy_setopt(c, CURLOPT_USE_SSL, use_ssl); | |
curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0); | |
status = curl_easy_perform(c); | |
assert(status == CURLE_OK); | |
curl_easy_cleanup(c); | |
} | |
int main(void) { | |
if (curl_global_init(CURL_GLOBAL_ALL)) { | |
abort(); | |
} | |
atexit(curl_global_cleanup); | |
test_easy(IMAP_URL, 0); // plain IMAP | |
test_easy(IMAP_URL, 1); // upgrade to TLS | |
test_easy(IMAPS_URL, 0); // start with TLS | |
test_multi(IMAP_URL, 0); // plain IMAP | |
test_multi(IMAP_URL, 1); // upgrade to TLS | |
test_multi(IMAPS_URL, 0); // start with TLS | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include <sys/select.h> | |
#include <curl/curl.h> | |
#define POP3_URL "pop3://testuser:testuser@localhost/" | |
#define POP3S_URL "pop3s://testuser:testuser@localhost/" | |
static long timeout_ = -1; | |
static int sockfd_ = -1; | |
static int events_ = -1; | |
static int socket_callback(CURL *c, curl_socket_t sockfd, int events, void *userp, void *socketp) { | |
sockfd_ = sockfd; | |
events_ = events; | |
return CURLM_OK; | |
} | |
static int multi_timer_callback(CURLM *m, long timeout, void *userp) { | |
timeout_ = timeout; | |
return CURLM_OK; | |
} | |
static void test_multi(const char *url, int use_ssl) { | |
struct timeval tv; | |
fd_set readfds; | |
fd_set writefds; | |
CURLMcode status; | |
CURLM *m; | |
CURL *c; | |
int n_fds; | |
if (curl_global_init(CURL_GLOBAL_ALL)) { | |
abort(); | |
} | |
atexit(curl_global_cleanup); | |
m = curl_multi_init(); | |
c = curl_easy_init(); | |
assert(m != NULL); | |
assert(c != NULL); | |
curl_multi_setopt(m, CURLMOPT_TIMERFUNCTION, multi_timer_callback); | |
curl_multi_setopt(m, CURLMOPT_SOCKETFUNCTION, socket_callback); | |
curl_easy_setopt(c, CURLOPT_URL, url); | |
curl_easy_setopt(c, CURLOPT_VERBOSE, 1); | |
curl_easy_setopt(c, CURLOPT_USE_SSL, use_ssl); | |
curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0); | |
status = curl_multi_add_handle(m, c); | |
assert(status == CURLM_OK); | |
status = curl_multi_socket_all(m, &n_fds); | |
assert(status == CURLM_OK); | |
assert(n_fds > 0); | |
assert(sockfd_ != -1); | |
assert(events_ != -1); | |
assert(timeout_ != -1); | |
do { | |
FD_ZERO(&readfds); | |
FD_ZERO(&writefds); | |
if (events_ & CURL_POLL_IN) { | |
FD_SET(sockfd_, &readfds); | |
} | |
if (events_ & CURL_POLL_OUT) { | |
FD_SET(sockfd_, &writefds); | |
} | |
if (timeout_ == -1) { | |
// 100 ms timeout | |
tv.tv_sec = 0; | |
tv.tv_usec = 100 * 1000; | |
} | |
else { | |
tv.tv_sec = timeout_ / 1000; | |
tv.tv_usec = (timeout_ % 1000) * 1000; | |
} | |
if (-1 == select(sockfd_ + 1, &readfds, &writefds, NULL, &tv)) { | |
perror("select"); | |
abort(); | |
} | |
status = curl_multi_socket_all(m, &n_fds); | |
assert(status == CURLM_OK); | |
} | |
while (n_fds > 0); | |
assert(events_ == CURL_POLL_REMOVE); | |
curl_multi_remove_handle(m, c); | |
curl_multi_cleanup(m); | |
curl_easy_cleanup(c); | |
} | |
static void test_easy(const char *url, int use_ssl) { | |
CURLcode status; | |
CURL *c; | |
c = curl_easy_init(); | |
assert(c != NULL); | |
curl_easy_setopt(c, CURLOPT_URL, url); | |
curl_easy_setopt(c, CURLOPT_VERBOSE, 1); | |
curl_easy_setopt(c, CURLOPT_USE_SSL, use_ssl); | |
curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0); | |
status = curl_easy_perform(c); | |
assert(status == CURLE_OK); | |
curl_easy_cleanup(c); | |
} | |
int main(void) { | |
if (curl_global_init(CURL_GLOBAL_ALL)) { | |
abort(); | |
} | |
atexit(curl_global_cleanup); | |
test_easy(POP3_URL, 0); // plain POP3 | |
test_easy(POP3_URL, 1); // upgrade to TLS | |
test_easy(POP3S_URL, 0); // start with TLS | |
test_multi(POP3_URL, 0); // plain POP3 | |
test_multi(POP3_URL, 1); // upgrade to TLS | |
test_multi(POP3S_URL, 0); // start with TLS | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include <sys/select.h> | |
#include <curl/curl.h> | |
#define SMTP_URL "smtp://localhost/" | |
#define SMTPS_URL "smtps://localhost/" | |
#define CRLF "\r\n" | |
typedef struct { | |
const char *p, *pe; | |
} READER; | |
static long timeout_ = -1; | |
static int sockfd_ = -1; | |
static int events_ = -1; | |
static int socket_callback(CURL *c, curl_socket_t sockfd, int events, void *userp, void *socketp) { | |
sockfd_ = sockfd; | |
events_ = events; | |
return CURLM_OK; | |
} | |
static int multi_timer_callback(CURLM *m, long timeout, void *userp) { | |
timeout_ = timeout; | |
return CURLM_OK; | |
} | |
static size_t read_callback(char *buffer, size_t size, size_t nitems, void *userp) { | |
READER *r = userp; | |
if (r->p >= r->pe) { | |
return 0; | |
} | |
size_t len = size * nitems; | |
size_t left = r->pe - r->p; | |
if (len > left) { | |
len = left; | |
} | |
memcpy(buffer, r->p, len); | |
r->p += len; | |
return len; | |
} | |
// this function leaks memory but we don't care because it's only a test | |
static CURL *create_easy_handle(const char *url, int use_ssl) { | |
#define CRLF "\r\n" | |
static const char data[] = | |
"Subject: Test 1,2,3" CRLF | |
CRLF | |
"This is a test message." CRLF | |
; | |
struct curl_slist *recipients; | |
READER *r; | |
CURL *c; | |
recipients = curl_slist_append(NULL, "\"Q.A. Tester\" <testuser@localhost>"); | |
c = curl_easy_init(); | |
assert(c != NULL); | |
curl_easy_setopt(c, CURLOPT_URL, url); | |
curl_easy_setopt(c, CURLOPT_VERBOSE, 1); | |
curl_easy_setopt(c, CURLOPT_USE_SSL, use_ssl); | |
curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0); | |
curl_easy_setopt(c, CURLOPT_MAIL_FROM, "\"Q.A. Tester\" <testuser@localhost>"); | |
curl_easy_setopt(c, CURLOPT_MAIL_RCPT, recipients); | |
curl_easy_setopt(c, CURLOPT_READFUNCTION, read_callback); | |
r = malloc(sizeof *r); | |
r->p = data; | |
r->pe = data + sizeof(data) - 1; | |
curl_easy_setopt(c, CURLOPT_READDATA, r); | |
return c; | |
} | |
static void test_multi(const char *url, int use_ssl) { | |
struct timeval tv; | |
fd_set readfds; | |
fd_set writefds; | |
CURLMcode status; | |
CURLM *m; | |
CURL *c; | |
int n_fds; | |
if (curl_global_init(CURL_GLOBAL_ALL)) { | |
abort(); | |
} | |
atexit(curl_global_cleanup); | |
m = curl_multi_init(); | |
assert(m != NULL); | |
curl_multi_setopt(m, CURLMOPT_TIMERFUNCTION, multi_timer_callback); | |
curl_multi_setopt(m, CURLMOPT_SOCKETFUNCTION, socket_callback); | |
c = create_easy_handle(url, use_ssl); | |
status = curl_multi_add_handle(m, c); | |
assert(status == CURLM_OK); | |
status = curl_multi_socket_all(m, &n_fds); | |
assert(status == CURLM_OK); | |
assert(n_fds > 0); | |
assert(sockfd_ != -1); | |
assert(events_ != -1); | |
assert(timeout_ != -1); | |
do { | |
FD_ZERO(&readfds); | |
FD_ZERO(&writefds); | |
if (events_ & CURL_POLL_IN) { | |
FD_SET(sockfd_, &readfds); | |
} | |
if (events_ & CURL_POLL_OUT) { | |
FD_SET(sockfd_, &writefds); | |
} | |
if (timeout_ == -1) { | |
// 100 ms timeout | |
tv.tv_sec = 0; | |
tv.tv_usec = 100 * 1000; | |
} | |
else { | |
tv.tv_sec = timeout_ / 1000; | |
tv.tv_usec = (timeout_ % 1000) * 1000; | |
} | |
if (-1 == select(sockfd_ + 1, &readfds, &writefds, NULL, &tv)) { | |
perror("select"); | |
abort(); | |
} | |
status = curl_multi_socket_all(m, &n_fds); | |
assert(status == CURLM_OK); | |
} | |
while (n_fds > 0); | |
assert(events_ == CURL_POLL_REMOVE); | |
curl_multi_remove_handle(m, c); | |
curl_multi_cleanup(m); | |
curl_easy_cleanup(c); | |
} | |
static void test_easy(const char *url, int use_ssl) { | |
CURLcode status; | |
CURL *c; | |
c = create_easy_handle(url, use_ssl); | |
status = curl_easy_perform(c); | |
puts(curl_easy_strerror(status)); | |
assert(status == CURLE_OK); | |
curl_easy_cleanup(c); | |
} | |
int main(void) { | |
if (curl_global_init(CURL_GLOBAL_ALL)) { | |
abort(); | |
} | |
atexit(curl_global_cleanup); | |
test_easy(SMTP_URL, 0); // plain SMTP | |
test_easy(SMTP_URL, 1); // upgrade to TLS | |
test_easy(SMTPS_URL, 0); // start with TLS | |
test_multi(SMTP_URL, 0); // plain SMTP | |
test_multi(SMTP_URL, 1); // upgrade to TLS | |
test_multi(SMTPS_URL, 0); // start with TLS | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment