Просмотр исходного кода

use timeout, authenticate in init/1

Anton Lebedevich 13 лет назад
Родитель
Сommit
65002570d5
1 измененных файлов с 19 добавлено и 17 удалено
  1. 19 17
      src/pgsql_sock.erl

+ 19 - 17
src/pgsql_sock.erl

@@ -17,43 +17,45 @@
 
 %% -- client interface --
 
-start_link(Host, Username, Opts) ->
-    gen_server:start_link(?MODULE, [Host, Username, Opts], []).
+start_link(Host, Username, Password, Opts) ->
+    gen_server:start_link(?MODULE, [Host, Username, Password, Opts], []).
 
 cancel(S) ->
     gen_server:cast(S, cancel}).
 
 %% -- gen_server implementation --
 
-init([C, Host, Username, Opts]) ->
-    Opts2 = ["user", 0, Username, 0],
-    case proplists:get_value(database, Opts, undefined) of
-        undefined -> Opts3 = Opts2;
-        Database  -> Opts3 = [Opts2 | ["database", 0, Database, 0]]
-    end,
-
+init([Host, Username, Password, Opts]) ->
+    %% TODO split connect/query timeout?
+    Timeout = proplists:get_value(timeout, Opts, 5000),
     Port = proplists:get_value(port, Opts, 5432),
     SockOpts = [{active, false}, {packet, raw}, binary, {nodelay, true}],
-    %% TODO connect timeout
-    {ok, S} = gen_tcp:connect(Host, Port, SockOpts),
+    {ok, S} = gen_tcp:connect(Host, Port, SockOpts, Timeout),
 
     State = #state{
       mod  = gen_tcp,
       sock = S,
-      decoder = pgsql_wire:init([])},
+      decoder = pgsql_wire:init([]),
+      timeout = Timeout},
 
     case proplists:get_value(ssl, Opts) of
         T when T == true; T == required ->
             ok = gen_tcp:send(S, <<8:?int32, 80877103:?int32>>),
-            {ok, <<Code>>} = gen_tcp:recv(S, 1),
+            {ok, <<Code>>} = gen_tcp:recv(S, 1, Timeout),
             State2 = start_ssl(Code, T, Opts, State);
         _ ->
             State2 = State
     end,
 
-    setopts(State2, [{active, true}]),
+    Opts2 = ["user", 0, Username, 0],
+    case proplists:get_value(database, Opts, undefined) of
+        undefined -> Opts3 = Opts2;
+        Database  -> Opts3 = [Opts2 | ["database", 0, Database, 0]]
+    end,
     send([<<196608:?int32>>, Opts3, 0], State2),
-    {ok, State2}.
+%% TODO    Async   = proplists:get_value(async, Opts, undefined),
+%% TODO    setopts(State2, [{active, true}]),
+    {ok, initialize(auth(User, Password, State2))}.
 
 handle_call(Call, _From, State) ->
     {stop, {unsupported_call, Call}, State}.
@@ -89,8 +91,8 @@ code_change(_OldVsn, State, _Extra) ->
 %% -- internal functions --
 
 start_ssl($S, _Flag, Opts, State) ->
-    #state{sock = S1} = State,
-    case ssl:connect(S1, Opts) of
+    #state{sock = S1, timeout = Timeout} = State,
+    case ssl:connect(S1, Opts, Timeout) of
         {ok, S2}        -> State#state{mod = ssl, sock = S2};
         {error, Reason} -> exit({ssl_negotiation_failed, Reason})
     end;