about summary refs log tree commit diff
path: root/btpd/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'btpd/http.c')
-rw-r--r--btpd/http.c251
1 files changed, 0 insertions, 251 deletions
diff --git a/btpd/http.c b/btpd/http.c
deleted file mode 100644
index f1e6b7e..0000000
--- a/btpd/http.c
+++ /dev/null
@@ -1,251 +0,0 @@
-#include <pthread.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <curl/curl.h>
-
-#include "btpd.h"
-#include "http.h"
-
-#define MAX_DOWNLOAD (1 << 18)  // 256kB
-#define CURL_SELECT_TIME (& (struct timeval) { 1, 0 })
-
-enum http_state {
-    HS_ADD,
-    HS_ACTIVE,
-    HS_DONE,
-    HS_NOADD,
-    HS_CANCEL
-};
-
-struct http {
-    long t_created;
-    enum http_state state;
-    char *url;
-    CURL *curlh;
-    struct http_res res;
-    BTPDQ_ENTRY(http) entry;
-    void (*cb)(struct http *, struct http_res *, void *);
-    void *cb_arg;
-};
-
-BTPDQ_HEAD(http_tq, http);
-
-static struct http_tq m_httpq = BTPDQ_HEAD_INITIALIZER(m_httpq);
-static pthread_mutex_t m_httpq_lock;
-static pthread_cond_t m_httpq_cond;
-static CURLM *m_curlh;
-
-static size_t
-http_write_cb(void *ptr, size_t size, size_t nmemb, void *arg)
-{
-    char *mem;
-    struct http_res *res = arg;
-    size_t nbytes = size * nmemb;
-    size_t nlength = res->length + nbytes;
-    if (nlength > MAX_DOWNLOAD)
-        return 0;
-    if ((mem = realloc(res->content, nlength)) == NULL)
-        return 0;
-    res->content = mem;
-    bcopy(ptr, res->content + res->length, nbytes);
-    res->length = nlength;
-    return nbytes;
-}
-
-int
-http_get(struct http **ret,
-    void (*cb)(struct http *, struct http_res *, void *), void *arg,
-    const char *fmt, ...)
-{
-    struct http *h = btpd_calloc(1, sizeof(*h));
-
-    h->state = HS_ADD;
-    h->cb = cb;
-    h->cb_arg = arg;
-    h->t_created = btpd_seconds;
-    if ((h->curlh = curl_easy_init()) == NULL)
-        btpd_err("Fatal error in curl.\n");
-
-    va_list ap;
-    va_start(ap, fmt);
-    if (vasprintf(&h->url, fmt, ap) == -1)
-        btpd_err("Out of memory.\n");
-    va_end(ap);
-
-    curl_easy_setopt(h->curlh, CURLOPT_URL, h->url);
-    curl_easy_setopt(h->curlh, CURLOPT_USERAGENT, BTPD_VERSION);
-    curl_easy_setopt(h->curlh, CURLOPT_WRITEFUNCTION, http_write_cb);
-    curl_easy_setopt(h->curlh, CURLOPT_WRITEDATA, &h->res);
-    curl_easy_setopt(h->curlh, CURLOPT_FOLLOWLOCATION, 1);
-
-    pthread_mutex_lock(&m_httpq_lock);
-    BTPDQ_INSERT_TAIL(&m_httpq, h, entry);
-    pthread_mutex_unlock(&m_httpq_lock);
-    pthread_cond_signal(&m_httpq_cond);
-
-    if (ret != NULL)
-        *ret = h;
-
-    return 0;
-}
-
-long
-http_server_busy_time(const char *url, long s)
-{
-    struct http *h;
-    size_t len = strlen(url);
-
-    pthread_mutex_lock(&m_httpq_lock);
-    h = BTPDQ_LAST(&m_httpq, http_tq);
-    while (h != NULL &&
-            !((h->state == HS_ACTIVE || h->state == HS_ADD) &&
-                strncmp(url, h->url, len) == 0))
-        h = BTPDQ_PREV(h, http_tq, entry);
-    pthread_mutex_unlock(&m_httpq_lock);
-
-    if (h == NULL || btpd_seconds - h->t_created >= s)
-        return 0;
-    else
-        return s - (btpd_seconds - h->t_created);
-}
-
-void
-http_cancel(struct http *http)
-{
-    pthread_mutex_lock(&m_httpq_lock);
-    if (http->state == HS_ADD)
-        http->state = HS_NOADD;
-    else
-        http->state = HS_CANCEL;
-    pthread_mutex_unlock(&m_httpq_lock);
-}
-
-int
-http_succeeded(struct http_res *res)
-{
-    return res->res == HRES_OK && res->code >= 200 && res->code < 300;
-}
-
-static void
-http_td_cb(void *arg)
-{
-    struct http *h = arg;
-    if (h->res.res == HRES_OK)
-        curl_easy_getinfo(h->curlh, CURLINFO_RESPONSE_CODE, &h->res.code);
-    if (h->res.res == HRES_FAIL)
-        h->res.errmsg = curl_easy_strerror(h->res.code);
-    if (h->state != HS_CANCEL)
-        h->cb(h, &h->res, h->cb_arg);
-    curl_easy_cleanup(h->curlh);
-    if (h->res.content != NULL)
-        free(h->res.content);
-    free(h->url);
-    free(h);
-}
-
-static void
-http_td_actions(void)
-{
-    int nmsgs;
-    struct http *http, *next;
-    struct http_tq postq;
-    CURLMsg *cmsg;
-
-    pthread_mutex_lock(&m_httpq_lock);
-    do {
-        while (BTPDQ_EMPTY(&m_httpq))
-            pthread_cond_wait(&m_httpq_cond, &m_httpq_lock);
-
-        BTPDQ_INIT(&postq);
-
-        BTPDQ_FOREACH_MUTABLE(http, &m_httpq, entry, next) {
-            switch (http->state) {
-            case HS_ADD:
-                curl_multi_add_handle(m_curlh, http->curlh);
-                http->state = HS_ACTIVE;
-                break;
-            case HS_CANCEL:
-                curl_multi_remove_handle(m_curlh, http->curlh);
-            case HS_NOADD:
-                BTPDQ_REMOVE(&m_httpq, http, entry);
-                BTPDQ_INSERT_TAIL(&postq, http, entry);
-                http->state = HS_CANCEL;
-                http->res.res = HRES_CANCEL;
-                break;
-            case HS_DONE:
-                abort();
-            default:
-                break;
-            }
-        }
-
-        while ((cmsg = curl_multi_info_read(m_curlh, &nmsgs)) != NULL) {
-            BTPDQ_FOREACH(http, &m_httpq, entry) {
-                if (http->curlh == cmsg->easy_handle)
-                    break;
-            }
-            assert(http != NULL);
-            BTPDQ_REMOVE(&m_httpq, http, entry);
-            BTPDQ_INSERT_TAIL(&postq, http, entry);
-            http->state = HS_DONE;
-            if (cmsg->data.result == 0)
-                http->res.res = HRES_OK;
-            else {
-                http->res.res = HRES_FAIL;
-                http->res.code = cmsg->data.result;
-            }
-            curl_multi_remove_handle(m_curlh, http->curlh);
-        }
-
-        if (!BTPDQ_EMPTY(&postq)) {
-            pthread_mutex_unlock(&m_httpq_lock);
-            td_post_begin();
-            BTPDQ_FOREACH(http, &postq, entry)
-                td_post(http_td_cb, http);
-            td_post_end();
-            pthread_mutex_lock(&m_httpq_lock);
-        }
-    } while (BTPDQ_EMPTY(&m_httpq));
-    pthread_mutex_unlock(&m_httpq_lock);
-}
-
-static void
-http_td(void *arg)
-{
-    fd_set rset, wset, eset;
-    int maxfd, nbusy;
-
-    for (;;) {
-        http_td_actions();
-
-        while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(m_curlh, &nbusy))
-            ;
-
-        if (nbusy > 0) {
-            FD_ZERO(&rset);
-            FD_ZERO(&wset);
-            FD_ZERO(&eset);
-            curl_multi_fdset(m_curlh, &rset, &wset, &eset, &maxfd);
-            select(maxfd + 1, &rset, &wset, &eset, CURL_SELECT_TIME);
-        }
-    }
-}
-
-static void
-errdie(int err)
-{
-    if (err != 0)
-        btpd_err("Fatal error in http_init.\n");
-}
-
-void
-http_init(void)
-{
-    pthread_t ret;
-    errdie(curl_global_init(0));
-    errdie((m_curlh = curl_multi_init()) == NULL);
-    errdie(pthread_mutex_init(&m_httpq_lock, NULL));
-    errdie(pthread_cond_init(&m_httpq_cond, NULL));
-    errdie(pthread_create(&ret, NULL, (void *(*)(void *))http_td, NULL));
-}