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