123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <?php
- use LeProxy\LeProxy\ConnectorFactory;
- use LeProxy\LeProxy\HttpProxyServer;
- use React\Http\Io\HttpBodyStream;
- use React\Http\Io\ServerRequest;
- use React\Promise\Promise;
- use React\Stream\ThroughStream;
- class HttpProxyServerTest extends PHPUnit_Framework_TestCase
- {
- public function testCtor()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $server = new HttpProxyServer($loop, $socket, $connector);
- }
- public function testRequestWithoutAuthenticationReturnsAuthenticationRequired()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $server = new HttpProxyServer($loop, $socket, $connector);
- $server->setAuthArray(array('user' => 'pass'));
- $request = new ServerRequest('GET', '/');
- $response = $server->handleRequest($request);
- $this->assertEquals(407, $response->getStatusCode());
- }
- public function testRequestWithInvalidAuthenticationReturnsAuthenticationRequired()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $server = new HttpProxyServer($loop, $socket, $connector);
- $server->setAuthArray(array('user' => 'pass'));
- $request = new ServerRequest('GET', '/', array('Proxy-Authorization' => 'Basic dXNlcg=='));
- $response = $server->handleRequest($request);
- $this->assertEquals(407, $response->getStatusCode());
- }
- public function testRequestWithValidAuthenticationReturnsSuccess()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $server = new HttpProxyServer($loop, $socket, $connector);
- $server->setAuthArray(array('user' => 'pass'));
- $request = new ServerRequest('GET', '/', array('Proxy-Authorization' => 'Basic dXNlcjpwYXNz'));
- $response = $server->handleRequest($request);
- $this->assertEquals(405, $response->getStatusCode());
- }
- public function testRequestProtectedLocalhostReturnsSuccess()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $server = new HttpProxyServer($loop, $socket, $connector);
- $server->allowUnprotected = false;
- $request = new ServerRequest('GET', '/', array(), null, '1.1', array('REMOTE_ADDR' => '127.0.0.1'));
- $response = $server->handleRequest($request);
- $this->assertEquals(405, $response->getStatusCode());
- }
- public function testRequestProtectedRemoteReturnsForbidden()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $server = new HttpProxyServer($loop, $socket, $connector);
- $server->allowUnprotected = false;
- $request = new ServerRequest('GET', '/', array(), null, '1.1', array('REMOTE_ADDR' => '192.168.1.1'));
- $response = $server->handleRequest($request);
- $this->assertEquals(403, $response->getStatusCode());
- }
- public function testRequestUnprotectedRemoteReturnsSuccess()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $server = new HttpProxyServer($loop, $socket, $connector);
- $server->allowUnprotected = true;
- $request = new ServerRequest('GET', '/', array(), null, '1.1', array('REMOTE_ADDR' => '192.168.1.1'));
- $response = $server->handleRequest($request);
- $this->assertEquals(405, $response->getStatusCode());
- }
- public function testRequestConnectCallsConnector()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $promise = new Promise(function () { });
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $connector->expects($this->once())->method('connect')->with('example.com:80?source=http%3A%2F%2F192.168.1.1%3A5060')->willReturn($promise);
- $server = new HttpProxyServer($loop, $socket, $connector);
- $request = new ServerRequest('CONNECT', 'http://example.com', array(), null, '1.1', array('REMOTE_ADDR' => '192.168.1.1', 'REMOTE_PORT' => 5060));
- $request = $request->withRequestTarget('example.com:80');
- $response = $server->handleRequest($request);
- $this->assertInstanceOf('React\Promise\PromiseInterface', $response);
- }
- public function testRequestConnectCallsConnectorBlockedReturnsForbidden()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $promise = \React\Promise\reject(new RuntimeException('', ConnectorFactory::CODE_BLOCKED));
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $connector->expects($this->once())->method('connect')->willReturn($promise);
- $server = new HttpProxyServer($loop, $socket, $connector);
- $request = new ServerRequest('CONNECT', 'http://example.com', array(), null, '1.1', array('REMOTE_ADDR' => '192.168.1.1', 'REMOTE_PORT' => 5060));
- $request = $request->withRequestTarget('example.com:80');
- $promise = $server->handleRequest($request);
- $response = null;
- $promise->then(function ($ret) use (&$response) {
- $response = $ret;
- });
- $this->assertNotNull($response);
- $this->assertEquals(403, $response->getStatusCode());
- }
- public function testRequestConnectCallsConnectorTimeoutReturnsGatewayTimeout()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $promise = \React\Promise\reject(new RuntimeException('', SOCKET_ETIMEDOUT));
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $connector->expects($this->once())->method('connect')->willReturn($promise);
- $server = new HttpProxyServer($loop, $socket, $connector);
- $request = new ServerRequest('CONNECT', 'http://example.com', array(), null, '1.1', array('REMOTE_ADDR' => '192.168.1.1', 'REMOTE_PORT' => 5060));
- $request = $request->withRequestTarget('example.com:80');
- $promise = $server->handleRequest($request);
- $response = null;
- $promise->then(function ($ret) use (&$response) {
- $response = $ret;
- });
- $this->assertNotNull($response);
- $this->assertEquals(504, $response->getStatusCode());
- }
- public function testRequestAbsoluteCallsConnector()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $promise = new Promise(function () { });
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $connector->expects($this->once())->method('connect')->with('example.com:80?source=http%3A%2F%2F192.168.1.1%3A5060')->willReturn($promise);
- $server = new HttpProxyServer($loop, $socket, $connector);
- $request = new ServerRequest('GET', 'http://example.com/path', array(), null, '1.1', array('REMOTE_ADDR' => '192.168.1.1', 'REMOTE_PORT' => 5060));
- $request = $request->withRequestTarget('http://example.com/path');
- $response = $server->handleRequest($request);
- $this->assertInstanceOf('React\Promise\PromiseInterface', $response);
- }
- public function testPlainRequestForwardsWithExplicitHeadersAsGiven()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $outgoing = $this->getMockBuilder('React\HttpClient\Request')->disableOriginalConstructor()->getMock();
- $client = $this->getMockBuilder('React\HttpClient\Client')->disableOriginalConstructor()->getMock();
- $client->expects($this->once())
- ->method('request')
- ->with('GET', 'http://example.com/', array('Cookie' => array('name=value'), 'USER-AGENT' => array('TEST')))
- ->willReturn($outgoing);
- $server = new HttpProxyServer($loop, $socket, $connector);
- $ref = new ReflectionProperty($server, 'client');
- $ref->setAccessible(true);
- $ref->setValue($server, $client);
- $request = new ServerRequest('GET', 'http://example.com/', array('Cookie' => 'name=value', 'USER-AGENT' => 'TEST'));
- $request = $request->withRequestTarget((string)$request->getUri());
- $request = $request->withBody(new HttpBodyStream(new ThroughStream(), null));
- $promise = $server->handleRequest($request);
- $this->assertInstanceOf('React\Promise\PromiseInterface', $promise);
- }
- public function testPlainRequestWithValidAuthenticationForwardsViaHttpClientWithoutAuthorizationHeader()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $socket = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
- $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $outgoing = $this->getMockBuilder('React\HttpClient\Request')->disableOriginalConstructor()->getMock();
- $client = $this->getMockBuilder('React\HttpClient\Client')->disableOriginalConstructor()->getMock();
- $client->expects($this->once())
- ->method('request')
- ->with('GET', 'http://example.com/', array('Cookie' => array('name=value'), 'User-Agent' => array()))
- ->willReturn($outgoing);
- $server = new HttpProxyServer($loop, $socket, $connector);
- $server->setAuthArray(array('user' => 'pass'));
- $ref = new ReflectionProperty($server, 'client');
- $ref->setAccessible(true);
- $ref->setValue($server, $client);
- $request = new ServerRequest('GET', 'http://example.com/', array('Proxy-Authorization' => 'Basic dXNlcjpwYXNz', 'Cookie' => 'name=value'));
- $request = $request->withRequestTarget((string)$request->getUri());
- $request = $request->withBody(new HttpBodyStream(new ThroughStream(), null));
- $promise = $server->handleRequest($request);
- $this->assertInstanceOf('React\Promise\PromiseInterface', $promise);
- }
- }
|