class EasyRdf_Http_Client in Zircon Profile 8
Same name and namespace in other branches
- 8.0 vendor/easyrdf/easyrdf/lib/EasyRdf/Http/Client.php \EasyRdf_Http_Client
This class is an implemetation of an HTTP client in PHP. It supports basic HTTP 1.0 and 1.1 requests. For a more complete implementation try Zend_Http_Client.
@package EasyRdf @copyright Copyright (c) 2009-2013 Nicholas J Humfrey @license http://www.opensource.org/licenses/bsd-license.php
Hierarchy
- class \EasyRdf_Http_Client
Expanded class hierarchy of EasyRdf_Http_Client
File
- vendor/
easyrdf/ easyrdf/ lib/ EasyRdf/ Http/ Client.php, line 49
View source
class EasyRdf_Http_Client {
/**
* Configuration array, set using the constructor or using ::setConfig()
*
* @var array
*/
private $config = array(
'maxredirects' => 5,
'useragent' => 'EasyRdf_Http_Client',
'timeout' => 10,
);
/**
* Request URI
*
* @var string
*/
private $uri = null;
/**
* Associative array of request headers
*
* @var array
*/
private $headers = array();
/**
* HTTP request method
*
* @var string
*/
private $method = 'GET';
/**
* Associative array of GET parameters
*
* @var array
*/
private $paramsGet = array();
/**
* The raw post data to send. Could be set by setRawData($data).
*
* @var string
*/
private $rawPostData = null;
/**
* Redirection counter
*
* @var int
*/
private $redirectCounter = 0;
/**
* Constructor method. Will create a new HTTP client. Accepts the target
* URL and optionally configuration array.
*
* @param string $uri
* @param array $config Configuration key-value pairs.
*/
public function __construct($uri = null, $config = null) {
if ($uri !== null) {
$this
->setUri($uri);
}
if ($config !== null) {
$this
->setConfig($config);
}
}
/**
* Set the URI for the next request
*
* @param string $uri
* @return EasyRdf_Http_Client
*/
public function setUri($uri) {
if (!is_string($uri)) {
$uri = strval($uri);
}
if (!preg_match('/^http(s?):/', $uri)) {
throw new InvalidArgumentException("EasyRdf_Http_Client only supports the 'http' and 'https' schemes.");
}
$this->uri = $uri;
return $this;
}
/**
* Get the URI for the next request
*
* @return string
*/
public function getUri($asString = true) {
return $this->uri;
}
/**
* Set configuration parameters for this HTTP client
*
* @param array $config
* @return EasyRdf_Http_Client
* @throws InvalidArgumentException
*/
public function setConfig($config = array()) {
if ($config == null or !is_array($config)) {
throw new InvalidArgumentException("\$config should be an array and cannot be null");
}
foreach ($config as $k => $v) {
$this->config[strtolower($k)] = $v;
}
return $this;
}
/**
* Set a request header
*
* @param string $name Header name (e.g. 'Accept')
* @param string $value Header value or null
* @return EasyRdf_Http_Client
*/
public function setHeaders($name, $value = null) {
$normalizedName = strtolower($name);
// If $value is null or false, unset the header
if ($value === null || $value === false) {
unset($this->headers[$normalizedName]);
}
else {
// Else, set the header
$this->headers[$normalizedName] = array(
$name,
$value,
);
}
return $this;
}
/**
* Set the next request's method
*
* Validated the passed method and sets it.
*
* @param string $method
* @return EasyRdf_Http_Client
* @throws InvalidArgumentException
*/
public function setMethod($method) {
if (!is_string($method) or !preg_match('/^[A-Z]+$/', $method)) {
throw new InvalidArgumentException("Invalid HTTP request method.");
}
$this->method = $method;
return $this;
}
/**
* Get the method for the next request
*
* @return string
*/
public function getMethod() {
return $this->method;
}
/**
* Get the value of a specific header
*
* Note that if the header has more than one value, an array
* will be returned.
*
* @param string $key
* @return string|array|null The header value or null if it is not set
*/
public function getHeader($key) {
$key = strtolower($key);
if (isset($this->headers[$key])) {
return $this->headers[$key][1];
}
else {
return null;
}
}
/**
* Set a GET parameter for the request.
*
* @param string $name
* @param string $value
* @return EasyRdf_Http_Client
*/
public function setParameterGet($name, $value = null) {
if ($value === null) {
if (isset($this->paramsGet[$name])) {
unset($this->paramsGet[$name]);
}
}
else {
$this->paramsGet[$name] = $value;
}
return $this;
}
/**
* Get a GET parameter for the request.
*
* @param string $name
* @return string value
*/
public function getParameterGet($name) {
if (isset($this->paramsGet[$name])) {
return $this->paramsGet[$name];
}
else {
return null;
}
}
/**
* Get all the GET parameters
*
* @return array
*/
public function getParametersGet() {
return $this->paramsGet;
}
/**
* Get the number of redirections done on the last request
*
* @return int
*/
public function getRedirectionsCount() {
return $this->redirectCounter;
}
/**
* Set the raw (already encoded) POST data.
*
* This function is here for two reasons:
* 1. For advanced user who would like to set their own data, already encoded
* 2. For backwards compatibilty: If someone uses the old post($data) method.
* this method will be used to set the encoded data.
*
* $data can also be stream (such as file) from which the data will be read.
*
* @param string|resource $data
* @return Zend_Http_Client
*/
public function setRawData($data) {
$this->rawPostData = $data;
return $this;
}
/**
* Get the raw (already encoded) POST data.
*
* @return string
*/
public function getRawData() {
return $this->rawPostData;
}
/**
* Clear all GET and POST parameters
*
* Should be used to reset the request parameters if the client is
* used for several concurrent requests.
*
* clearAll parameter controls if we clean just parameters or also
* headers
*
* @param bool $clearAll Should all data be cleared?
* @return EasyRdf_Http_Client
*/
public function resetParameters($clearAll = false) {
// Reset parameter data
$this->paramsGet = array();
$this->rawPostData = null;
$this->method = 'GET';
if ($clearAll) {
$this->headers = array();
}
else {
// Clear outdated headers
if (isset($this->headers['content-type'])) {
unset($this->headers['content-type']);
}
if (isset($this->headers['content-length'])) {
unset($this->headers['content-length']);
}
}
return $this;
}
/**
* Send the HTTP request and return an HTTP response object
*
* @return EasyRdf_Http_Response
* @throws EasyRdf_Exception
*/
public function request($method = null) {
if (!$this->uri) {
throw new EasyRdf_Exception("Set URI before calling EasyRdf_Http_Client->request()");
}
if ($method) {
$this
->setMethod($method);
}
$this->redirectCounter = 0;
$response = null;
// Send the first request. If redirected, continue.
do {
// Clone the URI and add the additional GET parameters to it
$uri = parse_url($this->uri);
if ($uri['scheme'] === 'http') {
$host = $uri['host'];
}
elseif ($uri['scheme'] === 'https') {
$host = 'ssl://' . $uri['host'];
}
else {
throw new EasyRdf_Exception("Unsupported URI scheme: " . $uri['scheme']);
}
if (isset($uri['port'])) {
$port = $uri['port'];
}
else {
if ($uri['scheme'] === 'https') {
$port = 443;
}
else {
$port = 80;
}
}
if (!empty($this->paramsGet)) {
if (!empty($uri['query'])) {
$uri['query'] .= '&';
}
else {
$uri['query'] = '';
}
$uri['query'] .= http_build_query($this->paramsGet, null, '&');
}
$headers = $this
->prepareHeaders($uri['host'], $port);
// Open socket to remote server
$socket = @fsockopen($host, $port, $errno, $errstr, $this->config['timeout']);
if (!$socket) {
throw new EasyRdf_Exception("Unable to connect to {$host}:{$port} ({$errstr})");
}
stream_set_timeout($socket, $this->config['timeout']);
$info = stream_get_meta_data($socket);
// Write the request
$path = $uri['path'];
if (empty($path)) {
$path = '/';
}
if (isset($uri['query'])) {
$path .= '?' . $uri['query'];
}
fwrite($socket, "{$this->method} {$path} HTTP/1.1\r\n");
foreach ($headers as $k => $v) {
if (is_string($k)) {
$v = ucfirst($k) . ": {$v}";
}
fwrite($socket, "{$v}\r\n");
}
fwrite($socket, "\r\n");
// Send the request body, if there is one set
if (isset($this->rawPostData)) {
fwrite($socket, $this->rawPostData);
}
// Read in the response
$content = '';
while (!feof($socket) && !$info['timed_out']) {
$content .= fgets($socket);
$info = stream_get_meta_data($socket);
}
if ($info['timed_out']) {
throw new EasyRdf_Exception("Request to {$host}:{$port} timed out");
}
// FIXME: support HTTP/1.1 100 Continue
// Close the socket
@fclose($socket);
// Parse the response string
$response = EasyRdf_Http_Response::fromString($content);
// If we got redirected, look for the Location header
if ($response
->isRedirect() && ($location = $response
->getHeader('location'))) {
// Avoid problems with buggy servers that add whitespace at the
// end of some headers (See ZF-11283)
$location = trim($location);
// Some servers return relative URLs in the location header
// resolve it in relation to previous request
$baseUri = new EasyRdf_ParsedUri($this->uri);
$location = $baseUri
->resolve($location)
->toString();
// If it is a 303 then drop the parameters and send a GET request
if ($response
->getStatus() == 303) {
$this
->resetParameters();
$this
->setMethod('GET');
}
// If we got a well formed absolute URI
if (parse_url($location)) {
$this
->setHeaders('host', null);
$this
->setUri($location);
}
else {
throw new EasyRdf_Exception("Failed to parse Location header returned by " . $this->uri);
}
++$this->redirectCounter;
}
else {
// If we didn't get any location, stop redirecting
break;
}
} while ($this->redirectCounter < $this->config['maxredirects']);
return $response;
}
/**
* Prepare the request headers
*
* @ignore
* @return array
*/
protected function prepareHeaders($host, $port) {
$headers = array();
// Set the host header
if (!isset($this->headers['host'])) {
// If the port is not default, add it
if ($port !== 80 and $port !== 443) {
$host .= ':' . $port;
}
$headers[] = "Host: {$host}";
}
// Set the connection header
if (!isset($this->headers['connection'])) {
$headers[] = "Connection: close";
}
// Set the user agent header
if (!isset($this->headers['user-agent'])) {
$headers[] = "User-Agent: {$this->config['useragent']}";
}
// If we have rawPostData set, set the content-length header
if (isset($this->rawPostData)) {
$headers[] = "Content-Length: " . strlen($this->rawPostData);
}
// Add all other user defined headers
foreach ($this->headers as $header) {
list($name, $value) = $header;
if (is_array($value)) {
$value = implode(', ', $value);
}
$headers[] = "{$name}: {$value}";
}
return $headers;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
EasyRdf_Http_Client:: |
private | property | Configuration array, set using the constructor or using ::setConfig() | |
EasyRdf_Http_Client:: |
private | property | Associative array of request headers | |
EasyRdf_Http_Client:: |
private | property | HTTP request method | |
EasyRdf_Http_Client:: |
private | property | Associative array of GET parameters | |
EasyRdf_Http_Client:: |
private | property | The raw post data to send. Could be set by setRawData($data). | |
EasyRdf_Http_Client:: |
private | property | Redirection counter | |
EasyRdf_Http_Client:: |
private | property | Request URI | |
EasyRdf_Http_Client:: |
public | function | Get the value of a specific header | |
EasyRdf_Http_Client:: |
public | function | Get the method for the next request | |
EasyRdf_Http_Client:: |
public | function | Get a GET parameter for the request. | |
EasyRdf_Http_Client:: |
public | function | Get all the GET parameters | |
EasyRdf_Http_Client:: |
public | function | Get the raw (already encoded) POST data. | |
EasyRdf_Http_Client:: |
public | function | Get the number of redirections done on the last request | |
EasyRdf_Http_Client:: |
public | function | Get the URI for the next request | |
EasyRdf_Http_Client:: |
protected | function | Prepare the request headers | |
EasyRdf_Http_Client:: |
public | function | Send the HTTP request and return an HTTP response object | |
EasyRdf_Http_Client:: |
public | function | Clear all GET and POST parameters | |
EasyRdf_Http_Client:: |
public | function | Set configuration parameters for this HTTP client | |
EasyRdf_Http_Client:: |
public | function | Set a request header | |
EasyRdf_Http_Client:: |
public | function | Set the next request's method | |
EasyRdf_Http_Client:: |
public | function | Set a GET parameter for the request. | |
EasyRdf_Http_Client:: |
public | function | Set the raw (already encoded) POST data. | |
EasyRdf_Http_Client:: |
public | function | Set the URI for the next request | |
EasyRdf_Http_Client:: |
public | function | Constructor method. Will create a new HTTP client. Accepts the target URL and optionally configuration array. |