HomePort
curl_ev.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Aalborg University. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  * conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  * of conditions and the following disclaimer in the documentation and/or other materials
12  * provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY Aalborg University ''AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Aalborg University OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  */
27 
28 #include "curl_ev_intern.h"
29 #include "hpd/common/hpd_common.h"
30 #include "hpd/hpd_shared_api.h"
31 
32 static size_t curl_ev_on_header(char *buffer, size_t size, size_t nmemb, void *userdata)
33 {
34  hpd_curl_ev_handle_t *handle = userdata;
35  if (handle->on_header) return handle->on_header(buffer, size, nmemb, handle->data);
36  else return size*nmemb;
37 }
38 
39 static size_t curl_ev_on_body(char *buffer, size_t size, size_t nmemb, void *userdata)
40 {
41  hpd_curl_ev_handle_t *handle = userdata;
42  if (handle->on_body) return handle->on_body(buffer, size, nmemb, handle->data);
43  else return size*nmemb;
44 }
45 
47 {
48  CURLcode cc;
49  if ((cc = curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, curl_ev_on_header)) ||
50  (cc = curl_easy_setopt(handle, CURLOPT_HEADERDATA, data)) ||
51  (cc = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curl_ev_on_body)) ||
52  (cc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, data)))
53  HPD_LOG_RETURN(context, HPD_E_UNKNOWN, "Curl returned an error [code: %i]", cc);
54 
55  return HPD_E_SUCCESS;
56 }
57 
59 {
60  hpd_error_t rc;
61 
62  if (!(handle->handle = curl_easy_init()))
63  HPD_LOG_RETURN(handle->context, HPD_E_UNKNOWN, "Curl init error");;
64 
65  if ((rc = curl_ev_init_curl_handle(handle->handle, handle->context, handle))) {
66  curl_easy_cleanup(handle->handle);
67  }
68  return rc;
69 }
70 
72 {
73  if (!context) return HPD_E_NULL;
74  if (!handle) HPD_LOG_RETURN_E_NULL(context);
75 
76  hpd_error_t rc;
77 
78  HPD_CALLOC(*handle, 1, hpd_curl_ev_handle_t);
79  (*handle)->context = context;
80 
81  if ((rc = curl_ev_create_curl_handle(*handle))) {
82  free(handle);
83  }
84  return rc;
85 
86  alloc_error:
87  HPD_LOG_RETURN_E_ALLOC(context);
88 }
89 
91 {
92  if (!handle) return HPD_E_NULL;
93  if (handle->curl_ev) HPD_LOG_RETURN(handle->context, HPD_E_STATE, "Handle is still attached");
94 
95  if (handle->headers) curl_slist_free_all(handle->headers);
96  if (handle->handle) curl_easy_cleanup(handle->handle);
97  if (handle->on_free) handle->on_free(handle->data);
98  free(handle);
99 
100  return HPD_E_SUCCESS;
101 }
102 
104 {
105  if (!handle) return HPD_E_NULL;
106  handle->on_header = on_header;
107  return HPD_E_SUCCESS;
108 }
109 
111 {
112  if (!handle) return HPD_E_NULL;
113  handle->on_body = on_body;
114  return HPD_E_SUCCESS;
115 }
116 
118 {
119  if (!handle) return HPD_E_NULL;
120  handle->on_done = on_done;
121  return HPD_E_SUCCESS;
122 }
123 
125 {
126  if (!handle) return HPD_E_NULL;
127  CURLcode cc;
128  if ((cc = curl_easy_setopt(handle->handle, CURLOPT_CUSTOMREQUEST, request)))
129  HPD_LOG_RETURN(handle->context, HPD_E_UNKNOWN, "Curl failed [code: %i]", cc);
130  return HPD_E_SUCCESS;
131 }
132 
134 {
135  if (!handle) return HPD_E_NULL;
136  handle->data = data;
137  handle->on_free = on_free;
138  return HPD_E_SUCCESS;
139 }
140 
146 {
147  if (!handle) return HPD_E_NULL;
148  CURLcode cc;
149  if ( (cc = curl_easy_setopt(handle->handle, CURLOPT_POSTFIELDSIZE, len)) ||
150  (cc = curl_easy_setopt(handle->handle, CURLOPT_COPYPOSTFIELDS, data)))
151  HPD_LOG_RETURN(handle->context, HPD_E_UNKNOWN, "Curl failed [code: %i]", cc);
152  return HPD_E_SUCCESS;
153 }
154 
156 {
157  if (!handle) return HPD_E_NULL;
158  CURLcode cc;
159  if ((cc = curl_easy_setopt(handle->handle, CURLOPT_URL, url)))
160  HPD_LOG_RETURN(handle->context, HPD_E_UNKNOWN, "Curl failed [code: %i]", cc);
161  return HPD_E_SUCCESS;
162 }
163 
165 {
166  if (!handle) return HPD_E_NULL;
167  CURLcode cc;
168  if ((cc = curl_easy_setopt(handle->handle, CURLOPT_VERBOSE, bool)))
169  HPD_LOG_RETURN(handle->context, HPD_E_UNKNOWN, "Curl failed [code: %i]", cc);
170 
171  return HPD_E_SUCCESS;
172 }
173 
179 {
180  if (!handle) return HPD_E_NULL;
181  CURLcode cc;
182  struct curl_slist *headers = curl_slist_append(handle->headers, header);
183  if (!headers) HPD_LOG_RETURN(handle->context, HPD_E_UNKNOWN, "Curl failed");
184  handle->headers = headers;
185  if ((cc = curl_easy_setopt(handle->handle, CURLOPT_HTTPHEADER, handle->headers)))
186  HPD_LOG_RETURN(handle->context, HPD_E_UNKNOWN, "Curl failed [code: %i]", cc);
187  return HPD_E_SUCCESS;
188 }
void(* hpd_curl_ev_free_f)(void *userdata)
Definition: hpd_curl_ev.h:37
hpd_curl_ev_f on_body
hpd_error_t hpd_curl_ev_init(hpd_curl_ev_handle_t **handle, const hpd_module_t *context)
Definition: curl_ev.c:71
#define HPD_LOG_RETURN(CONTEXT, E, FMT,...)
hpd_error_t hpd_curl_ev_add_header(hpd_curl_ev_handle_t *handle, const char *header)
HPD_E_UNKNOWN: handle may be in an inconsistent state, and should not be added before a call to this ...
Definition: curl_ev.c:178
const hpd_module_t * context
void(* hpd_curl_ev_done_f)(void *userdata, int curl_code)
Definition: hpd_curl_ev.h:38
char * url
hpd_curl_ev_done_f on_done
free(data.url)
size_t(* hpd_curl_ev_f)(char *buffer, size_t size, size_t nmemb, void *userdata)
Definition: hpd_curl_ev.h:36
hpd_curl_ev_free_f on_free
struct curl_slist * headers
#define HPD_CALLOC(PTR, NUM, CAST)
Allocates and zeros a structure.
Definition: hpd_common.h:44
hpd_error_t hpd_curl_ev_set_postfields(hpd_curl_ev_handle_t *handle, const void *data, size_t len)
HPD_E_UNKNOWN: handle may be in an inconsistent state, and should not be added before a call to this ...
Definition: curl_ev.c:145
enum hpd_error hpd_error_t
Definition: hpd_types.h:167
#define HPD_LOG_RETURN_E_ALLOC(CONTEXT)
hpd_curl_ev_f on_header
hpd_error_t hpd_curl_ev_set_header_callback(hpd_curl_ev_handle_t *handle, hpd_curl_ev_f on_header)
Definition: curl_ev.c:103
static hpd_error_t curl_ev_init_curl_handle(CURL *handle, const hpd_module_t *context, void *data)
Definition: curl_ev.c:46
hpd_error_t hpd_curl_ev_set_verbose(hpd_curl_ev_handle_t *handle, long int bool)
Definition: curl_ev.c:164
#define HPD_LOG_RETURN_E_NULL(CONTEXT)
struct data data
hpd_error_t hpd_curl_ev_set_body_callback(hpd_curl_ev_handle_t *handle, hpd_curl_ev_f on_body)
Definition: curl_ev.c:110
hpd_error_t hpd_curl_ev_set_url(hpd_curl_ev_handle_t *handle, const char *url)
Definition: curl_ev.c:155
static size_t curl_ev_on_body(char *buffer, size_t size, size_t nmemb, void *userdata)
Definition: curl_ev.c:39
hpd_error_t hpd_curl_ev_set_custom_request(hpd_curl_ev_handle_t *handle, const char *request)
Definition: curl_ev.c:124
static hpd_error_t curl_ev_create_curl_handle(hpd_curl_ev_handle_t *handle)
Definition: curl_ev.c:58
hpd_error_t hpd_curl_ev_set_done_callback(hpd_curl_ev_handle_t *handle, hpd_curl_ev_done_f on_done)
Definition: curl_ev.c:117
hpd_error_t hpd_curl_ev_cleanup(hpd_curl_ev_handle_t *handle)
Definition: curl_ev.c:90
curl_ev_t * curl_ev
static size_t curl_ev_on_header(char *buffer, size_t size, size_t nmemb, void *userdata)
Definition: curl_ev.c:32
hpd_error_t hpd_curl_ev_set_data(hpd_curl_ev_handle_t *handle, void *data, hpd_curl_ev_free_f on_free)
Definition: curl_ev.c:133