From e39c209c36847ba896ec1686528d33a77ca59a6b Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 15 May 2018 20:48:17 +0100 Subject: [PATCH] Switch from libsoup2.4 to libcurl4 to perform HTTP requests --- .gitlab-ci.yml | 2 +- Makefile | 4 +-- README.md | 2 +- delta-connection.c | 77 +++++++++++++++++++++++++++++++++++++++------- 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 489ff26..0e56fb7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,7 +16,7 @@ Debian 9: - cp /usr/local/lib/x86_64-linux-gnu/libdeltachat.so libdeltachat.so - cp /usr/local/lib/x86_64-linux-gnu/libnetpgp.so libnetpgp.so # purple-plugin-delta - - apt install --no-install-recommends -yy libpurple-dev libsoup2.4-dev libglib2.0-dev + - apt install --no-install-recommends -yy libpurple-dev libcurl4-openssl-dev libglib2.0-dev - make artifacts: paths: diff --git a/Makefile b/Makefile index e101c80..bc0d37c 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,11 @@ libdelta.so: *.c *.h Makefile -std=c11 \ -shared \ -fpic \ - $(shell pkg-config --cflags purple libsoup-2.4) \ + $(shell pkg-config --cflags purple libcurl) \ -o libdelta.so \ *.c \ -shared \ - $(shell pkg-config --libs purple libsoup-2.4) \ + $(shell pkg-config --libs purple libcurl) \ -ldeltachat clean: diff --git a/README.md b/README.md index 5737590..176a2a0 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ you'll need to build and install it according to Now, you'll need some other build dependencies: ``` -sudo apt install build-essential libpurple-dev libsoup2.4-dev libglib2.0-dev +sudo apt install build-essential libpurple-dev libcurl4-openssl-dev libglib2.0-dev ``` Finally, run `make` to create a `libdelta.so` file. diff --git a/delta-connection.c b/delta-connection.c index 15e5e5c..1429b6c 100644 --- a/delta-connection.c +++ b/delta-connection.c @@ -1,8 +1,12 @@ #include #include +#include + #include -#include + +#include +#include #include "delta-connection.h" #include "libdelta.h" @@ -40,23 +44,74 @@ _transpose_config(mrmailbox_t *mailbox, PurpleAccount *acct) mrmailbox_set_config_int(mailbox, PLUGIN_ACCOUNT_OPT_SMTP_SERVER_PORT, smtp_port); } +// This and WriteMemoryCallback are "borrowed" from https://curl.haxx.se/libcurl/c/getinmemory.html +struct MemoryStruct { + char *memory; + size_t size; +}; + +static size_t +WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)userp; + + mem->memory = realloc(mem->memory, mem->size + realsize + 1); + if(mem->memory == NULL) { + printf("not enough memory (realloc returned NULL)\n"); + return 0; + } + + memcpy(&(mem->memory[mem->size]), contents, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + + return realsize; +} + uintptr_t _http_get(const char *url) { - // FIXME: we could keep a soup session around for more than a single request + long status = 0; uintptr_t out = 0; - guint status; - SoupSession *session = soup_session_new(); - SoupMessage *msg = soup_message_new("GET", url); + CURL *curl = curl_easy_init(); + CURLcode res; - status = soup_session_send_message(session, msg); - - if (status >= 200 && status < 300) { - out = (uintptr_t)msg->response_body->data; + if (curl == NULL) { + return 0; } -// g_free(msg); // FIXME: huge memory leak -// g_free(session); + struct MemoryStruct chunk; + chunk.memory = malloc(1); /* will be grown as needed by the realloc above */ + chunk.size = 0; /* no data at this point */ + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); + + res = curl_easy_perform(curl); + if (res != CURLE_OK) { + printf("Failed to GET %s: %s\n", url, curl_easy_strerror(res)); + goto err; + } + + res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); + if (res != CURLE_OK) { + printf("Failed to read response code for %s: %s\n", url, curl_easy_strerror(res)); + goto err; + } + + if (status < 200 || status > 299) { + printf("Non-success HTTP response code for %s: %lu\n", url, status); + goto err; + } + + out = (uintptr_t)chunk.memory; + +err: + curl_easy_cleanup(curl); + + // Don't free chunk.memory - that will be done by deltachat-core return out; }