No longer simple IPs, better is UNL: Universal Node Locator
[core.git] / inc / classes / main / client / http / class_HttpClient.ph
1
2         /**
3          * Determines own remote IP address (e.g. can be used to probe if we are
4          * reachable from outside by determining external IP and then connect to it.
5          * This is accomblished by connecting to the IP of www.shipsimu.org which
6          * should default to 188.138.90.169 and requesting /ip.php which does only
7          * return the content of $_SERVER['REMOTE_ADDR']. Of course, this method
8          * requires a working Internet connection.
9          *
10          * This method is taken from a user comment on php.net and heavily rewritten.
11          * Compare to following link:
12          * http://de.php.net/manual/en/function.socket-create.php#49368
13          *
14          * @return      $externalAddress        The determined external IP address
15          * @todo        Make IP, host name, port and script name configurable
16          */
17         public static function determineExternalAddress () {
18                 // Get helper instance
19                 $helperInstance = new ConsoleTools();
20
21                 // First get a socket
22                 // @TODO Add some DNS caching here
23
24                 // Open connection
25                 if ($helperInstance->isProxyUsed() === TRUE) {
26                         // Resolve hostname into IP address
27                         $ip = $helperInstance->resolveIpAddress($helperInstance->getConfigInstance()->getConfigEntry('proxy_host'));
28
29                         // Connect to host through proxy connection
30                         $socketResource = fsockopen($ip, $helperInstance->getConfigInstance()->getConfigEntry('proxy_port'), $errorNo, $errorStr, 30);
31                 } else {
32                         // Connect to host directly
33                         $socketResource = fsockopen('188.138.90.169', 80, $errorNo, $errorStr, 30);
34                 }
35
36                 // Check if there was an error else
37                 if ($errorNo > 0) {
38                         // Then throw again
39                         throw new InvalidSocketException(array($helperInstance, $socketResource, $errorNo, $errorStr), BaseListener::EXCEPTION_INVALID_SOCKET);
40                 } // END - if
41
42                 // Prepare the GET request
43                 $request  = 'GET ' . ($helperInstance->isProxyUsed() === TRUE ? 'http://shipsimu.org' : '') . '/ip.php HTTP/1.0' . self::HTTP_EOL;
44                 $request .= 'Host: shipsimu.org' . self::HTTP_EOL;
45                 $request .= 'User-Agent: ' . $this->getUserAgent() . self::HTTP_EOL;
46                 $request .= 'Connection: close' . self::HTTP_EOL;
47
48                 // Do we use proxy?
49                 if ($helperInstance->isProxyUsed() === TRUE) {
50                         // CONNECT method?
51                         if ($helperInstance->getConfigInstance()->getConfigEntry('proxy_connect_method') == 'Y') {
52                                 // Setup proxy tunnel
53                                 $response = $helperInstance->setupProxyTunnel('shipsimu.org', 80, $socketResource);
54
55                                 // If the response is invalid, abort
56                                 if ((count($response) == 3) && (empty($response[0])) && (empty($response[1])) && (empty($response[2]))) {
57                                         // Invalid response!
58                                         $helperInstance->debugBackTrace('Proxy tunnel not working: response=' . print_r($response, TRUE));
59                                 } // END - if
60                         } else {
61                                 // Add header for proxy
62                                 $request .= 'Proxy-Connection: Keep-Alive' . self::HTTP_EOL;
63                         }
64                 } // END - if
65
66                 // Add last HTTP_EOL
67                 $request .= self::HTTP_EOL;
68
69                 // Send it to the socket
70                 fwrite($socketResource, $request);
71
72                 // Init IP (this will always be the last line)
73                 $externalAddress = 'invalid';
74
75                 // And read the reply
76                 while (!feof($socketResource)) {
77                         // Get line
78                         $externalAddress = trim(fgets($socketResource, 128));
79
80                         // Detect HTTP response
81                         if ((substr($externalAddress, 0, 7) == 'HTTP/1.') && (substr($externalAddress, -6, 6) != '200 OK')) {
82                                 // Stop processing
83                                 break;
84                         } // END - if
85                 } // END - while
86
87                 // Close socket
88                 fclose($socketResource);
89
90
91                 // Debug message
92                 /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONSOLE-TOOLS[' . __METHOD__ . ':' . __LINE__ . ']: Resolved external address: ' . $externalAddress);
93
94                 // Return determined external IP
95                 return $externalAddress;
96         }