libcurl - CURLOPT_MIMEPOST vs CURLOPT_POSTFIELDS - c

Tell me please, what is the main difference between options CURLOPT_MIMEPOST and CURLOPT_POSTFIELDS ?
What can be done with a CURLOPT_MIMEPOST - that cannot be done with CURLOPT_POSTFIELDS ?

CURLOPT_POSTFIELDS
Sends exactly the bytes you specify in the body of the HTTP request. With a default Content-type of application/x-www-form-urlencoded. libcurl will not add or encode the data in any way for you.
With the curl command line tool, you do this with -d.
CURLOPT_MIMEPOST
Makes libcurl send a "multipart formpost". That is a data stream using a format that allows the sender to send multiple "parts" of data to the server, each part being properly separated and identified. Each part has a name, content and its own set of headers. When an HTTP client "uploads a file", this is almost always done using multipart formposts.
Multipart formpost is structured data in the request body and this option helps you produce and send that format. An application can also produce that format by themselves should they prefer that and provide it with CURLOPT_POSTFIELDS or even using the callback CURLOPT_READFUNCTION.
With the curl command line tool, you do this with -F.
See Also
https://everything.curl.dev/libcurl-http/upload

Related

How to get Content-Length from response headers in CN1?

I implemented this but the response headers don't include Content-Length, even though I make sure the server replies that bit specifically. I also verified the response outside CN1 and it includes Content-Length. The full list of headers captured in ReadHeaders is (as seen from Android): null,Alt-Svc,Cache-Control,Connection,Content-Type,Date,ETag,Server,Transfer-Encoding,Vary,X-Android-Received-Millis,X-Android-Response-Source,X-Android-Selected-Protocol,X-Android-Sent-Millis,X-Cloud-Trace-Context,X-Powered-By. Right now to estimate download sizes I (1) call endpoint to get total size (2) call endpoint to get actual download and use NetworkManager progress listener, but it would be nice to be able to track progress with only one request (by using Content-Length). The vanilla RequestBuilder doesn't expose response headers so a direct usage of ConnectionRequest with readHeaders is needed. But the Content-Length is missing from getHeaderFieldNames
Note:
The reason why this wasn't working is because by default Android/CN1 sends a request with the header Accept-Enconding:gzip. This returns a chunked response that doesn't include the length header. I can't guarantee that this behavior matches every server response, but it does in my case (Node.js + Express)
To force a server to return a non-chunked response, set the header to "compress", "identity", or "deflate"
Example:
Rest.post(url).header("Accept-Encoding", "compress").fetchAsJsonMap(resp -> {...

Unable to retrieve attachments from a signed mail having ContentType as "application/pkcs7-mime; name=smime.p7m"

I am trying to read a digitally signed mail from java code using multipart and mime messaging and fetch the attachments (xml, pdf, txt etc.,) and message details.
My code is working fine for mails having Content-Type as : multipart/signed; protocol="application/x-pkcs7-signature";
But For few mails having Content-Type as : application/pkcs7-mime; smime-type=signed-data; name=smime.p7m it is not fetching the attachments and message details. Can anyone explain what is the difference between both of them and how to resolve it.
I recently came across this issue myself, and although this question is three month old, I leave an answer with my findings, just in case.
Both kinds of messages are instances of S/MIME signed messages as specified in RFC2633 (https://www.rfc-editor.org/rfc/rfc2633).
The multipart/signed; protocol="application/x-pkcs7-signature" indicates a clear-signed message (section 3.4.3.3 of the RFC), meaning you can read the original message content without having S/MIME capabilities in your client code. Hence no problem with these.
The application/pkcs7-mime; smime-type=signed-data; name=smime.p7m indicates an S/MIME signedData email (section 3.4.2) Your client code needs S/MIME capability in order to read the original message (even if you don’t care about the signature).
Easiest way (worked for me) is to use bouncycastle's SMIMESigned class (from the S/MIME API, https://mvnrepository.com/artifact/org.bouncycastle/bcmail-jdk15on), like this:
byte[] content = <the signed data's content as byte[]>;
ByteArrayDataSource dataSource = new ByteArrayDataSource(content,"multipart/signed");
SMIMESigned signedData = new SMIMESigned(new MimeMultipart(dataSource));
MimeBodyPart bodyPart = signedData.getContent();
<you can process the body part as normal from here>

Quickbook No apptoken detected; (PHP)errorCode=003102; statusCode=401

I am new in quickbooks API implementation, I am always getting one error No apptoken detected; errorCode=003102; statusCode=401 when I am doing API call for customer add etc.
I am giving my steps, please look over that.
My sandbox info like that
Consumer Key: qyprdffbBBInX4a82jG73Mreyy96tC
Consumer Secret: IgpJzJrYvb9FmmdB7A0ECDGHG62Cp7dqVWjfMTvU
Access Token: qyprdlo3WrK0KhGZMTeA857AuKiVy2eaAmpXsRvG3jycYaMQ
Access Token Secret: TdPGpcUI8AiAdWFiCyb8jAAygH16bzU7VRGaspx4
I am Using PHP.
First I have generated oauth_signature.
$URL =
rawurlencode('https://sandbox-quickbooks.api.intuit.com/v3/company/408554291/customer');
$method = 'POST'; $parameter =
rawurlencode('oauth_consumer_key=qyprdffbBBInX4a82jG73Mreyy96tC&oauth_nonce=BlyqIBbv3R4T0P4qglAv1RjoYisMZk1449659733&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1449659733&oauth_token=qyprdlo3WrK0KhGZMTeA857AuKiVy2eaAmpXsRvG3jycYaMQ&oauth_version=1.0');
$ukey =
rawurlencode('IgpJzJrYvb9FmmdB7A0ECDGHG62Cp7dqVWjfMTvU').'&'.rawurlencode('TdPGpcUI8AiAdWFiCyb8jAAygH16bzU7VRGaspx4');
$hasmac = hash_hmac("sha1", $BaseURL,$ukey,1);
and My oauth_signature is jZ8JhECy/e0kpPbUdZp/o/EUC7U=
When i call API with this oauth_signature, i am getting Error 'No apptoken detected; errorCode=003102; statusCode=401'
My CURL call like this
curl -X POST -H 'Content-Type: application/json, Authorization: OAuth
oauth_token=qyprdlo3WrK0KhGZMTeA857AuKiVy2eaAmpXsRvG3jycYaMQ,oauth_consumer_key=qyprdffbBBInX4a82jG73Mreyy96tC,oauth_signature_method=HMAC-SHA1,oauth_timestamp=1449659733,oauth_version=1.0,oauth_nonce=BlyqIBbv3R4T0P4qglAv1RjoYisMZk1449659733,oauth_signature=jZ8JhECy/e0kpPbUdZp/o/EUC7U='
-d '{"data": [{"BillAddr":{"Line1":"86 A Topsia","City":"Kolkata","Country":"India","CountrySubDivisionCode":"WB","PostalCode":"700102"},"Title":"Mr.","GivenName":"ApurbaK","MiddleName":"Kumar","FamilyName":"ApurbaK","PrimaryPhone":{"FreeFormNumber":"564545465"},"PrimaryEmailAddr":{"Address":"apurbahazra12#navsoft.in"}}]}'
'https://sandbox-quickbooks.api.intuit.com/v3/company/408554291/customer'
Please look over that.
Thanks,
Apurba
Firstly, you don't want to be doing this yourself -- use a library. OAuth is complex, and implementing it yourself is going to be a hairy process, rife with errors.
Go grab a library:
https://github.com/consolibyte/quickbooks-php
Follow the quick-start guide linked there, and benefit from the examples:
https://github.com/consolibyte/quickbooks-php/tree/master/docs/partner_platform/example_app_ipp_v3
With that said, if you do decide to write it yourself, make sure you follow the OAuth spec:
https://www.rfc-editor.org/rfc/rfc5849
So far, the issues I immediately see with your implementation are:
You can't hard-code the timestamp like this: &oauth_timestamp=1449659733 The timestamp should be ever-changing, and set to the currenty timestamp.
You can't hard-code a nonce like this: &oauth_nonce=BlyqIBbv3R4T0P4qglAv1RjoYisMZk1449659733 The nonce has to change with every single request so this is going to fail after your first request.
You haven't normalized your request parameters / sorted them, per the spec.
This is the incorrect way to specify multiple headers with cURL: -H 'Content-Type: application/json, Authorization: OAuth .... Please see the cURL docs: http://curl.haxx.se/docs/manpage.html#-H
In the code you posted, you haven't actually set $BaseURL anywhere, so right now you're signing an empty string (unless you forgot to paste some code somewhere?)
What is $ukey set to? It doesn't appear to be defined in your code anywhere (did you forget to paste some code in?)

How can I send a file, for example "exe", with Telnet?

With smtp, i know the commands: "HELO", "MAIL FROM", "RCPT TO", "QUIT", but i don't know how can i attach one file. Anyone can help me ?
telnet smtp.xxxx.xxxx 25
helo xxxx.xxxx
mail from: yyy#xxx.xxx
rcpt to: yy2#xxx.xxx
data
subject: hi
hello
.
quit
This is not something that can be easily done. You probably want to use a library (ex : in python) that will take care of formatting your email according to your needs.
In very brief :
Sending an attachement requires the email to be formatted according to the MIME RFC
A MIME formatted message will use some delimiters to separate the different parts of the message (ex : a plain text part, an HTML part, an attachment part, etc...)
Each MIME part will be prefixed by a header detailing the part content
an attachment part will be identified by a "Content-disposition" header, as detailed in RFC 2183.
The representation of your file will have to be specified using the "Content-Transfer-Encoding" header, described in RFC 2045. A common way to encode files for mail transfer is base64.
If you want to get an idea of how complex it is to generate an email with a valid attachment, you can use your email client to check the source of an email with an attachment (most email clients have this feature). That should eventually convince you to avoid doing this manually :)

Amazon MWS Connection String Not Working

The connection string below is returning an 'Invalid Address' error. The error message indicates that the API Version is missing, but it is included in the string (see the last parameter). Not sure what the issue is.
https://mws.amazonservices.com/AWSAccessKeyId=[ID Hidden]&Action=GetFeedSubmissionList
&Marketplace=ATVPDKIKX0DER&Merchant=[Merchant Hidden]&Signature=[Signature Hidden]
&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2013-10-17T00:37:34.100Z&Version=2009-01-01
I usually send my MWS calls through a HTTP POST command, because that's the only way to do a SubmitFeed. The following assumes that a GET works at all (I didn't test):
Your call is missing the ? separator between the query and the rest of the URL. So as a minimum, this should read:
https://mws.amazonservices.com/?AWSAccessKeyId....

Resources