Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@
ok: 1 or 0,
status: response status code,
data: response text/data,
size: size of data
size: size of data,
code: curl error code
}

Requests use a 30 second overall timeout and a 10 second connect timeout by
default. A timeout leaves `ok` at `0` and sets `code` to
`CURLE_OPERATION_TIMEDOUT`.

### `int http_get_file(const char *url, const char *file)`

Perform an HTTP GET request on `url` and save the response to `file`. Returns `0` on success and `-1` on failures.
Perform an HTTP GET request on `url` and save the response to `file`. Returns
`0` on success, `-2` on timeout, and `-1` on other failures.

### `void http_get_free(http_get_response_t *res)`

Expand Down
44 changes: 28 additions & 16 deletions src/http-get.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#include <curl/curl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "http-get.h"
Expand Down Expand Up @@ -40,27 +41,39 @@ static size_t http_get_cb(void *contents, size_t size, size_t nmemb, void *userp
return realsize;
}

static void http_get_configure(CURL *req, CURLSH *share) {
if (share) {
curl_easy_setopt(req, CURLOPT_SHARE, share);
}

curl_easy_setopt(req, CURLOPT_HTTPGET, 1);
curl_easy_setopt(req, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(req, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(req, CURLOPT_CONNECTTIMEOUT, HTTP_GET_CONNECT_TIMEOUT);
curl_easy_setopt(req, CURLOPT_TIMEOUT, HTTP_GET_TIMEOUT);
}

http_get_response_t *http_get_shared(const char *url, CURLSH *share) {
CURL *req = curl_easy_init();
if (!req) return NULL;

http_get_response_t *res = malloc(sizeof(http_get_response_t));
memset(res, 0, sizeof(http_get_response_t));

if (share) {
curl_easy_setopt(req, CURLOPT_SHARE, share);
if (!res) {
curl_easy_cleanup(req);
return NULL;
}
memset(res, 0, sizeof(http_get_response_t));

curl_easy_setopt(req, CURLOPT_URL, url);
curl_easy_setopt(req, CURLOPT_HTTPGET, 1);
curl_easy_setopt(req, CURLOPT_FOLLOWLOCATION, 1);
http_get_configure(req, share);
curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, http_get_cb);
curl_easy_setopt(req, CURLOPT_WRITEDATA, (void *) res);
curl_easy_setopt(req, CURLOPT_USERAGENT, "http-get.c/"HTTP_GET_VERSION);

int c = curl_easy_perform(req);
res->code = curl_easy_perform(req);

curl_easy_getinfo(req, CURLINFO_RESPONSE_CODE, &res->status);
res->ok = (200 == res->status && CURLE_ABORTED_BY_CALLBACK != c) ? 1 : 0;
res->ok = (200 == res->status && CURLE_OK == res->code) ? 1 : 0;
curl_easy_cleanup(req);

return res;
Expand Down Expand Up @@ -93,26 +106,25 @@ int http_get_file_shared(const char *url, const char *file, CURLSH *share) {
if (!req) return -1;

FILE *fp = fopen(file, "wb");
if (!fp) return -1;

if (share) {
curl_easy_setopt(req, CURLOPT_SHARE, share);
if (!fp) {
curl_easy_cleanup(req);
return -1;
}

curl_easy_setopt(req, CURLOPT_URL, url);
curl_easy_setopt(req, CURLOPT_HTTPGET, 1);
curl_easy_setopt(req, CURLOPT_FOLLOWLOCATION, 1);
http_get_configure(req, share);
curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, http_get_file_cb);
curl_easy_setopt(req, CURLOPT_WRITEDATA, fp);
int res = curl_easy_perform(req);
CURLcode res = curl_easy_perform(req);

long status;
curl_easy_getinfo(req, CURLINFO_RESPONSE_CODE, &status);

curl_easy_cleanup(req);
fclose(fp);

return (200 == status && CURLE_ABORTED_BY_CALLBACK != res) ? 0 : -1;
if (CURLE_OPERATION_TIMEDOUT == res) return -2;
return (200 == status && CURLE_OK == res) ? 0 : -1;
}

int http_get_file(const char *url, const char *file) {
Expand Down
4 changes: 4 additions & 0 deletions src/http-get.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
#define HTTP_GET_H 1

#include <stdlib.h>
#include <curl/curl.h>

#define HTTP_GET_VERSION "0.4.0"
#define HTTP_GET_TIMEOUT 30L
#define HTTP_GET_CONNECT_TIMEOUT 10L

typedef struct {
char *data;
size_t size;
long status;
int ok;
CURLcode code;
} http_get_response_t;

http_get_response_t *http_get(const char *);
Expand Down