caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] OCaml-ssl and input_string
@ 2008-05-05 19:54 asmadeus77
  2008-05-06 10:12 ` Berke Durak
  0 siblings, 1 reply; 3+ messages in thread
From: asmadeus77 @ 2008-05-05 19:54 UTC (permalink / raw)
  To: caml-list

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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] OCaml-ssl and input_string
  2008-05-05 19:54 [Caml-list] OCaml-ssl and input_string asmadeus77
@ 2008-05-06 10:12 ` Berke Durak
  2008-05-06 10:33   ` asmadeus77
  0 siblings, 1 reply; 3+ messages in thread
From: Berke Durak @ 2008-05-06 10:12 UTC (permalink / raw)
  To: asmadeus77; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 403 bytes --]

Hello,

>From what I've inferred from ocaml-ssl's documentation, its "read" function
has Unix-like non-blocking
semantics.

This means that read returns the number of bytes available, not the number
of bytes requested.

Hence you need an extra buffering/parsing layer on top of SSL sockets.
However you are using
IMAP, which is line-oriented, I guess Ssl.input_string should do what you
want.
-- 
Berke

[-- Attachment #2: Type: text/html, Size: 466 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] OCaml-ssl and input_string
  2008-05-06 10:12 ` Berke Durak
@ 2008-05-06 10:33   ` asmadeus77
  0 siblings, 0 replies; 3+ messages in thread
From: asmadeus77 @ 2008-05-06 10:33 UTC (permalink / raw)
  To: Berke Durak; +Cc: caml-list

Hello,
Well, I don't know how it should work, but from what I've seen, it
seems that its read function will wait untill there is something to
read if nothing is available.

Anyway, I have written an input_line (read character by character
untill a '\n') function which allows me to stop as soon as I can match
the begining of the line read with a pattern I get on the greeting.
That will work untill someone tries to send me funny mails with lots
of line feeds followed by weird 8-10 characters strings followed by a
space, I guess it's safe enough.

I just don't feel confident writing things such as :

  let ret = Buffer.create 1024 in
  let str = ref (input_line s) in
  while try Scanf.sscanf !str (Scanf.format_from_string (id^ " ")  "")
(fun _ -> ()) (); false with _-> true do
    Buffer.add_string ret !str;
    str:=input_line s
  done;
  Buffer.contents ret




On 5/6/08, Berke Durak <berke.durak@gmail.com> wrote:
> Hello,
>
> From what I've inferred from ocaml-ssl's documentation, its "read" function
> has Unix-like non-blocking
> semantics.
>
> This means that read returns the number of bytes available, not the number
> of bytes requested.
>
> Hence you need an extra buffering/parsing layer on top of SSL sockets.
> However you are using
> IMAP, which is line-oriented, I guess Ssl.input_string should do what you
> want.
> --
> Berke
>


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-05-06 10:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-05 19:54 [Caml-list] OCaml-ssl and input_string asmadeus77
2008-05-06 10:12 ` Berke Durak
2008-05-06 10:33   ` asmadeus77

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).