Overview

Namespaces

  • Evenement
  • None
  • PHP
  • Psr
    • Http
      • Message
  • Ratchet
    • Http
    • RFC6455
      • Handshake
      • Messaging
    • Server
    • Session
      • Serialize
      • Storage
        • Proxy
    • Wamp
    • WebSocket
  • React
    • EventLoop
      • Tick
      • Timer
    • Socket
    • Stream
  • Symfony
    • Component
      • HttpFoundation
        • Session
          • Attribute
          • Flash
          • Storage
            • Handler
            • Proxy
      • Routing
        • Annotation
        • Exception
        • Generator
          • Dumper
        • Loader
          • DependencyInjection
        • Matcher
          • Dumper
        • Tests
          • Annotation
          • Fixtures
            • AnnotatedClasses
            • OtherAnnotatedClasses
          • Generator
            • Dumper
          • Loader
          • Matcher
            • Dumper

Classes

  • Connector
  • DnsConnector
  • LimitingServer
  • SecureConnector
  • SecureServer
  • Server
  • TcpConnector
  • TimeoutConnector
  • UnixConnector

Interfaces

  • ConnectionInterface
  • ConnectorInterface
  • ServerInterface
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: namespace React\Socket;
  4: 
  5: use React\Dns\Resolver\Resolver;
  6: use React\Promise;
  7: use React\Promise\CancellablePromiseInterface;
  8: 
  9: final class DnsConnector implements ConnectorInterface
 10: {
 11:     private $connector;
 12:     private $resolver;
 13: 
 14:     public function __construct(ConnectorInterface $connector, Resolver $resolver)
 15:     {
 16:         $this->connector = $connector;
 17:         $this->resolver = $resolver;
 18:     }
 19: 
 20:     public function connect($uri)
 21:     {
 22:         if (strpos($uri, '://') === false) {
 23:             $parts = parse_url('tcp://' . $uri);
 24:             unset($parts['scheme']);
 25:         } else {
 26:             $parts = parse_url($uri);
 27:         }
 28: 
 29:         if (!$parts || !isset($parts['host'])) {
 30:             return Promise\reject(new \InvalidArgumentException('Given URI "' . $uri . '" is invalid'));
 31:         }
 32: 
 33:         $host = trim($parts['host'], '[]');
 34:         $connector = $this->connector;
 35: 
 36:         return $this
 37:             ->resolveHostname($host)
 38:             ->then(function ($ip) use ($connector, $host, $parts) {
 39:                 $uri = '';
 40: 
 41:                 // prepend original scheme if known
 42:                 if (isset($parts['scheme'])) {
 43:                     $uri .= $parts['scheme'] . '://';
 44:                 }
 45: 
 46:                 if (strpos($ip, ':') !== false) {
 47:                     // enclose IPv6 addresses in square brackets before appending port
 48:                     $uri .= '[' . $ip . ']';
 49:                 } else {
 50:                     $uri .= $ip;
 51:                 }
 52: 
 53:                 // append original port if known
 54:                 if (isset($parts['port'])) {
 55:                     $uri .= ':' . $parts['port'];
 56:                 }
 57: 
 58:                 // append orignal path if known
 59:                 if (isset($parts['path'])) {
 60:                     $uri .= $parts['path'];
 61:                 }
 62: 
 63:                 // append original query if known
 64:                 if (isset($parts['query'])) {
 65:                     $uri .= '?' . $parts['query'];
 66:                 }
 67: 
 68:                 // append original hostname as query if resolved via DNS and if
 69:                 // destination URI does not contain "hostname" query param already
 70:                 $args = array();
 71:                 parse_str(isset($parts['query']) ? $parts['query'] : '', $args);
 72:                 if ($host !== $ip && !isset($args['hostname'])) {
 73:                     $uri .= (isset($parts['query']) ? '&' : '?') . 'hostname=' . rawurlencode($host);
 74:                 }
 75: 
 76:                 // append original fragment if known
 77:                 if (isset($parts['fragment'])) {
 78:                     $uri .= '#' . $parts['fragment'];
 79:                 }
 80: 
 81:                 return $connector->connect($uri);
 82:             });
 83:     }
 84: 
 85:     private function resolveHostname($host)
 86:     {
 87:         if (false !== filter_var($host, FILTER_VALIDATE_IP)) {
 88:             return Promise\resolve($host);
 89:         }
 90: 
 91:         $promise = $this->resolver->resolve($host);
 92: 
 93:         return new Promise\Promise(
 94:             function ($resolve, $reject) use ($promise) {
 95:                 // resolve/reject with result of DNS lookup
 96:                 $promise->then($resolve, $reject);
 97:             },
 98:             function ($_, $reject) use ($promise) {
 99:                 // cancellation should reject connection attempt
100:                 $reject(new \RuntimeException('Connection attempt cancelled during DNS lookup'));
101: 
102:                 // (try to) cancel pending DNS lookup
103:                 if ($promise instanceof CancellablePromiseInterface) {
104:                     $promise->cancel();
105:                 }
106:             }
107:         );
108:     }
109: }
110: 
Ratchet API documentation generated by ApiGen 2.8.0