Gitweb links:

...log 
http://git.netsurf-browser.org/netsurf.git/shortlog/af4234d4f2fbd8d4e054fda702296ec887a92121
...commit 
http://git.netsurf-browser.org/netsurf.git/commit/af4234d4f2fbd8d4e054fda702296ec887a92121
...tree 
http://git.netsurf-browser.org/netsurf.git/tree/af4234d4f2fbd8d4e054fda702296ec887a92121

The branch, vince/curlapiupdates has been created
        at  af4234d4f2fbd8d4e054fda702296ec887a92121 (commit)

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=af4234d4f2fbd8d4e054fda702296ec887a92121
commit af4234d4f2fbd8d4e054fda702296ec887a92121
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>

    Remove use of depricated API after libcurl 7.56

diff --git a/content/fetch.h b/content/fetch.h
index 843fec9..e7180d0 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -94,6 +94,16 @@ typedef struct fetch_msg {
 } fetch_msg;
 
 /**
+ * Fetcher post data types
+ */
+typedef enum {
+       FETCH_POSTDATA_NONE,
+       FETCH_POSTDATA_URLENC,
+       FETCH_POSTDATA_MULTIPART,
+} fetch_postdata_type;
+
+
+/**
  * Fetch POST multipart data
  */
 struct fetch_multipart_data {
@@ -106,6 +116,20 @@ struct fetch_multipart_data {
        bool file; /**< Item is a file */
 };
 
+/**
+ * fetch POST data
+ */
+struct fetch_postdata {
+       fetch_postdata_type type;
+       union {
+               /** Url encoded POST string if type is FETCH_POSTDATA_URLENC */
+               char *urlenc;
+               /** Multipart post data if type is FETCH_POSTDATA_MULTIPART */
+               struct fetch_multipart_data *multipart;
+       } data;
+};
+
+
 typedef void (*fetch_callback)(const fetch_msg *msg, void *p);
 
 /**
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index 1377ec7..35793c4 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -222,6 +222,16 @@ struct cert_info {
        long err;               /**< OpenSSL error code */
 };
 
+#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 depricated curl_formadd */
+#define NSCURL_POSTDATA_T curl_mime
+#define NSCURL_POSTDATA_CURLOPT CURLOPT_MIMEPOST
+#define NSCURL_POSTDATA_FREE(x) curl_mime_free(x)
+#else
+#define NSCURL_POSTDATA_T struct curl_httppost
+#define NSCURL_POSTDATA_CURLOPT CURLOPT_HTTPPOST
+#define NSCURL_POSTDATA_FREE(x) curl_formfree(x)
+#endif
+
 /** Information for a single fetch. */
 struct curl_fetch_info {
        struct fetch *fetch_handle; /**< The fetch handle we're parented by. */
@@ -239,9 +249,11 @@ struct curl_fetch_info {
        unsigned long content_length;   /**< Response Content-Length, or 0. */
        char *cookie_string;    /**< Cookie string for this fetch */
        char *realm;            /**< HTTP Auth Realm */
-       char *post_urlenc;      /**< Url encoded POST string, or 0. */
+       struct fetch_postdata *postdata; /**< POST data */
+       NSCURL_POSTDATA_T *curl_postdata; /**< POST data in curl representation 
*/
+
        long http_code; /**< HTTP result code from cURL. */
-       struct curl_httppost *post_multipart;   /**< Multipart post data, or 0. 
*/
+
        uint64_t last_progress_update;  /**< Time of last progress update */
        int cert_depth; /**< deepest certificate in use */
        struct cert_info cert_data[MAX_CERT_DEPTH]; /**< HTTPS certificate data 
*/
@@ -348,85 +360,59 @@ static bool fetch_curl_can_fetch(const nsurl *url)
 }
 
 
+
 /**
- * Convert a list of struct ::fetch_multipart_data to a list of
- * struct curl_httppost for libcurl.
+ * allocate postdata
  */
-static struct curl_httppost *
-fetch_curl_post_convert(const struct fetch_multipart_data *control)
+static struct fetch_postdata *
+fetch_curl_alloc_postdata(const char *post_urlenc,
+                         const struct fetch_multipart_data *post_multipart)
 {
-       struct curl_httppost *post = 0, *last = 0;
-       CURLFORMcode code;
-       nserror ret;
-
-       for (; control; control = control->next) {
-               if (control->file) {
-                       char *leafname = NULL;
-                       ret = guit->file->basename(control->value, &leafname, 
NULL);
-                       if (ret != NSERROR_OK) {
-                               continue;
+       struct fetch_postdata *postdata;
+       postdata = calloc(1, sizeof(struct fetch_postdata));
+       if (postdata != NULL) {
+
+               if (post_urlenc) {
+                       postdata->type = FETCH_POSTDATA_URLENC;
+                       postdata->data.urlenc = strdup(post_urlenc);
+                       if (postdata->data.urlenc == NULL) {
+                               free(postdata);
+                               postdata = NULL;
                        }
-
-                       /* We have to special case filenames of "", so curl
-                        * a) actually attempts the fetch and
-                        * b) doesn't attempt to open the file ""
-                        */
-                       if (control->value[0] == '\0') {
-                               /* dummy buffer - needs to be static so
-                                * pointer's still valid when we go out
-                                * of scope (not that libcurl should be
-                                * attempting to access it, of course).
-                                */
-                               static char buf;
-
-                               code = curl_formadd(&post, &last,
-                                       CURLFORM_COPYNAME, control->name,
-                                       CURLFORM_BUFFER, control->value,
-                                       /* needed, as basename("") == "." */
-                                       CURLFORM_FILENAME, "",
-                                       CURLFORM_BUFFERPTR, &buf,
-                                       CURLFORM_BUFFERLENGTH, 0,
-                                       CURLFORM_CONTENTTYPE,
-                                               "application/octet-stream",
-                                       CURLFORM_END);
-                               if (code != CURL_FORMADD_OK)
-                                       NSLOG(netsurf, INFO,
-                                             "curl_formadd: %d (%s)", code,
-                                             control->name);
-                       } else {
-                               char *mimetype = 
guit->fetch->mimetype(control->value);
-                               code = curl_formadd(&post, &last,
-                                       CURLFORM_COPYNAME, control->name,
-                                       CURLFORM_FILE, control->rawfile,
-                                       CURLFORM_FILENAME, leafname,
-                                       CURLFORM_CONTENTTYPE,
-                                       (mimetype != 0 ? mimetype : 
"text/plain"),
-                                       CURLFORM_END);
-                               if (code != CURL_FORMADD_OK)
-                                       NSLOG(netsurf, INFO,
-                                             "curl_formadd: %d (%s=%s)",
-                                             code,
-                                             control->name,
-                                             control->value);
-                               free(mimetype);
+               } else if (post_multipart) {
+                       postdata->type = FETCH_POSTDATA_MULTIPART;
+                       postdata->data.multipart = 
fetch_multipart_data_clone(post_multipart);
+                       if (postdata->data.multipart == NULL) {
+                               free(postdata);
+                               postdata = NULL;
                        }
-                       free(leafname);
-               }
-               else {
-                       code = curl_formadd(&post, &last,
-                                       CURLFORM_COPYNAME, control->name,
-                                       CURLFORM_COPYCONTENTS, control->value,
-                                       CURLFORM_END);
-                       if (code != CURL_FORMADD_OK)
-                               NSLOG(netsurf, INFO,
-                                     "curl_formadd: %d (%s=%s)", code,
-                                     control->name, control->value);
+               } else {
+                       postdata->type = FETCH_POSTDATA_NONE;
                }
        }
-
-       return post;
+       return postdata;
 }
 
+/**
+ * free postdata
+ */
+static void fetch_curl_free_postdata(struct fetch_postdata *postdata)
+{
+       if (postdata != NULL) {
+               switch (postdata->type) {
+               case FETCH_POSTDATA_NONE:
+                       break;
+               case FETCH_POSTDATA_URLENC:
+                       free(postdata->data.urlenc);
+                       break;
+               case FETCH_POSTDATA_MULTIPART:
+                       fetch_multipart_data_destroy(postdata->data.multipart);
+                       break;
+               }
+
+               free(postdata);
+       }
+}
 
 /**
  * Start fetching data for the given URL.
@@ -481,30 +467,26 @@ fetch_curl_setup(struct fetch *parent_fetch,
        fetch->headers = NULL;
        fetch->url = nsurl_ref(url);
        fetch->host = nsurl_get_component(url, NSURL_HOST);
+       if (fetch->host == NULL) {
+               goto failed;
+       }
+
        fetch->location = NULL;
        fetch->content_length = 0;
        fetch->http_code = 0;
        fetch->cookie_string = NULL;
        fetch->realm = NULL;
-       fetch->post_urlenc = NULL;
-       fetch->post_multipart = NULL;
-       if (post_urlenc) {
-               fetch->post_urlenc = strdup(post_urlenc);
-       } else if (post_multipart) {
-               fetch->post_multipart = fetch_curl_post_convert(post_multipart);
-       }
        fetch->last_progress_update = 0;
+       fetch->postdata = fetch_curl_alloc_postdata(post_urlenc, 
post_multipart);
+       if (fetch->postdata == NULL) {
+               goto failed;
+       }
+       fetch->curl_postdata = NULL;
 
        /* Clear certificate chain data */
        memset(fetch->cert_data, 0, sizeof(fetch->cert_data));
        fetch->cert_depth = -1;
 
-       if ((fetch->host == NULL) ||
-           (post_multipart != NULL && fetch->post_multipart == NULL) ||
-           (post_urlenc != NULL && fetch->post_urlenc == NULL)) {
-               goto failed;
-       }
-
 #define APPEND(list, value) \
        slist = curl_slist_append(list, value);         \
        if (slist == NULL)                              \
@@ -554,9 +536,7 @@ failed:
                lwc_string_unref(fetch->host);
 
        nsurl_unref(fetch->url);
-       free(fetch->post_urlenc);
-       if (fetch->post_multipart)
-               curl_formfree(fetch->post_multipart);
+       fetch_curl_free_postdata(fetch->postdata);
        curl_slist_free_all(fetch->headers);
        free(fetch);
        return NULL;
@@ -867,6 +847,304 @@ fetch_curl_report_certs_upstream(struct curl_fetch_info 
*f)
        f->sent_ssl_chain = true;
 }
 
+#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 depricated curl_formadd */
+
+/**
+ * curl mime data context
+ */
+struct curl_mime_ctx {
+       char *buffer;
+       curl_off_t size;
+       curl_off_t position;
+};
+
+static size_t mime_data_read_callback(char *buffer, size_t size, size_t 
nitems, void *arg)
+{
+       struct curl_mime_ctx *mctx = (struct curl_mime_ctx *) arg;
+       curl_off_t sz = mctx->size - mctx->position;
+
+       nitems *= size;
+       if(sz > (curl_off_t)nitems) {
+               sz = nitems;
+       }
+       if(sz) {
+               memcpy(buffer, mctx->buffer + mctx->position, sz);
+       }
+       mctx->position += sz;
+       return sz;
+}
+
+static int mime_data_seek_callback(void *arg, curl_off_t offset, int origin)
+{
+       struct curl_mime_ctx *mctx = (struct curl_mime_ctx *) arg;
+
+       switch(origin) {
+       case SEEK_END:
+               offset += mctx->size;
+               break;
+       case SEEK_CUR:
+               offset += mctx->position;
+               break;
+       }
+
+       if(offset < 0) {
+               return CURL_SEEKFUNC_FAIL;
+       }
+       mctx->position = offset;
+       return CURL_SEEKFUNC_OK;
+}
+
+static void mime_data_free_callback(void *arg)
+{
+       struct curl_mime_ctx *mctx = (struct curl_mime_ctx *) arg;
+       free(mctx);
+}
+
+/**
+ * Convert a POST data list to a libcurl curl_mime.
+ *
+ * \param chandle curl fetch handle.
+ * \param multipart limked list of struct ::fetch_multipart forming post data.
+ */
+static curl_mime *
+fetch_curl_postdata_convert(CURL *chandle,
+                           const struct fetch_multipart_data *multipart)
+{
+       curl_mime *cmime;
+       curl_mimepart *part;
+       CURLcode code;
+       size_t value_len;
+
+       cmime = curl_mime_init(chandle);
+       if (cmime == NULL) {
+               goto convert_failed;
+       }
+
+       /* iterate post data */
+       for (; multipart != NULL; multipart = multipart->next) {
+               part = curl_mime_addpart(cmime);
+               if (part == NULL) {
+                       goto convert_failed;
+               }
+
+               code = curl_mime_name(part, multipart->name);
+               if (code != CURLE_OK) {
+                       goto convert_failed;
+               }
+
+               value_len = strlen(multipart->value);
+
+               if (multipart->file && value_len==0) {
+                       /* file entries with no filename require special 
handling */
+                       code=curl_mime_data(part, multipart->value, value_len);
+                       if (code != CURLE_OK) {
+                               goto convert_failed;
+                       }
+
+                       code = curl_mime_filename(part, "");
+                       if (code != CURLE_OK) {
+                               goto convert_failed;
+                       }
+
+                       code = curl_mime_type(part, "application/octet-stream");
+                       if (code != CURLE_OK) {
+                               goto convert_failed;
+                       }
+
+               } else if(multipart->file) {
+                       /* file entry */
+                       nserror ret;
+                       char *leafname = NULL;
+                       char *mimetype = NULL;
+
+                       code = curl_mime_filedata(part, multipart->rawfile);
+                       if (code != CURLE_OK) {
+                               goto convert_failed;
+                       }
+
+                       ret = guit->file->basename(multipart->value, &leafname, 
NULL);
+                       if (ret != NSERROR_OK) {
+                               goto convert_failed;
+                       }
+                       code = curl_mime_filename(part, leafname);
+                       free(leafname);
+                       if (code != CURLE_OK) {
+                               goto convert_failed;
+                       }
+
+                       mimetype = guit->fetch->mimetype(multipart->value);
+                       if (mimetype == NULL) {
+                               mimetype=strdup("text/plain");
+                       }
+                       if (mimetype == NULL) {
+                               goto convert_failed;
+                       }
+                       code = curl_mime_type(part, mimetype);
+                       free(mimetype);
+                       if (code != CURLE_OK) {
+                               goto convert_failed;
+                       }
+
+               } else if(value_len > sizeof (struct curl_mime_ctx)) {
+                       /* reference the existing multipart data */
+                       struct curl_mime_ctx *cb_ctx;
+                       cb_ctx = malloc(sizeof(struct curl_mime_ctx));
+                       if (cb_ctx == NULL) {
+                               goto convert_failed;
+                       }
+                       cb_ctx->buffer = multipart->value;
+                       cb_ctx->size = value_len;
+                       cb_ctx->position = 0;
+                       code = curl_mime_data_cb(part,
+                                                value_len,
+                                                mime_data_read_callback,
+                                                mime_data_seek_callback,
+                                                mime_data_free_callback,
+                                                cb_ctx);
+                       if (code != CURLE_OK) {
+                               free(cb_ctx);
+                               goto convert_failed;
+                       }
+               } else {
+                       /* simple copy data */
+                       code=curl_mime_data(part, multipart->value, value_len);
+                       if (code != CURLE_OK) {
+                               goto convert_failed;
+                       }
+               }
+       }
+
+       return cmime;
+
+convert_failed:
+       NSLOG(netsurf, INFO, "postdata conversion failed with curl code: %d", 
code);
+       curl_mime_free(cmime);
+       return NULL;
+}
+
+#else /* LIBCURL_VERSION_NUM >= 0x073800 */
+
+/**
+ * Convert a list of struct ::fetch_multipart_data to a list of
+ * struct curl_httppost for libcurl.
+ */
+static struct curl_httppost *
+fetch_curl_postdata_convert(CURL *chandle,
+                           const struct fetch_multipart_data *control)
+{
+       struct curl_httppost *post = NULL, *last = NULL;
+       CURLFORMcode code;
+       nserror ret;
+
+       for (; control; control = control->next) {
+               if (control->file) {
+                       char *leafname = NULL;
+                       ret = guit->file->basename(control->value, &leafname, 
NULL);
+                       if (ret != NSERROR_OK) {
+                               continue;
+                       }
+
+                       /* We have to special case filenames of "", so curl
+                        * a) actually attempts the fetch and
+                        * b) doesn't attempt to open the file ""
+                        */
+                       if (control->value[0] == '\0') {
+                               /* dummy buffer - needs to be static so
+                                * pointer's still valid when we go out
+                                * of scope (not that libcurl should be
+                                * attempting to access it, of course).
+                                */
+                               static char buf;
+
+                               code = curl_formadd(&post, &last,
+                                                   CURLFORM_COPYNAME, 
control->name,
+                                                   CURLFORM_BUFFER, 
control->value,
+                                                   /* needed, as basename("") 
== "." */
+                                                   CURLFORM_FILENAME, "",
+                                                   CURLFORM_BUFFERPTR, &buf,
+                                                   CURLFORM_BUFFERLENGTH, 0,
+                                                   CURLFORM_CONTENTTYPE,
+                                                   "application/octet-stream",
+                                                   CURLFORM_END);
+                               if (code != CURL_FORMADD_OK)
+                                       NSLOG(netsurf, INFO,
+                                             "curl_formadd: %d (%s)", code,
+                                             control->name);
+                       } else {
+                               char *mimetype = 
guit->fetch->mimetype(control->value);
+                               code = curl_formadd(&post, &last,
+                                                   CURLFORM_COPYNAME, 
control->name,
+                                                   CURLFORM_FILE, 
control->rawfile,
+                                                   CURLFORM_FILENAME, leafname,
+                                                   CURLFORM_CONTENTTYPE,
+                                                   (mimetype != 0 ? mimetype : 
"text/plain"),
+                                                   CURLFORM_END);
+                               if (code != CURL_FORMADD_OK)
+                                       NSLOG(netsurf, INFO,
+                                             "curl_formadd: %d (%s=%s)",
+                                             code,
+                                             control->name,
+                                             control->value);
+                               free(mimetype);
+                       }
+                       free(leafname);
+               } else {
+                       code = curl_formadd(&post, &last,
+                                           CURLFORM_COPYNAME, control->name,
+                                           CURLFORM_COPYCONTENTS, 
control->value,
+                                           CURLFORM_END);
+                       if (code != CURL_FORMADD_OK)
+                               NSLOG(netsurf, INFO,
+                                     "curl_formadd: %d (%s=%s)", code,
+                                     control->name, control->value);
+               }
+       }
+
+       return post;
+}
+
+#endif  /* LIBCURL_VERSION_NUM >= 0x073800 */
+
+/**
+ * Setup multipart post data
+ */
+static CURLcode fetch_curl_set_postdata(struct curl_fetch_info *f)
+{
+       CURLcode code;
+
+#undef SETOPT
+#define SETOPT(option, value) { \
+       code = curl_easy_setopt(f->curl_handle, option, value); \
+       if (code != CURLE_OK)                                   \
+               return code;                                    \
+       }
+
+       switch (f->postdata->type) {
+       case FETCH_POSTDATA_NONE:
+               SETOPT(CURLOPT_POSTFIELDS, NULL);
+               SETOPT(NSCURL_POSTDATA_CURLOPT, NULL);
+               SETOPT(CURLOPT_HTTPGET, 1L);
+               break;
+
+       case FETCH_POSTDATA_URLENC:
+               SETOPT(NSCURL_POSTDATA_CURLOPT, NULL);
+               SETOPT(CURLOPT_HTTPGET, 0L);
+               SETOPT(CURLOPT_POSTFIELDS, f->postdata->data.urlenc);
+               break;
+
+       case FETCH_POSTDATA_MULTIPART:
+               SETOPT(CURLOPT_POSTFIELDS, NULL);
+               SETOPT(CURLOPT_HTTPGET, 0L);
+               if (f->curl_postdata == NULL) {
+                       f->curl_postdata =
+                               fetch_curl_postdata_convert(f->curl_handle,
+                                                           
f->postdata->data.multipart);
+               }
+               SETOPT(NSCURL_POSTDATA_CURLOPT, f->curl_postdata);
+               break;
+       }
+       return code;
+}
 
 /**
  * Set options specific for a fetch.
@@ -892,18 +1170,9 @@ static CURLcode fetch_curl_set_options(struct 
curl_fetch_info *f)
        SETOPT(CURLOPT_WRITEHEADER, f);
        SETOPT(CURLOPT_PROGRESSDATA, f);
        SETOPT(CURLOPT_HTTPHEADER, f->headers);
-       if (f->post_urlenc) {
-               SETOPT(CURLOPT_HTTPPOST, NULL);
-               SETOPT(CURLOPT_HTTPGET, 0L);
-               SETOPT(CURLOPT_POSTFIELDS, f->post_urlenc);
-       } else if (f->post_multipart) {
-               SETOPT(CURLOPT_POSTFIELDS, NULL);
-               SETOPT(CURLOPT_HTTPGET, 0L);
-               SETOPT(CURLOPT_HTTPPOST, f->post_multipart);
-       } else {
-               SETOPT(CURLOPT_POSTFIELDS, NULL);
-               SETOPT(CURLOPT_HTTPPOST, NULL);
-               SETOPT(CURLOPT_HTTPGET, 1L);
+       code = fetch_curl_set_postdata(f);
+       if (code != CURLE_OK) {
+               return code;
        }
 
        f->cookie_string = urldb_get_cookie(f->url, true);
@@ -1163,10 +1432,8 @@ static void fetch_curl_free(void *vf)
        if (f->headers) {
                curl_slist_free_all(f->headers);
        }
-       free(f->post_urlenc);
-       if (f->post_multipart) {
-               curl_formfree(f->post_multipart);
-       }
+       fetch_curl_free_postdata(f->postdata);
+       NSCURL_POSTDATA_FREE(f->curl_postdata);
 
        /* free certificate data */
        for (i = 0; i < MAX_CERT_DEPTH; i++) {
@@ -1201,7 +1468,7 @@ static bool fetch_curl_process_headers(struct 
curl_fetch_info *f)
        http_code = f->http_code;
        NSLOG(netsurf, INFO, "HTTP status code %li", http_code);
 
-       if (http_code == 304 && !f->post_urlenc && !f->post_multipart) {
+       if ((http_code == 304) && (f->postdata->type==FETCH_POSTDATA_NONE)) {
                /* Not Modified && GET request */
                msg.type = FETCH_NOTMODIFIED;
                fetch_send_callback(&msg, f->fetch_handle);


-----------------------------------------------------------------------


-- 
NetSurf Browser
_______________________________________________
netsurf-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to