aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2018-04-04 18:53:56 +0200
committerRomain Forlot <romain.forlot@iot.bzh>2018-05-04 14:59:54 +0200
commit61c01cc4bb615337ee0591fea987eb6bee83a78e (patch)
tree0b51db320d76c3abbef4018cc269983239babc47
parent27c0ffd6e475eba00aa8883a822a841a4555cf2d (diff)
POST using unescaped arguments
Add the ability to make a POST request without urlencode the arguments. This will only concatenate them instead. You can also specify the used separator. Change-Id: Icb61a5a20771a89e89159132365d86ee4c982d1c Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
-rw-r--r--curl-wrap.c99
-rw-r--r--curl-wrap.h10
-rw-r--r--escape.c6
-rw-r--r--escape.h3
4 files changed, 103 insertions, 15 deletions
diff --git a/curl-wrap.c b/curl-wrap.c
index 3c566a3..d2aacaf 100644
--- a/curl-wrap.c
+++ b/curl-wrap.c
@@ -33,6 +33,50 @@ struct buffer {
char *data;
};
+static const char* curl_concatenate_args(const char * const *args, const char *sep, size_t *length)
+{
+ int i;
+ size_t lq, l;
+ const char *null;
+ char *result, *front;
+
+ /* ensure args */
+ if (!args) {
+ null = NULL;
+ args = &null;
+ }
+ if (!sep)
+ sep = "";
+
+ /* compute lengths */
+ lq = 0;
+ i = 0;
+ while (args[i]) {
+ lq += strlen(args[i]);
+ i++;
+ }
+
+ /* allocation */
+ result = malloc(1 + lq + (i ? i - 1 : 0) * strlen(sep));
+ if (result) {
+ /* make the resulting args string contenated */
+ i = 0;
+ front = result;
+ l = 0;
+ while (args[i]) {
+ if (i) {
+ front = stpcpy(front, sep);
+ }
+ front = stpcpy(front, args[i]);
+ i++;
+ }
+ *front = 0;
+ if (length)
+ *length = (size_t)(front - result);
+ }
+ return result;
+}
+
/* write callback for filling buffers with the response */
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
@@ -50,7 +94,7 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdat
return sz;
}
-/*
+/*
* Perform the CURL operation for 'curl' and put the result in
* memory. If 'result' isn't NULL it receives the returned content
* that then must be freed. If 'size' isn't NULL, it receives the
@@ -69,15 +113,15 @@ int curl_wrap_perform(CURL *curl, char **result, size_t *size)
buffer.size = 0;
buffer.data = NULL;
- /* Perform the request, res will get the return code */
+ /* Perform the request, res will get the return code */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
- /* Perform the request, res will get the return code */
+ /* Perform the request, res will get the return code */
code = curl_easy_perform(curl);
rc = code == CURLE_OK;
- /* Check for no errors */
+ /* Check for no errors */
if (rc) {
/* no error */
if (size)
@@ -184,27 +228,58 @@ CURL *curl_wrap_prepare_post_url_data(const char *url, const char *datatype, con
curl = curl_easy_init();
if (curl
- && CURLE_OK == curl_easy_setopt(curl, CURLOPT_URL, url)
- && (!szdata || CURLE_OK == curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, szdata))
- && CURLE_OK == curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data)
- && (!datatype || curl_wrap_add_header_value(curl, "content-type", datatype)))
+ && CURLE_OK == curl_easy_setopt(curl, CURLOPT_URL, url)
+ && (!szdata || CURLE_OK == curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, szdata))
+ && CURLE_OK == curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data)
+ && (!datatype || curl_wrap_add_header_value(curl, "content-type", datatype)))
return curl;
curl_easy_cleanup(curl);
return NULL;
}
-CURL *curl_wrap_prepare_post(const char *base, const char *path, const char * const *args)
+static CURL *curl_wrap_prepare_post(const char *base, const char *path, int unescape_flag, const char *separator, const char * const *args, const char *simple_args)
{
CURL *res;
char *url;
- char *data;
- size_t szdata;
+ const char *data = NULL;
+ size_t szdata = 0;
url = escape_url(base, path, NULL, NULL);
- data = escape_args(args, &szdata);
+ if(args) {
+ data = unescape_flag ?
+ curl_concatenate_args(args, separator, &szdata) :
+ escape_args(args, &szdata);
+ }
+ else {
+ data = unescape_flag ?
+ escape_str(simple_args, &szdata) :
+ simple_args;
+ }
+ szdata = szdata ? szdata : strlen(data);
+
res = url ? curl_wrap_prepare_post_url_data(url, NULL, data, szdata) : NULL;
free(url);
return res;
}
+CURL *curl_wrap_prepare_post_simple_unescaped(const char *base, const char *path, const char *args)
+{
+ return curl_wrap_prepare_post(base, path, 1, NULL, NULL, args);
+}
+
+CURL *curl_wrap_prepare_post_simple_escaped(const char *base, const char *path, char *args)
+{
+ return curl_wrap_prepare_post(base, path, 0, NULL, NULL, args);
+}
+
+CURL *curl_wrap_prepare_post_unescaped(const char *base, const char *path, const char *separator, const char * const *args)
+{
+ return curl_wrap_prepare_post(base, path, 1, separator, args, NULL);
+}
+
+CURL *curl_wrap_prepare_post_escaped(const char *base, const char *path, const char * const *args)
+{
+ return curl_wrap_prepare_post(base, path, 0, NULL, args, NULL);
+}
+
/* vim: set colorcolumn=80: */
diff --git a/curl-wrap.h b/curl-wrap.h
index 2e44f47..a6106e4 100644
--- a/curl-wrap.h
+++ b/curl-wrap.h
@@ -35,11 +35,17 @@ extern CURL *curl_wrap_prepare_get(const char *base, const char *path, const cha
extern CURL *curl_wrap_prepare_post_url_data(const char *url, const char *datatype, const char *data, size_t szdata);
-extern CURL *curl_wrap_prepare_post(const char *base, const char *path, const char * const *args);
-
extern int curl_wrap_add_header(CURL *curl, const char *header);
extern int curl_wrap_add_header_value(CURL *curl, const char *name, const char *value);
+CURL *curl_wrap_prepare_post_simple_unescaped(const char *base, const char *path, const char *args);
+
+CURL *curl_wrap_prepare_post_simple_escaped(const char *base, const char *path, char *args);
+
+CURL *curl_wrap_prepare_post_unescaped(const char *base, const char *path, const char *separator, const char * const *args);
+
+CURL *curl_wrap_prepare_post_escaped(const char *base, const char *path, const char * const *args);
+
/* vim: set colorcolumn=80: */
diff --git a/escape.c b/escape.c
index 3bb25c2..f370fc9 100644
--- a/escape.c
+++ b/escape.c
@@ -313,6 +313,12 @@ char *escape_args(const char * const *args, size_t *length)
return escape_url(NULL, NULL, args, length);
}
+const char *escape_str(const char* str, size_t *length)
+{
+ const char *a[2] = { str, NULL };
+ return escape_args(a, length);
+}
+
const char **unescape_args(const char *args)
{
const char **r, **q;
diff --git a/escape.h b/escape.h
index 7d548db..eb108a1 100644
--- a/escape.h
+++ b/escape.h
@@ -17,7 +17,8 @@
#pragma once
extern char *escape_url(const char *base, const char *path, const char * const *args, size_t *length);
-extern char *escape_args(const char * const *args, size_t *length);
+extern const char *escape_args(const char * const *args, size_t *length);
+extern const char *escape_str(const char *str, size_t *length);
extern const char **unescape_args(const char *args);
/* vim: set colorcolumn=80: */