qnikst / HaskellNet

Haskell library which provides client support for POP3, SMTP, and IMAP protocols.
Other
87 stars 54 forks source link

Add support for more flexible backend streams #9

Open ppetr opened 11 years ago

ppetr commented 11 years ago

I wanted to use IMAP with TLS and this turned out to be quite complex. (Relates to #7.) So far, I found these solutions:

I'm willing to participate on those changes, if we reach some consensus.

mejrpete commented 11 years ago

This is something that I would love to see implemented. It would do wonders for a project that I was participating on that was more or less abandoned a while ago because of difficulties with this and related issues.

I'd also be willing to participate if I can be of any help.

jtdaugherty commented 11 years ago

Great! I don't have a strong preference as to which approach is taken. I also don't have time to work on this myself right now, so I'm going to be especially appreciative of anyone who wants to take this on. :) With that said, the MonadIO approach seems like a good middle ground for now until something clearer with e.g. conduit arises. As far as I can tell, there is not a community consensus on which iterative I/O approach to use, anyway. Regardless: if you want to hack up a conduit implementation just to see how it might go, that would be great. Or you can just submit a pull request for the MonadIO approach and have done with it.

ppetr commented 11 years ago

@jtdaugherty It seems that converting to MonadIO is just enough so that it's possible to support conduit. I hacked a function that converts a conduit into a MonadIO variant of BSStream:

conduitToStream
    :: (MonadIO m)
    => Source m ByteString
    -> Sink (Flush ByteString) m ()
    -> m (BSStreamM m)

Similarly, I constructed

tlsContextConduit
    :: (MonadIO m)
    => Context
    -> (Source m ByteString, Sink (Flush ByteString) m ())

for TLS contexts from Network.TLS. Combined together, I got IMAP working on TLS.

One problem is that it doesn't really make sense to close a conduit. Another conduit can be appended after it and continue its processing. This can be also viewed as that closing a connection is the responsibility of whoever created it, not IMAP's. So currently for conduits bsClose does nothing and bsIsOpen return always True. Any ideas?

With this structure, I think we could

  1. Patch HaskellNet to use MonadIO everywhere.
  2. Add a new package HaskellNet-conduit that will depend on conduit and provide BSStreams from conduits.
jtdaugherty commented 11 years ago

I think having a separate integration package like HaskellNet-conduit makes a lot of sense. As for the specifics of how best to go about doing it, I really couldn't say. :)