From b22fc5b74aecd505d4e2df01258171fc65d312cf Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 2 Nov 2009 06:56:31 -0800 Subject: Revert "Rebuilt HTTPClient class as an extension of PEAR HTTP_Request2 package, adding redirect handling and convenience functions." Going to restructure a little more before finalizing this... This reverts commit fa37967858c3c29000797e510e5f98aca8ab558f. --- extlib/Net/URL2.php | 471 ++++++++++++++++++++-------------------------------- 1 file changed, 178 insertions(+), 293 deletions(-) (limited to 'extlib/Net') diff --git a/extlib/Net/URL2.php b/extlib/Net/URL2.php index f7fbcd9ce..7a654aed8 100644 --- a/extlib/Net/URL2.php +++ b/extlib/Net/URL2.php @@ -1,58 +1,44 @@ | +// +-----------------------------------------------------------------------+ +// +// $Id: URL2.php,v 1.10 2008/04/26 21:57:08 schmidt Exp $ +// +// Net_URL2 Class (PHP5 Only) + +// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php /** - * Net_URL2, a class representing a URL as per RFC 3986. - * - * PHP version 5 - * - * LICENSE: - * - * Copyright (c) 2007-2009, Peytz & Co. A/S - * 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 PHP_LexerGenerator 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 OWNER OR - * 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. - * - * @category Networking - * @package Net_URL2 - * @author Christian Schmidt - * @copyright 2007-2008 Peytz & Co. A/S - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: URL2.php 286661 2009-08-02 12:50:54Z schmidt $ - * @link http://www.rfc-editor.org/rfc/rfc3986.txt - */ - -/** - * Represents a URL as per RFC 3986. - * - * @category Networking - * @package Net_URL2 - * @author Christian Schmidt - * @copyright 2007-2008 Peytz & Co. ApS - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/Net_URL2 + * @license BSD License */ class Net_URL2 { @@ -60,24 +46,24 @@ class Net_URL2 * Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default * is true. */ - const OPTION_STRICT = 'strict'; + const OPTION_STRICT = 'strict'; /** * Represent arrays in query using PHP's [] notation. Default is true. */ - const OPTION_USE_BRACKETS = 'use_brackets'; + const OPTION_USE_BRACKETS = 'use_brackets'; /** * URL-encode query variable keys. Default is true. */ - const OPTION_ENCODE_KEYS = 'encode_keys'; + const OPTION_ENCODE_KEYS = 'encode_keys'; /** * Query variable separators when parsing the query string. Every character * is considered a separator. Default is specified by the * arg_separator.input php.ini setting (this defaults to "&"). */ - const OPTION_SEPARATOR_INPUT = 'input_separator'; + const OPTION_SEPARATOR_INPUT = 'input_separator'; /** * Query variable separator used when generating the query string. Default @@ -89,7 +75,7 @@ class Net_URL2 /** * Default options corresponds to how PHP handles $_GET. */ - private $_options = array( + private $options = array( self::OPTION_STRICT => true, self::OPTION_USE_BRACKETS => true, self::OPTION_ENCODE_KEYS => true, @@ -100,43 +86,41 @@ class Net_URL2 /** * @var string|bool */ - private $_scheme = false; + private $scheme = false; /** * @var string|bool */ - private $_userinfo = false; + private $userinfo = false; /** * @var string|bool */ - private $_host = false; + private $host = false; /** * @var int|bool */ - private $_port = false; + private $port = false; /** * @var string */ - private $_path = ''; + private $path = ''; /** * @var string|bool */ - private $_query = false; + private $query = false; /** * @var string|bool */ - private $_fragment = false; + private $fragment = false; /** - * Constructor. - * * @param string $url an absolute or relative URL - * @param array $options an array of OPTION_xxx constants + * @param array $options */ public function __construct($url, $options = null) { @@ -146,12 +130,12 @@ class Net_URL2 ini_get('arg_separator.output')); if (is_array($options)) { foreach ($options as $optionName => $value) { - $this->setOption($optionName, $value); + $this->setOption($optionName); } } if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) { - $this->_scheme = $reg[1]; + $this->scheme = $reg[1]; $url = substr($url, strlen($reg[0])); } @@ -161,58 +145,19 @@ class Net_URL2 } $i = strcspn($url, '?#'); - $this->_path = substr($url, 0, $i); + $this->path = substr($url, 0, $i); $url = substr($url, $i); if (preg_match('@^\?([^#]*)@', $url, $reg)) { - $this->_query = $reg[1]; + $this->query = $reg[1]; $url = substr($url, strlen($reg[0])); } if ($url) { - $this->_fragment = substr($url, 1); + $this->fragment = substr($url, 1); } } - /** - * Magic Setter. - * - * This method will magically set the value of a private variable ($var) - * with the value passed as the args - * - * @param string $var The private variable to set. - * @param mixed $arg An argument of any type. - * @return void - */ - public function __set($var, $arg) - { - $method = 'set' . $var; - if (method_exists($this, $method)) { - $this->$method($arg); - } - } - - /** - * Magic Getter. - * - * This is the magic get method to retrieve the private variable - * that was set by either __set() or it's setter... - * - * @param string $var The property name to retrieve. - * @return mixed $this->$var Either a boolean false if the - * property is not set or the value - * of the private property. - */ - public function __get($var) - { - $method = 'get' . $var; - if (method_exists($this, $method)) { - return $this->$method(); - } - - return false; - } - /** * Returns the scheme, e.g. "http" or "urn", or false if there is no * scheme specified, i.e. if this is a relative URL. @@ -221,23 +166,18 @@ class Net_URL2 */ public function getScheme() { - return $this->_scheme; + return $this->scheme; } /** - * Sets the scheme, e.g. "http" or "urn". Specify false if there is no - * scheme specified, i.e. if this is a relative URL. - * - * @param string|bool $scheme e.g. "http" or "urn", or false if there is no - * scheme specified, i.e. if this is a relative - * URL + * @param string|bool $scheme * * @return void * @see getScheme() */ public function setScheme($scheme) { - $this->_scheme = $scheme; + $this->scheme = $scheme; } /** @@ -248,9 +188,7 @@ class Net_URL2 */ public function getUser() { - return $this->_userinfo !== false - ? preg_replace('@:.*$@', '', $this->_userinfo) - : false; + return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false; } /** @@ -263,9 +201,7 @@ class Net_URL2 */ public function getPassword() { - return $this->_userinfo !== false - ? substr(strstr($this->_userinfo, ':'), 1) - : false; + return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false; } /** @@ -276,7 +212,7 @@ class Net_URL2 */ public function getUserinfo() { - return $this->_userinfo; + return $this->userinfo; } /** @@ -284,15 +220,15 @@ class Net_URL2 * in the userinfo part as username ":" password. * * @param string|bool $userinfo userinfo or username - * @param string|bool $password optional password, or false + * @param string|bool $password * * @return void */ public function setUserinfo($userinfo, $password = false) { - $this->_userinfo = $userinfo; + $this->userinfo = $userinfo; if ($password !== false) { - $this->_userinfo .= ':' . $password; + $this->userinfo .= ':' . $password; } } @@ -300,24 +236,21 @@ class Net_URL2 * Returns the host part, or false if there is no authority part, e.g. * relative URLs. * - * @return string|bool a hostname, an IP address, or false + * @return string|bool */ public function getHost() { - return $this->_host; + return $this->host; } /** - * Sets the host part. Specify false if there is no authority part, e.g. - * relative URLs. - * - * @param string|bool $host a hostname, an IP address, or false + * @param string|bool $host * * @return void */ public function setHost($host) { - $this->_host = $host; + $this->host = $host; } /** @@ -328,72 +261,65 @@ class Net_URL2 */ public function getPort() { - return $this->_port; + return $this->port; } /** - * Sets the port number. Specify false if there is no port number specified, - * i.e. if the default port is to be used. - * - * @param int|bool $port a port number, or false + * @param int|bool $port * * @return void */ public function setPort($port) { - $this->_port = intval($port); + $this->port = intval($port); } /** * Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or - * false if there is no authority. + * false if there is no authority none. * * @return string|bool */ public function getAuthority() { - if (!$this->_host) { + if (!$this->host) { return false; } $authority = ''; - if ($this->_userinfo !== false) { - $authority .= $this->_userinfo . '@'; + if ($this->userinfo !== false) { + $authority .= $this->userinfo . '@'; } - $authority .= $this->_host; + $authority .= $this->host; - if ($this->_port !== false) { - $authority .= ':' . $this->_port; + if ($this->port !== false) { + $authority .= ':' . $this->port; } return $authority; } /** - * Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify - * false if there is no authority. - * - * @param string|false $authority a hostname or an IP addresse, possibly - * with userinfo prefixed and port number - * appended, e.g. "foo:bar@example.org:81". + * @param string|false $authority * * @return void */ public function setAuthority($authority) { - $this->_userinfo = false; - $this->_host = false; - $this->_port = false; - if (preg_match('@^(([^\@]*)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) { + $this->user = false; + $this->pass = false; + $this->host = false; + $this->port = false; + if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) { if ($reg[1]) { - $this->_userinfo = $reg[2]; + $this->userinfo = $reg[2]; } - $this->_host = $reg[3]; + $this->host = $reg[3]; if (isset($reg[5])) { - $this->_port = intval($reg[5]); + $this->port = intval($reg[5]); } } } @@ -405,74 +331,65 @@ class Net_URL2 */ public function getPath() { - return $this->_path; + return $this->path; } /** - * Sets the path part (possibly an empty string). - * - * @param string $path a path + * @param string $path * * @return void */ public function setPath($path) { - $this->_path = $path; + $this->path = $path; } /** * Returns the query string (excluding the leading "?"), or false if "?" - * is not present in the URL. + * isn't present in the URL. * * @return string|bool * @see self::getQueryVariables() */ public function getQuery() { - return $this->_query; + return $this->query; } /** - * Sets the query string (excluding the leading "?"). Specify false if "?" - * is not present in the URL. - * - * @param string|bool $query a query string, e.g. "foo=1&bar=2" + * @param string|bool $query * * @return void * @see self::setQueryVariables() */ public function setQuery($query) { - $this->_query = $query; + $this->query = $query; } /** - * Returns the fragment name, or false if "#" is not present in the URL. + * Returns the fragment name, or false if "#" isn't present in the URL. * * @return string|bool */ public function getFragment() { - return $this->_fragment; + return $this->fragment; } /** - * Sets the fragment name. Specify false if "#" is not present in the URL. - * - * @param string|bool $fragment a fragment excluding the leading "#", or - * false + * @param string|bool $fragment * * @return void */ public function setFragment($fragment) { - $this->_fragment = $fragment; + $this->fragment = $fragment; } /** * Returns the query string like an array as the variables would appear in - * $_GET in a PHP script. If the URL does not contain a "?", an empty array - * is returned. + * $_GET in a PHP script. * * @return array */ @@ -481,7 +398,7 @@ class Net_URL2 $pattern = '/[' . preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') . ']/'; - $parts = preg_split($pattern, $this->_query, -1, PREG_SPLIT_NO_EMPTY); + $parts = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY); $return = array(); foreach ($parts as $part) { @@ -528,8 +445,6 @@ class Net_URL2 } /** - * Sets the query string to the specified variable in the query string. - * * @param array $array (name => value) array * * @return void @@ -537,11 +452,11 @@ class Net_URL2 public function setQueryVariables(array $array) { if (!$array) { - $this->_query = false; + $this->query = false; } else { foreach ($array as $name => $value) { if ($this->getOption(self::OPTION_ENCODE_KEYS)) { - $name = self::urlencode($name); + $name = rawurlencode($name); } if (is_array($value)) { @@ -551,21 +466,19 @@ class Net_URL2 : ($name . '=' . $v); } } elseif (!is_null($value)) { - $parts[] = $name . '=' . self::urlencode($value); + $parts[] = $name . '=' . $value; } else { $parts[] = $name; } } - $this->_query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT), - $parts); + $this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT), + $parts); } } /** - * Sets the specified variable in the query string. - * - * @param string $name variable name - * @param mixed $value variable value + * @param string $name + * @param mixed $value * * @return array */ @@ -577,9 +490,7 @@ class Net_URL2 } /** - * Removes the specifed variable from the query string. - * - * @param string $name a query string variable, e.g. "foo" in "?foo=1" + * @param string $name * * @return void */ @@ -600,38 +511,27 @@ class Net_URL2 // See RFC 3986, section 5.3 $url = ""; - if ($this->_scheme !== false) { - $url .= $this->_scheme . ':'; + if ($this->scheme !== false) { + $url .= $this->scheme . ':'; } $authority = $this->getAuthority(); if ($authority !== false) { $url .= '//' . $authority; } - $url .= $this->_path; + $url .= $this->path; - if ($this->_query !== false) { - $url .= '?' . $this->_query; + if ($this->query !== false) { + $url .= '?' . $this->query; } - if ($this->_fragment !== false) { - $url .= '#' . $this->_fragment; + if ($this->fragment !== false) { + $url .= '#' . $this->fragment; } return $url; } - /** - * Returns a string representation of this URL. - * - * @return string - * @see toString() - */ - public function __toString() - { - return $this->getURL(); - } - /** * Returns a normalized string representation of this URL. This is useful * for comparison of URLs. @@ -655,38 +555,36 @@ class Net_URL2 // See RFC 3886, section 6 // Schemes are case-insensitive - if ($this->_scheme) { - $this->_scheme = strtolower($this->_scheme); + if ($this->scheme) { + $this->scheme = strtolower($this->scheme); } // Hostnames are case-insensitive - if ($this->_host) { - $this->_host = strtolower($this->_host); + if ($this->host) { + $this->host = strtolower($this->host); } // Remove default port number for known schemes (RFC 3986, section 6.2.3) - if ($this->_port && - $this->_scheme && - $this->_port == getservbyname($this->_scheme, 'tcp')) { + if ($this->port && + $this->scheme && + $this->port == getservbyname($this->scheme, 'tcp')) { - $this->_port = false; + $this->port = false; } // Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1) - foreach (array('_userinfo', '_host', '_path') as $part) { + foreach (array('userinfo', 'host', 'path') as $part) { if ($this->$part) { - $this->$part = preg_replace('/%[0-9a-f]{2}/ie', - 'strtoupper("\0")', - $this->$part); + $this->$part = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part); } } // Path segment normalization (RFC 3986, section 6.2.2.3) - $this->_path = self::removeDotSegments($this->_path); + $this->path = self::removeDotSegments($this->path); // Scheme based normalization (RFC 3986, section 6.2.3) - if ($this->_host && !$this->_path) { - $this->_path = '/'; + if ($this->host && !$this->path) { + $this->path = '/'; } } @@ -697,7 +595,7 @@ class Net_URL2 */ public function isAbsolute() { - return (bool) $this->_scheme; + return (bool) $this->scheme; } /** @@ -710,7 +608,7 @@ class Net_URL2 */ public function resolve($reference) { - if (!$reference instanceof Net_URL2) { + if (is_string($reference)) { $reference = new self($reference); } if (!$this->isAbsolute()) { @@ -719,54 +617,54 @@ class Net_URL2 // A non-strict parser may ignore a scheme in the reference if it is // identical to the base URI's scheme. - if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) { - $reference->_scheme = false; + if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) { + $reference->scheme = false; } $target = new self(''); - if ($reference->_scheme !== false) { - $target->_scheme = $reference->_scheme; + if ($reference->scheme !== false) { + $target->scheme = $reference->scheme; $target->setAuthority($reference->getAuthority()); - $target->_path = self::removeDotSegments($reference->_path); - $target->_query = $reference->_query; + $target->path = self::removeDotSegments($reference->path); + $target->query = $reference->query; } else { $authority = $reference->getAuthority(); if ($authority !== false) { $target->setAuthority($authority); - $target->_path = self::removeDotSegments($reference->_path); - $target->_query = $reference->_query; + $target->path = self::removeDotSegments($reference->path); + $target->query = $reference->query; } else { - if ($reference->_path == '') { - $target->_path = $this->_path; - if ($reference->_query !== false) { - $target->_query = $reference->_query; + if ($reference->path == '') { + $target->path = $this->path; + if ($reference->query !== false) { + $target->query = $reference->query; } else { - $target->_query = $this->_query; + $target->query = $this->query; } } else { - if (substr($reference->_path, 0, 1) == '/') { - $target->_path = self::removeDotSegments($reference->_path); + if (substr($reference->path, 0, 1) == '/') { + $target->path = self::removeDotSegments($reference->path); } else { // Merge paths (RFC 3986, section 5.2.3) - if ($this->_host !== false && $this->_path == '') { - $target->_path = '/' . $this->_path; + if ($this->host !== false && $this->path == '') { + $target->path = '/' . $this->path; } else { - $i = strrpos($this->_path, '/'); + $i = strrpos($this->path, '/'); if ($i !== false) { - $target->_path = substr($this->_path, 0, $i + 1); + $target->path = substr($this->path, 0, $i + 1); } - $target->_path .= $reference->_path; + $target->path .= $reference->path; } - $target->_path = self::removeDotSegments($target->_path); + $target->path = self::removeDotSegments($target->path); } - $target->_query = $reference->_query; + $target->query = $reference->query; } $target->setAuthority($this->getAuthority()); } - $target->_scheme = $this->_scheme; + $target->scheme = $this->scheme; } - $target->_fragment = $reference->_fragment; + $target->fragment = $reference->fragment; return $target; } @@ -779,7 +677,7 @@ class Net_URL2 * * @return string a path */ - public static function removeDotSegments($path) + private static function removeDotSegments($path) { $output = ''; @@ -787,25 +685,28 @@ class Net_URL2 // method $j = 0; while ($path && $j++ < 100) { + // Step A if (substr($path, 0, 2) == './') { - // Step 2.A $path = substr($path, 2); } elseif (substr($path, 0, 3) == '../') { - // Step 2.A $path = substr($path, 3); + + // Step B } elseif (substr($path, 0, 3) == '/./' || $path == '/.') { - // Step 2.B $path = '/' . substr($path, 3); + + // Step C } elseif (substr($path, 0, 4) == '/../' || $path == '/..') { - // Step 2.C - $path = '/' . substr($path, 4); - $i = strrpos($output, '/'); + $path = '/' . substr($path, 4); + $i = strrpos($output, '/'); $output = $i === false ? '' : substr($output, 0, $i); + + // Step D } elseif ($path == '.' || $path == '..') { - // Step 2.D $path = ''; + + // Step E } else { - // Step 2.E $i = strpos($path, '/'); if ($i === 0) { $i = strpos($path, '/', 1); @@ -821,22 +722,6 @@ class Net_URL2 return $output; } - /** - * Percent-encodes all non-alphanumeric characters except these: _ . - ~ - * Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP - * 5.2.x and earlier. - * - * @param $raw the string to encode - * @return string - */ - public static function urlencode($string) - { - $encoded = rawurlencode($string); - // This is only necessary in PHP < 5.3. - $encoded = str_replace('%7E', '~', $encoded); - return $encoded; - } - /** * Returns a Net_URL2 instance representing the canonical URL of the * currently executing PHP script. @@ -852,13 +737,13 @@ class Net_URL2 // Begin with a relative URL $url = new self($_SERVER['PHP_SELF']); - $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; - $url->_host = $_SERVER['SERVER_NAME']; + $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; + $url->host = $_SERVER['SERVER_NAME']; $port = intval($_SERVER['SERVER_PORT']); - if ($url->_scheme == 'http' && $port != 80 || - $url->_scheme == 'https' && $port != 443) { + if ($url->scheme == 'http' && $port != 80 || + $url->scheme == 'https' && $port != 443) { - $url->_port = $port; + $url->port = $port; } return $url; } @@ -888,7 +773,7 @@ class Net_URL2 // Begin with a relative URL $url = new self($_SERVER['REQUEST_URI']); - $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; + $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; // Set host and possibly port $url->setAuthority($_SERVER['HTTP_HOST']); return $url; @@ -907,10 +792,10 @@ class Net_URL2 */ function setOption($optionName, $value) { - if (!array_key_exists($optionName, $this->_options)) { + if (!array_key_exists($optionName, $this->options)) { return false; } - $this->_options[$optionName] = $value; + $this->options[$optionName] = $value; } /** @@ -922,7 +807,7 @@ class Net_URL2 */ function getOption($optionName) { - return isset($this->_options[$optionName]) - ? $this->_options[$optionName] : false; + return isset($this->options[$optionName]) + ? $this->options[$optionName] : false; } } -- cgit v1.2.3-54-g00ecf