You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
2.2 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <?php
  2. namespace p3k\HTTP\Tests;
  3. use p3k\HTTP;
  4. use p3k\HTTP\Curl;
  5. use PHPUnit\Framework\TestCase;
  6. // Real requests through curl to PHP's built-in server on 127.0.0.1.
  7. class CurlPinningTest extends TestCase {
  8. private static $server;
  9. private static $port;
  10. public static function setUpBeforeClass(): void {
  11. self::$port = 20000 + random_int(0, 9999);
  12. self::$server = proc_open(
  13. [PHP_BINARY, '-S', '127.0.0.1:' . self::$port, '-t', __DIR__ . '/server'],
  14. [1 => ['file', '/dev/null', 'w'], 2 => ['file', '/dev/null', 'w']],
  15. $pipes
  16. );
  17. for($i = 0; $i < 50; $i++) {
  18. $socket = @fsockopen('127.0.0.1', self::$port);
  19. if($socket) { fclose($socket); return; }
  20. usleep(100000);
  21. }
  22. self::fail('The test server did not start');
  23. }
  24. public static function tearDownAfterClass(): void {
  25. proc_terminate(self::$server);
  26. }
  27. private function http() {
  28. $http = new HTTP('test');
  29. // "pinned.example" exists only in this resolver; curl can reach it only
  30. // through the pinned address.
  31. $http->set_safe_mode(true, ['127.0.0.1'], function($host) { return $host === 'pinned.example' ? ['127.0.0.1'] : []; });
  32. return $http;
  33. }
  34. public function testConnectsToThePinnedAddress() {
  35. $response = $this->http()->get('http://pinned.example:' . self::$port . '/');
  36. $this->assertSame(200, $response['code']);
  37. $this->assertSame('host=pinned.example:' . self::$port, $response['body']);
  38. }
  39. public function testRedirectsAreCheckedHopByHop() {
  40. $port = self::$port;
  41. $response = $this->http()->get("http://pinned.example:$port/?to=" . rawurlencode("http://127.0.0.1:$port/"));
  42. $this->assertSame(200, $response['code']);
  43. $this->assertSame("http://127.0.0.1:$port/", $response['url']);
  44. $response = $this->http()->get("http://pinned.example:$port/?to=" . rawurlencode("http://127.0.0.2:$port/"));
  45. $this->assertSame('blocked_url', $response['error']);
  46. }
  47. public function testPinnedCurlRefusesOtherProtocols() {
  48. $curl = new Curl();
  49. $curl->pin_addresses([]);
  50. $response = $curl->get('dict://127.0.0.1:' . self::$port . '/info');
  51. $this->assertSame(0, $response['code']);
  52. $this->assertNotSame('', $response['error_description']);
  53. }
  54. }