10 defined(
'JPATH_PLATFORM') or die;
43 if (!self::isSupported())
45 throw new RuntimeException(
'Cannot use a socket transport when fsockopen() is not available.');
48 $this->options = $options;
66 public function request($method,
JUri $uri, $data = null, array $headers = null, $timeout = null, $userAgent = null)
68 $connection = $this->connect($uri, $timeout);
71 if (is_resource($connection))
74 $meta = stream_get_meta_data($connection);
76 if ($meta[
'timed_out'])
78 throw new RuntimeException(
'Server connection timed out.');
83 throw new RuntimeException(
'Not connected to server.');
87 $path = $uri->
toString(array(
'path',
'query'));
93 if (!is_scalar($data))
95 $data = http_build_query($data);
98 if (!isset($headers[
'Content-Type']))
100 $headers[
'Content-Type'] =
'application/x-www-form-urlencoded; charset=utf-8';
104 $headers[
'Content-Length'] = strlen($data);
109 $request[] = strtoupper($method) .
' ' . ((empty($path)) ?
'/' : $path) .
' HTTP/1.0';
110 $request[] =
'Host: ' . $uri->
getHost();
113 if (isset($userAgent))
115 $headers[
'User-Agent'] = $userAgent;
119 if (is_array($headers))
121 foreach ($headers as $k => $v)
123 $request[] = $k .
': ' . $v;
135 fwrite($connection, implode(
"\r\n", $request) .
"\r\n\r\n");
140 while (!feof($connection))
142 $content .= fgets($connection, 4096);
145 return $this->getResponse($content);
158 protected function getResponse($content)
165 throw new UnexpectedValueException(
'No content in response.');
169 $response = explode(
"\r\n\r\n", $content, 2);
172 $headers = explode(
"\r\n", $response[0]);
175 $return->body = empty($response[1]) ?
'' : $response[1];
178 preg_match(
'/[0-9]{3}/', array_shift($headers), $matches);
181 if (is_numeric($code))
183 $return->code = (int) $code;
189 throw new UnexpectedValueException(
'No HTTP response code found.');
193 foreach ($headers as $header)
195 $pos = strpos($header,
':');
196 $return->headers[trim(substr($header, 0, $pos))] = trim(substr($header, ($pos + 1)));
213 protected function connect(
JUri $uri, $timeout = null)
224 $port = ($uri->
getScheme() ==
'https') ? 443 : 80;
234 $key = md5($host . $port);
237 if (!empty($this->connections[$key]) && is_resource($this->connections[$key]))
240 $meta = stream_get_meta_data($this->connections[$key]);
244 if (!fclose($this->connections[$key]))
246 throw new RuntimeException(
'Cannot close connection');
251 elseif (!$meta[
'timed_out'])
253 return $this->connections[$key];
257 if (!is_numeric($timeout))
259 $timeout = ini_get(
'default_socket_timeout');
264 $track_errors = ini_get(
'track_errors');
265 ini_set(
'track_errors',
true);
269 $connection = @fsockopen($host, $port, $errno, $err, $timeout);
276 $php_errormsg = sprintf(
'Could not connect to resource: %s', $uri, $err, $errno);
280 ini_set(
'track_errors', $track_errors);
282 throw new RuntimeException($php_errormsg);
286 ini_set(
'track_errors', $track_errors);
289 $this->connections[$key] = $connection;
294 stream_set_timeout($this->connections[$key], (
int) $timeout);
297 return $this->connections[$key];
307 public static function isSupported()
309 return function_exists(
'fsockopen') && is_callable(
'fsockopen');