Ruby Net::IMAP and Exchange
Posted Tue, 26 May 2009
Exchange's server-side filters are pretty weak, so I decided to work around them by writing a tool that will fix my inbox and filter mail appropriately so that any client I use to view mail with (OWA, whatever) has the same view with no client-local filters. It's likely/possible there's already a tool that does this; let's ignore that possibility for now.
Ruby comes with Net::IMAP, but it doesn't come with an authenticator that supports 'PLAIN' auth, so we have to provide one:
# Learned the 'PLAIN' expected format from imapsync. class PlainAuthenticator def process(data) # Net::IMAP takes care of base64 encoding the result of this... return "[email protected]}\[email protected]}\[email protected]}" end def initialize(user, password) @user = user @password = password end end Net::IMAP::add_authenticator('PLAIN', PlainAuthenticator)Now that we have that, let's try connecting.
imap = Net::IMAP.new("exchange.example.com", "imaps", usessl=true) imap.authenticate("PLAIN", user, passwd)This fails, because Exchange's IMAP server ignores the RFC:
/usr/lib/ruby/1.8/net/imap.rb:3122:in `parse_error': unexpected token CRLF (expected SPACE) (Net::IMAP::ResponseParseError) from /usr/lib/ruby/1.8/net/imap.rb:2974:in `match' from /usr/lib/ruby/1.8/net/imap.rb:1959:in `continue_req' from /usr/lib/ruby/1.8/net/imap.rb:1946:in `response' ...Expected a space, not a crlf. The failure is in continue_req, which expects what the RFC says:
continue_req ::= "+" SPACE (resp_text / base64)However, Exchange's IMAP server doesn't send a space after the plus. Great, let's fix that by overriding the continue_req method:
# Copied/modified from net/imap.rb, don't modify that file, put this # in your own code to override the continue_req method module Net class IMAP class ResponseParser def continue_req match(T_PLUS) #match(T_SPACE) # Comment this line out to not expect a space. return ContinuationRequest.new(resp_text, @str) end end end endOnce you've done that, everything else seems to work normally. I have only tested listing mail folders thus far, but the hacks above allow you to get this far.