File tree 3 files changed +26
-5
lines changed
3 files changed +26
-5
lines changed Original file line number Diff line number Diff line change @@ -295,7 +295,8 @@ $proxy = new ProxyConnector(
295
295
connection attempt.
296
296
If the authentication details are missing or not accepted by the remote HTTP
297
297
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).
299
300
300
301
#### Advanced secure proxy connections
301
302
Original file line number Diff line number Diff line change @@ -151,11 +151,14 @@ public function connect($uri)
151
151
return ;
152
152
}
153
153
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
156
160
$ 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 ();
159
162
}
160
163
161
164
// all okay, resolve with stream instance
Original file line number Diff line number Diff line change @@ -208,6 +208,23 @@ public function testRejectsAndClosesIfStreamWritesTooMuchData()
208
208
$ promise ->then (null , $ this ->expectCallableOnceWithExceptionCode (SOCKET_EMSGSIZE ));
209
209
}
210
210
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
+
211
228
public function testRejectsAndClosesIfStreamReturnsNonSuccess ()
212
229
{
213
230
$ stream = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (array ('close ' , 'write ' ))->getMock ();
You can’t perform that action at this time.
0 commit comments