Skip to content

Commit 5db04ad

Browse files
committed
Use socket error codes for connection rejections
1 parent c5b0495 commit 5db04ad

File tree

4 files changed

+27
-13
lines changed

4 files changed

+27
-13
lines changed

src/ProxyConnector.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public function connect($uri)
128128

129129
return $this->connector->connect($proxyUri)->then(function (ConnectionInterface $stream) use ($host, $port, $auth) {
130130
$deferred = new Deferred(function ($_, $reject) use ($stream) {
131-
$reject(new RuntimeException('Operation canceled while waiting for response from proxy'));
131+
$reject(new RuntimeException('Connection canceled while waiting for response from proxy (ECONNABORTED)', defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103));
132132
$stream->close();
133133
});
134134

@@ -146,14 +146,14 @@ public function connect($uri)
146146
try {
147147
$response = Psr7\parse_response(substr($buffer, 0, $pos));
148148
} catch (Exception $e) {
149-
$deferred->reject(new RuntimeException('Invalid response received from proxy: ' . $e->getMessage(), 0, $e));
149+
$deferred->reject(new RuntimeException('Invalid response received from proxy (EBADMSG)', defined('SOCKET_EBADMSG') ? SOCKET_EBADMSG: 71, $e));
150150
$stream->close();
151151
return;
152152
}
153153

154154
// status must be 2xx
155155
if ($response->getStatusCode() < 200 || $response->getStatusCode() >= 300) {
156-
$deferred->reject(new RuntimeException('Proxy rejected with HTTP error code: ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase(), $response->getStatusCode()));
156+
$deferred->reject(new RuntimeException('Proxy refused connection with HTTP error code ' . $response->getStatusCode() . ' (' . $response->getReasonPhrase() . ') (ECONNREFUSED)', defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111));
157157
$stream->close();
158158
return;
159159
}
@@ -172,18 +172,18 @@ public function connect($uri)
172172

173173
// stop buffering when 8 KiB have been read
174174
if (isset($buffer[8192])) {
175-
$deferred->reject(new RuntimeException('Proxy must not send more than 8 KiB of headers'));
175+
$deferred->reject(new RuntimeException('Proxy must not send more than 8 KiB of headers (EMSGSIZE)', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 90));
176176
$stream->close();
177177
}
178178
};
179179
$stream->on('data', $fn);
180180

181181
$stream->on('error', function (Exception $e) use ($deferred) {
182-
$deferred->reject(new RuntimeException('Stream error while waiting for response from proxy', 0, $e));
182+
$deferred->reject(new RuntimeException('Stream error while waiting for response from proxy (EIO)', defined('SOCKET_EIO') ? SOCKET_EIO : 5, $e));
183183
});
184184

185185
$stream->on('close', function () use ($deferred) {
186-
$deferred->reject(new RuntimeException('Connection to proxy lost while waiting for response'));
186+
$deferred->reject(new RuntimeException('Connection to proxy lost while waiting for response (ECONNRESET)', defined('SOCKET_ECONNRESET') ? SOCKET_ECONNRESET : 104));
187187
});
188188

189189
$stream->write("CONNECT " . $host . ":" . $port . " HTTP/1.1\r\nHost: " . $host . ":" . $port . "\r\n" . $auth . "\r\n");

tests/AbstractTestCase.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,20 @@ protected function expectCallableOnceWith($value)
3737
return $mock;
3838
}
3939

40+
protected function expectCallableOnceWithExceptionCode($code)
41+
{
42+
$mock = $this->createCallableMock();
43+
$mock
44+
->expects($this->once())
45+
->method('__invoke')
46+
->with($this->callback(function ($e) use ($code) {
47+
return $e->getCode() === $code;
48+
}));
49+
50+
return $mock;
51+
}
52+
53+
4054
protected function expectCallableOnceParameter($type)
4155
{
4256
$mock = $this->createCallableMock();

tests/FunctionalTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function testPlainGoogleDoesNotAcceptConnectMethod()
4444

4545
$promise = $proxy->connect('google.com:80');
4646

47-
$this->setExpectedException('RuntimeException', 'Method Not Allowed', 405);
47+
$this->setExpectedException('RuntimeException', '405 (Method Not Allowed)', SOCKET_ECONNREFUSED);
4848
Block\await($promise, $this->loop, 3.0);
4949
}
5050

@@ -59,7 +59,7 @@ public function testSecureGoogleDoesNotAcceptConnectMethod()
5959

6060
$promise = $proxy->connect('google.com:80');
6161

62-
$this->setExpectedException('RuntimeException', 'Method Not Allowed', 405);
62+
$this->setExpectedException('RuntimeException', '405 (Method Not Allowed)', SOCKET_ECONNREFUSED);
6363
Block\await($promise, $this->loop, 3.0);
6464
}
6565

@@ -69,7 +69,7 @@ public function testSecureGoogleDoesNotAcceptPlainStream()
6969

7070
$promise = $proxy->connect('google.com:80');
7171

72-
$this->setExpectedException('RuntimeException', 'Connection to proxy lost');
72+
$this->setExpectedException('RuntimeException', 'Connection to proxy lost', SOCKET_ECONNRESET);
7373
Block\await($promise, $this->loop, 3.0);
7474
}
7575
}

tests/ProxyConnectorTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public function testRejectsAndClosesIfStreamWritesNonHttp()
188188
$stream->expects($this->once())->method('close');
189189
$stream->emit('data', array("invalid\r\n\r\n"));
190190

191-
$promise->then(null, $this->expectCallableOnce());
191+
$promise->then(null, $this->expectCallableOnceWithExceptionCode(SOCKET_EBADMSG));
192192
}
193193

194194
public function testRejectsAndClosesIfStreamWritesTooMuchData()
@@ -205,7 +205,7 @@ public function testRejectsAndClosesIfStreamWritesTooMuchData()
205205
$stream->expects($this->once())->method('close');
206206
$stream->emit('data', array(str_repeat('*', 100000)));
207207

208-
$promise->then(null, $this->expectCallableOnce());
208+
$promise->then(null, $this->expectCallableOnceWithExceptionCode(SOCKET_EMSGSIZE));
209209
}
210210

211211
public function testRejectsAndClosesIfStreamReturnsNonSuccess()
@@ -222,7 +222,7 @@ public function testRejectsAndClosesIfStreamReturnsNonSuccess()
222222
$stream->expects($this->once())->method('close');
223223
$stream->emit('data', array("HTTP/1.1 403 Not allowed\r\n\r\n"));
224224

225-
$promise->then(null, $this->expectCallableOnce());
225+
$promise->then(null, $this->expectCallableOnceWithExceptionCode(SOCKET_ECONNREFUSED));
226226
}
227227

228228
public function testResolvesIfStreamReturnsSuccess()
@@ -280,6 +280,6 @@ public function testCancelPromiseWillCloseOpenConnectionAndReject()
280280

281281
$promise->cancel();
282282

283-
$promise->then(null, $this->expectCallableOnce());
283+
$promise->then(null, $this->expectCallableOnceWithExceptionCode(SOCKET_ECONNABORTED));
284284
}
285285
}

0 commit comments

Comments
 (0)