bd06c93f60e1593831d45c4dc59b379722420380
[core.git] / inc / main / classes / client / http / class_HttpClient.php
1 <?php
2 // Own namespace
3 namespace CoreFramework\Client\Http;
4
5 /**
6  * A HTTP client class
7  *
8  * @author              Roland Haeder <webmaster@ship-simu.org>
9  * @version             0.0.0
10  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
11  * @license             GNU GPL 3.0 or any newer version
12  * @link                http://www.ship-simu.org
13  *
14  * This program is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <http://www.gnu.org/licenses/>.
26  */
27 class HttpClient extends BaseClient implements Client {
28         // Constants
29         const HTTP_EOL = "\r\n";
30         const HTTP_USER_AGENT = 'HttpClient-Core/1.0';
31
32         /**
33          * Protected constructor
34          *
35          * @return      void
36          */
37         protected function __construct () {
38                 // Set default user agent string (to allow other classes to override this)
39                 $this->setUserAgent(self::HTTP_USER_AGENT);
40
41                 // Call parent constructor
42                 parent::__construct(__CLASS__);
43         }
44
45         /**
46          * Creates an instance of this Client class and prepares it for usage
47          *
48          * @param       $socketResource         Resource of a socket (optional)
49          * @return      $clientInstance         An instance of a Client class
50          */
51         public final static function createHttpClient ($socketResouce = FALSE) {
52                 // Get a new instance
53                 $clientInstance = new HttpClient();
54
55                 // Set socket resource
56                 $clientInstance->setSocketResource($socketResource);
57
58                 // Return the prepared instance
59                 return $clientInstance;
60         }
61
62         /**
63          * Checks wether proxy configuration is used
64          *
65          * @return      $isUsed         Wether proxy is used
66          */
67         protected function isProxyUsed () {
68                 // Do we have cache?
69                 if (!isset($GLOBALS[__METHOD__])) {
70                         // Determine it
71                         $GLOBALS[__METHOD__] = (($this->getConfigInstance()->getConfigEntry('proxy_host') != '') && ($this->getConfigInstance()->getConfigEntry('proxy_port') > 0));
72                 } // END - if
73
74                 // Return cache
75                 return $GLOBALS[__METHOD__];
76         }
77
78         /**
79          * Sets up a proxy tunnel for given hostname and through resource
80          *
81          * @param       $host           Host to connect to
82          * @param       $port           Port number to connect to
83          * @return      $response       Response array
84          */
85         protected function setupProxyTunnel ($host, $port) {
86                 // Initialize array
87                 $response = array('', '', '');
88
89                 // Do the connect
90                 $respArray = $this->doConnectRequest($host, $port);
91
92                 // Analyze first header line
93                 if (((strtolower($respArray[0]) !== 'http/1.0') && (strtolower($respArray[0]) !== 'http/1.1')) || ($respArray[1] != '200')) {
94                         // Response code is not 200
95                         return $response;
96                 } // END - if
97
98                 // All fine!
99                 return $respArray;
100         }
101
102         /**
103          * Sends a raw HTTP request out to given IP/host and port number
104          *
105          * @param       $method                 Request method (GET, POST, HEAD, CONNECT, ...)
106          * @param       $host                   Host to connect to
107          * @param       $port                   Port number to connect to
108          * @return      $responseArray  Array with raw response
109          */
110         private function sendRawHttpRequest ($method, $host, $port, array $header = array()) {
111                 // Minimum raw HTTP/1.1 request
112                 $rawRequest  = $method . ' ' . $host . ':' . $port . ' HTTP/1.1' . self::HTTP_EOL;
113                 $rawRequest .= 'Host: ' . $host . ':' . $port . self::HTTP_EOL;
114
115                 // Use login data to proxy? (username at least)
116                 if ($this->getConfigInstance()->getConfigEntry('proxy_username') != '') {
117                         // Add it as well
118                         $encodedAuth = base64_encode($this->getConfigInstance()->getConfigEntry('proxy_username') . ':' . $this->getConfigInstance()->getConfigEntry('proxy_password'));
119                         $rawRequest .= 'Proxy-Authorization: Basic ' . $encodedAuth . self::HTTP_EOL;
120                 } // END - if
121
122                 // Add last new-line
123                 $rawRequest .= self::HTTP_EOL;
124                 //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('HTTP-CLIENT[' . __METHOD__ . ':' . __LINE__ . ']: rawRequest=' . $rawRequest);
125
126                 // Write request
127                 fwrite($this->getSocketResource(), $rawRequest);
128
129                 // Got response?
130                 if (feof($this->getSocketResource())) {
131                         // No response received
132                         return $response;
133                 } // END - if
134
135                 // Read the first line
136                 $resp = trim(fgets($this->getSocketResource(), 10240));
137
138                 // "Explode" the string to an array
139                 $responseArray = explode(' ', $resp);
140
141                 // And return it
142                 return $responseArray;
143         }
144
145         /**
146          * A HTTP/1.1 CONNECT request
147          *
148          * @param       $host   Host to connect to
149          * @param       $port   Port number to connect to
150          * @return      $responseArray  An array with the read response
151          */
152         public function doConnectRequest ($host, $port) {
153                 // Prepare extra header(s)
154                 $headers = array(
155                         'Proxy-Connection' => 'Keep-Alive'
156                 );
157
158                 // Prepare raw request
159                 $responseArray = $this->sendRawHttpRequest('CONNECT', $host, $port, $headers);
160
161                 // Return response array
162                 return $responseArray;
163         }
164
165 }