cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Question about Content-type: multipart

From: Ray Satiro via curl-library <curl-library_at_cool.haxx.se>
Date: Mon, 7 Mar 2016 17:56:55 -0500

On 3/7/2016 3:10 AM, Waitman Gobble wrote:
> Thanks for the replies, I will read through them and figure it out. I
> really appreciate it.
> I didn't post the entire file.
>
> One thing I think the problem is in lib/http.c
>
> else if(data->set.postfields)
> expectsend = (curl_off_t)strlen(data->set.postfields);
>
> strlen is wrong, the binary data has a character that cuts it off at
> byte 172, the string is actually much bigger.
>
> The documentation states that curl will use strlen if POSTFIELDSIZE is
> not provided. But it looks like it's using strlen anyway..:(
> I'm guessing that' why it's sitting there until the end of time?
>
> using the form struct doesn't look like it will help. I don't see how
> to put "already" formatted data into the struct.. Basically I'd have
> to regurgitate the data and break it into objects and feed back into
> the form api, which seems not so good. But perhaps I'm mistaken.

The code you're citing in http.c [1] afaict shouldn't be called in your
case unless a rewind is necessary due to some problem. However if that
code is called it sets the size to data->state.infilesize:

     switch(data->set.httpreq) {
     case HTTPREQ_POST:
       if(data->state.infilesize != -1)
         expectsend = data->state.infilesize;
       else if(data->set.postfields)
         expectsend = (curl_off_t)strlen(data->set.postfields);
       break;

data->state.infilesize should be != -1 because in transfer.c [2] if the
method is not PUT then data->state.infilesize = data->set.postfieldsize.

Regardless I totally misread what you are doing, it is unusual. I looked
at your repo [3] and it appears you have a file that basically contains
a raw multipart post and you want to send that to the server as one
without libcurl handling the parts. In order to do that you need to set
the boundary header, so ignore my comment about removing that header it
appears you are on the right track.

The reason why the file fails to post is you are not sending the correct
boundary value in the header. multipart boundaries in content are
supposed to start with two dashes and then the header value, so in other
words if your boundary value was foo then you'd have a header like
"Content-Type: multipart/form-data; boundary=foo" and boundaries in the
preformatted content like:

--foo
Content-Disposition: form-data; name="bar"

data
--foo
Content-Disposition: form-data; name="baz"

data
--foo--

So take away the first two dashes and it's foo, or in your case you have
this in the raw data and the header:
-----------------------------84927149120355803091994092429
but in the header remove two dashes and make it this:
---------------------------84927149120355803091994092429

 From RFC 2046 [4]:

The Content-Type field for multipart entities requires one parameter,
"boundary". The boundary delimiter line is then defined as a line
consisting entirely of two hyphen characters ("-", decimal value 45)
followed by the boundary parameter value from the Content-Type header
field, optional linear whitespace, and a terminating CRLF.

That still doesn't explain why libcurl is waiting on BSD but not on
Linux. That could be a separate issue. If you discover what that is or
have a way to reproduce let us know.

Also note for your example to be compatible on Windows it must be opened
with "rb".

[1]: https://github.com/curl/curl/blob/curl-7_47_1/lib/http.c#L411-L416
[2]:
https://github.com/curl/curl/blob/curl-7_47_1/lib/transfer.c#L1340-L1343
[3]: http://git.cloudqx.com/root/test-curl
[4]: https://tools.ietf.org/html/rfc2046#section-5.1.1

-------------------------------------------------------------------
List admin: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2016-03-07