22
33namespace Clue \React \Socks ;
44
5- use React \Promise \When ;
65use React \Promise \Deferred ;
76use React \Dns \Resolver \Factory as DnsFactory ;
87use React \Dns \Resolver \Resolver ;
@@ -133,7 +132,9 @@ public function createConnector()
133132 public function getConnection ($ host , $ port )
134133 {
135134 if (strlen ($ host ) > 255 || $ port > 65535 || $ port < 0 ) {
136- return When::reject (new InvalidArgumentException ('Invalid target specified ' ));
135+ $ deferred = new Deferred ();
136+ $ deferred ->reject (new InvalidArgumentException ('Invalid target specified ' ));
137+ return $ deferred ->promise ();
137138 }
138139 $ deferred = new Deferred ();
139140
@@ -155,40 +156,43 @@ public function getConnection($host, $port)
155156
156157 $ loop = $ this ->loop ;
157158 $ that = $ this ;
158- When::all (
159- array (
160- $ this ->connector ->create ($ this ->socksHost , $ this ->socksPort )->then (
161- null ,
162- function ($ error ) {
163- throw new Exception ('Unable to connect to socks server ' , 0 , $ error );
164- }
165- ),
166- $ this ->resolve ($ host )->then (
167- null ,
159+
160+ // simultaneously start TCP connection and DNS resolution
161+ $ connecting = $ this ->connector ->create ($ this ->socksHost , $ this ->socksPort );
162+ $ resolving = $ this ->resolve ($ host );
163+
164+ $ deferred ->resolve ($ connecting ->then (
165+ function (Stream $ stream ) use ($ that , $ resolving , $ loop , $ timerTimeout , $ protocolVersion , $ auth , $ timestampTimeout , $ port ) {
166+ // connection established, wait for DNS resolver
167+ return $ resolving ->then (
168+ function ($ host ) use ($ stream , $ port , $ timestampTimeout , $ that , $ loop , $ timerTimeout , $ protocolVersion , $ auth ) {
169+ // DNS resolver completed => cancel timeout
170+ $ loop ->cancelTimer ($ timerTimeout );
171+
172+ $ timeout = max ($ timestampTimeout - microtime (true ), 0.1 );
173+ return $ that ->handleConnectedSocks ($ stream , $ host , $ port , $ timeout , $ protocolVersion , $ auth );
174+ },
168175 function ($ error ) {
169176 throw new Exception ('Unable to resolve remote hostname ' , 0 , $ error );
170177 }
171- )
172- ),
173- function ($ fulfilled ) use ($ deferred , $ port , $ timestampTimeout , $ that , $ loop , $ timerTimeout , $ protocolVersion , $ auth ) {
174- $ loop ->cancelTimer ($ timerTimeout );
175-
176- $ timeout = max ($ timestampTimeout - microtime (true ), 0.1 );
177- $ deferred ->resolve ($ that ->handleConnectedSocks ($ fulfilled [0 ], $ fulfilled [1 ], $ port , $ timeout , $ protocolVersion , $ auth ));
178+ );
178179 },
179- function ($ error ) use ($ deferred , $ loop , $ timerTimeout ) {
180+ function ($ error ) use ($ loop , $ timerTimeout ) {
180181 $ loop ->cancelTimer ($ timerTimeout );
181- $ deferred -> reject ( new Exception ('Unable to connect to socks server ' , 0 , $ error) );
182+ throw new Exception ('Unable to connect to socks server ' , 0 , $ error );
182183 }
183- );
184+ ));
185+
184186 return $ deferred ->promise ();
185187 }
186188
187189 private function resolve ($ host )
188190 {
189191 // return if it's already an IP or we want to resolve remotely (socks 4 only supports resolving locally)
190192 if (false !== filter_var ($ host , FILTER_VALIDATE_IP ) || ($ this ->protocolVersion !== '4 ' && !$ this ->resolveLocal )) {
191- return When::resolve ($ host );
193+ $ deferred = new Deferred ();
194+ $ deferred ->resolve ($ host );
195+ return $ deferred ->promise ();
192196 }
193197
194198 return $ this ->resolver ->resolve ($ host );
@@ -197,10 +201,9 @@ private function resolve($host)
197201 public function handleConnectedSocks (Stream $ stream , $ host , $ port , $ timeout , $ protocolVersion , $ auth =null )
198202 {
199203 $ deferred = new Deferred ();
200- $ resolver = $ deferred ->resolver ();
201204
202- $ timerTimeout = $ this ->loop ->addTimer ($ timeout , function () use ($ resolver ) {
203- $ resolver ->reject (new Exception ('Timeout while establishing socks session ' ));
205+ $ timerTimeout = $ this ->loop ->addTimer ($ timeout , function () use ($ deferred ) {
206+ $ deferred ->reject (new Exception ('Timeout while establishing socks session ' ));
204207 });
205208
206209 $ reader = new StreamReader ($ stream );
@@ -211,14 +214,14 @@ public function handleConnectedSocks(Stream $stream, $host, $port, $timeout, $pr
211214 } else {
212215 $ promise = $ this ->handleSocks4 ($ stream , $ host , $ port , $ reader );
213216 }
214- $ promise ->then (function () use ($ resolver , $ stream ) {
215- $ resolver ->resolve ($ stream );
216- }, function ($ error ) use ($ resolver ) {
217- $ resolver ->reject (new Exception ('Unable to communicate... ' , 0 , $ error ));
217+ $ promise ->then (function () use ($ deferred , $ stream ) {
218+ $ deferred ->resolve ($ stream );
219+ }, function ($ error ) use ($ deferred ) {
220+ $ deferred ->reject (new Exception ('Unable to communicate... ' , 0 , $ error ));
218221 });
219222
220223 $ loop = $ this ->loop ;
221- $ deferred ->then (
224+ $ deferred ->promise ()-> then (
222225 function (Stream $ stream ) use ($ timerTimeout , $ loop , $ reader ) {
223226 $ loop ->cancelTimer ($ timerTimeout );
224227 $ stream ->removeAllListeners ('end ' );
@@ -237,8 +240,8 @@ function ($error) use ($stream, $timerTimeout, $loop, $reader) {
237240 }
238241 );
239242
240- $ stream ->on ('end ' , function (Stream $ stream ) use ($ resolver ) {
241- $ resolver ->reject (new Exception ('Premature end while establishing socks session ' ));
243+ $ stream ->on ('end ' , function (Stream $ stream ) use ($ deferred ) {
244+ $ deferred ->reject (new Exception ('Premature end while establishing socks session ' ));
242245 });
243246
244247 return $ deferred ->promise ();
0 commit comments