Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] OCaml-ssl and input_string
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: asmadeus77@g...
Subject: [Caml-list] OCaml-ssl and input_string
Hello,

I'm making a simple mail client for gmail using IMAP, and I need to
use ssl sockets.
So far so good, there's a library called ocaml-ssl which works quite
well, untill you need to read what the server sends.

At first, the function input_string in the library is defined by
let input_string ssl =
  let bufsize = 1024 in
  let buf = String.create bufsize in
  let ret = ref "" in
  let r = ref 1 in
    while !r <> 0
    do
      r := read ssl buf 0 bufsize;
      ret := !ret ^ (String.sub buf 0 !r)
    done;
    !ret

Which doesn't work, since read will wait untill there is something to
read if there is nothing waiting to be read, thus will never return 0.
I've changed the loop condition to "while !r = bufsize", initializing
r with bufsize, and I've been satisfied with the result during my
early testing (discovering the IMAP protocol in toplevel)

Now, though, I've encountered a problem - it seems that the function
returns too early, meaning that there is still some text left to be
read after it has been invoked.
I've discovered that the size of the returned strings is quite often
1400 or 648, but it can be anything, and changing the variable
"bufsize" doesn't help (I guess it's the size of the packets sent by
the server, but couldn't the socket hold more characters ? There's
usually been a couple of seconds between two input_string calls, so
there should be more than just a couple of KBs)

I've tried adding a poll - (same function with "let fdescr_of_ssl =
file_descr_of_socket ssl in while Unix.select [fdescr_of_ssl] [] []
10. <> [],[],[] do") - but the result, though better, isn't granteed
unless I set the timeout to at least 5-10 seconds, and even there I've
had cases of uncomplete returns, even though they were rare enough to
bear with.

Anyway, I've decided to program this mail client to avoid waiting for
the slow gmail web view, so I'd like to not to use a select there :

Is it possible to read the socket untill a known string, to be sure
the request is done, without waiting after it ? (the string I need to
match is "known_identifier_without_space OK Success\r\n" eventually
leaving the "OK Success" as wildcards to check for (it could be "BAD
why it is bad\r\n"))

I can assume I'm not making two requests at once, thus being sure that
I can read the socket by large chunks untill the end matches, but I
would rather not do so if possible.

Any clue ?

Thanks,
Dominique Martinet

PS : A friend of mine is wondering if there's a regexp for ranges in
the Str module (like "aaaa?" would be "a{3-4}" in pcre), I'm sure
he'll be glad if someone could ensure him there isn't any :P