cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Question regarding multiple IMAP operations

From: Ray Satiro via curl-library <curl-library_at_cool.haxx.se>
Date: Wed, 27 May 2015 18:42:26 -0400

On 5/27/2015 3:09 PM, Adam wrote:
> Ray, I've actually written C89 code to parse IMAP responses. libcurl
> IMAP is indeed garbage, because the only thing it does for you that a
> straight socket doesn't is encryption (which is well documented w/tons
> of code samples anyway). So as soon as I remove these crashes I will
> post my code to hopefully make it a bit more of a complete IMAP
> library. I've already come this far w/libcurl despite it's awkward
> callback schemes so don't feel like switching now.

The imap code isn't garbage it's just limited in what it can do. That's
very different from bad code. If you have contributions to make to
imap.c that's great. Contributions aren't guaranteed to be added,
however. If the changes you are making are substantial you should
discuss it to get some feedback and a better idea if what you are
writing is something that could be accepted. That way you won't waste
time. And please review the coding guidelines at [1].

I am not the best person to do a review for whatever you propose so you
will probably not hear much from me on that. My IMAP experience is
limited to using regular expressions to parse results from the servers
and is not in any way RFC compliant.

> Let's say I want first list folders, the default, then 1 second later
> I want to "EXAMINE OUTBOX", then 1 second later I want to read first
> message ""imap://imap.example.com/INBOX/;UID=1
> <http://imap.example.com/INBOX/;UID=1>" There are no code samples
> showing how to do multiple requests like this.
>
> Would something like this be the correct way? Or is this what the
> multi_ function families are for? Not this exactly, but doing stuff
> like this I'm getting a lot of different crashes, and I'm not using
> any handles after calling cleanup.

The code is incorrect you want to keep the same scheme host port in the
url so the connection is reused. You want to use CURLOPT_CUSTOMREQUEST
instead of CURLOPT_URL to send a custom request. So for example

curl_easy_setopt(curl, CURLOPT_URL, "imaps://imap.gmail.com:993/");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "EXAMINE INBOX");

you should see in the body the results of the examine command. if you
want to then fetch INBOX email id 1 you'd do:

curl_easy_setopt(curl, CURLOPT_URL,
"imaps://imap.gmail.com:993/INBOX/;UID=1");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);

now that e-mail is in the body in addition to examine results (assuming
you didn't clear the memory in between).

The thing about IMAP support is certain commands have limited support
depending on how you format the URL (APPEND, SELECT, FETCH, LIST,
SEARCH) and other commands you have to use CUSTOMREQUEST. The latter is
considered exactly that, a custom request, so the parsing is not done
for you. In those cases you will find the results written to the header,
not the body. I encourage you to review imap.c [3].

Since you have already written IMAP parsing you may already be aware of
this but when you request a URL like this:
imaps://imap.example.com/INBOX/;UID=1
what actually happens is these two commands
SELECT INBOX
FETCH 1 BODY[]
That behavior is specified according to the RFC [2]. Since libcurl sent
the command it recognizes the response, so it should parse it out and
put it in the body. If you send FETCH 1 BODY[] as a custom command
though the response is not parsed out so it's in the header section
instead of the body.

And as an example of limitation libcurl can't handle %0D%0A in the URL
even though it's technically allowed in the urls according to the RFC.
That maybe? could be a problem during search but if you don't use the {}
for data block, you can still do it straightaway like
imaps://imap.gmail.com:993/INBOX?charset%20UTF-8%20SUBJECT%20test
which actually does:
SELECT INBOX
SEARCH charset UTF-8 SUBJECT test
and your body will contain a response of
* SEARCH 1 2 3 4
or whatever

Also the etiquette for this mailing list is no top-posting [4].

[1]: http://curl.haxx.se/dev/contribute.html#Naming
[2]: https://tools.ietf.org/html/rfc5092
[3]: https://github.com/bagder/curl/blob/master/lib/imap.c
[4]: http://curl.haxx.se/mail/etiquette.html#Do_Not_Top_Post

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2015-05-28