File tree Expand file tree Collapse file tree 3 files changed +26
-5
lines changed Expand file tree Collapse file tree 3 files changed +26
-5
lines changed Original file line number Diff line number Diff line change @@ -295,7 +295,8 @@ $proxy = new ProxyConnector(
295295 connection attempt.
296296 If the authentication details are missing or not accepted by the remote HTTP
297297 proxy server, it is expected to reject each connection attempt with a
298- ` 407 ` (Proxy Authentication Required) response status code.
298+ ` 407 ` (Proxy Authentication Required) response status code and an exception
299+ error code of ` SOCKET_EACCES ` (13).
299300
300301#### Advanced secure proxy connections
301302
Original file line number Diff line number Diff line change @@ -151,11 +151,14 @@ public function connect($uri)
151151 return ;
152152 }
153153
154- // status must be 2xx
155- if ($ response ->getStatusCode () < 200 || $ response ->getStatusCode () >= 300 ) {
154+ if ($ response ->getStatusCode () === 407 ) {
155+ // map status code 407 (Proxy Authentication Required) to EACCES
156+ $ deferred ->reject (new RuntimeException ('Proxy denied connection due to invalid authentication ' . $ response ->getStatusCode () . ' ( ' . $ response ->getReasonPhrase () . ') (EACCES) ' , defined ('SOCKET_EACCES ' ) ? SOCKET_EACCES : 13 ));
157+ return $ stream ->close ();
158+ } elseif ($ response ->getStatusCode () < 200 || $ response ->getStatusCode () >= 300 ) {
159+ // map non-2xx status code to ECONNREFUSED
156160 $ deferred ->reject (new RuntimeException ('Proxy refused connection with HTTP error code ' . $ response ->getStatusCode () . ' ( ' . $ response ->getReasonPhrase () . ') (ECONNREFUSED) ' , defined ('SOCKET_ECONNREFUSED ' ) ? SOCKET_ECONNREFUSED : 111 ));
157- $ stream ->close ();
158- return ;
161+ return $ stream ->close ();
159162 }
160163
161164 // all okay, resolve with stream instance
Original file line number Diff line number Diff line change @@ -208,6 +208,23 @@ public function testRejectsAndClosesIfStreamWritesTooMuchData()
208208 $ promise ->then (null , $ this ->expectCallableOnceWithExceptionCode (SOCKET_EMSGSIZE ));
209209 }
210210
211+ public function testRejectsAndClosesIfStreamReturnsProyAuthenticationRequired ()
212+ {
213+ $ stream = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (array ('close ' , 'write ' ))->getMock ();
214+
215+ $ promise = \React \Promise \resolve ($ stream );
216+ $ this ->connector ->expects ($ this ->once ())->method ('connect ' )->willReturn ($ promise );
217+
218+ $ proxy = new ProxyConnector ('proxy.example.com ' , $ this ->connector );
219+
220+ $ promise = $ proxy ->connect ('google.com:80 ' );
221+
222+ $ stream ->expects ($ this ->once ())->method ('close ' );
223+ $ stream ->emit ('data ' , array ("HTTP/1.1 407 Proxy Authentication Required \r\n\r\n" ));
224+
225+ $ promise ->then (null , $ this ->expectCallableOnceWithExceptionCode (SOCKET_EACCES ));
226+ }
227+
211228 public function testRejectsAndClosesIfStreamReturnsNonSuccess ()
212229 {
213230 $ stream = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (array ('close ' , 'write ' ))->getMock ();
You can’t perform that action at this time.
0 commit comments