Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
libreport.spec.in | 2 +-
po/POTFILES.in | 2 +-
src/include/Makefile.am | 2 +-
src/include/abrt_curl.h | 117 ---------
src/include/libreport_curl.h | 117 +++++++++
src/lib/Makefile.am | 2 +-
src/lib/abrt_curl.c | 499 -------------------------------------
src/lib/curl.c | 499 +++++++++++++++++++++++++++++++++++++
src/lib/json.c | 2 +-
src/plugins/abrt-bodhi.c | 2 +-
src/plugins/abrt_rh_support.c | 2 +-
src/plugins/reporter-kerneloops.c | 2 +-
src/plugins/reporter-rhtsupport.c | 2 +-
src/plugins/reporter-upload.c | 2 +-
src/plugins/ureport.c | 2 +-
15 files changed, 627 insertions(+), 627 deletions(-)
delete mode 100644 src/include/abrt_curl.h
create mode 100644 src/include/libreport_curl.h
delete mode 100644 src/lib/abrt_curl.c
create mode 100644 src/lib/curl.c
diff --git a/libreport.spec.in b/libreport.spec.in
index f758d2e..599986d 100644
--- a/libreport.spec.in
+++ b/libreport.spec.in
@@ -321,7 +321,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null ||
:
%files web-devel
%defattr(-,root,root,-)
-%{_includedir}/libreport/abrt_curl.h
+%{_includedir}/libreport/libreport_curl.h
%{_libdir}/pkgconfig/libreport-web.pc
%files python
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9fac721..f32ba57 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -11,7 +11,7 @@ src/gui-wizard-gtk/wizard.c
src/gui-wizard-gtk/wizard.glade
src/lib/event_config.c
src/lib/parse_options.c
-src/lib/abrt_curl.c
+src/lib/curl.c
src/lib/client.c
src/lib/run_event.c
src/lib/problem_data.c
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index fc73545..61b49a3 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -6,7 +6,7 @@ libreport_include_HEADERS = \
problem_data.h \
report.h \
run_event.h \
- abrt_curl.h \
+ libreport_curl.h \
\
internal_libreport.h \
internal_abrt_dbus.h
diff --git a/src/include/abrt_curl.h b/src/include/abrt_curl.h
deleted file mode 100644
index ca3c5b8..0000000
--- a/src/include/abrt_curl.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- Copyright (C) 2010 ABRT team
- Copyright (C) 2010 RedHat Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-#ifndef ABRT_CURL_H_
-#define ABRT_CURL_H_
-
-#include <curl/curl.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-CURL* xcurl_easy_init();
-
-/* Set proxy according to the url and call curl_easy_perform */
-CURLcode curl_easy_perform_with_proxy(CURL *handle, const char *url);
-
-typedef struct abrt_post_state {
- /* Supplied by caller: */
- int flags;
- const char *username;
- const char *password;
- /* Results of POST transaction: */
- int http_resp_code;
- unsigned header_cnt;
- char **headers;
- char *curl_error_msg;
- char *body;
- size_t body_size;
- char errmsg[CURL_ERROR_SIZE];
-} abrt_post_state_t;
-
-abrt_post_state_t *new_abrt_post_state(int flags);
-void free_abrt_post_state(abrt_post_state_t *state);
-char *find_header_in_abrt_post_state(abrt_post_state_t *state, const char *str);
-
-enum {
- ABRT_POST_WANT_HEADERS = (1 << 0),
- ABRT_POST_WANT_ERROR_MSG = (1 << 1),
- ABRT_POST_WANT_BODY = (1 << 2),
- ABRT_POST_WANT_SSL_VERIFY = (1 << 3),
-};
-enum {
- /* Must be -1! CURLOPT_POSTFIELDSIZE interprets -1 as "use strlen" */
- ABRT_POST_DATA_STRING = -1,
- ABRT_POST_DATA_FROMFILE = -2,
- ABRT_POST_DATA_FROMFILE_AS_FORM_DATA = -3,
- ABRT_POST_DATA_STRING_AS_FORM_DATA = -4,
-};
-int
-abrt_post(abrt_post_state_t *state,
- const char *url,
- const char *content_type,
- const char **additional_headers,
- const char *data,
- off_t data_size);
-static inline int
-abrt_post_string(abrt_post_state_t *state,
- const char *url,
- const char *content_type,
- const char **additional_headers,
- const char *str)
-{
- return abrt_post(state, url, content_type, additional_headers,
- str, ABRT_POST_DATA_STRING);
-}
-static inline int
-abrt_post_string_as_form_data(abrt_post_state_t *state,
- const char *url,
- const char *content_type,
- const char **additional_headers,
- const char *str)
-{
- return abrt_post(state, url, content_type, additional_headers,
- str, ABRT_POST_DATA_STRING_AS_FORM_DATA);
-}
-static inline int
-abrt_post_file(abrt_post_state_t *state,
- const char *url,
- const char *content_type,
- const char **additional_headers,
- const char *filename)
-{
- return abrt_post(state, url, content_type, additional_headers,
- filename, ABRT_POST_DATA_FROMFILE);
-}
-static inline int
-abrt_post_file_as_form(abrt_post_state_t *state,
- const char *url,
- const char *content_type,
- const char **additional_headers,
- const char *filename)
-{
- return abrt_post(state, url, content_type, additional_headers,
- filename, ABRT_POST_DATA_FROMFILE_AS_FORM_DATA);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/include/libreport_curl.h b/src/include/libreport_curl.h
new file mode 100644
index 0000000..ca3c5b8
--- /dev/null
+++ b/src/include/libreport_curl.h
@@ -0,0 +1,117 @@
+/*
+ Copyright (C) 2010 ABRT team
+ Copyright (C) 2010 RedHat Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#ifndef ABRT_CURL_H_
+#define ABRT_CURL_H_
+
+#include <curl/curl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CURL* xcurl_easy_init();
+
+/* Set proxy according to the url and call curl_easy_perform */
+CURLcode curl_easy_perform_with_proxy(CURL *handle, const char *url);
+
+typedef struct abrt_post_state {
+ /* Supplied by caller: */
+ int flags;
+ const char *username;
+ const char *password;
+ /* Results of POST transaction: */
+ int http_resp_code;
+ unsigned header_cnt;
+ char **headers;
+ char *curl_error_msg;
+ char *body;
+ size_t body_size;
+ char errmsg[CURL_ERROR_SIZE];
+} abrt_post_state_t;
+
+abrt_post_state_t *new_abrt_post_state(int flags);
+void free_abrt_post_state(abrt_post_state_t *state);
+char *find_header_in_abrt_post_state(abrt_post_state_t *state, const char *str);
+
+enum {
+ ABRT_POST_WANT_HEADERS = (1 << 0),
+ ABRT_POST_WANT_ERROR_MSG = (1 << 1),
+ ABRT_POST_WANT_BODY = (1 << 2),
+ ABRT_POST_WANT_SSL_VERIFY = (1 << 3),
+};
+enum {
+ /* Must be -1! CURLOPT_POSTFIELDSIZE interprets -1 as "use strlen" */
+ ABRT_POST_DATA_STRING = -1,
+ ABRT_POST_DATA_FROMFILE = -2,
+ ABRT_POST_DATA_FROMFILE_AS_FORM_DATA = -3,
+ ABRT_POST_DATA_STRING_AS_FORM_DATA = -4,
+};
+int
+abrt_post(abrt_post_state_t *state,
+ const char *url,
+ const char *content_type,
+ const char **additional_headers,
+ const char *data,
+ off_t data_size);
+static inline int
+abrt_post_string(abrt_post_state_t *state,
+ const char *url,
+ const char *content_type,
+ const char **additional_headers,
+ const char *str)
+{
+ return abrt_post(state, url, content_type, additional_headers,
+ str, ABRT_POST_DATA_STRING);
+}
+static inline int
+abrt_post_string_as_form_data(abrt_post_state_t *state,
+ const char *url,
+ const char *content_type,
+ const char **additional_headers,
+ const char *str)
+{
+ return abrt_post(state, url, content_type, additional_headers,
+ str, ABRT_POST_DATA_STRING_AS_FORM_DATA);
+}
+static inline int
+abrt_post_file(abrt_post_state_t *state,
+ const char *url,
+ const char *content_type,
+ const char **additional_headers,
+ const char *filename)
+{
+ return abrt_post(state, url, content_type, additional_headers,
+ filename, ABRT_POST_DATA_FROMFILE);
+}
+static inline int
+abrt_post_file_as_form(abrt_post_state_t *state,
+ const char *url,
+ const char *content_type,
+ const char **additional_headers,
+ const char *filename)
+{
+ return abrt_post(state, url, content_type, additional_headers,
+ filename, ABRT_POST_DATA_FROMFILE_AS_FORM_DATA);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index cd19e90..d2282db 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -91,7 +91,7 @@ libabrt_dbus_la_LIBADD = \
$(DBUS_LIBS)
libreport_web_la_SOURCES = \
- abrt_curl.c \
+ curl.c \
abrt_xmlrpc.h abrt_xmlrpc.c \
proxies.h proxies.c \
ureport.h json.c
diff --git a/src/lib/abrt_curl.c b/src/lib/abrt_curl.c
deleted file mode 100644
index 1ae773d..0000000
--- a/src/lib/abrt_curl.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- Copyright (C) 2010 ABRT team
- Copyright (C) 2010 RedHat Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-#include "internal_libreport.h"
-#include "abrt_curl.h"
-#include "proxies.h"
-
-/*
- * Utility functions
- */
-CURL* xcurl_easy_init()
-{
- CURL* curl = curl_easy_init();
- if (!curl)
- {
- error_msg_and_die("Can't create curl handle");
- }
- return curl;
-}
-
-static char*
-check_curl_error(CURLcode err, const char* msg)
-{
- if (err)
- return xasprintf("%s: %s", msg, curl_easy_strerror(err));
- return NULL;
-}
-
-static void
-die_if_curl_error(CURLcode err)
-{
- if (err) {
- char *msg = check_curl_error(err, "curl");
- error_msg_and_die("%s", msg);
- }
-}
-
-static void
-xcurl_easy_setopt_ptr(CURL *handle, CURLoption option, const void *parameter)
-{
- CURLcode err = curl_easy_setopt(handle, option, parameter);
- if (err) {
- char *msg = check_curl_error(err, "curl");
- error_msg_and_die("%s", msg);
- }
-}
-static inline void
-xcurl_easy_setopt_long(CURL *handle, CURLoption option, long parameter)
-{
- xcurl_easy_setopt_ptr(handle, option, (void*)parameter);
-}
-
-static void
-xcurl_easy_setopt_off_t(CURL *handle, CURLoption option, curl_off_t parameter)
-{
- /* Can't reuse xcurl_easy_setopt_ptr: paramter is too wide */
- CURLcode err = curl_easy_setopt(handle, option, parameter);
- if (err) {
- char *msg = check_curl_error(err, "curl");
- error_msg_and_die("%s", msg);
- }
-}
-
-CURLcode curl_easy_perform_with_proxy(CURL *handle, const char *url)
-{
- GList *proxy_list, *li;
- CURLcode curl_err;
-
- proxy_list = get_proxy_list(url);
-
- if (proxy_list)
- {
- /* Try with each proxy before giving up. */
- /* TODO: Should we repeat the perform call only on certain errors? */
- for (li = proxy_list, curl_err = 1; curl_err && li; li =
g_list_next(li))
- {
- xcurl_easy_setopt_ptr(handle, CURLOPT_PROXY, li->data);
- VERB3 log("Proxy set to: '%s'", (const char
*)li->data);
-
- curl_err = curl_easy_perform(handle);
- }
- } else
- curl_err = curl_easy_perform(handle);
-
- list_free_with_free(proxy_list);
-
- return curl_err;
-}
-
-/*
- * post_state utility functions
- */
-
-abrt_post_state_t *new_abrt_post_state(int flags)
-{
- abrt_post_state_t *state = (abrt_post_state_t *)xzalloc(sizeof(*state));
- state->flags = flags;
- return state;
-}
-
-void free_abrt_post_state(abrt_post_state_t *state)
-{
- char **headers = state->headers;
- if (headers)
- {
- while (*headers)
- free(*headers++);
- free(state->headers);
- }
- free(state->curl_error_msg);
- free(state->body);
- free(state);
-}
-
-char *find_header_in_abrt_post_state(abrt_post_state_t *state, const char *str)
-{
- char **headers = state->headers;
- if (headers)
- {
- unsigned len = strlen(str);
- while (*headers)
- {
- if (strncmp(*headers, str, len) == 0)
- return skip_whitespace(*headers + len);
- headers++;
- }
- }
- return NULL;
-}
-
-/*
- * abrt_post: perform HTTP POST transaction
- */
-
-/* "save headers" callback */
-static size_t
-save_headers(void *buffer_pv, size_t count, size_t nmemb, void *ptr)
-{
- abrt_post_state_t* state = (abrt_post_state_t*)ptr;
- size_t size = count * nmemb;
-
- char *h = xstrndup((char*)buffer_pv, size);
- strchrnul(h, '\r')[0] = '\0';
- strchrnul(h, '\n')[0] = '\0';
-
- unsigned cnt = state->header_cnt;
-
- /* Check for the case when curl follows a redirect:
- * header 0: 'HTTP/1.1 301 Moved Permanently'
- * header 1: 'Connection: close'
- * header 2: 'Location: NEW_URL'
- * header 3: ''
- * header 0: 'HTTP/1.1 200 OK' <-- we need to forget all hdrs and start
anew
- */
- if (cnt != 0
- && strncmp(h, "HTTP/", 5) == 0
- && state->headers[cnt-1][0] == '\0' /* prev header is an empty
string */
- ) {
- char **headers = state->headers;
- if (headers)
- {
- while (*headers)
- free(*headers++);
- }
- cnt = 0;
- }
-
- VERB3 log("save_headers: header %d: '%s'", cnt, h);
- state->headers = (char**)xrealloc(state->headers, (cnt+2) *
sizeof(state->headers[0]));
- state->headers[cnt] = h;
- state->header_cnt = ++cnt;
- state->headers[cnt] = NULL;
-
- return size;
-}
-
-/* "read local data from a file" callback */
-static size_t fread_with_reporting(void *ptr, size_t size, size_t nmemb, void *userdata)
-{
- static time_t last_t; // hack
-
- FILE *fp = (FILE*)userdata;
- time_t t = time(NULL);
-
- // Report current file position every 16 seconds
- if (!(t & 0xf) && last_t != t)
- {
- last_t = t;
- off_t cur_pos = ftello(fp);
- fseeko(fp, 0, SEEK_END);
- off_t sz = ftello(fp);
- fseeko(fp, cur_pos, SEEK_SET);
- log(_("Uploaded: %llu of %llu kbytes"),
- (unsigned long long)cur_pos / 1024,
- (unsigned long long)sz / 1024);
- }
-
- return fread(ptr, size, nmemb, fp);
-}
-
-static int curl_debug(CURL *handle, curl_infotype it, char *buf, size_t bufsize, void
*unused)
-{
- if (logmode == 0)
- return 0;
-
- switch (it) {
- case CURLINFO_TEXT: /* The data is informational text. */
- log("curl: %.*s", (int) bufsize, buf);
- break;
- case CURLINFO_HEADER_IN: /* The data is header (or header-like) data received from
the peer. */
- log("curl rcvd header: '%.*s'", (int) bufsize, buf);
- break;
- case CURLINFO_HEADER_OUT: /* The data is header (or header-like) data sent to the
peer. */
- log("curl sent header: '%.*s'", (int) bufsize, buf);
- break;
- case CURLINFO_DATA_IN: /* The data is protocol data received from the peer. */
- if (g_verbose >= 3)
- log("curl rcvd data: '%.*s'", (int) bufsize, buf);
- else
- log("curl rcvd data %u bytes", (int) bufsize);
- break;
- case CURLINFO_DATA_OUT: /* The data is protocol data sent to the peer. */
- if (g_verbose >= 3)
- log("curl sent data: '%.*s'", (int) bufsize, buf);
- else
- log("curl sent data %u bytes", (int) bufsize);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-int
-abrt_post(abrt_post_state_t *state,
- const char *url,
- const char *content_type,
- const char **additional_headers,
- const char *data,
- off_t data_size)
-{
- CURLcode curl_err;
- long response_code;
- abrt_post_state_t localstate;
-
- VERB3 log("abrt_post('%s','%s')", url, data);
-
- if (!state)
- {
- memset(&localstate, 0, sizeof(localstate));
- state = &localstate;
- }
-
- state->http_resp_code = response_code = -1;
-
- CURL *handle = xcurl_easy_init();
-
- // Buffer[CURL_ERROR_SIZE] curl stores human readable error messages in.
- // This may be more helpful than just return code from curl_easy_perform.
- // curl will need it until curl_easy_cleanup.
- state->errmsg[0] = '\0';
- xcurl_easy_setopt_ptr(handle, CURLOPT_ERRORBUFFER, state->errmsg);
- // Shut off the built-in progress meter completely
- xcurl_easy_setopt_long(handle, CURLOPT_NOPROGRESS, 1);
-
- if (g_verbose >= 2) {
- // "Display a lot of verbose information about its operations.
- // Very useful for libcurl and/or protocol debugging and understanding.
- // The verbose information will be sent to stderr, or the stream set
- // with CURLOPT_STDERR"
- xcurl_easy_setopt_long(handle, CURLOPT_VERBOSE, 1);
- xcurl_easy_setopt_ptr(handle, CURLOPT_DEBUGFUNCTION, curl_debug);
- }
-
- // TODO: do we need to check for CURLE_URL_MALFORMAT error *here*,
- // not in curl_easy_perform?
- xcurl_easy_setopt_ptr(handle, CURLOPT_URL, url);
-
- // Auth if configured
- if (state->username) {
- // bitmask of allowed auth methods
- xcurl_easy_setopt_long(handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
- xcurl_easy_setopt_ptr(handle, CURLOPT_USERNAME, state->username);
- xcurl_easy_setopt_ptr(handle, CURLOPT_PASSWORD, (state->password ?
state->password : ""));
- }
-
- // Do a regular HTTP post. This also makes curl use
- // a "Content-Type: application/x-www-form-urlencoded" header.
- // (This is by far the most commonly used POST method).
- xcurl_easy_setopt_long(handle, CURLOPT_POST, 1);
- // Supply POST data...
- struct curl_httppost* post = NULL;
- struct curl_httppost* last = NULL;
- FILE* data_file = NULL;
- if (data_size == ABRT_POST_DATA_FROMFILE) {
- // ...from a file
- data_file = fopen(data, "r");
- if (!data_file)
-//FIXME:
- perror_msg_and_die("Can't open '%s'", data);
- xcurl_easy_setopt_ptr(handle, CURLOPT_READDATA, data_file);
- // Want to use custom read function
- xcurl_easy_setopt_ptr(handle, CURLOPT_READFUNCTION, (const
void*)fread_with_reporting);
- // Without this, curl would send "Content-Length: -1"
- // servers don't like that: "413 Request Entity Too Large"
- fseeko(data_file, 0, SEEK_END);
- off_t sz = ftello(data_file);
- fseeko(data_file, 0, SEEK_SET);
- xcurl_easy_setopt_off_t(handle, CURLOPT_POSTFIELDSIZE_LARGE, sz);
- } else if (data_size == ABRT_POST_DATA_FROMFILE_AS_FORM_DATA) {
- // ...from a file, in multipart/formdata format
- const char *basename = strrchr(data, '/');
- if (basename) basename++;
- else basename = data;
-#if 0
- // Simple way, without custom reader function
- CURLFORMcode curlform_err = curl_formadd(&post, &last,
- CURLFORM_PTRNAME, "file", // element name
- CURLFORM_FILE, data, // filename to read from
- CURLFORM_CONTENTTYPE, content_type,
- CURLFORM_FILENAME, basename, // filename to put in the form
- CURLFORM_END);
-#else
- data_file = fopen(data, "r");
- if (!data_file)
-//FIXME:
- perror_msg_and_die("Can't open '%s'", data);
- // Want to use custom read function
- xcurl_easy_setopt_ptr(handle, CURLOPT_READFUNCTION, (const
void*)fread_with_reporting);
- // Need to know file size
- fseeko(data_file, 0, SEEK_END);
- off_t sz = ftello(data_file);
- fseeko(data_file, 0, SEEK_SET);
- // Create formdata
- CURLFORMcode curlform_err = curl_formadd(&post, &last,
- CURLFORM_PTRNAME, "file", // element name
- // use CURLOPT_READFUNCTION for reading, pass data_file as its
last param:
- CURLFORM_STREAM, data_file,
- CURLFORM_CONTENTSLENGTH, (long)sz, // a must if we use
CURLFORM_STREAM option
-//FIXME: what if file size doesn't fit in long?
- CURLFORM_CONTENTTYPE, content_type,
- CURLFORM_FILENAME, basename, // filename to put in the form
- CURLFORM_END);
-#endif
- if (curlform_err != 0)
-//FIXME:
- error_msg_and_die("out of memory or read error (curl_formadd error code:
%d)", (int)curlform_err);
- xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPPOST, post);
- } else if (data_size == ABRT_POST_DATA_STRING_AS_FORM_DATA) {
- CURLFORMcode curlform_err = curl_formadd(&post, &last,
- CURLFORM_PTRNAME, "file", // element name
- // curl bug - missing filename
- //
http://curl.haxx.se/mail/lib-2011-07/0176.html
- //
https://github.com/bagder/curl/commit/45d883d
- // fixed in curl-7.22.0~144
- // tested with curl-7.24.0-3
- // should be working on F17
- CURLFORM_BUFFER, "*buffer*", // provides filename
- CURLFORM_BUFFERPTR, data,
- CURLFORM_BUFFERLENGTH, (long)strlen(data),
-//FIXME: what if file size doesn't fit in long?
- CURLFORM_CONTENTTYPE, content_type,
- CURLFORM_END);
- if (curlform_err != 0)
- error_msg_and_die("out of memory or read error (curl_formadd error code:
%d)", (int)curlform_err);
- xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPPOST, post);
- } else {
- // .. from a blob in memory
- xcurl_easy_setopt_ptr(handle, CURLOPT_POSTFIELDS, data);
- // note1: if data_size == ABRT_POST_DATA_STRING == -1, curl will use
strlen(data)
- xcurl_easy_setopt_long(handle, CURLOPT_POSTFIELDSIZE, data_size);
- // We don't use CURLOPT_POSTFIELDSIZE_LARGE because
- // I'm not sure CURLOPT_POSTFIELDSIZE_LARGE special-cases -1.
- // Not a big problem: memory blobs >4GB are very unlikely.
- }
-
- struct curl_slist *httpheader_list = NULL;
-
- // Override "Content-Type:"
- if (data_size != ABRT_POST_DATA_FROMFILE_AS_FORM_DATA
- && data_size != ABRT_POST_DATA_STRING_AS_FORM_DATA)
- {
- char *content_type_header = xasprintf("Content-Type: %s",
content_type);
- // Note: curl_slist_append() copies content_type_header
- httpheader_list = curl_slist_append(httpheader_list, content_type_header);
- if (!httpheader_list)
- error_msg_and_die("out of memory");
- free(content_type_header);
- }
-
- for (; additional_headers && *additional_headers; additional_headers++)
- {
- httpheader_list = curl_slist_append(httpheader_list, *additional_headers);
- if (!httpheader_list)
- error_msg_and_die("out of memory");
- }
-
- // Add User-Agent: ABRT/N.M
- httpheader_list = curl_slist_append(httpheader_list, "User-Agent:
ABRT/"VERSION);
- if (!httpheader_list)
- error_msg_and_die("out of memory");
-
- if (httpheader_list)
- xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPHEADER, httpheader_list);
-
-// Disabled: was observed to also handle "305 Use proxy" redirect,
-// apparently with POST->GET remapping - which server didn't like at all.
-// Attempted to suppress remapping on 305 using CURLOPT_POSTREDIR of -1,
-// but it still did not work.
-#if 0
- // Please handle 301/302 redirects for me
- xcurl_easy_setopt_long(handle, CURLOPT_FOLLOWLOCATION, 1);
- xcurl_easy_setopt_long(handle, CURLOPT_MAXREDIRS, 10);
- // Bitmask to control how libcurl acts on redirects after POSTs.
- // Bit 0 set (value CURL_REDIR_POST_301) makes libcurl
- // not convert POST requests into GET requests when following
- // a 301 redirection. Bit 1 (value CURL_REDIR_POST_302) makes libcurl
- // maintain the request method after a 302 redirect.
- // CURL_REDIR_POST_ALL is a convenience define that sets both bits.
- // The non-RFC behaviour is ubiquitous in web browsers, so the library
- // does the conversion by default to maintain consistency.
- // However, a server may require a POST to remain a POST.
- xcurl_easy_setopt_long(handle, CURLOPT_POSTREDIR, -1L /*CURL_REDIR_POST_ALL*/ );
-#endif
-
- // Prepare for saving information
- if (state->flags & ABRT_POST_WANT_HEADERS)
- {
- xcurl_easy_setopt_ptr(handle, CURLOPT_HEADERFUNCTION, (void*)save_headers);
- xcurl_easy_setopt_ptr(handle, CURLOPT_WRITEHEADER, state);
- }
- FILE* body_stream = NULL;
- if (state->flags & ABRT_POST_WANT_BODY)
- {
- body_stream = open_memstream(&state->body, &state->body_size);
- if (!body_stream)
- error_msg_and_die("out of memory");
- xcurl_easy_setopt_ptr(handle, CURLOPT_WRITEDATA, body_stream);
- }
- if (!(state->flags & ABRT_POST_WANT_SSL_VERIFY))
- {
- xcurl_easy_setopt_long(handle, CURLOPT_SSL_VERIFYPEER, 0);
- xcurl_easy_setopt_long(handle, CURLOPT_SSL_VERIFYHOST, 0);
- }
-
- // This is the place where everything happens.
- // Here errors are not limited to "out of memory", can't just die.
- curl_err = curl_easy_perform_with_proxy(handle, url);
- if (curl_err)
- {
- VERB2 log("curl_easy_perform: error %d", (int)curl_err);
- if (state->flags & ABRT_POST_WANT_ERROR_MSG)
- {
- state->curl_error_msg = check_curl_error(curl_err,
"curl_easy_perform");
- VERB3 log("curl_easy_perform: error_msg: %s",
state->curl_error_msg);
- }
- goto ret;
- }
-
- // curl-7.20.1 doesn't do it, we get NULL body in the log message below
- // unless we fflush the body memstream ourself
- if (body_stream)
- fflush(body_stream);
-
- // Headers/body are already saved (if requested), extract more info
- curl_err = curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &response_code);
- die_if_curl_error(curl_err);
- state->http_resp_code = response_code;
- VERB3 log("after curl_easy_perform: http code %ld body:'%s'",
response_code, state->body);
-
- ret:
- curl_easy_cleanup(handle);
- if (httpheader_list)
- curl_slist_free_all(httpheader_list);
- if (body_stream)
- fclose(body_stream);
- if (data_file)
- fclose(data_file);
- if (post)
- curl_formfree(post);
-
- return response_code;
-}
diff --git a/src/lib/curl.c b/src/lib/curl.c
new file mode 100644
index 0000000..98b24f5
--- /dev/null
+++ b/src/lib/curl.c
@@ -0,0 +1,499 @@
+/*
+ Copyright (C) 2010 ABRT team
+ Copyright (C) 2010 RedHat Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "internal_libreport.h"
+#include "libreport_curl.h"
+#include "proxies.h"
+
+/*
+ * Utility functions
+ */
+CURL* xcurl_easy_init()
+{
+ CURL* curl = curl_easy_init();
+ if (!curl)
+ {
+ error_msg_and_die("Can't create curl handle");
+ }
+ return curl;
+}
+
+static char*
+check_curl_error(CURLcode err, const char* msg)
+{
+ if (err)
+ return xasprintf("%s: %s", msg, curl_easy_strerror(err));
+ return NULL;
+}
+
+static void
+die_if_curl_error(CURLcode err)
+{
+ if (err) {
+ char *msg = check_curl_error(err, "curl");
+ error_msg_and_die("%s", msg);
+ }
+}
+
+static void
+xcurl_easy_setopt_ptr(CURL *handle, CURLoption option, const void *parameter)
+{
+ CURLcode err = curl_easy_setopt(handle, option, parameter);
+ if (err) {
+ char *msg = check_curl_error(err, "curl");
+ error_msg_and_die("%s", msg);
+ }
+}
+static inline void
+xcurl_easy_setopt_long(CURL *handle, CURLoption option, long parameter)
+{
+ xcurl_easy_setopt_ptr(handle, option, (void*)parameter);
+}
+
+static void
+xcurl_easy_setopt_off_t(CURL *handle, CURLoption option, curl_off_t parameter)
+{
+ /* Can't reuse xcurl_easy_setopt_ptr: paramter is too wide */
+ CURLcode err = curl_easy_setopt(handle, option, parameter);
+ if (err) {
+ char *msg = check_curl_error(err, "curl");
+ error_msg_and_die("%s", msg);
+ }
+}
+
+CURLcode curl_easy_perform_with_proxy(CURL *handle, const char *url)
+{
+ GList *proxy_list, *li;
+ CURLcode curl_err;
+
+ proxy_list = get_proxy_list(url);
+
+ if (proxy_list)
+ {
+ /* Try with each proxy before giving up. */
+ /* TODO: Should we repeat the perform call only on certain errors? */
+ for (li = proxy_list, curl_err = 1; curl_err && li; li =
g_list_next(li))
+ {
+ xcurl_easy_setopt_ptr(handle, CURLOPT_PROXY, li->data);
+ VERB3 log("Proxy set to: '%s'", (const char
*)li->data);
+
+ curl_err = curl_easy_perform(handle);
+ }
+ } else
+ curl_err = curl_easy_perform(handle);
+
+ list_free_with_free(proxy_list);
+
+ return curl_err;
+}
+
+/*
+ * post_state utility functions
+ */
+
+abrt_post_state_t *new_abrt_post_state(int flags)
+{
+ abrt_post_state_t *state = (abrt_post_state_t *)xzalloc(sizeof(*state));
+ state->flags = flags;
+ return state;
+}
+
+void free_abrt_post_state(abrt_post_state_t *state)
+{
+ char **headers = state->headers;
+ if (headers)
+ {
+ while (*headers)
+ free(*headers++);
+ free(state->headers);
+ }
+ free(state->curl_error_msg);
+ free(state->body);
+ free(state);
+}
+
+char *find_header_in_abrt_post_state(abrt_post_state_t *state, const char *str)
+{
+ char **headers = state->headers;
+ if (headers)
+ {
+ unsigned len = strlen(str);
+ while (*headers)
+ {
+ if (strncmp(*headers, str, len) == 0)
+ return skip_whitespace(*headers + len);
+ headers++;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * abrt_post: perform HTTP POST transaction
+ */
+
+/* "save headers" callback */
+static size_t
+save_headers(void *buffer_pv, size_t count, size_t nmemb, void *ptr)
+{
+ abrt_post_state_t* state = (abrt_post_state_t*)ptr;
+ size_t size = count * nmemb;
+
+ char *h = xstrndup((char*)buffer_pv, size);
+ strchrnul(h, '\r')[0] = '\0';
+ strchrnul(h, '\n')[0] = '\0';
+
+ unsigned cnt = state->header_cnt;
+
+ /* Check for the case when curl follows a redirect:
+ * header 0: 'HTTP/1.1 301 Moved Permanently'
+ * header 1: 'Connection: close'
+ * header 2: 'Location: NEW_URL'
+ * header 3: ''
+ * header 0: 'HTTP/1.1 200 OK' <-- we need to forget all hdrs and start
anew
+ */
+ if (cnt != 0
+ && strncmp(h, "HTTP/", 5) == 0
+ && state->headers[cnt-1][0] == '\0' /* prev header is an empty
string */
+ ) {
+ char **headers = state->headers;
+ if (headers)
+ {
+ while (*headers)
+ free(*headers++);
+ }
+ cnt = 0;
+ }
+
+ VERB3 log("save_headers: header %d: '%s'", cnt, h);
+ state->headers = (char**)xrealloc(state->headers, (cnt+2) *
sizeof(state->headers[0]));
+ state->headers[cnt] = h;
+ state->header_cnt = ++cnt;
+ state->headers[cnt] = NULL;
+
+ return size;
+}
+
+/* "read local data from a file" callback */
+static size_t fread_with_reporting(void *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ static time_t last_t; // hack
+
+ FILE *fp = (FILE*)userdata;
+ time_t t = time(NULL);
+
+ // Report current file position every 16 seconds
+ if (!(t & 0xf) && last_t != t)
+ {
+ last_t = t;
+ off_t cur_pos = ftello(fp);
+ fseeko(fp, 0, SEEK_END);
+ off_t sz = ftello(fp);
+ fseeko(fp, cur_pos, SEEK_SET);
+ log(_("Uploaded: %llu of %llu kbytes"),
+ (unsigned long long)cur_pos / 1024,
+ (unsigned long long)sz / 1024);
+ }
+
+ return fread(ptr, size, nmemb, fp);
+}
+
+static int curl_debug(CURL *handle, curl_infotype it, char *buf, size_t bufsize, void
*unused)
+{
+ if (logmode == 0)
+ return 0;
+
+ switch (it) {
+ case CURLINFO_TEXT: /* The data is informational text. */
+ log("curl: %.*s", (int) bufsize, buf);
+ break;
+ case CURLINFO_HEADER_IN: /* The data is header (or header-like) data received from
the peer. */
+ log("curl rcvd header: '%.*s'", (int) bufsize, buf);
+ break;
+ case CURLINFO_HEADER_OUT: /* The data is header (or header-like) data sent to the
peer. */
+ log("curl sent header: '%.*s'", (int) bufsize, buf);
+ break;
+ case CURLINFO_DATA_IN: /* The data is protocol data received from the peer. */
+ if (g_verbose >= 3)
+ log("curl rcvd data: '%.*s'", (int) bufsize, buf);
+ else
+ log("curl rcvd data %u bytes", (int) bufsize);
+ break;
+ case CURLINFO_DATA_OUT: /* The data is protocol data sent to the peer. */
+ if (g_verbose >= 3)
+ log("curl sent data: '%.*s'", (int) bufsize, buf);
+ else
+ log("curl sent data %u bytes", (int) bufsize);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int
+abrt_post(abrt_post_state_t *state,
+ const char *url,
+ const char *content_type,
+ const char **additional_headers,
+ const char *data,
+ off_t data_size)
+{
+ CURLcode curl_err;
+ long response_code;
+ abrt_post_state_t localstate;
+
+ VERB3 log("abrt_post('%s','%s')", url, data);
+
+ if (!state)
+ {
+ memset(&localstate, 0, sizeof(localstate));
+ state = &localstate;
+ }
+
+ state->http_resp_code = response_code = -1;
+
+ CURL *handle = xcurl_easy_init();
+
+ // Buffer[CURL_ERROR_SIZE] curl stores human readable error messages in.
+ // This may be more helpful than just return code from curl_easy_perform.
+ // curl will need it until curl_easy_cleanup.
+ state->errmsg[0] = '\0';
+ xcurl_easy_setopt_ptr(handle, CURLOPT_ERRORBUFFER, state->errmsg);
+ // Shut off the built-in progress meter completely
+ xcurl_easy_setopt_long(handle, CURLOPT_NOPROGRESS, 1);
+
+ if (g_verbose >= 2) {
+ // "Display a lot of verbose information about its operations.
+ // Very useful for libcurl and/or protocol debugging and understanding.
+ // The verbose information will be sent to stderr, or the stream set
+ // with CURLOPT_STDERR"
+ xcurl_easy_setopt_long(handle, CURLOPT_VERBOSE, 1);
+ xcurl_easy_setopt_ptr(handle, CURLOPT_DEBUGFUNCTION, curl_debug);
+ }
+
+ // TODO: do we need to check for CURLE_URL_MALFORMAT error *here*,
+ // not in curl_easy_perform?
+ xcurl_easy_setopt_ptr(handle, CURLOPT_URL, url);
+
+ // Auth if configured
+ if (state->username) {
+ // bitmask of allowed auth methods
+ xcurl_easy_setopt_long(handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ xcurl_easy_setopt_ptr(handle, CURLOPT_USERNAME, state->username);
+ xcurl_easy_setopt_ptr(handle, CURLOPT_PASSWORD, (state->password ?
state->password : ""));
+ }
+
+ // Do a regular HTTP post. This also makes curl use
+ // a "Content-Type: application/x-www-form-urlencoded" header.
+ // (This is by far the most commonly used POST method).
+ xcurl_easy_setopt_long(handle, CURLOPT_POST, 1);
+ // Supply POST data...
+ struct curl_httppost* post = NULL;
+ struct curl_httppost* last = NULL;
+ FILE* data_file = NULL;
+ if (data_size == ABRT_POST_DATA_FROMFILE) {
+ // ...from a file
+ data_file = fopen(data, "r");
+ if (!data_file)
+//FIXME:
+ perror_msg_and_die("Can't open '%s'", data);
+ xcurl_easy_setopt_ptr(handle, CURLOPT_READDATA, data_file);
+ // Want to use custom read function
+ xcurl_easy_setopt_ptr(handle, CURLOPT_READFUNCTION, (const
void*)fread_with_reporting);
+ // Without this, curl would send "Content-Length: -1"
+ // servers don't like that: "413 Request Entity Too Large"
+ fseeko(data_file, 0, SEEK_END);
+ off_t sz = ftello(data_file);
+ fseeko(data_file, 0, SEEK_SET);
+ xcurl_easy_setopt_off_t(handle, CURLOPT_POSTFIELDSIZE_LARGE, sz);
+ } else if (data_size == ABRT_POST_DATA_FROMFILE_AS_FORM_DATA) {
+ // ...from a file, in multipart/formdata format
+ const char *basename = strrchr(data, '/');
+ if (basename) basename++;
+ else basename = data;
+#if 0
+ // Simple way, without custom reader function
+ CURLFORMcode curlform_err = curl_formadd(&post, &last,
+ CURLFORM_PTRNAME, "file", // element name
+ CURLFORM_FILE, data, // filename to read from
+ CURLFORM_CONTENTTYPE, content_type,
+ CURLFORM_FILENAME, basename, // filename to put in the form
+ CURLFORM_END);
+#else
+ data_file = fopen(data, "r");
+ if (!data_file)
+//FIXME:
+ perror_msg_and_die("Can't open '%s'", data);
+ // Want to use custom read function
+ xcurl_easy_setopt_ptr(handle, CURLOPT_READFUNCTION, (const
void*)fread_with_reporting);
+ // Need to know file size
+ fseeko(data_file, 0, SEEK_END);
+ off_t sz = ftello(data_file);
+ fseeko(data_file, 0, SEEK_SET);
+ // Create formdata
+ CURLFORMcode curlform_err = curl_formadd(&post, &last,
+ CURLFORM_PTRNAME, "file", // element name
+ // use CURLOPT_READFUNCTION for reading, pass data_file as its
last param:
+ CURLFORM_STREAM, data_file,
+ CURLFORM_CONTENTSLENGTH, (long)sz, // a must if we use
CURLFORM_STREAM option
+//FIXME: what if file size doesn't fit in long?
+ CURLFORM_CONTENTTYPE, content_type,
+ CURLFORM_FILENAME, basename, // filename to put in the form
+ CURLFORM_END);
+#endif
+ if (curlform_err != 0)
+//FIXME:
+ error_msg_and_die("out of memory or read error (curl_formadd error code:
%d)", (int)curlform_err);
+ xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPPOST, post);
+ } else if (data_size == ABRT_POST_DATA_STRING_AS_FORM_DATA) {
+ CURLFORMcode curlform_err = curl_formadd(&post, &last,
+ CURLFORM_PTRNAME, "file", // element name
+ // curl bug - missing filename
+ //
http://curl.haxx.se/mail/lib-2011-07/0176.html
+ //
https://github.com/bagder/curl/commit/45d883d
+ // fixed in curl-7.22.0~144
+ // tested with curl-7.24.0-3
+ // should be working on F17
+ CURLFORM_BUFFER, "*buffer*", // provides filename
+ CURLFORM_BUFFERPTR, data,
+ CURLFORM_BUFFERLENGTH, (long)strlen(data),
+//FIXME: what if file size doesn't fit in long?
+ CURLFORM_CONTENTTYPE, content_type,
+ CURLFORM_END);
+ if (curlform_err != 0)
+ error_msg_and_die("out of memory or read error (curl_formadd error code:
%d)", (int)curlform_err);
+ xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPPOST, post);
+ } else {
+ // .. from a blob in memory
+ xcurl_easy_setopt_ptr(handle, CURLOPT_POSTFIELDS, data);
+ // note1: if data_size == ABRT_POST_DATA_STRING == -1, curl will use
strlen(data)
+ xcurl_easy_setopt_long(handle, CURLOPT_POSTFIELDSIZE, data_size);
+ // We don't use CURLOPT_POSTFIELDSIZE_LARGE because
+ // I'm not sure CURLOPT_POSTFIELDSIZE_LARGE special-cases -1.
+ // Not a big problem: memory blobs >4GB are very unlikely.
+ }
+
+ struct curl_slist *httpheader_list = NULL;
+
+ // Override "Content-Type:"
+ if (data_size != ABRT_POST_DATA_FROMFILE_AS_FORM_DATA
+ && data_size != ABRT_POST_DATA_STRING_AS_FORM_DATA)
+ {
+ char *content_type_header = xasprintf("Content-Type: %s",
content_type);
+ // Note: curl_slist_append() copies content_type_header
+ httpheader_list = curl_slist_append(httpheader_list, content_type_header);
+ if (!httpheader_list)
+ error_msg_and_die("out of memory");
+ free(content_type_header);
+ }
+
+ for (; additional_headers && *additional_headers; additional_headers++)
+ {
+ httpheader_list = curl_slist_append(httpheader_list, *additional_headers);
+ if (!httpheader_list)
+ error_msg_and_die("out of memory");
+ }
+
+ // Add User-Agent: ABRT/N.M
+ httpheader_list = curl_slist_append(httpheader_list, "User-Agent:
ABRT/"VERSION);
+ if (!httpheader_list)
+ error_msg_and_die("out of memory");
+
+ if (httpheader_list)
+ xcurl_easy_setopt_ptr(handle, CURLOPT_HTTPHEADER, httpheader_list);
+
+// Disabled: was observed to also handle "305 Use proxy" redirect,
+// apparently with POST->GET remapping - which server didn't like at all.
+// Attempted to suppress remapping on 305 using CURLOPT_POSTREDIR of -1,
+// but it still did not work.
+#if 0
+ // Please handle 301/302 redirects for me
+ xcurl_easy_setopt_long(handle, CURLOPT_FOLLOWLOCATION, 1);
+ xcurl_easy_setopt_long(handle, CURLOPT_MAXREDIRS, 10);
+ // Bitmask to control how libcurl acts on redirects after POSTs.
+ // Bit 0 set (value CURL_REDIR_POST_301) makes libcurl
+ // not convert POST requests into GET requests when following
+ // a 301 redirection. Bit 1 (value CURL_REDIR_POST_302) makes libcurl
+ // maintain the request method after a 302 redirect.
+ // CURL_REDIR_POST_ALL is a convenience define that sets both bits.
+ // The non-RFC behaviour is ubiquitous in web browsers, so the library
+ // does the conversion by default to maintain consistency.
+ // However, a server may require a POST to remain a POST.
+ xcurl_easy_setopt_long(handle, CURLOPT_POSTREDIR, -1L /*CURL_REDIR_POST_ALL*/ );
+#endif
+
+ // Prepare for saving information
+ if (state->flags & ABRT_POST_WANT_HEADERS)
+ {
+ xcurl_easy_setopt_ptr(handle, CURLOPT_HEADERFUNCTION, (void*)save_headers);
+ xcurl_easy_setopt_ptr(handle, CURLOPT_WRITEHEADER, state);
+ }
+ FILE* body_stream = NULL;
+ if (state->flags & ABRT_POST_WANT_BODY)
+ {
+ body_stream = open_memstream(&state->body, &state->body_size);
+ if (!body_stream)
+ error_msg_and_die("out of memory");
+ xcurl_easy_setopt_ptr(handle, CURLOPT_WRITEDATA, body_stream);
+ }
+ if (!(state->flags & ABRT_POST_WANT_SSL_VERIFY))
+ {
+ xcurl_easy_setopt_long(handle, CURLOPT_SSL_VERIFYPEER, 0);
+ xcurl_easy_setopt_long(handle, CURLOPT_SSL_VERIFYHOST, 0);
+ }
+
+ // This is the place where everything happens.
+ // Here errors are not limited to "out of memory", can't just die.
+ curl_err = curl_easy_perform_with_proxy(handle, url);
+ if (curl_err)
+ {
+ VERB2 log("curl_easy_perform: error %d", (int)curl_err);
+ if (state->flags & ABRT_POST_WANT_ERROR_MSG)
+ {
+ state->curl_error_msg = check_curl_error(curl_err,
"curl_easy_perform");
+ VERB3 log("curl_easy_perform: error_msg: %s",
state->curl_error_msg);
+ }
+ goto ret;
+ }
+
+ // curl-7.20.1 doesn't do it, we get NULL body in the log message below
+ // unless we fflush the body memstream ourself
+ if (body_stream)
+ fflush(body_stream);
+
+ // Headers/body are already saved (if requested), extract more info
+ curl_err = curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &response_code);
+ die_if_curl_error(curl_err);
+ state->http_resp_code = response_code;
+ VERB3 log("after curl_easy_perform: http code %ld body:'%s'",
response_code, state->body);
+
+ ret:
+ curl_easy_cleanup(handle);
+ if (httpheader_list)
+ curl_slist_free_all(httpheader_list);
+ if (body_stream)
+ fclose(body_stream);
+ if (data_file)
+ fclose(data_file);
+ if (post)
+ curl_formfree(post);
+
+ return response_code;
+}
diff --git a/src/lib/json.c b/src/lib/json.c
index 659eda2..651010d 100644
--- a/src/lib/json.c
+++ b/src/lib/json.c
@@ -23,7 +23,7 @@
#include "internal_libreport.h"
#include "ureport.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
/* on success 1 returned, on error zero is returned and appropriate value
diff --git a/src/plugins/abrt-bodhi.c b/src/plugins/abrt-bodhi.c
index 91f0eed..632a351 100644
--- a/src/plugins/abrt-bodhi.c
+++ b/src/plugins/abrt-bodhi.c
@@ -24,7 +24,7 @@
#include <rpm/rpmpgp.h>
#include "internal_libreport.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "client.h"
//699198,705037,705036
diff --git a/src/plugins/abrt_rh_support.c b/src/plugins/abrt_rh_support.c
index 8d05e84..233edfa 100644
--- a/src/plugins/abrt_rh_support.c
+++ b/src/plugins/abrt_rh_support.c
@@ -20,7 +20,7 @@
#include <libxml/xmlwriter.h>
#include <curl/curl.h>
#include "internal_libreport.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "abrt_rh_support.h"
struct reportfile {
diff --git a/src/plugins/reporter-kerneloops.c b/src/plugins/reporter-kerneloops.c
index 81ab93e..843c10b 100644
--- a/src/plugins/reporter-kerneloops.c
+++ b/src/plugins/reporter-kerneloops.c
@@ -16,7 +16,7 @@
Anton Arapov <anton(a)redhat.com>
Arjan van de Ven <arjan(a)linux.intel.com>
*/
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "internal_libreport.h"
/* helpers */
diff --git a/src/plugins/reporter-rhtsupport.c b/src/plugins/reporter-rhtsupport.c
index 4e4cccb..215b7c1 100644
--- a/src/plugins/reporter-rhtsupport.c
+++ b/src/plugins/reporter-rhtsupport.c
@@ -19,7 +19,7 @@
#include <libtar.h>
#include "internal_libreport.h"
#include "client.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "abrt_xmlrpc.h"
#include "abrt_rh_support.h"
#include "reporter-rhtsupport.h"
diff --git a/src/plugins/reporter-upload.c b/src/plugins/reporter-upload.c
index 16b588d..38de383 100644
--- a/src/plugins/reporter-upload.c
+++ b/src/plugins/reporter-upload.c
@@ -17,7 +17,7 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <libtar.h>
-#include "abrt_curl.h"
+#include "libreport_curl.h"
#include "internal_libreport.h"
//TODO: use this for better logging
diff --git a/src/plugins/ureport.c b/src/plugins/ureport.c
index 5ffcea3..c75af63 100644
--- a/src/plugins/ureport.c
+++ b/src/plugins/ureport.c
@@ -20,7 +20,7 @@
#include <json/json.h>
#include "internal_libreport.h"
#include "ureport.h"
-#include "abrt_curl.h"
+#include "libreport_curl.h"
/*
* Loads uReport configuration from various sources.
--
1.7.10.2