curl / Mailing Lists / curl-library / Single Mail

curl-library

Improving form post API

From: Andrew <andrew_at_boredomsoft.org>
Date: Tue, 20 Jun 2017 14:15:01 -0700

Hello,

In the user survey this year I made a comment about curl_formadd being a
pain for bindings to languages that don't allow variadic foreign functions.

I commented on Daniel's blog post about the survey that I'd like to help
move this forward. But since C is still a "read only" language for me,
I'm not sure how much help I can be except to share my perspective as a
developer and user of the language binding I was referring to
(https://github.com/charonn0/RB-libcURL).

It seems I'm not alone in thinking that this function is problematic:
https://github.com/curl/curl/wiki/formpost-API-redesigned

Daniel identifies three issues with the current API:
  * complicated (multitple varargs, several ways to do the same thing)
  * error-prone (due to the above)
  * the use of the public struct makes it hard to change - and yet
    hardly any users actually create the linked list of headers
    themselves!

He suggests a new API where the form is an opaque handle that you get
from curl_form_init, and then you call curl_form_addpart on the form
handle to get a handle to a new part. Parts are populated with
curl_form_set_name and curl_form_set_data.

I really like the idea of using an opaque handle instead of a pointer to
a list of structures, and this is basically how I already present it in
my binding. I also agree with the notion that CURLFORM_PTRCONTENTS,
CURLFORM_PTRNAME, and CURLFORM_ARRAY should be deprecated. For
small/non-file form parts using a pointer for the contents doesn't seem
obviously useful, and a pointer for the name even less so. My binding
doesn't even expose these features to the user. It also seems like
encoding several CURLFORM_FILE in the same form part might be a problem
if curl_form_set_data overwrites the previous data.

Seemingly missing in the proposal are equivalents for CURLFORM_STREAM
and CURLFORM_BUFFERPTR. If curl_form_set_data were to always copy the
data then I don't see how these modes could be made to work. Perhaps if
instead of separate functions for the name and data there were a single
curl_form_setopt function? e.g.

  curl_form_setopt(part1, CURLFORM_COPYNAME, "name", 4);
  curl_form_setopt(part1, CURLFORM_BUFFERPTR, someptr, 6);
  curl_form_setopt(part2, CURLFORM_COPYNAME, "shoesize", 8);
  curl_form_setopt(part2, CURLFORM_STREAM, usercontext, -1);

This would also mean that you don't need separate functions for
CURLFORM_CONTENTTYPE, CURLFORM_CONTENTHEADER, etc.

Also a curl_form_setopt function could be made to work with both
individual parts or the overall form depending on whether the form or
the part are passed in as the first argument (though this might be
confusing).

Thanks for reading,
Andrew Lambert
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2017-06-20