@@ -277,46 +277,28 @@ close(#smtp_client_socket{socket = Socket}) ->
277277 quit (Socket ).
278278
279279- spec send_it (Email :: email (), Options :: options ()) ->
280- binary ()
281- | smtp_session_error ().
280+ binary ()
281+ | smtp_session_error ().
282282send_it (Email , Options ) ->
283283 NoMXLookups = proplists :get_value (no_mx_lookups , Options , false ),
284- Relay = case proplists :get_value (relay , Options ) of
285- <<Domain /binary >> when NoMXLookups =:= 'true' ->
286- % % maybe we're supposed to relay to a host directly
287- [{to_string (Domain ), [{0 , to_string (Domain )}]}];
288- <<Domain /binary >> ->
289- [{to_string (Domain ), smtp_util :mxlookup (to_string (Domain ))}];
290- [<<_ /binary >> | _ ] = Domains when NoMXLookups =:= 'true' ->
291- % % maybe we're supposed to relay to a host directly
292- [{to_string (Domain ), {0 , to_string (Domain )}} || Domain <- Domains ];
293- [<<_ /binary >> | _ ] = Domains ->
294- [{to_string (Domain ), smtp_util :mxlookup (to_string (Domain ))} || Domain <- Domains ];
295- [List | _ ] = Domains when is_list (List ) andalso NoMXLookups =:= 'true' ->
296- % % maybe we're supposed to relay to a host directly
297- [{Domain , [{0 , Domain }]} || Domain <- Domains ];
298- [List | _ ] = Domains when is_list (List ) ->
299- [{Domain , smtp_util :mxlookup (Domain )} || Domain <- Domains ];
300- Domain when NoMXLookups =:= 'true' ->
301- % % maybe we're supposed to relay to a host directly
302- [{Domain , [{0 , Domain }]}];
303- Domain ->
304- [{Domain , smtp_util :mxlookup (Domain )}]
305- end ,
306- [? TRACE (Options , " MX records for ~s are ~p~n " , [RelayDomain , MXRecords ])
307- || {RelayDomain , MXRecords } <- Relay
284+ Domain = proplists :get_value (relay , Options ),
285+ Relay = get_mx_records (Domain , NoMXLookups , Options ),
286+
287+ [? TRACE (Options , " MX records for ~s are ~p~n " , [RelayDomain , MXRecords ])
288+ || {RelayDomain , MXRecords } <- Relay
308289 ],
290+
309291 Hosts = lists :flatmap (fun ({_ , MXRecords }) -> MXRecords end , Relay ),
310292 case try_smtp_sessions (Hosts , Options , []) of
311293 {error , _ , _ } = Error ->
312294 Error ;
313295 {ok , ClientSocket } ->
314296 # smtp_client_socket {
315- socket = Socket ,
316- host = Host ,
317- extensions = Extensions ,
318- options = Options1
319- } = ClientSocket ,
297+ socket = Socket ,
298+ host = Host ,
299+ extensions = Extensions ,
300+ options = Options1
301+ } = ClientSocket ,
320302 try
321303 try_sending_it (Email , Socket , Extensions , Options1 )
322304 catch
@@ -327,11 +309,34 @@ send_it(Email, Options) ->
327309 end
328310 end .
329311
312+ get_mx_records (<<Domain /binary >>, 'true' , Options ) ->
313+ % % maybe we're supposed to relay to a host directly
314+ ? TRACE (Options , " relaying directly to host ~s~n " , [Domain ]),
315+ [{to_string (Domain ), [{0 , to_string (Domain )}]}];
316+ get_mx_records (<<Domain /binary >>, 'false' , Options ) ->
317+ ? TRACE (Options , " mx lookup on ~s : ~p~n " , [Domain , smtp_util :mxlookup (to_string (Domain ))]),
318+ [{to_string (Domain ), smtp_util :mxlookup (to_string (Domain ))}];
319+ get_mx_records ([<<_ /binary >> | _ ] = Domains , 'true' , _Options ) ->
320+ % % maybe we're supposed to relay to a host directly
321+ [{to_string (Domain ), {0 , to_string (Domain )}} || Domain <- Domains ];
322+ get_mx_records ([<<_ /binary >> | _ ] = Domains , 'false' , _Options ) ->
323+ [{to_string (Domain ), smtp_util :mxlookup (to_string (Domain ))} || Domain <- Domains ];
324+ get_mx_records ([List | _ ] = Domains , 'true' , _Options ) when is_list (List ) ->
325+ % % maybe we're supposed to relay to a host directly
326+ [{Domain , [{0 , Domain }]} || Domain <- Domains ];
327+ get_mx_records ([List | _ ] = Domains , 'false' , _Options ) when is_list (List ) ->
328+ [{Domain , smtp_util :mxlookup (Domain )} || Domain <- Domains ];
329+ get_mx_records (Domain , 'true' , _Options ) ->
330+ % % maybe we're supposed to relay to a host directly
331+ [{Domain , [{0 , Domain }]}];
332+ get_mx_records (Domain , 'false' , _Options ) ->
333+ [{Domain , smtp_util :mxlookup (Domain )}].
334+
330335- spec try_smtp_sessions (
331- Hosts :: [{non_neg_integer (), string ()}, ...], Options :: options (), RetryList :: list ()
332- ) ->
333- {ok , smtp_client_socket ()}
334- | smtp_session_error ().
336+ Hosts :: [{non_neg_integer (), string ()}, ...], Options :: options (), RetryList :: list ()
337+ ) ->
338+ {ok , smtp_client_socket ()}
339+ | smtp_session_error ().
335340try_smtp_sessions ([{_Distance , Host } | _Tail ] = Hosts , Options , RetryList ) ->
336341 try
337342 {ok , open_smtp_session (Host , Options )}
@@ -671,10 +676,10 @@ do_AUTH_each(Socket, Username, Password, ["CRAM-MD5" | Tail], Options) ->
671676 smtp_socket :send (Socket , [String , " \r\n " ]),
672677 case read_possible_multiline_reply (Socket ) of
673678 {ok , <<" 235" , _Rest /binary >>} ->
674- ? TRACE (Options , " authentication accepted~n " , []),
679+ ? TRACE (Options , " CRAM-MD5 authentication accepted~n " , []),
675680 true ;
676681 {ok , Msg } ->
677- ? TRACE (Options , " authentication rejected: ~s~n " , [Msg ]),
682+ ? TRACE (Options , " CRAM-mD5 authentication rejected: ~s~n " , [Msg ]),
678683 do_AUTH_each (Socket , Username , Password , Tail , Options )
679684 end ;
680685 {ok , Something } ->
@@ -686,13 +691,17 @@ do_AUTH_each(Socket, Username, Password, ["XOAUTH2" | Tail], Options) ->
686691 smtp_socket :send (Socket , [" AUTH XOAUTH2 " , Str , " \r\n " ]),
687692 case read_possible_multiline_reply (Socket ) of
688693 {ok , <<" 235" , _Rest /binary >>} ->
694+ ? TRACE (Options , " XOAUTH2 authentication accepted~n " , []),
689695 true ;
690696 {ok , _Msg } ->
691697 do_AUTH_each (Socket , Username , Password , Tail , Options )
692698 end ;
693699do_AUTH_each (Socket , Username , Password , [" LOGIN" | Tail ], Options ) ->
700+ ? TRACE (Options , " trying AUTH LOGIN: ~p~n " , [Socket ]),
694701 smtp_socket :send (Socket , " AUTH LOGIN\r\n " ),
695- {ok , Prompt } = read_possible_multiline_reply (Socket ),
702+ Return = read_possible_multiline_reply (Socket , Options ),
703+ ? TRACE (Options , " AUTH LOGIN prompt return: ~p~n " , [Return ]),
704+ {ok , Prompt } = Return ,
696705 case is_auth_username_prompt (Prompt ) of
697706 true ->
698707 % % base64 Username: or username:
@@ -719,19 +728,20 @@ do_AUTH_each(Socket, Username, Password, ["LOGIN" | Tail], Options) ->
719728 do_AUTH_each (Socket , Username , Password , Tail , Options )
720729 end ;
721730 false ->
722- ? TRACE (Options , " got ~s~n " , [Prompt ]),
731+ ? TRACE (Options , " not an auth login prompt, got ~s~n " , [Prompt ]),
723732 do_AUTH_each (Socket , Username , Password , Tail , Options )
724733 end ;
725734do_AUTH_each (Socket , Username , Password , [" PLAIN" | Tail ], Options ) ->
735+ ? TRACE (Options , " trying AUTH PLAIN~n " , []),
726736 AuthString = base64 :encode (<<0 , Username /binary , 0 , Password /binary >>),
727737 smtp_socket :send (Socket , [" AUTH PLAIN " , AuthString , " \r\n " ]),
728738 case read_possible_multiline_reply (Socket ) of
729739 {ok , <<" 235" , _Rest /binary >>} ->
730- ? TRACE (Options , " authentication accepted~n " , []),
740+ ? TRACE (Options , " PLAIN authentication accepted~n " , []),
731741 true ;
732742 Else ->
733- % TODO do we need to bother trying the multi-step PLAIN?
734- ? TRACE (Options , " authentication rejected ~p~n " , [Else ]),
743+ % TODO do we need to bother trying the multi-step PLAIN?
744+ ? TRACE (Options , " PLAIN authentication rejected ~p~n " , [Else ]),
735745 do_AUTH_each (Socket , Username , Password , Tail , Options )
736746 end ;
737747do_AUTH_each (Socket , Username , Password , [Type | Tail ], Options ) ->
@@ -803,6 +813,9 @@ try_STARTTLS(Socket, Options, Extensions) ->
803813 {false , if_available } ->
804814 ? TRACE (Options , " TLS failed~n " , []),
805815 {Socket , Extensions };
816+ {true , _ } ->
817+ ? TRACE (Options , " TLS already started~n " , []),
818+ {Socket , Extensions };
806819 {{S , E }, _ } ->
807820 ? TRACE (Options , " TLS started~n " , []),
808821 {S , E }
@@ -844,8 +857,8 @@ do_STARTTLS(Socket, Options) ->
844857 error_logger :error_msg (" SSL not started.~n " ),
845858 erlang :throw ({permanent_failure , ssl_not_started });
846859 {error , already_ssl } ->
847- { ok , Extensions } = try_EHLO ( Socket , Options ),
848- { Socket , Extensions } ;
860+ ? TRACE ( Options , " already SSL " , [] ),
861+ true ;
849862 Else ->
850863 ? TRACE (Options , " ~p~n " , [Else ]),
851864 false
@@ -889,6 +902,7 @@ connect(Host, Options) ->
889902 undefined -> 5000 ;
890903 OTimeout -> OTimeout
891904 end ,
905+ ? TRACE (Options , " connect to ~s ://~s :~p~n " , [Proto , Host , Port ]),
892906 case smtp_socket :connect (Proto , Host , Port , SockOpts , Timeout ) of
893907 {ok , Socket } ->
894908 case read_possible_multiline_reply (Socket ) of
@@ -908,6 +922,9 @@ connect(Host, Options) ->
908922% % read a multiline reply (eg. EHLO reply)
909923- spec read_possible_multiline_reply (Socket :: smtp_socket :socket ()) -> {ok , binary ()}.
910924read_possible_multiline_reply (Socket ) ->
925+ read_possible_multiline_reply (Socket , 'undefined' ).
926+
927+ read_possible_multiline_reply (Socket , Options ) ->
911928 case smtp_socket :recv (Socket , 0 , ? TIMEOUT ) of
912929 {ok , Packet } ->
913930 case binstr :substr (Packet , 4 , 1 ) of
@@ -917,12 +934,15 @@ read_possible_multiline_reply(Socket) ->
917934 <<" " >> ->
918935 {ok , Packet }
919936 end ;
937+ Error when Options =:= undefined ->
938+ throw ({network_failure , Error });
920939 Error ->
940+ ? TRACE (Options , " failed to recv packet: ~p~n " , [Error ]),
921941 throw ({network_failure , Error })
922942 end .
923943
924944- spec read_multiline_reply (Socket :: smtp_socket :socket (), Code :: binary (), Acc :: [binary ()]) ->
925- {ok , binary ()}.
945+ {ok , binary ()}.
926946read_multiline_reply (Socket , Code , Acc ) ->
927947 case smtp_socket :recv (Socket , 0 , ? TIMEOUT ) of
928948 {ok , Packet } ->
@@ -936,6 +956,7 @@ read_multiline_reply(Socket, Code, Acc) ->
936956 throw ({unexpected_response , lists :reverse ([Packet | Acc ])})
937957 end ;
938958 Error ->
959+ io :format (" ~p : network failure: ~p~n " , [? LINE , Error ]),
939960 throw ({network_failure , Error })
940961 end .
941962
0 commit comments