Initial import from local backup (Documents-Playground/pakerpale)
This commit is contained in:
33
application/libraries/Requests/Auth.php
Normal file
33
application/libraries/Requests/Auth.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Authentication provider interface
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Authentication
|
||||
*/
|
||||
|
||||
/**
|
||||
* Authentication provider interface
|
||||
*
|
||||
* Implement this interface to act as an authentication provider.
|
||||
*
|
||||
* Parameters should be passed via the constructor where possible, as this
|
||||
* makes it much easier for users to use your provider.
|
||||
*
|
||||
* @see Requests_Hooks
|
||||
* @package Requests
|
||||
* @subpackage Authentication
|
||||
*/
|
||||
interface Requests_Auth {
|
||||
/**
|
||||
* Register hooks as needed
|
||||
*
|
||||
* This method is called in {@see Requests::request} when the user has set
|
||||
* an instance as the 'auth' option. Use this callback to register all the
|
||||
* hooks you'll need.
|
||||
*
|
||||
* @see Requests_Hooks::register
|
||||
* @param Requests_Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Requests_Hooks &$hooks);
|
||||
}
|
||||
88
application/libraries/Requests/Auth/Basic.php
Normal file
88
application/libraries/Requests/Auth/Basic.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* Basic Authentication provider
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Authentication
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic Authentication provider
|
||||
*
|
||||
* Provides a handler for Basic HTTP authentication via the Authorization
|
||||
* header.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Authentication
|
||||
*/
|
||||
class Requests_Auth_Basic implements Requests_Auth {
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $pass;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws Requests_Exception On incorrect number of arguments (`authbasicbadargs`)
|
||||
* @param array|null $args Array of user and password. Must have exactly two elements
|
||||
*/
|
||||
public function __construct($args = null) {
|
||||
if (is_array($args)) {
|
||||
if (count($args) !== 2) {
|
||||
throw new Requests_Exception('Invalid number of arguments', 'authbasicbadargs');
|
||||
}
|
||||
|
||||
list($this->user, $this->pass) = $args;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the necessary callbacks
|
||||
*
|
||||
* @see curl_before_send
|
||||
* @see fsockopen_header
|
||||
* @param Requests_Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Requests_Hooks &$hooks) {
|
||||
$hooks->register('curl.before_send', array(&$this, 'curl_before_send'));
|
||||
$hooks->register('fsockopen.after_headers', array(&$this, 'fsockopen_header'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cURL parameters before the data is sent
|
||||
*
|
||||
* @param resource $handle cURL resource
|
||||
*/
|
||||
public function curl_before_send(&$handle) {
|
||||
curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($handle, CURLOPT_USERPWD, $this->getAuthString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra headers to the request before sending
|
||||
*
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_header(&$out) {
|
||||
$out .= "Authorization: Basic " . base64_encode($this->getAuthString()) . "\r\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication string (user:pass)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthString() {
|
||||
return $this->user . ':' . $this->pass;
|
||||
}
|
||||
}
|
||||
171
application/libraries/Requests/Cookie.php
Normal file
171
application/libraries/Requests/Cookie.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* Cookie storage object
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Cookies
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cookie storage object
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Cookies
|
||||
*/
|
||||
class Requests_Cookie {
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Cookie attributes
|
||||
*
|
||||
* Valid keys are (currently) path, domain, expires, max-age, secure and
|
||||
* httponly.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $attributes = array();
|
||||
|
||||
/**
|
||||
* Create a new cookie object
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param array $attributes Associative array of attribute data
|
||||
*/
|
||||
public function __construct($name, $value, $attributes = array()) {
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a cookie for a Cookie header
|
||||
*
|
||||
* This is used when sending cookies to a server.
|
||||
*
|
||||
* @return string Cookie formatted for Cookie header
|
||||
*/
|
||||
public function formatForHeader() {
|
||||
return sprintf('%s=%s', $this->name, $this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a cookie for a Set-Cookie header
|
||||
*
|
||||
* This is used when sending cookies to clients. This isn't really
|
||||
* applicable to client-side usage, but might be handy for debugging.
|
||||
*
|
||||
* @return string Cookie formatted for Set-Cookie header
|
||||
*/
|
||||
public function formatForSetCookie() {
|
||||
$header_value = $this->formatForHeader();
|
||||
if (!empty($this->attributes)) {
|
||||
$parts = array();
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
// Ignore non-associative attributes
|
||||
if (is_numeric($key)) {
|
||||
$parts[] = $value;
|
||||
}
|
||||
else {
|
||||
$parts[] = sprintf('%s=%s', $key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$header_value .= '; ' . implode('; ', $parts);
|
||||
}
|
||||
return $header_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cookie value
|
||||
*
|
||||
* Attributes and other data can be accessed via methods.
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a cookie string into a cookie object
|
||||
*
|
||||
* Based on Mozilla's parsing code in Firefox and related projects, which
|
||||
* is an intentional deviation from RFC 2109 and RFC 2616. RFC 6265
|
||||
* specifies some of this handling, but not in a thorough manner.
|
||||
*
|
||||
* @param string Cookie header value (from a Set-Cookie header)
|
||||
* @return Requests_Cookie Parsed cookie object
|
||||
*/
|
||||
public static function parse($string, $name = '') {
|
||||
$parts = explode(';', $string);
|
||||
$kvparts = array_shift($parts);
|
||||
|
||||
if (!empty($name)) {
|
||||
$value = $string;
|
||||
}
|
||||
elseif (strpos($kvparts, '=') === false) {
|
||||
// Some sites might only have a value without the equals separator.
|
||||
// Deviate from RFC 6265 and pretend it was actually a blank name
|
||||
// (`=foo`)
|
||||
//
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=169091
|
||||
$name = '';
|
||||
$value = $kvparts;
|
||||
}
|
||||
else {
|
||||
list($name, $value) = explode('=', $kvparts, 2);
|
||||
}
|
||||
$name = trim($name);
|
||||
$value = trim($value);
|
||||
|
||||
// Attribute key are handled case-insensitively
|
||||
$attributes = new Requests_Utility_CaseInsensitiveDictionary();
|
||||
|
||||
if (!empty($parts)) {
|
||||
foreach ($parts as $part) {
|
||||
if (strpos($part, '=') === false) {
|
||||
$part_key = $part;
|
||||
$part_value = true;
|
||||
}
|
||||
else {
|
||||
list($part_key, $part_value) = explode('=', $part, 2);
|
||||
$part_value = trim($part_value);
|
||||
}
|
||||
|
||||
$part_key = trim($part_key);
|
||||
$attributes[$part_key] = $part_value;
|
||||
}
|
||||
}
|
||||
|
||||
return new Requests_Cookie($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all Set-Cookie headers from request headers
|
||||
*
|
||||
* @param Requests_Response_Headers $headers
|
||||
* @return array
|
||||
*/
|
||||
public static function parseFromHeaders(Requests_Response_Headers $headers) {
|
||||
$cookie_headers = $headers->getValues('Set-Cookie');
|
||||
if (empty($cookie_headers)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$cookies = array();
|
||||
foreach ($cookie_headers as $header) {
|
||||
$parsed = self::parse($header);
|
||||
$cookies[$parsed->name] = $parsed;
|
||||
}
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
}
|
||||
146
application/libraries/Requests/Cookie/Jar.php
Normal file
146
application/libraries/Requests/Cookie/Jar.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Cookie holder object
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Cookies
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cookie holder object
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Cookies
|
||||
*/
|
||||
class Requests_Cookie_Jar implements ArrayAccess, IteratorAggregate {
|
||||
/**
|
||||
* Actual item data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cookies = array();
|
||||
|
||||
/**
|
||||
* Create a new jar
|
||||
*
|
||||
* @param array $cookies Existing cookie values
|
||||
*/
|
||||
public function __construct($cookies = array()) {
|
||||
$this->cookies = $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise cookie data into a Requests_Cookie
|
||||
*
|
||||
* @param string|Requests_Cookie $cookie
|
||||
* @return Requests_Cookie
|
||||
*/
|
||||
public function normalizeCookie($cookie, $key = null) {
|
||||
if ($cookie instanceof Requests_Cookie) {
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
return Requests_Cookie::parse($cookie, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given item exists
|
||||
*
|
||||
* @param string $key Item key
|
||||
* @return boolean Does the item exist?
|
||||
*/
|
||||
public function offsetExists($key) {
|
||||
return isset($this->cookies[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the item
|
||||
*
|
||||
* @param string $key Item key
|
||||
* @return string Item value
|
||||
*/
|
||||
public function offsetGet($key) {
|
||||
if (!isset($this->cookies[$key]))
|
||||
return null;
|
||||
|
||||
return $this->cookies[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given item
|
||||
*
|
||||
* @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
|
||||
*
|
||||
* @param string $key Item name
|
||||
* @param string $value Item value
|
||||
*/
|
||||
public function offsetSet($key, $value) {
|
||||
if ($key === null) {
|
||||
throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
|
||||
}
|
||||
|
||||
$this->cookies[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the given header
|
||||
*
|
||||
* @param string $key
|
||||
*/
|
||||
public function offsetUnset($key) {
|
||||
unset($this->cookies[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the data
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the cookie handler with the request's hooking system
|
||||
*
|
||||
* @param Requests_Hooker $hooks Hooking system
|
||||
*/
|
||||
public function register(Requests_Hooker $hooks) {
|
||||
$hooks->register('requests.before_request', array($this, 'before_request'));
|
||||
$hooks->register('requests.before_redirect_check', array($this, 'before_redirect_check'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Cookie header to a request if we have any
|
||||
*
|
||||
* As per RFC 6265, cookies are separated by '; '
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $data
|
||||
* @param string $type
|
||||
* @param array $options
|
||||
*/
|
||||
public function before_request(&$url, &$headers, &$data, &$type, &$options) {
|
||||
if (!empty($this->cookies)) {
|
||||
$cookies = array();
|
||||
foreach ($this->cookies as $key => $cookie) {
|
||||
$cookie = $this->normalizeCookie($cookie, $key);
|
||||
$cookies[] = $cookie->formatForHeader();
|
||||
}
|
||||
|
||||
$headers['Cookie'] = implode('; ', $cookies);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all cookies from a response and attach them to the response
|
||||
*
|
||||
* @var Requests_Response $response
|
||||
*/
|
||||
public function before_redirect_check(Requests_Response &$return) {
|
||||
$cookies = Requests_Cookie::parseFromHeaders($return->headers);
|
||||
$this->cookies = array_merge($this->cookies, $cookies);
|
||||
$return->cookies = $this;
|
||||
}
|
||||
}
|
||||
62
application/libraries/Requests/Exception.php
Normal file
62
application/libraries/Requests/Exception.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for HTTP requests
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for HTTP requests
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception extends Exception {
|
||||
/**
|
||||
* Type of exception
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Data associated with the exception
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* @param string $message Exception message
|
||||
* @param string $type Exception type
|
||||
* @param mixed $data Associated data
|
||||
* @param integer $code Exception numerical code, if applicable
|
||||
*/
|
||||
public function __construct($message, $type, $data = null, $code = 0) {
|
||||
parent::__construct($message, $code);
|
||||
|
||||
$this->type = $type;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@see getCode()}, but a string code.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return string
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives any relevant data
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
67
application/libraries/Requests/Exception/HTTP.php
Normal file
67
application/libraries/Requests/Exception/HTTP.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception based on HTTP response
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception based on HTTP response
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP extends Requests_Exception {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 0;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unknown';
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* There is no mechanism to pass in the status code, as this is set by the
|
||||
* subclass used. Reason phrases can vary, however.
|
||||
*
|
||||
* @param string $reason Reason phrase
|
||||
* @param mixed $data Associated data
|
||||
*/
|
||||
public function __construct($reason = null, $data = null) {
|
||||
if ($reason !== null) {
|
||||
$this->reason = $reason;
|
||||
}
|
||||
|
||||
$message = sprintf('%d %s', $this->code, $this->reason);
|
||||
parent::__construct($message, 'httpresponse', $data, $this->code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status message
|
||||
*/
|
||||
public function getReason() {
|
||||
return $this->reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct exception class for a given error code
|
||||
*
|
||||
* @param int $code HTTP status code
|
||||
* @return string Exception class name to use
|
||||
*/
|
||||
public static function get_class($code) {
|
||||
$class = sprintf('Requests_Exception_HTTP_%d', $code);
|
||||
if (class_exists($class)) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
return 'Requests_Exception_HTTP_Unknown';
|
||||
}
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/400.php
Normal file
27
application/libraries/Requests/Exception/HTTP/400.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 400 Bad Request responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 400 Bad Request responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_400 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 400;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Bad Request';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/401.php
Normal file
27
application/libraries/Requests/Exception/HTTP/401.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 401 Unauthorized responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 401 Unauthorized responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_401 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 401;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unauthorized';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/402.php
Normal file
27
application/libraries/Requests/Exception/HTTP/402.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 402 Payment Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 402 Payment Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_402 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 402;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Payment Required';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/403.php
Normal file
27
application/libraries/Requests/Exception/HTTP/403.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 403 Forbidden responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 403 Forbidden responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_403 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 403;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Forbidden';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/404.php
Normal file
27
application/libraries/Requests/Exception/HTTP/404.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 404 Not Found responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 404 Not Found responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_404 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 404;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Found';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/405.php
Normal file
27
application/libraries/Requests/Exception/HTTP/405.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 405 Method Not Allowed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 405 Method Not Allowed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_405 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 405;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Method Not Allowed';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/406.php
Normal file
27
application/libraries/Requests/Exception/HTTP/406.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 406 Not Acceptable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 406 Not Acceptable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_406 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 406;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Acceptable';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/407.php
Normal file
27
application/libraries/Requests/Exception/HTTP/407.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 407 Proxy Authentication Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 407 Proxy Authentication Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_407 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 407;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Proxy Authentication Required';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/408.php
Normal file
27
application/libraries/Requests/Exception/HTTP/408.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 408 Request Timeout responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 408 Request Timeout responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_408 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 408;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Timeout';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/409.php
Normal file
27
application/libraries/Requests/Exception/HTTP/409.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 409 Conflict responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 409 Conflict responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_409 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 409;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Conflict';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/410.php
Normal file
27
application/libraries/Requests/Exception/HTTP/410.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 410 Gone responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 410 Gone responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_410 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 410;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Gone';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/411.php
Normal file
27
application/libraries/Requests/Exception/HTTP/411.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 411 Length Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 411 Length Required responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_411 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 411;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Length Required';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/412.php
Normal file
27
application/libraries/Requests/Exception/HTTP/412.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 412 Precondition Failed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 412 Precondition Failed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_412 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 412;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Precondition Failed';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/413.php
Normal file
27
application/libraries/Requests/Exception/HTTP/413.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 413 Request Entity Too Large responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 413 Request Entity Too Large responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_413 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 413;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Entity Too Large';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/414.php
Normal file
27
application/libraries/Requests/Exception/HTTP/414.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 414 Request-URI Too Large responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 414 Request-URI Too Large responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_414 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 414;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request-URI Too Large';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/415.php
Normal file
27
application/libraries/Requests/Exception/HTTP/415.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 415 Unsupported Media Type responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 415 Unsupported Media Type responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_415 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 415;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unsupported Media Type';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/416.php
Normal file
27
application/libraries/Requests/Exception/HTTP/416.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 416 Requested Range Not Satisfiable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 416 Requested Range Not Satisfiable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_416 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 416;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Requested Range Not Satisfiable';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/417.php
Normal file
27
application/libraries/Requests/Exception/HTTP/417.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 417 Expectation Failed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 417 Expectation Failed responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_417 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 417;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Expectation Failed';
|
||||
}
|
||||
29
application/libraries/Requests/Exception/HTTP/418.php
Normal file
29
application/libraries/Requests/Exception/HTTP/418.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 418 I'm A Teapot responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2324
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 418 I'm A Teapot responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2324
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_418 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 418;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = "I'm A Teapot";
|
||||
}
|
||||
29
application/libraries/Requests/Exception/HTTP/428.php
Normal file
29
application/libraries/Requests/Exception/HTTP/428.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 428 Precondition Required responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 428 Precondition Required responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_428 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 428;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Precondition Required';
|
||||
}
|
||||
29
application/libraries/Requests/Exception/HTTP/429.php
Normal file
29
application/libraries/Requests/Exception/HTTP/429.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 429 Too Many Requests responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/draft-nottingham-http-new-status-04
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 429 Too Many Requests responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/draft-nottingham-http-new-status-04
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_429 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 429;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Too Many Requests';
|
||||
}
|
||||
29
application/libraries/Requests/Exception/HTTP/431.php
Normal file
29
application/libraries/Requests/Exception/HTTP/431.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 431 Request Header Fields Too Large responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 431 Request Header Fields Too Large responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_431 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 431;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Header Fields Too Large';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/500.php
Normal file
27
application/libraries/Requests/Exception/HTTP/500.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 500 Internal Server Error responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 500 Internal Server Error responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_500 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 500;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Internal Server Error';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/501.php
Normal file
27
application/libraries/Requests/Exception/HTTP/501.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 501 Not Implemented responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 501 Not Implemented responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_501 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 501;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Implemented';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/502.php
Normal file
27
application/libraries/Requests/Exception/HTTP/502.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 502 Bad Gateway responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 502 Bad Gateway responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_502 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 502;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Bad Gateway';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/503.php
Normal file
27
application/libraries/Requests/Exception/HTTP/503.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 503 Service Unavailable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 503 Service Unavailable responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_503 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 503;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Service Unavailable';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/504.php
Normal file
27
application/libraries/Requests/Exception/HTTP/504.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 504 Gateway Timeout responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 504 Gateway Timeout responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_504 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 504;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Gateway Timeout';
|
||||
}
|
||||
27
application/libraries/Requests/Exception/HTTP/505.php
Normal file
27
application/libraries/Requests/Exception/HTTP/505.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 505 HTTP Version Not Supported responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 505 HTTP Version Not Supported responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_505 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 505;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'HTTP Version Not Supported';
|
||||
}
|
||||
29
application/libraries/Requests/Exception/HTTP/511.php
Normal file
29
application/libraries/Requests/Exception/HTTP/511.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 511 Network Authentication Required responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for 511 Network Authentication Required responses
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_511 extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 511;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Network Authentication Required';
|
||||
}
|
||||
44
application/libraries/Requests/Exception/HTTP/Unknown.php
Normal file
44
application/libraries/Requests/Exception/HTTP/Unknown.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for unknown status responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception for unknown status responses
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Exception_HTTP_Unknown extends Requests_Exception_HTTP {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 0;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unknown';
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* If `$data` is an instance of {@see Requests_Response}, uses the status
|
||||
* code from it. Otherwise, sets as 0
|
||||
*
|
||||
* @param string $reason Reason phrase
|
||||
* @param mixed $data Associated data
|
||||
*/
|
||||
public function __construct($reason = null, $data = null) {
|
||||
if ($data instanceof Requests_Response) {
|
||||
$this->code = $data->status_code;
|
||||
}
|
||||
|
||||
parent::__construct($reason, $data);
|
||||
}
|
||||
}
|
||||
33
application/libraries/Requests/Hooker.php
Normal file
33
application/libraries/Requests/Hooker.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Event dispatcher
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Event dispatcher
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
interface Requests_Hooker {
|
||||
/**
|
||||
* Register a callback for a hook
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param callback $callback Function/method to call on event
|
||||
* @param int $priority Priority number. <0 is executed earlier, >0 is executed later
|
||||
*/
|
||||
public function register($hook, $callback, $priority = 0);
|
||||
|
||||
/**
|
||||
* Dispatch a message
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param array $parameters Parameters to pass to callbacks
|
||||
* @return boolean Successfulness
|
||||
*/
|
||||
public function dispatch($hook, $parameters = array());
|
||||
}
|
||||
61
application/libraries/Requests/Hooks.php
Normal file
61
application/libraries/Requests/Hooks.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles adding and dispatching events
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles adding and dispatching events
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
class Requests_Hooks implements Requests_Hooker {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
// pass
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback for a hook
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param callback $callback Function/method to call on event
|
||||
* @param int $priority Priority number. <0 is executed earlier, >0 is executed later
|
||||
*/
|
||||
public function register($hook, $callback, $priority = 0) {
|
||||
if (!isset($this->hooks[$hook])) {
|
||||
$this->hooks[$hook] = array();
|
||||
}
|
||||
if (!isset($this->hooks[$hook][$priority])) {
|
||||
$this->hooks[$hook][$priority] = array();
|
||||
}
|
||||
|
||||
$this->hooks[$hook][$priority][] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a message
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param array $parameters Parameters to pass to callbacks
|
||||
* @return boolean Successfulness
|
||||
*/
|
||||
public function dispatch($hook, $parameters = array()) {
|
||||
if (empty($this->hooks[$hook])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->hooks[$hook] as $priority => $hooked) {
|
||||
foreach ($hooked as $callback) {
|
||||
call_user_func_array($callback, $parameters);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
390
application/libraries/Requests/IDNAEncoder.php
Normal file
390
application/libraries/Requests/IDNAEncoder.php
Normal file
@@ -0,0 +1,390 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* IDNA URL encoder
|
||||
*
|
||||
* Note: Not fully compliant, as nameprep does nothing yet.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
* @see http://tools.ietf.org/html/rfc3490 IDNA specification
|
||||
* @see http://tools.ietf.org/html/rfc3492 Punycode/Bootstrap specification
|
||||
*/
|
||||
class Requests_IDNAEncoder {
|
||||
/**
|
||||
* ACE prefix used for IDNA
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3490#section-5
|
||||
* @var string
|
||||
*/
|
||||
const ACE_PREFIX = 'xn--';
|
||||
|
||||
/**#@+
|
||||
* Bootstrap constant for Punycode
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3492#section-5
|
||||
* @var int
|
||||
*/
|
||||
const BOOTSTRAP_BASE = 36;
|
||||
const BOOTSTRAP_TMIN = 1;
|
||||
const BOOTSTRAP_TMAX = 26;
|
||||
const BOOTSTRAP_SKEW = 38;
|
||||
const BOOTSTRAP_DAMP = 700;
|
||||
const BOOTSTRAP_INITIAL_BIAS = 72;
|
||||
const BOOTSTRAP_INITIAL_N = 128;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Encode a hostname using Punycode
|
||||
*
|
||||
* @param string $string Hostname
|
||||
* @return string Punycode-encoded hostname
|
||||
*/
|
||||
public static function encode($string) {
|
||||
$parts = explode('.', $string);
|
||||
foreach ($parts as &$part) {
|
||||
$part = self::to_ascii($part);
|
||||
}
|
||||
return implode('.', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 string to an ASCII string using Punycode
|
||||
*
|
||||
* @throws Requests_Exception Provided string longer than 64 ASCII characters (`idna.provided_too_long`)
|
||||
* @throws Requests_Exception Prepared string longer than 64 ASCII characters (`idna.prepared_too_long`)
|
||||
* @throws Requests_Exception Provided string already begins with xn-- (`idna.provided_is_prefixed`)
|
||||
* @throws Requests_Exception Encoded string longer than 64 ASCII characters (`idna.encoded_too_long`)
|
||||
*
|
||||
* @param string $string ASCII or UTF-8 string (max length 64 characters)
|
||||
* @return string ASCII string
|
||||
*/
|
||||
public static function to_ascii($string) {
|
||||
// Step 1: Check if the string is already ASCII
|
||||
if (self::is_ascii($string)) {
|
||||
// Skip to step 7
|
||||
if (strlen($string) < 64) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
throw new Requests_Exception('Provided string is too long', 'idna.provided_too_long', $string);
|
||||
}
|
||||
|
||||
// Step 2: nameprep
|
||||
$string = self::nameprep($string);
|
||||
|
||||
// Step 3: UseSTD3ASCIIRules is false, continue
|
||||
// Step 4: Check if it's ASCII now
|
||||
if (self::is_ascii($string)) {
|
||||
// Skip to step 7
|
||||
if (strlen($string) < 64) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
throw new Requests_Exception('Prepared string is too long', 'idna.prepared_too_long', $string);
|
||||
}
|
||||
|
||||
// Step 5: Check ACE prefix
|
||||
if (strpos($string, self::ACE_PREFIX) === 0) {
|
||||
throw new Requests_Exception('Provided string begins with ACE prefix', 'idna.provided_is_prefixed', $string);
|
||||
}
|
||||
|
||||
// Step 6: Encode with Punycode
|
||||
$string = self::punycode_encode($string);
|
||||
|
||||
// Step 7: Prepend ACE prefix
|
||||
$string = self::ACE_PREFIX . $string;
|
||||
|
||||
// Step 8: Check size
|
||||
if (strlen($string) < 64) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
throw new Requests_Exception('Encoded string is too long', 'idna.encoded_too_long', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given string contains only ASCII characters
|
||||
*
|
||||
* @internal (Testing found regex was the fastest implementation)
|
||||
*
|
||||
* @param string $string
|
||||
* @return bool Is the string ASCII-only?
|
||||
*/
|
||||
protected static function is_ascii($string) {
|
||||
return (preg_match('/(?:[^\x00-\x7F])/', $string) !== 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a string for use as an IDNA name
|
||||
*
|
||||
* @todo Implement this based on RFC 3491 and the newer 5891
|
||||
* @param string $string
|
||||
* @return string Prepared string
|
||||
*/
|
||||
protected static function nameprep($string) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 string to a UCS-4 codepoint array
|
||||
*
|
||||
* Based on Requests_IRI::replace_invalid_with_pct_encoding()
|
||||
*
|
||||
* @throws Requests_Exception Invalid UTF-8 codepoint (`idna.invalidcodepoint`)
|
||||
* @param string $input
|
||||
* @return array Unicode code points
|
||||
*/
|
||||
protected static function utf8_to_codepoints($input) {
|
||||
$codepoints = array();
|
||||
|
||||
// Get number of bytes
|
||||
$strlen = strlen($input);
|
||||
|
||||
for ($position = 0; $position < $strlen; $position++) {
|
||||
$value = ord($input[$position]);
|
||||
|
||||
// One byte sequence:
|
||||
if ((~$value & 0x80) === 0x80) {
|
||||
$character = $value;
|
||||
$length = 1;
|
||||
$remaining = 0;
|
||||
}
|
||||
// Two byte sequence:
|
||||
elseif (($value & 0xE0) === 0xC0) {
|
||||
$character = ($value & 0x1F) << 6;
|
||||
$length = 2;
|
||||
$remaining = 1;
|
||||
}
|
||||
// Three byte sequence:
|
||||
elseif (($value & 0xF0) === 0xE0) {
|
||||
$character = ($value & 0x0F) << 12;
|
||||
$length = 3;
|
||||
$remaining = 2;
|
||||
}
|
||||
// Four byte sequence:
|
||||
elseif (($value & 0xF8) === 0xF0) {
|
||||
$character = ($value & 0x07) << 18;
|
||||
$length = 4;
|
||||
$remaining = 3;
|
||||
}
|
||||
// Invalid byte:
|
||||
else {
|
||||
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $value);
|
||||
}
|
||||
|
||||
if ($remaining > 0) {
|
||||
if ($position + $length > $strlen) {
|
||||
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
for ($position++; $remaining > 0; $position++) {
|
||||
$value = ord($input[$position]);
|
||||
|
||||
// If it is invalid, count the sequence as invalid and reprocess the current byte:
|
||||
if (($value & 0xC0) !== 0x80) {
|
||||
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
|
||||
$character |= ($value & 0x3F) << (--$remaining * 6);
|
||||
}
|
||||
$position--;
|
||||
}
|
||||
|
||||
if (
|
||||
// Non-shortest form sequences are invalid
|
||||
$length > 1 && $character <= 0x7F
|
||||
|| $length > 2 && $character <= 0x7FF
|
||||
|| $length > 3 && $character <= 0xFFFF
|
||||
// Outside of range of ucschar codepoints
|
||||
// Noncharacters
|
||||
|| ($character & 0xFFFE) === 0xFFFE
|
||||
|| $character >= 0xFDD0 && $character <= 0xFDEF
|
||||
|| (
|
||||
// Everything else not in ucschar
|
||||
$character > 0xD7FF && $character < 0xF900
|
||||
|| $character < 0x20
|
||||
|| $character > 0x7E && $character < 0xA0
|
||||
|| $character > 0xEFFFD
|
||||
)
|
||||
) {
|
||||
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
|
||||
$codepoints[] = $character;
|
||||
}
|
||||
|
||||
return $codepoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC3492-compliant encoder
|
||||
*
|
||||
* @internal Pseudo-code from Section 6.3 is commented with "#" next to relevant code
|
||||
* @throws Requests_Exception On character outside of the domain (never happens with Punycode) (`idna.character_outside_domain`)
|
||||
*
|
||||
* @param string $input UTF-8 encoded string to encode
|
||||
* @return string Punycode-encoded string
|
||||
*/
|
||||
public static function punycode_encode($input) {
|
||||
$output = '';
|
||||
# let n = initial_n
|
||||
$n = self::BOOTSTRAP_INITIAL_N;
|
||||
# let delta = 0
|
||||
$delta = 0;
|
||||
# let bias = initial_bias
|
||||
$bias = self::BOOTSTRAP_INITIAL_BIAS;
|
||||
# let h = b = the number of basic code points in the input
|
||||
$h = $b = 0; // see loop
|
||||
# copy them to the output in order
|
||||
$codepoints = self::utf8_to_codepoints($input);
|
||||
|
||||
foreach ($codepoints as $char) {
|
||||
if ($char < 128) {
|
||||
// Character is valid ASCII
|
||||
// TODO: this should also check if it's valid for a URL
|
||||
$output .= chr($char);
|
||||
$h++;
|
||||
}
|
||||
// Check if the character is non-ASCII, but below initial n
|
||||
// This never occurs for Punycode, so ignore in coverage
|
||||
// @codeCoverageIgnoreStart
|
||||
elseif ($char < $n) {
|
||||
throw new Requests_Exception('Invalid character', 'idna.character_outside_domain', $char);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
else {
|
||||
$extended[$char] = true;
|
||||
}
|
||||
}
|
||||
$extended = array_keys($extended);
|
||||
sort($extended);
|
||||
$b = $h;
|
||||
# [copy them] followed by a delimiter if b > 0
|
||||
if (strlen($output) > 0) {
|
||||
$output .= '-';
|
||||
}
|
||||
# {if the input contains a non-basic code point < n then fail}
|
||||
# while h < length(input) do begin
|
||||
while ($h < count($codepoints)) {
|
||||
# let m = the minimum code point >= n in the input
|
||||
$m = array_shift($extended);
|
||||
//printf('next code point to insert is %s' . PHP_EOL, dechex($m));
|
||||
# let delta = delta + (m - n) * (h + 1), fail on overflow
|
||||
$delta += ($m - $n) * ($h + 1);
|
||||
# let n = m
|
||||
$n = $m;
|
||||
# for each code point c in the input (in order) do begin
|
||||
for ($num = 0; $num < count($codepoints); $num++) {
|
||||
$c = $codepoints[$num];
|
||||
# if c < n then increment delta, fail on overflow
|
||||
if ($c < $n) {
|
||||
$delta++;
|
||||
}
|
||||
# if c == n then begin
|
||||
elseif ($c === $n) {
|
||||
# let q = delta
|
||||
$q = $delta;
|
||||
# for k = base to infinity in steps of base do begin
|
||||
for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) {
|
||||
# let t = tmin if k <= bias {+ tmin}, or
|
||||
# tmax if k >= bias + tmax, or k - bias otherwise
|
||||
if ($k <= ($bias + self::BOOTSTRAP_TMIN)) {
|
||||
$t = self::BOOTSTRAP_TMIN;
|
||||
}
|
||||
elseif ($k >= ($bias + self::BOOTSTRAP_TMAX)) {
|
||||
$t = self::BOOTSTRAP_TMAX;
|
||||
}
|
||||
else {
|
||||
$t = $k - $bias;
|
||||
}
|
||||
# if q < t then break
|
||||
if ($q < $t) {
|
||||
break;
|
||||
}
|
||||
# output the code point for digit t + ((q - t) mod (base - t))
|
||||
$digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
|
||||
//printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($digit));
|
||||
$output .= self::digit_to_char($digit);
|
||||
# let q = (q - t) div (base - t)
|
||||
$q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
|
||||
# end
|
||||
}
|
||||
# output the code point for digit q
|
||||
$output .= self::digit_to_char($q);
|
||||
//printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($q));
|
||||
# let bias = adapt(delta, h + 1, test h equals b?)
|
||||
$bias = self::adapt($delta, $h + 1, $h === $b);
|
||||
//printf('bias becomes %d' . PHP_EOL, $bias);
|
||||
# let delta = 0
|
||||
$delta = 0;
|
||||
# increment h
|
||||
$h++;
|
||||
# end
|
||||
}
|
||||
# end
|
||||
}
|
||||
# increment delta and n
|
||||
$delta++;
|
||||
$n++;
|
||||
# end
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a digit to its respective character
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3492#section-5
|
||||
* @throws Requests_Exception On invalid digit (`idna.invalid_digit`)
|
||||
*
|
||||
* @param int $digit Digit in the range 0-35
|
||||
* @return string Single character corresponding to digit
|
||||
*/
|
||||
protected static function digit_to_char($digit) {
|
||||
// @codeCoverageIgnoreStart
|
||||
// As far as I know, this never happens, but still good to be sure.
|
||||
if ($digit < 0 || $digit > 35) {
|
||||
throw new Requests_Exception(sprintf('Invalid digit %d', $digit), 'idna.invalid_digit', $digit);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$digits = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
return substr($digits, $digit, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt the bias
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3492#section-6.1
|
||||
* @param int $delta
|
||||
* @param int $numpoints
|
||||
* @param bool $firsttime
|
||||
* @return int New bias
|
||||
*/
|
||||
protected static function adapt($delta, $numpoints, $firsttime) {
|
||||
# function adapt(delta,numpoints,firsttime):
|
||||
# if firsttime then let delta = delta div damp
|
||||
if ($firsttime) {
|
||||
$delta = floor($delta / self::BOOTSTRAP_DAMP);
|
||||
}
|
||||
# else let delta = delta div 2
|
||||
else {
|
||||
$delta = floor($delta / 2);
|
||||
}
|
||||
# let delta = delta + (delta div numpoints)
|
||||
$delta += floor($delta / $numpoints);
|
||||
# let k = 0
|
||||
$k = 0;
|
||||
# while delta > ((base - tmin) * tmax) div 2 do begin
|
||||
$max = floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN) * self::BOOTSTRAP_TMAX) / 2);
|
||||
while ($delta > $max) {
|
||||
# let delta = delta div (base - tmin)
|
||||
$delta = floor($delta / (self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN));
|
||||
# let k = k + base
|
||||
$k += self::BOOTSTRAP_BASE;
|
||||
# end
|
||||
}
|
||||
# return k + (((base - tmin + 1) * delta) div (delta + skew))
|
||||
return $k + floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN + 1) * $delta) / ($delta + self::BOOTSTRAP_SKEW));
|
||||
}
|
||||
}
|
||||
221
application/libraries/Requests/IPv6.php
Normal file
221
application/libraries/Requests/IPv6.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* Class to validate and to work with IPv6 addresses
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to validate and to work with IPv6 addresses
|
||||
*
|
||||
* This was originally based on the PEAR class of the same name, but has been
|
||||
* entirely rewritten.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
class Requests_IPv6
|
||||
{
|
||||
/**
|
||||
* Uncompresses an IPv6 address
|
||||
*
|
||||
* RFC 4291 allows you to compress consecutive zero pieces in an address to
|
||||
* '::'. This method expects a valid IPv6 address and expands the '::' to
|
||||
* the required number of zero pieces.
|
||||
*
|
||||
* Example: FF01::101 -> FF01:0:0:0:0:0:0:101
|
||||
* ::1 -> 0:0:0:0:0:0:0:1
|
||||
*
|
||||
* @author Alexander Merz <alexander.merz@web.de>
|
||||
* @author elfrink at introweb dot nl
|
||||
* @author Josh Peck <jmp at joshpeck dot org>
|
||||
* @copyright 2003-2005 The PHP Group
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @param string $ip An IPv6 address
|
||||
* @return string The uncompressed IPv6 address
|
||||
*/
|
||||
public static function uncompress($ip)
|
||||
{
|
||||
$c1 = -1;
|
||||
$c2 = -1;
|
||||
if (substr_count($ip, '::') === 1)
|
||||
{
|
||||
list($ip1, $ip2) = explode('::', $ip);
|
||||
if ($ip1 === '')
|
||||
{
|
||||
$c1 = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c1 = substr_count($ip1, ':');
|
||||
}
|
||||
if ($ip2 === '')
|
||||
{
|
||||
$c2 = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c2 = substr_count($ip2, ':');
|
||||
}
|
||||
if (strpos($ip2, '.') !== false)
|
||||
{
|
||||
$c2++;
|
||||
}
|
||||
// ::
|
||||
if ($c1 === -1 && $c2 === -1)
|
||||
{
|
||||
$ip = '0:0:0:0:0:0:0:0';
|
||||
}
|
||||
// ::xxx
|
||||
else if ($c1 === -1)
|
||||
{
|
||||
$fill = str_repeat('0:', 7 - $c2);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
// xxx::
|
||||
else if ($c2 === -1)
|
||||
{
|
||||
$fill = str_repeat(':0', 7 - $c1);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
// xxx::xxx
|
||||
else
|
||||
{
|
||||
$fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
}
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses an IPv6 address
|
||||
*
|
||||
* RFC 4291 allows you to compress consecutive zero pieces in an address to
|
||||
* '::'. This method expects a valid IPv6 address and compresses consecutive
|
||||
* zero pieces to '::'.
|
||||
*
|
||||
* Example: FF01:0:0:0:0:0:0:101 -> FF01::101
|
||||
* 0:0:0:0:0:0:0:1 -> ::1
|
||||
*
|
||||
* @see uncompress()
|
||||
* @param string $ip An IPv6 address
|
||||
* @return string The compressed IPv6 address
|
||||
*/
|
||||
public static function compress($ip)
|
||||
{
|
||||
// Prepare the IP to be compressed
|
||||
$ip = self::uncompress($ip);
|
||||
$ip_parts = self::split_v6_v4($ip);
|
||||
|
||||
// Replace all leading zeros
|
||||
$ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
|
||||
|
||||
// Find bunches of zeros
|
||||
if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$max = 0;
|
||||
$pos = null;
|
||||
foreach ($matches[0] as $match)
|
||||
{
|
||||
if (strlen($match[0]) > $max)
|
||||
{
|
||||
$max = strlen($match[0]);
|
||||
$pos = $match[1];
|
||||
}
|
||||
}
|
||||
|
||||
$ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
|
||||
}
|
||||
|
||||
if ($ip_parts[1] !== '')
|
||||
{
|
||||
return implode(':', $ip_parts);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $ip_parts[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits an IPv6 address into the IPv6 and IPv4 representation parts
|
||||
*
|
||||
* RFC 4291 allows you to represent the last two parts of an IPv6 address
|
||||
* using the standard IPv4 representation
|
||||
*
|
||||
* Example: 0:0:0:0:0:0:13.1.68.3
|
||||
* 0:0:0:0:0:FFFF:129.144.52.38
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
|
||||
*/
|
||||
private static function split_v6_v4($ip)
|
||||
{
|
||||
if (strpos($ip, '.') !== false)
|
||||
{
|
||||
$pos = strrpos($ip, ':');
|
||||
$ipv6_part = substr($ip, 0, $pos);
|
||||
$ipv4_part = substr($ip, $pos + 1);
|
||||
return array($ipv6_part, $ipv4_part);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array($ip, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an IPv6 address
|
||||
*
|
||||
* Checks if the given IP is a valid IPv6 address
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return bool true if $ip is a valid IPv6 address
|
||||
*/
|
||||
public static function check_ipv6($ip)
|
||||
{
|
||||
$ip = self::uncompress($ip);
|
||||
list($ipv6, $ipv4) = self::split_v6_v4($ip);
|
||||
$ipv6 = explode(':', $ipv6);
|
||||
$ipv4 = explode('.', $ipv4);
|
||||
if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
|
||||
{
|
||||
foreach ($ipv6 as $ipv6_part)
|
||||
{
|
||||
// The section can't be empty
|
||||
if ($ipv6_part === '')
|
||||
return false;
|
||||
|
||||
// Nor can it be over four characters
|
||||
if (strlen($ipv6_part) > 4)
|
||||
return false;
|
||||
|
||||
// Remove leading zeros (this is safe because of the above)
|
||||
$ipv6_part = ltrim($ipv6_part, '0');
|
||||
if ($ipv6_part === '')
|
||||
$ipv6_part = '0';
|
||||
|
||||
// Check the value is valid
|
||||
$value = hexdec($ipv6_part);
|
||||
if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
|
||||
return false;
|
||||
}
|
||||
if (count($ipv4) === 4)
|
||||
{
|
||||
foreach ($ipv4 as $ipv4_part)
|
||||
{
|
||||
$value = (int) $ipv4_part;
|
||||
if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
1220
application/libraries/Requests/IRI.php
Normal file
1220
application/libraries/Requests/IRI.php
Normal file
File diff suppressed because it is too large
Load Diff
49
application/libraries/Requests/LICENSE
Normal file
49
application/libraries/Requests/LICENSE
Normal file
@@ -0,0 +1,49 @@
|
||||
Requests
|
||||
========
|
||||
|
||||
Copyright (c) 2010-2012 Ryan McCue and contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
ComplexPie IRI Parser
|
||||
=====================
|
||||
|
||||
Copyright (c) 2007-2010, Geoffrey Sneddon and Steve Minutillo.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the SimplePie Team nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
35
application/libraries/Requests/Proxy.php
Normal file
35
application/libraries/Requests/Proxy.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Proxy connection interface
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
/**
|
||||
* Proxy connection interface
|
||||
*
|
||||
* Implement this interface to handle proxy settings and authentication
|
||||
*
|
||||
* Parameters should be passed via the constructor where possible, as this
|
||||
* makes it much easier for users to use your provider.
|
||||
*
|
||||
* @see Requests_Hooks
|
||||
* @package Requests
|
||||
* @subpackage Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
interface Requests_Proxy {
|
||||
/**
|
||||
* Register hooks as needed
|
||||
*
|
||||
* This method is called in {@see Requests::request} when the user has set
|
||||
* an instance as the 'auth' option. Use this callback to register all the
|
||||
* hooks you'll need.
|
||||
*
|
||||
* @see Requests_Hooks::register
|
||||
* @param Requests_Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Requests_Hooks &$hooks);
|
||||
}
|
||||
150
application/libraries/Requests/Proxy/HTTP.php
Normal file
150
application/libraries/Requests/Proxy/HTTP.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP Proxy connection interface
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTTP Proxy connection interface
|
||||
*
|
||||
* Provides a handler for connection via an HTTP proxy
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
class Requests_Proxy_HTTP implements Requests_Proxy {
|
||||
/**
|
||||
* Proxy host and port
|
||||
*
|
||||
* Notation: "host:port" (eg 127.0.0.1:8080 or someproxy.com:3128)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $proxy;
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $pass;
|
||||
|
||||
/**
|
||||
* Do we need to authenticate? (ie username & password have been provided)
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $use_authentication;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws Requests_Exception On incorrect number of arguments (`authbasicbadargs`)
|
||||
* @param array|null $args Array of user and password. Must have exactly two elements
|
||||
*/
|
||||
public function __construct($args = null) {
|
||||
if (is_string($args)) {
|
||||
$this->proxy = $args;
|
||||
}
|
||||
elseif (is_array($args)) {
|
||||
if (count($args) == 1) {
|
||||
list($this->proxy) = $args;
|
||||
}
|
||||
elseif (count($args) == 3) {
|
||||
list($this->proxy, $this->user, $this->pass) = $args;
|
||||
$this->use_authentication = true;
|
||||
}
|
||||
else {
|
||||
throw new Requests_Exception( 'Invalid number of arguments', 'proxyhttpbadargs');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the necessary callbacks
|
||||
*
|
||||
* @since 1.6
|
||||
* @see curl_before_send
|
||||
* @see fsockopen_remote_socket
|
||||
* @see fsockopen_remote_host_path
|
||||
* @see fsockopen_header
|
||||
* @param Requests_Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Requests_Hooks &$hooks) {
|
||||
$hooks->register('curl.before_send', array(&$this, 'curl_before_send'));
|
||||
|
||||
$hooks->register('fsockopen.remote_socket', array(&$this, 'fsockopen_remote_socket'));
|
||||
$hooks->register('fsockopen.remote_host_path', array(&$this, 'fsockopen_remote_host_path'));
|
||||
if( $this->use_authentication ) {
|
||||
$hooks->register('fsockopen.after_headers', array(&$this, 'fsockopen_header'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cURL parameters before the data is sent
|
||||
*
|
||||
* @since 1.6
|
||||
* @param resource $handle cURL resource
|
||||
*/
|
||||
public function curl_before_send(&$handle) {
|
||||
curl_setopt($handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
curl_setopt($handle, CURLOPT_PROXY, $this->proxy);
|
||||
|
||||
if ($this->use_authentication) {
|
||||
curl_setopt($handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
||||
curl_setopt($handle, CURLOPT_PROXYUSERPWD, $this->get_auth_string());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter remote socket information before opening socket connection
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_remote_socket( &$remote_socket ) {
|
||||
$remote_socket = $this->proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter remote path before getting stream data
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_remote_host_path( &$path, $url ) {
|
||||
$path = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra headers to the request before sending
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_header( &$out ) {
|
||||
$out .= "Proxy-Authorization: Basic " . base64_encode($this->get_auth_string()) . "\r\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication string (user:pass)
|
||||
*
|
||||
* @since 1.6
|
||||
* @return string
|
||||
*/
|
||||
public function get_auth_string() {
|
||||
return $this->user . ':' . $this->pass;
|
||||
}
|
||||
}
|
||||
95
application/libraries/Requests/Response.php
Normal file
95
application/libraries/Requests/Response.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP response class
|
||||
*
|
||||
* Contains a response from Requests::request()
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTTP response class
|
||||
*
|
||||
* Contains a response from Requests::request()
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Response {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->headers = new Requests_Response_Headers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Response body
|
||||
* @var string
|
||||
*/
|
||||
public $body = '';
|
||||
|
||||
/**
|
||||
* Raw HTTP data from the transport
|
||||
* @var string
|
||||
*/
|
||||
public $raw = '';
|
||||
|
||||
/**
|
||||
* Headers, as an associative array
|
||||
* @var array
|
||||
*/
|
||||
public $headers = array();
|
||||
|
||||
/**
|
||||
* Status code, false if non-blocking
|
||||
* @var integer|boolean
|
||||
*/
|
||||
public $status_code = false;
|
||||
|
||||
/**
|
||||
* Whether the request succeeded or not
|
||||
* @var boolean
|
||||
*/
|
||||
public $success = false;
|
||||
|
||||
/**
|
||||
* Number of redirects the request used
|
||||
* @var integer
|
||||
*/
|
||||
public $redirects = 0;
|
||||
|
||||
/**
|
||||
* URL requested
|
||||
* @var string
|
||||
*/
|
||||
public $url = '';
|
||||
|
||||
/**
|
||||
* Previous requests (from redirects)
|
||||
* @var array Array of Requests_Response objects
|
||||
*/
|
||||
public $history = array();
|
||||
|
||||
/**
|
||||
* Cookies from the request
|
||||
*/
|
||||
public $cookies = array();
|
||||
|
||||
/**
|
||||
* Throws an exception if the request was not successful
|
||||
*
|
||||
* @throws Requests_Exception If `$allow_redirects` is false, and code is 3xx (`response.no_redirects`)
|
||||
* @throws Requests_Exception_HTTP On non-successful status code. Exception class corresponds to code (e.g. {@see Requests_Exception_HTTP_404})
|
||||
* @param boolean $allow_redirects Set to false to throw on a 3xx as well
|
||||
*/
|
||||
public function throw_for_status($allow_redirects = true) {
|
||||
if ($this->status_code >= 300 && $this->status_code < 400) {
|
||||
if (!$allow_redirects) {
|
||||
throw new Requests_Exception('Redirection not allowed', 'response.no_redirects', $this);
|
||||
}
|
||||
}
|
||||
|
||||
elseif (!$this->success) {
|
||||
$exception = Requests_Exception_HTTP::get_class($this->status_code);
|
||||
throw new $exception(null, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
95
application/libraries/Requests/Response/Headers.php
Normal file
95
application/libraries/Requests/Response/Headers.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Requests_Response_Headers extends Requests_Utility_CaseInsensitiveDictionary {
|
||||
/**
|
||||
* Get the given header
|
||||
*
|
||||
* Unlike {@see self::getValues()}, this returns a string. If there are
|
||||
* multiple values, it concatenates them with a comma as per RFC2616.
|
||||
*
|
||||
* Avoid using this where commas may be used unquoted in values, such as
|
||||
* Set-Cookie headers.
|
||||
*
|
||||
* @param string $key
|
||||
* @return string Header value
|
||||
*/
|
||||
public function offsetGet($key) {
|
||||
$key = strtolower($key);
|
||||
if (!isset($this->data[$key]))
|
||||
return null;
|
||||
|
||||
return $this->flatten($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given item
|
||||
*
|
||||
* @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
|
||||
*
|
||||
* @param string $key Item name
|
||||
* @param string $value Item value
|
||||
*/
|
||||
public function offsetSet($key, $value) {
|
||||
if ($key === null) {
|
||||
throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
|
||||
}
|
||||
|
||||
$key = strtolower($key);
|
||||
|
||||
if (!isset($this->data[$key])) {
|
||||
$this->data[$key] = array();
|
||||
}
|
||||
|
||||
$this->data[$key][] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values for a given header
|
||||
*
|
||||
* @param string $key
|
||||
* @return array Header values
|
||||
*/
|
||||
public function getValues($key) {
|
||||
$key = strtolower($key);
|
||||
if (!isset($this->data[$key]))
|
||||
return null;
|
||||
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens a value into a string
|
||||
*
|
||||
* Converts an array into a string by imploding values with a comma, as per
|
||||
* RFC2616's rules for folding headers.
|
||||
*
|
||||
* @param string|array $value Value to flatten
|
||||
* @return string Flattened value
|
||||
*/
|
||||
public function flatten($value) {
|
||||
if (is_array($value))
|
||||
$value = implode(',', $value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the data
|
||||
*
|
||||
* Converts the internal
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new Requests_Utility_FilteredIterator($this->data, array($this, 'flatten'));
|
||||
}
|
||||
}
|
||||
151
application/libraries/Requests/SSL.php
Normal file
151
application/libraries/Requests/SSL.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
/**
|
||||
* SSL utilities for Requests
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* SSL utilities for Requests
|
||||
*
|
||||
* Collection of utilities for working with and verifying SSL certificates.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
class Requests_SSL {
|
||||
/**
|
||||
* Verify the certificate against common name and subject alternative names
|
||||
*
|
||||
* Unfortunately, PHP doesn't check the certificate against the alternative
|
||||
* names, leading things like 'https://www.github.com/' to be invalid.
|
||||
* Instead
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
|
||||
*
|
||||
* @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
|
||||
* @param string $host Host name to verify against
|
||||
* @param resource $context Stream context
|
||||
* @return bool
|
||||
*/
|
||||
public static function verify_certificate($host, $cert) {
|
||||
// Calculate the valid wildcard match if the host is not an IP address
|
||||
$parts = explode('.', $host);
|
||||
if (ip2long($host) === false) {
|
||||
$parts[0] = '*';
|
||||
}
|
||||
$wildcard = implode('.', $parts);
|
||||
|
||||
$has_dns_alt = false;
|
||||
|
||||
// Check the subjectAltName
|
||||
if (!empty($cert['extensions']) && !empty($cert['extensions']['subjectAltName'])) {
|
||||
$altnames = explode(',', $cert['extensions']['subjectAltName']);
|
||||
foreach ($altnames as $altname) {
|
||||
$altname = trim($altname);
|
||||
if (strpos($altname, 'DNS:') !== 0)
|
||||
continue;
|
||||
|
||||
$has_dns_alt = true;
|
||||
|
||||
// Strip the 'DNS:' prefix and trim whitespace
|
||||
$altname = trim(substr($altname, 4));
|
||||
|
||||
// Check for a match
|
||||
if (self::match_domain($host, $altname) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to checking the common name if we didn't get any dNSName
|
||||
// alt names, as per RFC2818
|
||||
if (!$has_dns_alt && !empty($cert['subject']['CN'])) {
|
||||
// Check for a match
|
||||
if (self::match_domain($host, $cert['subject']['CN']) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that a reference name is valid
|
||||
*
|
||||
* Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
|
||||
* - Wildcards can only occur in a name with more than 3 components
|
||||
* - Wildcards can only occur as the last character in the first
|
||||
* component
|
||||
* - Wildcards may be preceded by additional characters
|
||||
*
|
||||
* We modify these rules to be a bit stricter and only allow the wildcard
|
||||
* character to be the full first component; that is, with the exclusion of
|
||||
* the third rule.
|
||||
*
|
||||
* @param string $reference Reference dNSName
|
||||
* @return boolean Is the name valid?
|
||||
*/
|
||||
public static function verify_reference_name($reference) {
|
||||
$parts = explode('.', $reference);
|
||||
|
||||
// Check the first part of the name
|
||||
$first = array_shift($parts);
|
||||
|
||||
if (strpos($first, '*') !== false) {
|
||||
// Check that the wildcard is the full part
|
||||
if ($first !== '*') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that we have at least 3 components (including first)
|
||||
if (count($parts) < 2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the remaining parts
|
||||
foreach ($parts as $part) {
|
||||
if (strpos($part, '*') !== false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing found, verified!
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a hostname against a dNSName reference
|
||||
*
|
||||
* @param string $host Requested host
|
||||
* @param string $reference dNSName to match against
|
||||
* @return boolean Does the domain match?
|
||||
*/
|
||||
public static function match_domain($host, $reference) {
|
||||
// Check if the reference is blacklisted first
|
||||
if (self::verify_reference_name($reference) !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for a direct match
|
||||
if ($host === $reference) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate the valid wildcard match if the host is not an IP address
|
||||
// Also validates that the host has 3 parts or more, as per Firefox's
|
||||
// ruleset.
|
||||
if (ip2long($host) === false) {
|
||||
$parts = explode('.', $host);
|
||||
$parts[0] = '*';
|
||||
$wildcard = implode('.', $parts);
|
||||
if ($wildcard === $reference) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
253
application/libraries/Requests/Session.php
Normal file
253
application/libraries/Requests/Session.php
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
/**
|
||||
* Session handler for persistent requests and default parameters
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Session Handler
|
||||
*/
|
||||
|
||||
/**
|
||||
* Session handler for persistent requests and default parameters
|
||||
*
|
||||
* Allows various options to be set as default values, and merges both the
|
||||
* options and URL properties together. A base URL can be set for all requests,
|
||||
* with all subrequests resolved from this. Base options can be set (including
|
||||
* a shared cookie jar), then overridden for individual requests.
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Session Handler
|
||||
*/
|
||||
class Requests_Session {
|
||||
/**
|
||||
* Base URL for requests
|
||||
*
|
||||
* URLs will be made absolute using this as the base
|
||||
* @var string|null
|
||||
*/
|
||||
public $url = null;
|
||||
|
||||
/**
|
||||
* Base headers for requests
|
||||
* @var array
|
||||
*/
|
||||
public $headers = array();
|
||||
|
||||
/**
|
||||
* Base data for requests
|
||||
*
|
||||
* If both the base data and the per-request data are arrays, the data will
|
||||
* be merged before sending the request.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $data = array();
|
||||
|
||||
/**
|
||||
* Base options for requests
|
||||
*
|
||||
* The base options are merged with the per-request data for each request.
|
||||
* The only default option is a shared cookie jar between requests.
|
||||
*
|
||||
* Values here can also be set directly via properties on the Session
|
||||
* object, e.g. `$session->useragent = 'X';`
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = array();
|
||||
|
||||
/**
|
||||
* Create a new session
|
||||
*
|
||||
* @param string|null $url Base URL for requests
|
||||
* @param array $headers Default headers for requests
|
||||
* @param array $data Default data for requests
|
||||
* @param array $options Default options for requests
|
||||
*/
|
||||
public function __construct($url = null, $headers = array(), $data = array(), $options = array()) {
|
||||
$this->url = $url;
|
||||
$this->headers = $headers;
|
||||
$this->data = $data;
|
||||
$this->options = $options;
|
||||
|
||||
if (empty($this->options['cookies'])) {
|
||||
$this->options['cookies'] = new Requests_Cookie_Jar();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a property's value
|
||||
*
|
||||
* @param string $key Property key
|
||||
* @return mixed|null Property value, null if none found
|
||||
*/
|
||||
public function __get($key) {
|
||||
if (isset($this->options[$key]))
|
||||
return $this->options[$key];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a property's value
|
||||
*
|
||||
* @param string $key Property key
|
||||
* @param mixed $value Property value
|
||||
*/
|
||||
public function __set($key, $value) {
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a property's value
|
||||
*
|
||||
* @param string $key Property key
|
||||
*/
|
||||
public function __isset($key) {
|
||||
return isset($this->options[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a property's value
|
||||
*
|
||||
* @param string $key Property key
|
||||
*/
|
||||
public function __unset($key) {
|
||||
$this->options[$key] = null;
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @see request()
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $options
|
||||
* @return Requests_Response
|
||||
*/
|
||||
/**
|
||||
* Send a GET request
|
||||
*/
|
||||
public function get($url, $headers = array(), $options = array()) {
|
||||
return $this->request($url, $headers, null, Requests::GET, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a HEAD request
|
||||
*/
|
||||
public function head($url, $headers = array(), $options = array()) {
|
||||
return $this->request($url, $headers, null, Requests::HEAD, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DELETE request
|
||||
*/
|
||||
public function delete($url, $headers = array(), $options = array()) {
|
||||
return $this->request($url, $headers, null, Requests::DELETE, $options);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @see request()
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $data
|
||||
* @param array $options
|
||||
* @return Requests_Response
|
||||
*/
|
||||
/**
|
||||
* Send a POST request
|
||||
*/
|
||||
public function post($url, $headers = array(), $data = array(), $options = array()) {
|
||||
return $this->request($url, $headers, $data, Requests::POST, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PUT request
|
||||
*/
|
||||
public function put($url, $headers = array(), $data = array(), $options = array()) {
|
||||
return $this->request($url, $headers, $data, Requests::PUT, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PATCH request
|
||||
*
|
||||
* Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
|
||||
* specification recommends that should send an ETag
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc5789
|
||||
*/
|
||||
public function patch($url, $headers, $data = array(), $options = array()) {
|
||||
return $this->request($url, $headers, $data, Requests::PATCH, $options);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Main interface for HTTP requests
|
||||
*
|
||||
* This method initiates a request and sends it via a transport before
|
||||
* parsing.
|
||||
*
|
||||
* @see Requests::request()
|
||||
*
|
||||
* @throws Requests_Exception On invalid URLs (`nonhttp`)
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Extra headers to send with the request
|
||||
* @param array $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
|
||||
* @param string $type HTTP request type (use Requests constants)
|
||||
* @param array $options Options for the request (see {@see Requests::request})
|
||||
* @return Requests_Response
|
||||
*/
|
||||
public function request($url, $headers = array(), $data = array(), $type = Requests::GET, $options = array()) {
|
||||
$request = $this->merge_request(compact('url', 'headers', 'data', 'options'));
|
||||
|
||||
return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple HTTP requests simultaneously
|
||||
*
|
||||
* @see Requests::request_multiple()
|
||||
*
|
||||
* @param array $requests Requests data (see {@see Requests::request_multiple})
|
||||
* @param array $options Global and default options (see {@see Requests::request})
|
||||
* @return array Responses (either Requests_Response or a Requests_Exception object)
|
||||
*/
|
||||
public function request_multiple($requests, $options = array()) {
|
||||
foreach ($requests as $key => $request) {
|
||||
$requests[$key] = $this->merge_request($request, false);
|
||||
}
|
||||
|
||||
$options = array_merge($this->options, $options);
|
||||
|
||||
// Disallow forcing the type, as that's a per request setting
|
||||
unset($options['type']);
|
||||
|
||||
return Requests::request_multiple($requests, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a request's data with the default data
|
||||
*
|
||||
* @param array $request Request data (same form as {@see request_multiple})
|
||||
* @param boolean $merge_options Should we merge options as well?
|
||||
* @return array Request data
|
||||
*/
|
||||
protected function merge_request($request, $merge_options = true) {
|
||||
if ($this->url !== null) {
|
||||
$request['url'] = Requests_IRI::absolutize($this->url, $request['url']);
|
||||
$request['url'] = $request['url']->uri;
|
||||
}
|
||||
$request['headers'] = array_merge($this->headers, $request['headers']);
|
||||
|
||||
if (is_array($request['data']) && is_array($this->data)) {
|
||||
$request['data'] = array_merge($this->data, $request['data']);
|
||||
}
|
||||
|
||||
if ($merge_options !== false) {
|
||||
$request['options'] = array_merge($this->options, $request['options']);
|
||||
|
||||
// Disallow forcing the type, as that's a per request setting
|
||||
unset($request['options']['type']);
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
41
application/libraries/Requests/Transport.php
Normal file
41
application/libraries/Requests/Transport.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Base HTTP transport
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Transport
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base HTTP transport
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Transport
|
||||
*/
|
||||
interface Requests_Transport {
|
||||
/**
|
||||
* Perform a request
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see Requests::response()} for documentation
|
||||
* @return string Raw HTTP result
|
||||
*/
|
||||
public function request($url, $headers = array(), $data = array(), $options = array());
|
||||
|
||||
/**
|
||||
* Send multiple requests simultaneously
|
||||
*
|
||||
* @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
|
||||
* @param array $options Global options, see {@see Requests::response()} for documentation
|
||||
* @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
|
||||
*/
|
||||
public function request_multiple($requests, $options);
|
||||
|
||||
/**
|
||||
* Self-test whether the transport can be used
|
||||
* @return bool
|
||||
*/
|
||||
public static function test();
|
||||
}
|
||||
349
application/libraries/Requests/Transport/cURL.php
Normal file
349
application/libraries/Requests/Transport/cURL.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
/**
|
||||
* cURL HTTP transport
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Transport
|
||||
*/
|
||||
|
||||
/**
|
||||
* cURL HTTP transport
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Transport
|
||||
*/
|
||||
class Requests_Transport_cURL implements Requests_Transport {
|
||||
/**
|
||||
* Raw HTTP data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $headers = '';
|
||||
|
||||
/**
|
||||
* Information on the current request
|
||||
*
|
||||
* @var array cURL information array, see {@see http://php.net/curl_getinfo}
|
||||
*/
|
||||
public $info;
|
||||
|
||||
/**
|
||||
* Version string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* cURL handle
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $fp;
|
||||
|
||||
/**
|
||||
* Have we finished the headers yet?
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $done_headers = false;
|
||||
|
||||
/**
|
||||
* If streaming to a file, keep the file pointer
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $stream_handle;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$curl = curl_version();
|
||||
$this->version = $curl['version'];
|
||||
$this->fp = curl_init();
|
||||
|
||||
curl_setopt($this->fp, CURLOPT_HEADER, false);
|
||||
curl_setopt($this->fp, CURLOPT_RETURNTRANSFER, 1);
|
||||
if (version_compare($this->version, '7.10.5', '>=')) {
|
||||
curl_setopt($this->fp, CURLOPT_ENCODING, '');
|
||||
}
|
||||
if (version_compare($this->version, '7.19.4', '>=')) {
|
||||
curl_setopt($this->fp, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a request
|
||||
*
|
||||
* @throws Requests_Exception On a cURL error (`curlerror`)
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see Requests::response()} for documentation
|
||||
* @return string Raw HTTP result
|
||||
*/
|
||||
public function request($url, $headers = array(), $data = array(), $options = array()) {
|
||||
$this->setup_handle($url, $headers, $data, $options);
|
||||
|
||||
$options['hooks']->dispatch('curl.before_send', array(&$this->fp));
|
||||
|
||||
if ($options['filename'] !== false) {
|
||||
$this->stream_handle = fopen($options['filename'], 'wb');
|
||||
curl_setopt($this->fp, CURLOPT_FILE, $this->stream_handle);
|
||||
}
|
||||
|
||||
if (isset($options['verify'])) {
|
||||
if ($options['verify'] === false) {
|
||||
curl_setopt($this->fp, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($this->fp, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
|
||||
} elseif (is_string($options['verify'])) {
|
||||
curl_setopt($this->fp, CURLOPT_CAINFO, $options['verify']);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['verifyname']) && $options['verifyname'] === false) {
|
||||
curl_setopt($this->fp, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
$response = curl_exec($this->fp);
|
||||
|
||||
$options['hooks']->dispatch('curl.after_send', array(&$fake_headers));
|
||||
|
||||
if (curl_errno($this->fp) === 23 || curl_errno($this->fp) === 61) {
|
||||
curl_setopt($this->fp, CURLOPT_ENCODING, 'none');
|
||||
$response = curl_exec($this->fp);
|
||||
}
|
||||
|
||||
$this->process_response($response, $options);
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple requests simultaneously
|
||||
*
|
||||
* @param array $requests Request data
|
||||
* @param array $options Global options
|
||||
* @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
|
||||
*/
|
||||
public function request_multiple($requests, $options) {
|
||||
$multihandle = curl_multi_init();
|
||||
$subrequests = array();
|
||||
$subhandles = array();
|
||||
|
||||
$class = get_class($this);
|
||||
foreach ($requests as $id => $request) {
|
||||
$subrequests[$id] = new $class();
|
||||
$subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
|
||||
$request['options']['hooks']->dispatch('curl.before_multi_add', array(&$subhandles[$id]));
|
||||
curl_multi_add_handle($multihandle, $subhandles[$id]);
|
||||
}
|
||||
|
||||
$completed = 0;
|
||||
$responses = array();
|
||||
|
||||
$request['options']['hooks']->dispatch('curl.before_multi_exec', array(&$multihandle));
|
||||
|
||||
do {
|
||||
$active = false;
|
||||
|
||||
do {
|
||||
$status = curl_multi_exec($multihandle, $active);
|
||||
}
|
||||
while ($status === CURLM_CALL_MULTI_PERFORM);
|
||||
|
||||
$to_process = array();
|
||||
|
||||
// Read the information as needed
|
||||
while ($done = curl_multi_info_read($multihandle)) {
|
||||
$key = array_search($done['handle'], $subhandles, true);
|
||||
if (!isset($to_process[$key])) {
|
||||
$to_process[$key] = $done;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the finished requests before we start getting the new ones
|
||||
foreach ($to_process as $key => $done) {
|
||||
$options = $requests[$key]['options'];
|
||||
$responses[$key] = $subrequests[$key]->process_response(curl_multi_getcontent($done['handle']), $options);
|
||||
|
||||
$options['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$key], $requests[$key]));
|
||||
|
||||
curl_multi_remove_handle($multihandle, $done['handle']);
|
||||
curl_close($done['handle']);
|
||||
|
||||
if (!is_string($responses[$key])) {
|
||||
$options['hooks']->dispatch('multiple.request.complete', array(&$responses[$key], $key));
|
||||
}
|
||||
$completed++;
|
||||
}
|
||||
}
|
||||
while ($active || $completed < count($subrequests));
|
||||
|
||||
$request['options']['hooks']->dispatch('curl.after_multi_exec', array(&$multihandle));
|
||||
|
||||
curl_multi_close($multihandle);
|
||||
|
||||
return $responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cURL handle for use in a multi-request
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see Requests::response()} for documentation
|
||||
* @return resource Subrequest's cURL handle
|
||||
*/
|
||||
public function &get_subrequest_handle($url, $headers, $data, $options) {
|
||||
$this->setup_handle($url, $headers, $data, $options);
|
||||
|
||||
if ($options['filename'] !== false) {
|
||||
$this->stream_handle = fopen($options['filename'], 'wb');
|
||||
curl_setopt($this->fp, CURLOPT_FILE, $this->stream_handle);
|
||||
}
|
||||
|
||||
return $this->fp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the cURL handle for the given data
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see Requests::response()} for documentation
|
||||
*/
|
||||
protected function setup_handle($url, $headers, $data, $options) {
|
||||
$options['hooks']->dispatch('curl.before_request', array(&$this->fp));
|
||||
|
||||
$headers = Requests::flatten($headers);
|
||||
if (in_array($options['type'], array(Requests::HEAD, Requests::GET, Requests::DELETE)) & !empty($data)) {
|
||||
$url = self::format_get($url, $data);
|
||||
}
|
||||
elseif (!empty($data) && !is_string($data)) {
|
||||
$data = http_build_query($data, null, '&');
|
||||
}
|
||||
|
||||
switch ($options['type']) {
|
||||
case Requests::POST:
|
||||
curl_setopt($this->fp, CURLOPT_POST, true);
|
||||
curl_setopt($this->fp, CURLOPT_POSTFIELDS, $data);
|
||||
break;
|
||||
case Requests::PATCH:
|
||||
case Requests::PUT:
|
||||
curl_setopt($this->fp, CURLOPT_CUSTOMREQUEST, $options['type']);
|
||||
curl_setopt($this->fp, CURLOPT_POSTFIELDS, $data);
|
||||
break;
|
||||
case Requests::DELETE:
|
||||
curl_setopt($this->fp, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
break;
|
||||
case Requests::HEAD:
|
||||
curl_setopt($this->fp, CURLOPT_NOBODY, true);
|
||||
break;
|
||||
}
|
||||
|
||||
curl_setopt($this->fp, CURLOPT_URL, $url);
|
||||
curl_setopt($this->fp, CURLOPT_TIMEOUT, $options['timeout']);
|
||||
curl_setopt($this->fp, CURLOPT_CONNECTTIMEOUT, $options['timeout']);
|
||||
curl_setopt($this->fp, CURLOPT_REFERER, $url);
|
||||
curl_setopt($this->fp, CURLOPT_USERAGENT, $options['useragent']);
|
||||
curl_setopt($this->fp, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
if (true === $options['blocking']) {
|
||||
curl_setopt($this->fp, CURLOPT_HEADERFUNCTION, array(&$this, 'stream_headers'));
|
||||
}
|
||||
}
|
||||
|
||||
public function process_response($response, $options) {
|
||||
if ($options['blocking'] === false) {
|
||||
curl_close($this->fp);
|
||||
$fake_headers = '';
|
||||
$options['hooks']->dispatch('curl.after_request', array(&$fake_headers));
|
||||
return false;
|
||||
}
|
||||
if ($options['filename'] !== false) {
|
||||
fclose($this->stream_handle);
|
||||
$this->headers = trim($this->headers);
|
||||
}
|
||||
else {
|
||||
$this->headers .= $response;
|
||||
}
|
||||
|
||||
if (curl_errno($this->fp)) {
|
||||
throw new Requests_Exception('cURL error ' . curl_errno($this->fp) . ': ' . curl_error($this->fp), 'curlerror', $this->fp);
|
||||
return;
|
||||
}
|
||||
$this->info = curl_getinfo($this->fp);
|
||||
|
||||
curl_close($this->fp);
|
||||
$options['hooks']->dispatch('curl.after_request', array(&$this->headers));
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the headers as they are received
|
||||
*
|
||||
* @param resource $handle cURL resource
|
||||
* @param string $headers Header string
|
||||
* @return integer Length of provided header
|
||||
*/
|
||||
protected function stream_headers($handle, $headers) {
|
||||
// Why do we do this? cURL will send both the final response and any
|
||||
// interim responses, such as a 100 Continue. We don't need that.
|
||||
// (We may want to keep this somewhere just in case)
|
||||
if ($this->done_headers) {
|
||||
$this->headers = '';
|
||||
$this->done_headers = false;
|
||||
}
|
||||
$this->headers .= $headers;
|
||||
|
||||
if ($headers === "\r\n") {
|
||||
$this->done_headers = true;
|
||||
}
|
||||
return strlen($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a URL given GET data
|
||||
*
|
||||
* @param string $url
|
||||
* @param array|object $data Data to build query using, see {@see http://php.net/http_build_query}
|
||||
* @return string URL with data
|
||||
*/
|
||||
protected static function format_get($url, $data) {
|
||||
if (!empty($data)) {
|
||||
$url_parts = parse_url($url);
|
||||
if (empty($url_parts['query'])) {
|
||||
$query = $url_parts['query'] = '';
|
||||
}
|
||||
else {
|
||||
$query = $url_parts['query'];
|
||||
}
|
||||
|
||||
$query .= '&' . http_build_query($data, null, '&');
|
||||
$query = trim($query, '&');
|
||||
|
||||
if (empty($url_parts['query'])) {
|
||||
$url .= '?' . $query;
|
||||
}
|
||||
else {
|
||||
$url = str_replace($url_parts['query'], $query, $url);
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this transport is valid
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return boolean True if the transport is valid, false otherwise.
|
||||
*/
|
||||
public static function test() {
|
||||
return (function_exists('curl_init') && function_exists('curl_exec'));
|
||||
}
|
||||
}
|
||||
3554
application/libraries/Requests/Transport/cacert.pem
Normal file
3554
application/libraries/Requests/Transport/cacert.pem
Normal file
File diff suppressed because it is too large
Load Diff
381
application/libraries/Requests/Transport/fsockopen.php
Normal file
381
application/libraries/Requests/Transport/fsockopen.php
Normal file
@@ -0,0 +1,381 @@
|
||||
<?php
|
||||
/**
|
||||
* fsockopen HTTP transport
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Transport
|
||||
*/
|
||||
|
||||
/**
|
||||
* fsockopen HTTP transport
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Transport
|
||||
*/
|
||||
class Requests_Transport_fsockopen implements Requests_Transport {
|
||||
/**
|
||||
* Raw HTTP data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $headers = '';
|
||||
|
||||
/**
|
||||
* Stream metadata
|
||||
*
|
||||
* @var array Associative array of properties, see {@see http://php.net/stream_get_meta_data}
|
||||
*/
|
||||
public $info;
|
||||
|
||||
protected $connect_error = '';
|
||||
|
||||
/**
|
||||
* Perform a request
|
||||
*
|
||||
* @throws Requests_Exception On failure to connect to socket (`fsockopenerror`)
|
||||
* @throws Requests_Exception On socket timeout (`timeout`)
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see Requests::response()} for documentation
|
||||
* @return string Raw HTTP result
|
||||
*/
|
||||
public function request($url, $headers = array(), $data = array(), $options = array()) {
|
||||
$options['hooks']->dispatch('fsockopen.before_request');
|
||||
|
||||
$url_parts = parse_url($url);
|
||||
$host = $url_parts['host'];
|
||||
$context = stream_context_create();
|
||||
$verifyname = false;
|
||||
|
||||
// HTTPS support
|
||||
if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
|
||||
$remote_socket = 'ssl://' . $host;
|
||||
$url_parts['port'] = 443;
|
||||
|
||||
$context_options = array(
|
||||
'verify_peer' => true,
|
||||
// 'CN_match' => $host,
|
||||
'capture_peer_cert' => true
|
||||
);
|
||||
$verifyname = true;
|
||||
|
||||
// SNI, if enabled (OpenSSL >=0.9.8j)
|
||||
if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) {
|
||||
$context_options['SNI_enabled'] = true;
|
||||
if (isset($options['verifyname']) && $options['verifyname'] === false) {
|
||||
$context_options['SNI_enabled'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['verify'])) {
|
||||
if ($options['verify'] === false) {
|
||||
$context_options['verify_peer'] = false;
|
||||
} elseif (is_string($options['verify'])) {
|
||||
$context_options['cafile'] = $options['verify'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['verifyname']) && $options['verifyname'] === false) {
|
||||
$verifyname = false;
|
||||
}
|
||||
|
||||
stream_context_set_option($context, array('ssl' => $context_options));
|
||||
}
|
||||
else {
|
||||
$remote_socket = 'tcp://' . $host;
|
||||
}
|
||||
|
||||
$proxy = isset( $options['proxy'] );
|
||||
$proxy_auth = $proxy && isset( $options['proxy_username'] ) && isset( $options['proxy_password'] );
|
||||
|
||||
if (!isset($url_parts['port'])) {
|
||||
$url_parts['port'] = 80;
|
||||
}
|
||||
$remote_socket .= ':' . $url_parts['port'];
|
||||
|
||||
set_error_handler(array($this, 'connect_error_handler'), E_WARNING | E_NOTICE);
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.remote_socket', array(&$remote_socket));
|
||||
|
||||
$fp = stream_socket_client($remote_socket, $errno, $errstr, $options['timeout'], STREAM_CLIENT_CONNECT, $context);
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
if ($verifyname) {
|
||||
if (!$this->verify_certificate_from_context($host, $context)) {
|
||||
throw new Requests_Exception('SSL certificate did not match the requested domain name', 'ssl.no_match');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$fp) {
|
||||
if ($errno === 0) {
|
||||
// Connection issue
|
||||
throw new Requests_Exception(rtrim($this->connect_error), 'fsockopen.connect_error');
|
||||
}
|
||||
else {
|
||||
throw new Requests_Exception($errstr, 'fsockopenerror');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$request_body = '';
|
||||
$out = '';
|
||||
switch ($options['type']) {
|
||||
case Requests::POST:
|
||||
case Requests::PUT:
|
||||
case Requests::PATCH:
|
||||
if (isset($url_parts['path'])) {
|
||||
$path = $url_parts['path'];
|
||||
if (isset($url_parts['query'])) {
|
||||
$path .= '?' . $url_parts['query'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
$path = '/';
|
||||
}
|
||||
|
||||
$options['hooks']->dispatch( 'fsockopen.remote_host_path', array( &$path, $url ) );
|
||||
$out = $options['type'] . " $path HTTP/1.0\r\n";
|
||||
|
||||
if (is_array($data)) {
|
||||
$request_body = http_build_query($data, null, '&');
|
||||
}
|
||||
else {
|
||||
$request_body = $data;
|
||||
}
|
||||
if (empty($headers['Content-Length'])) {
|
||||
$headers['Content-Length'] = strlen($request_body);
|
||||
}
|
||||
if (empty($headers['Content-Type'])) {
|
||||
$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
|
||||
}
|
||||
break;
|
||||
case Requests::HEAD:
|
||||
case Requests::GET:
|
||||
case Requests::DELETE:
|
||||
$path = self::format_get($url_parts, $data);
|
||||
$options['hooks']->dispatch('fsockopen.remote_host_path', array(&$path, $url));
|
||||
$out = $options['type'] . " $path HTTP/1.0\r\n";
|
||||
break;
|
||||
}
|
||||
$out .= "Host: {$url_parts['host']}";
|
||||
|
||||
if ($url_parts['port'] !== 80) {
|
||||
$out .= ":{$url_parts['port']}";
|
||||
}
|
||||
$out .= "\r\n";
|
||||
|
||||
$out .= "User-Agent: {$options['useragent']}\r\n";
|
||||
$accept_encoding = $this->accept_encoding();
|
||||
if (!empty($accept_encoding)) {
|
||||
$out .= "Accept-Encoding: $accept_encoding\r\n";
|
||||
}
|
||||
|
||||
$headers = Requests::flatten($headers);
|
||||
|
||||
if (!empty($headers)) {
|
||||
$out .= implode($headers, "\r\n") . "\r\n";
|
||||
}
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.after_headers', array(&$out));
|
||||
|
||||
if (substr($out, -2) !== "\r\n") {
|
||||
$out .= "\r\n";
|
||||
}
|
||||
|
||||
$out .= "Connection: Close\r\n\r\n" . $request_body;
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.before_send', array(&$out));
|
||||
|
||||
fwrite($fp, $out);
|
||||
$options['hooks']->dispatch('fsockopen.after_send', array(&$fake_headers));
|
||||
|
||||
if (!$options['blocking']) {
|
||||
fclose($fp);
|
||||
$fake_headers = '';
|
||||
$options['hooks']->dispatch('fsockopen.after_request', array(&$fake_headers));
|
||||
return '';
|
||||
}
|
||||
stream_set_timeout($fp, $options['timeout']);
|
||||
|
||||
$this->info = stream_get_meta_data($fp);
|
||||
|
||||
$this->headers = '';
|
||||
$this->info = stream_get_meta_data($fp);
|
||||
if (!$options['filename']) {
|
||||
while (!feof($fp)) {
|
||||
$this->info = stream_get_meta_data($fp);
|
||||
if ($this->info['timed_out']) {
|
||||
throw new Requests_Exception('fsocket timed out', 'timeout');
|
||||
}
|
||||
|
||||
$this->headers .= fread($fp, 1160);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$download = fopen($options['filename'], 'wb');
|
||||
$doingbody = false;
|
||||
$response = '';
|
||||
while (!feof($fp)) {
|
||||
$this->info = stream_get_meta_data($fp);
|
||||
if ($this->info['timed_out']) {
|
||||
throw new Requests_Exception('fsocket timed out', 'timeout');
|
||||
}
|
||||
|
||||
$block = fread($fp, 1160);
|
||||
if ($doingbody) {
|
||||
fwrite($download, $block);
|
||||
}
|
||||
else {
|
||||
$response .= $block;
|
||||
if (strpos($response, "\r\n\r\n")) {
|
||||
list($this->headers, $block) = explode("\r\n\r\n", $response, 2);
|
||||
$doingbody = true;
|
||||
fwrite($download, $block);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($download);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.after_request', array(&$this->headers));
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple requests simultaneously
|
||||
*
|
||||
* @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
|
||||
* @param array $options Global options, see {@see Requests::response()} for documentation
|
||||
* @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
|
||||
*/
|
||||
public function request_multiple($requests, $options) {
|
||||
$responses = array();
|
||||
$class = get_class($this);
|
||||
foreach ($requests as $id => $request) {
|
||||
try {
|
||||
$handler = new $class();
|
||||
$responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
|
||||
|
||||
$request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request));
|
||||
}
|
||||
catch (Requests_Exception $e) {
|
||||
$responses[$id] = $e;
|
||||
}
|
||||
|
||||
if (!is_string($responses[$id])) {
|
||||
$request['options']['hooks']->dispatch('multiple.request.complete', array(&$responses[$id], $id));
|
||||
}
|
||||
}
|
||||
|
||||
return $responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the encodings we can accept
|
||||
*
|
||||
* @return string Accept-Encoding header value
|
||||
*/
|
||||
protected static function accept_encoding() {
|
||||
$type = array();
|
||||
if (function_exists('gzinflate')) {
|
||||
$type[] = 'deflate;q=1.0';
|
||||
}
|
||||
|
||||
if (function_exists('gzuncompress')) {
|
||||
$type[] = 'compress;q=0.5';
|
||||
}
|
||||
|
||||
$type[] = 'gzip;q=0.5';
|
||||
|
||||
return implode(', ', $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a URL given GET data
|
||||
*
|
||||
* @param array $url_parts
|
||||
* @param array|object $data Data to build query using, see {@see http://php.net/http_build_query}
|
||||
* @return string URL with data
|
||||
*/
|
||||
protected static function format_get($url_parts, $data) {
|
||||
if (!empty($data)) {
|
||||
if (empty($url_parts['query']))
|
||||
$url_parts['query'] = '';
|
||||
|
||||
$url_parts['query'] .= '&' . http_build_query($data, null, '&');
|
||||
$url_parts['query'] = trim($url_parts['query'], '&');
|
||||
}
|
||||
if (isset($url_parts['path'])) {
|
||||
if (isset($url_parts['query'])) {
|
||||
$get = $url_parts['path'] . '?' . $url_parts['query'];
|
||||
}
|
||||
else {
|
||||
$get = $url_parts['path'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
$get = '/';
|
||||
}
|
||||
return $get;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler for stream_socket_client()
|
||||
*
|
||||
* @param int $errno Error number (e.g. E_WARNING)
|
||||
* @param string $errstr Error message
|
||||
*/
|
||||
public function connect_error_handler($errno, $errstr) {
|
||||
// Double-check we can handle it
|
||||
if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) {
|
||||
// Return false to indicate the default error handler should engage
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->connect_error .= $errstr . "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the certificate against common name and subject alternative names
|
||||
*
|
||||
* Unfortunately, PHP doesn't check the certificate against the alternative
|
||||
* names, leading things like 'https://www.github.com/' to be invalid.
|
||||
* Instead
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
|
||||
*
|
||||
* @throws Requests_Exception On failure to connect via TLS (`fsockopen.ssl.connect_error`)
|
||||
* @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
|
||||
* @param string $host Host name to verify against
|
||||
* @param resource $context Stream context
|
||||
* @return bool
|
||||
*/
|
||||
public function verify_certificate_from_context($host, $context) {
|
||||
$meta = stream_context_get_options($context);
|
||||
|
||||
// If we don't have SSL options, then we couldn't make the connection at
|
||||
// all
|
||||
if (empty($meta) || empty($meta['ssl']) || empty($meta['ssl']['peer_certificate'])) {
|
||||
throw new Requests_Exception(rtrim($this->connect_error), 'ssl.connect_error');
|
||||
}
|
||||
|
||||
$cert = openssl_x509_parse($meta['ssl']['peer_certificate']);
|
||||
|
||||
return Requests_SSL::verify_certificate($host, $cert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this transport is valid
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return boolean True if the transport is valid, false otherwise.
|
||||
*/
|
||||
public static function test() {
|
||||
return function_exists('fsockopen');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
class Requests_Utility_CaseInsensitiveDictionary implements ArrayAccess, IteratorAggregate {
|
||||
/**
|
||||
* Actual item data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* Check if the given item exists
|
||||
*
|
||||
* @param string $key Item key
|
||||
* @return boolean Does the item exist?
|
||||
*/
|
||||
public function offsetExists($key) {
|
||||
$key = strtolower($key);
|
||||
return isset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the item
|
||||
*
|
||||
* @param string $key Item key
|
||||
* @return string Item value
|
||||
*/
|
||||
public function offsetGet($key) {
|
||||
$key = strtolower($key);
|
||||
if (!isset($this->data[$key]))
|
||||
return null;
|
||||
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given item
|
||||
*
|
||||
* @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
|
||||
*
|
||||
* @param string $key Item name
|
||||
* @param string $value Item value
|
||||
*/
|
||||
public function offsetSet($key, $value) {
|
||||
if ($key === null) {
|
||||
throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
|
||||
}
|
||||
|
||||
$key = strtolower($key);
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the given header
|
||||
*
|
||||
* @param string $key
|
||||
*/
|
||||
public function offsetUnset($key) {
|
||||
unset($this->data[strtolower($key)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the data
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the headers as an array
|
||||
*
|
||||
* @return array Header data
|
||||
*/
|
||||
public function getAll() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
38
application/libraries/Requests/Utility/FilteredIterator.php
Normal file
38
application/libraries/Requests/Utility/FilteredIterator.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Iterator for arrays requiring filtered values
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
|
||||
/**
|
||||
* Iterator for arrays requiring filtered values
|
||||
*
|
||||
* @package Requests
|
||||
* @subpackage Utilities
|
||||
*/
|
||||
class Requests_Utility_FilteredIterator extends ArrayIterator {
|
||||
/**
|
||||
* Create a new iterator
|
||||
*
|
||||
* @param array $data
|
||||
* @param callable $callback Callback to be called on each value
|
||||
*/
|
||||
public function __construct($data, $callback) {
|
||||
parent::__construct($data);
|
||||
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current item's value after filtering
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function current() {
|
||||
$value = parent::current();
|
||||
$value = call_user_func($this->callback, $value);
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user