From 8c964555633510dd85def6836f4b720366dce5ef Mon Sep 17 00:00:00 2001 From: carl <> Date: Sat, 4 Aug 2007 16:21:24 +0000 Subject: Fixed #672 --- framework/Web/THttpRequest.php | 2437 ++++++++++++++++++++-------------------- 1 file changed, 1225 insertions(+), 1212 deletions(-) (limited to 'framework/Web/THttpRequest.php') diff --git a/framework/Web/THttpRequest.php b/framework/Web/THttpRequest.php index ef0660cc..bc3f9912 100644 --- a/framework/Web/THttpRequest.php +++ b/framework/Web/THttpRequest.php @@ -1,1213 +1,1226 @@ - - * @link http://www.pradosoft.com/ - * @copyright Copyright © 2005 PradoSoft - * @license http://www.pradosoft.com/license/ - * @version $Id$ - * @package System.Web - */ - -Prado::using('System.Web.TUrlManager'); - -/** - * THttpRequest class - * - * THttpRequest provides storage and access scheme for user request sent via HTTP. - * It also encapsulates a uniform way to parse and construct URLs. - * - * User post data can be retrieved from THttpRequest by using it like an associative array. - * For example, to test if a user supplies a variable named 'param1', you can use, - * - * if(isset($request['param1'])) ... - * // equivalent to: - * // if($request->contains('param1')) ... - * - * To get the value of 'param1', use, - * - * $value=$request['param1']; - * // equivalent to: - * // $value=$request->itemAt('param1'); - * - * To traverse the user post data, use - * - * foreach($request as $name=>$value) ... - * - * Note, POST and GET variables are merged together in THttpRequest. - * If a variable name appears in both POST and GET data, then POST data - * takes precedence. - * - * To construct a URL that can be recognized by Prado, use {@link constructUrl()}. - * The format of the recognizable URLs is determined according to - * {@link setUrlManager UrlManager}. By default, the following two formats - * are recognized: - * - * /index.php?ServiceID=ServiceParameter&Name1=Value1&Name2=Value2 - * /index.php/ServiceID,ServiceParameter/Name1,Value1/Name2,Value2 - * - * The first format is called 'Get' while the second 'Path', which is specified - * via {@link setUrlFormat UrlFormat}. For advanced users who want to use - * their own URL formats, they can write customized URL management modules - * and install the managers as application modules and set {@link setUrlManager UrlManager}. - * - * The ServiceID in the above URLs is as defined in the application configuration - * (e.g. the default page service's service ID is 'page'). - * As a consequence, your GET variable names should not conflict with the service - * IDs that your application supports. - * - * THttpRequest also provides the cookies sent by the user, user information such - * as his browser capabilities, accepted languages, etc. - * - * By default, THttpRequest is registered with {@link TApplication} as the - * request module. It can be accessed via {@link TApplication::getRequest()}. - * - * @author Qiang Xue - * @version $Id$ - * @package System.Web - * @since 3.0 - */ -class THttpRequest extends TApplicationComponent implements IteratorAggregate,ArrayAccess,Countable,IModule -{ - /** - * @var TUrlManager the URL manager module - */ - private $_urlManager=null; - /** - * @var string the ID of the URL manager module - */ - private $_urlManagerID=''; - /** - * @var string Separator used to separate GET variable name and value when URL format is Path. - */ - private $_separator=','; - /** - * @var string requested service ID - */ - private $_serviceID=null; - /** - * @var string requested service parameter - */ - private $_serviceParam=null; - /** - * @var THttpCookieCollection cookies sent from user - */ - private $_cookies=null; - /** - * @var string requested URI (URL w/o host info) - */ - private $_requestUri; - /** - * @var string path info of URL - */ - private $_pathInfo; - /** - * @var boolean whether the session ID should be kept in cookie only - */ - private $_cookieOnly=false; - private $_urlFormat=THttpRequestUrlFormat::Get; - private $_services; - private $_requestResolved=false; - private $_enableCookieValidation=false; - /** - * @var string request URL - */ - private $_url=null; - - /** - * @var string module id - */ - private $_id; - - /** - * @var array contains all request variables - */ - private $_items=array(); - - /** - * @return string id of this module - */ - public function getID() - { - return $this->_id; - } - - /** - * @param string id of this module - */ - public function setID($value) - { - $this->_id=$value; - } - - /** - * Initializes the module. - * This method is required by IModule and is invoked by application. - * @param TXmlElement module configuration - */ - public function init($config) - { - if(empty($this->_urlManagerID)) - { - $this->_urlManager=new TUrlManager; - $this->_urlManager->init(null); - } - else - { - $this->_urlManager=$this->getApplication()->getModule($this->_urlManagerID); - if($this->_urlManager===null) - throw new TConfigurationException('httprequest_urlmanager_inexist',$this->_urlManagerID); - if(!($this->_urlManager instanceof TUrlManager)) - throw new TConfigurationException('httprequest_urlmanager_invalid',$this->_urlManagerID); - } - - // Fill in default request info when the script is run in command line - if(php_sapi_name()==='cli') - { - $_SERVER['REMOTE_ADDR']='127.0.0.1'; - $_SERVER['REQUEST_METHOD']='GET'; - $_SERVER['SERVER_NAME']='localhost'; - $_SERVER['SERVER_PORT']=80; - $_SERVER['HTTP_USER_AGENT']=''; - } - - $this->_cookieOnly=(int)ini_get('session.use_cookies') && (int)ini_get('session.use_only_cookies'); - - // Info about server variables: - // PHP_SELF contains real URI (w/ path info, w/o query string) - // SCRIPT_NAME is the real URI for the requested script (w/o path info and query string) - // QUERY_STRING is the string following the '?' in the ur (eg the a=x part in http://foo/bar?a=x) - // REQUEST_URI contains the URI part entered in the browser address bar - // SCRIPT_FILENAME is the file path to the executing script - if(isset($_SERVER['REQUEST_URI'])) - $this->_requestUri=$_SERVER['REQUEST_URI']; - else // TBD: in this case, SCRIPT_NAME need to be escaped - $this->_requestUri=$_SERVER['SCRIPT_NAME'].(empty($_SERVER['QUERY_STRING'])?'':'?'.$_SERVER['QUERY_STRING']); - - if(isset($_SERVER['PATH_INFO'])) - $this->_pathInfo=$_SERVER['PATH_INFO']; - else if(strpos($_SERVER['PHP_SELF'],$_SERVER['SCRIPT_NAME'])===0) - $this->_pathInfo=substr($_SERVER['PHP_SELF'],strlen($_SERVER['SCRIPT_NAME'])); - else - $this->_pathInfo=''; - - if(get_magic_quotes_gpc()) - { - if(isset($_GET)) - $_GET=$this->stripSlashes($_GET); - if(isset($_POST)) - $_POST=$this->stripSlashes($_POST); - if(isset($_REQUEST)) - $_REQUEST=$this->stripSlashes($_REQUEST); - if(isset($_COOKIE)) - $_COOKIE=$this->stripSlashes($_COOKIE); - } - - $this->getApplication()->setRequest($this); - } - - /** - * Strips slashes from input data. - * This method is applied when magic quotes is enabled. - * @param mixed input data to be processed - * @return mixed processed data - */ - public function stripSlashes(&$data) - { - return is_array($data)?array_map(array($this,'stripSlashes'),$data):stripslashes($data); - } - - /** - * @return TUri the request URL - */ - public function getUrl() - { - if($this->_url===null) - { - $secure=$this->getIsSecureConnection(); - $url=$secure?'https://':'http://'; - if(empty($_SERVER['HTTP_HOST'])) - { - $url.=$_SERVER['SERVER_NAME']; - $port=$_SERVER['SERVER_PORT']; - if(($port!=80 && !$secure) || ($port!=443 && $secure)) - $url.=':'.$port; - } - else - $url.=$_SERVER['HTTP_HOST']; - $url.=$this->getRequestUri(); - $this->_url=new TUri($url); - } - return $this->_url; - } - - /** - * @return string the ID of the URL manager module - */ - public function getUrlManager() - { - return $this->_urlManagerID; - } - - /** - * Sets the URL manager module. - * By default, {@link TUrlManager} is used for managing URLs. - * You may specify a different module for URL managing tasks - * by loading it as an application module and setting this property - * with the module ID. - * @param string the ID of the URL manager module - */ - public function setUrlManager($value) - { - $this->_urlManagerID=$value; - } - - /** - * @return TUrlManager the URL manager module - */ - public function getUrlManagerModule() - { - return $this->_urlManager; - } - - /** - * @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get. - */ - public function getUrlFormat() - { - return $this->_urlFormat; - } - - /** - * Sets the format of URLs constructed and interpretted by the request module. - * A Get URL format is like index.php?name1=value1&name2=value2 - * while a Path URL format is like index.php/name1,value1/name2,value. - * Changing the UrlFormat will affect {@link constructUrl} and how GET variables - * are parsed. - * @param THttpRequestUrlFormat the format of URLs. - */ - public function setUrlFormat($value) - { - $this->_urlFormat=TPropertyValue::ensureEnum($value,'THttpRequestUrlFormat'); - } - - /** - * @return string separator used to separate GET variable name and value when URL format is Path. Defaults to comma ','. - */ - public function getUrlParamSeparator() - { - return $this->_separator; - } - - /** - * @param string separator used to separate GET variable name and value when URL format is Path. - * @throws TInvalidDataValueException if the separator is not a single character - */ - public function setUrlParamSeparator($value) - { - if(strlen($value)===1) - $this->_separator=$value; - else - throw new TInvalidDataValueException('httprequest_separator_invalid'); - } - - /** - * @return string request type, can be GET, POST, HEAD, or PUT - */ - public function getRequestType() - { - return $_SERVER['REQUEST_METHOD']; - } - - /** - * @return boolean if the request is sent via secure channel (https) - */ - public function getIsSecureConnection() - { - return isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'],'off'); - } - - /** - * @return string part of the request URL after script name and before question mark. - */ - public function getPathInfo() - { - return $this->_pathInfo; - } - - /** - * @return string part of that request URL after the question mark - */ - public function getQueryString() - { - return isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:''; - } - - /** - * @return string part of that request URL after the host info (including pathinfo and query string) - */ - public function getRequestUri() - { - return $this->_requestUri; - } - - /** - * @return string schema and hostname of the requested URL - */ - public function getBaseUrl() - { - return ($this->getIsSecureConnection() ? "https://" : "http://") . $_SERVER ['HTTP_HOST']; - } - - /** - * @return string entry script URL (w/o host part) - */ - public function getApplicationUrl() - { - return $_SERVER['SCRIPT_NAME']; - } - - /** - * @return string entry script URL (w/ host part) - */ - public function getAbsoluteApplicationUrl() - { - return $this->getBaseUrl() . $this->getApplicationUrl(); - } - - /** - * @return string application entry script file path (processed w/ realpath()) - */ - public function getApplicationFilePath() - { - return realpath($_SERVER['SCRIPT_FILENAME']); - } - - /** - * @return string server name - */ - public function getServerName() - { - return $_SERVER['SERVER_NAME']; - } - - /** - * @return integer server port number - */ - public function getServerPort() - { - return $_SERVER['SERVER_PORT']; - } - - /** - * @return string URL referrer, null if not present - */ - public function getUrlReferrer() - { - return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null; - } - - /** - * @return array user browser capabilities - * @see get_browser - */ - public function getBrowser() - { - return get_browser(); - } - - /** - * @return string user agent - */ - public function getUserAgent() - { - return $_SERVER['HTTP_USER_AGENT']; - } - - /** - * @return string user IP address - */ - public function getUserHostAddress() - { - return $_SERVER['REMOTE_ADDR']; - } - - /** - * @return string user host name, null if cannot be determined - */ - public function getUserHost() - { - return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null; - } - - /** - * @return string user browser accept types - */ - public function getAcceptTypes() - { - // TBD: break it into array?? - return $_SERVER['HTTP_ACCEPT']; - } - - /** - * Returns a list of user preferred languages. - * The languages are returned as an array. Each array element - * represents a single language preference. The languages are ordered - * according to user preferences. The first language is the most preferred. - * @return array list of user preferred languages. - */ - public function getUserLanguages() - { - return Prado::getUserLanguages(); - } - - /** - * @return boolean whether cookies should be validated. Defaults to false. - */ - public function getEnableCookieValidation() - { - return $this->_enableCookieValidation; - } - - /** - * @param boolean whether cookies should be validated. - */ - public function setEnableCookieValidation($value) - { - $this->_enableCookieValidation=TPropertyValue::ensureBoolean($value); - } - - /** - * @return THttpCookieCollection list of cookies to be sent - */ - public function getCookies() - { - if($this->_cookies===null) - { - $this->_cookies=new THttpCookieCollection; - if($this->getEnableCookieValidation()) - { - $sm=$this->getApplication()->getSecurityManager(); - foreach($_COOKIE as $key=>$value) - { - if(($value=$sm->validateData($value))!==false) - $this->_cookies->add(new THttpCookie($key,$value)); - } - } - else - { - foreach($_COOKIE as $key=>$value) - $this->_cookies->add(new THttpCookie($key,$value)); - } - } - return $this->_cookies; - } - - /** - * @return array list of uploaded files. - */ - public function getUploadedFiles() - { - return $_FILES; - } - - /** - * @return array list of server variables. - */ - public function getServerVariables() - { - return $_SERVER; - } - - /** - * @return array list of environment variables. - */ - public function getEnvironmentVariables() - { - return $_ENV; - } - - /** - * Constructs a URL that can be recognized by PRADO. - * The actual construction work is done by the URL manager module. - * This method may append session information to the generated URL if needed. - * You may provide your own URL manager module by setting {@link setUrlManager UrlManager} - * to provide your own URL scheme. - * @param string service ID - * @param string service parameter - * @param array GET parameters, null if not needed - * @param boolean whether to encode the ampersand in URL, defaults to true. - * @param boolean whether to encode the GET parameters (their names and values), defaults to false. - * @return string URL - * @see TUrlManager::constructUrl - */ - public function constructUrl($serviceID,$serviceParam,$getItems=null,$encodeAmpersand=true,$encodeGetItems=true) - { - $url=$this->_urlManager->constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems); - if(defined('SID') && SID != '' && !$this->_cookieOnly) - return $url . (strpos($url,'?')===false? '?' : ($encodeAmpersand?'&':'&')) . SID; - else - return $url; - } - - /** - * Parses the request URL and returns an array of input parameters (excluding GET variables). - * You may override this method to support customized URL format. - * @return array list of input parameters, indexed by parameter names - * @see TUrlManager::parseUrl - */ - protected function parseUrl() - { - return $this->_urlManager->parseUrl(); - } - - /** - * Resolves the requested service. - * This method implements a URL-based service resolution. - * A URL in the format of /index.php?sp=serviceID.serviceParameter - * will be resolved with the serviceID and the serviceParameter. - * You may override this method to provide your own way of service resolution. - * @param array list of valid service IDs - * @return string the currently requested service ID, null if no service ID is found - * @see constructUrl - */ - public function resolveRequest($serviceIDs) - { - Prado::trace("Resolving request from ".$_SERVER['REMOTE_ADDR'],'System.Web.THttpRequest'); - $this->_items=array_merge($_GET,$this->parseUrl(),$_POST); - $this->_requestResolved=true; - foreach($serviceIDs as $serviceID) - { - if($this->contains($serviceID)) - { - $this->setServiceID($serviceID); - $this->setServiceParameter($this->itemAt($serviceID)); - return $serviceID; - } - } - return null; - } - - /** - * @return boolean true if request is already resolved, false otherwise. - */ - public function getRequestResolved() - { - return $this->_requestResolved; - } - - /** - * @return string requested service ID - */ - public function getServiceID() - { - return $this->_serviceID; - } - - /** - * Sets the requested service ID. - * @param string requested service ID - */ - public function setServiceID($value) - { - $this->_serviceID=$value; - } - - /** - * @return string requested service parameter - */ - public function getServiceParameter() - { - return $this->_serviceParam; - } - - /** - * Sets the requested service parameter. - * @param string requested service parameter - */ - public function setServiceParameter($value) - { - $this->_serviceParam=$value; - } - - //------ The following methods enable THttpRequest to be TMap-like ----- - - /** - * Returns an iterator for traversing the items in the list. - * This method is required by the interface IteratorAggregate. - * @return Iterator an iterator for traversing the items in the list. - */ - public function getIterator() - { - return new TMapIterator($this->_items); - } - - /** - * @return integer the number of items in the request - */ - public function getCount() - { - return count($this->_items); - } - - /** - * Returns the number of items in the request. - * This method is required by Countable interface. - * @return integer number of items in the request. - */ - public function count() - { - return $this->getCount(); - } - - /** - * @return array the key list - */ - public function getKeys() - { - return array_keys($this->_items); - } - - /** - * Returns the item with the specified key. - * This method is exactly the same as {@link offsetGet}. - * @param mixed the key - * @return mixed the element at the offset, null if no element is found at the offset - */ - public function itemAt($key) - { - return isset($this->_items[$key]) ? $this->_items[$key] : null; - } - - /** - * Adds an item into the request. - * Note, if the specified key already exists, the old value will be overwritten. - * @param mixed key - * @param mixed value - */ - public function add($key,$value) - { - $this->_items[$key]=$value; - } - - /** - * Removes an item from the request by its key. - * @param mixed the key of the item to be removed - * @return mixed the removed value, null if no such key exists. - * @throws TInvalidOperationException if the item cannot be removed - */ - public function remove($key) - { - if(isset($this->_items[$key]) || array_key_exists($key,$this->_items)) - { - $value=$this->_items[$key]; - unset($this->_items[$key]); - return $value; - } - else - return null; - } - - /** - * Removes all items in the request. - */ - public function clear() - { - foreach(array_keys($this->_items) as $key) - $this->remove($key); - } - - /** - * @param mixed the key - * @return boolean whether the request contains an item with the specified key - */ - public function contains($key) - { - return isset($this->_items[$key]) || array_key_exists($key,$this->_items); - } - - /** - * @return array the list of items in array - */ - public function toArray() - { - return $this->_items; - } - - /** - * Returns whether there is an element at the specified offset. - * This method is required by the interface ArrayAccess. - * @param mixed the offset to check on - * @return boolean - */ - public function offsetExists($offset) - { - return $this->contains($offset); - } - - /** - * Returns the element at the specified offset. - * This method is required by the interface ArrayAccess. - * @param integer the offset to retrieve element. - * @return mixed the element at the offset, null if no element is found at the offset - */ - public function offsetGet($offset) - { - return $this->itemAt($offset); - } - - /** - * Sets the element at the specified offset. - * This method is required by the interface ArrayAccess. - * @param integer the offset to set element - * @param mixed the element value - */ - public function offsetSet($offset,$item) - { - $this->add($offset,$item); - } - - /** - * Unsets the element at the specified offset. - * This method is required by the interface ArrayAccess. - * @param mixed the offset to unset element - */ - public function offsetUnset($offset) - { - $this->remove($offset); - } -} - -/** - * THttpCookieCollection class. - * - * THttpCookieCollection implements a collection class to store cookies. - * Besides using all functionalities from {@link TList}, you can also - * retrieve a cookie by its name using either {@link findCookieByName} or - * simply: - * - * $cookie=$collection[$cookieName]; - * - * - * @author Qiang Xue - * @version $Id$ - * @package System.Web - * @since 3.0 - */ -class THttpCookieCollection extends TList -{ - /** - * @var mixed owner of this collection - */ - private $_o; - - /** - * Constructor. - * @param mixed owner of this collection. - */ - public function __construct($owner=null) - { - $this->_o=$owner; - } - - /** - * Inserts an item at the specified position. - * This overrides the parent implementation by performing additional - * operations for each newly added THttpCookie object. - * @param integer the specified position. - * @param mixed new item - * @throws TInvalidDataTypeException if the item to be inserted is not a THttpCookie object. - */ - public function insertAt($index,$item) - { - if($item instanceof THttpCookie) - { - parent::insertAt($index,$item); - if($this->_o instanceof THttpResponse) - $this->_o->addCookie($item); - } - else - throw new TInvalidDataTypeException('httpcookiecollection_httpcookie_required'); - } - - /** - * Removes an item at the specified position. - * This overrides the parent implementation by performing additional - * cleanup work when removing a TCookie object. - * @param integer the index of the item to be removed. - * @return mixed the removed item. - */ - public function removeAt($index) - { - $item=parent::removeAt($index); - if($this->_o instanceof THttpResponse) - $this->_o->removeCookie($item); - return $item; - } - - /** - * @param integer|string index of the cookie in the collection or the cookie's name - * @return THttpCookie the cookie found - */ - public function itemAt($index) - { - if(is_integer($index)) - return parent::itemAt($index); - else - return $this->findCookieByName($index); - } - - /** - * Finds the cookie with the specified name. - * @param string the name of the cookie to be looked for - * @return THttpCookie the cookie, null if not found - */ - public function findCookieByName($name) - { - foreach($this as $cookie) - if($cookie->getName()===$name) - return $cookie; - return null; - } -} - -/** - * THttpCookie class. - * - * A THttpCookie instance stores a single cookie, including the cookie name, value, - * domain, path, expire, and secure. - * - * @author Qiang Xue - * @version $Id$ - * @package System.Web - * @since 3.0 - */ -class THttpCookie extends TComponent -{ - /** - * @var string domain of the cookie - */ - private $_domain=''; - /** - * @var string name of the cookie - */ - private $_name; - /** - * @var string value of the cookie - */ - private $_value=0; - /** - * @var integer expire of the cookie - */ - private $_expire=0; - /** - * @var string path of the cookie - */ - private $_path='/'; - /** - * @var boolean whether cookie should be sent via secure connection - */ - private $_secure=false; - - /** - * Constructor. - * @param string name of this cookie - * @param string value of this cookie - */ - public function __construct($name,$value) - { - $this->_name=$name; - $this->_value=$value; - } - - /** - * @return string the domain to associate the cookie with - */ - public function getDomain() - { - return $this->_domain; - } - - /** - * @param string the domain to associate the cookie with - */ - public function setDomain($value) - { - $this->_domain=$value; - } - - /** - * @return integer the time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. - */ - public function getExpire() - { - return $this->_expire; - } - - /** - * @param integer the time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. - */ - public function setExpire($value) - { - $this->_expire=TPropertyValue::ensureInteger($value); - } - - /** - * @return string the name of the cookie - */ - public function getName() - { - return $this->_name; - } - - /** - * @param string the name of the cookie - */ - public function setName($value) - { - $this->_name=$value; - } - - /** - * @return string the value of the cookie - */ - public function getValue() - { - return $this->_value; - } - - /** - * @param string the value of the cookie - */ - public function setValue($value) - { - $this->_value=$value; - } - - /** - * @return string the path on the server in which the cookie will be available on, default is '/' - */ - public function getPath() - { - return $this->_path; - } - - /** - * @param string the path on the server in which the cookie will be available on - */ - public function setPath($value) - { - $this->_path=$value; - } - - /** - * @return boolean whether the cookie should only be transmitted over a secure HTTPS connection - */ - public function getSecure() - { - return $this->_secure; - } - - /** - * @param boolean ether the cookie should only be transmitted over a secure HTTPS connection - */ - public function setSecure($value) - { - $this->_secure=TPropertyValue::ensureBoolean($value); - } -} - -/** - * TUri class - * - * TUri represents a URI. Given a URI - * http://joe:whatever@example.com:8080/path/to/script.php?param=value#anchor - * it will be decomposed as follows, - * - scheme: http - * - host: example.com - * - port: 8080 - * - user: joe - * - password: whatever - * - path: /path/to/script.php - * - query: param=value - * - fragment: anchor - * - * @author Qiang Xue - * @version $Id$ - * @package System.Web - * @since 3.0 - */ -class TUri extends TComponent -{ - /** - * @var array list of default ports for known schemes - */ - private static $_defaultPort=array( - 'ftp'=>21, - 'gopher'=>70, - 'http'=>80, - 'https'=>443, - 'news'=>119, - 'nntp'=>119, - 'wais'=>210, - 'telnet'=>23 - ); - /** - * @var string scheme of the URI - */ - private $_scheme; - /** - * @var string host name of the URI - */ - private $_host; - /** - * @var integer port of the URI - */ - private $_port; - /** - * @var string user of the URI - */ - private $_user; - /** - * @var string password of the URI - */ - private $_pass; - /** - * @var string path of the URI - */ - private $_path; - /** - * @var string query string of the URI - */ - private $_query; - /** - * @var string fragment of the URI - */ - private $_fragment; - /** - * @var string the URI - */ - private $_uri; - - /** - * Constructor. - * Decomposes the specified URI into parts. - * @param string URI to be represented - * @throws TInvalidDataValueException if URI is of bad format - */ - public function __construct($uri) - { - if(($ret=@parse_url($uri))!==false) - { - // decoding??? - $this->_scheme=isset($ret['scheme'])?$ret['scheme']:''; - $this->_host=isset($ret['host'])?$ret['host']:''; - $this->_port=isset($ret['port'])?$ret['port']:''; - $this->_user=isset($ret['user'])?$ret['user']:''; - $this->_pass=isset($ret['pass'])?$ret['pass']:''; - $this->_path=isset($ret['path'])?$ret['path']:''; - $this->_query=isset($ret['query'])?$ret['query']:''; - $this->_fragment=isset($ret['fragment'])?$ret['fragment']:''; - $this->_uri=$uri; - } - else - { - throw new TInvalidDataValueException('uri_format_invalid',$uri); - } - } - - /** - * @return string URI - */ - public function getUri() - { - return $this->_uri; - } - - /** - * @return string scheme of the URI, such as 'http', 'https', 'ftp', etc. - */ - public function getScheme() - { - return $this->_scheme; - } - - /** - * @return string hostname of the URI - */ - public function getHost() - { - return $this->_host; - } - - /** - * @return integer port number of the URI - */ - public function getPort() - { - return $this->_port; - } - - /** - * @return string username of the URI - */ - public function getUser() - { - return $this->_user; - } - - /** - * @return string password of the URI - */ - public function getPassword() - { - return $this->_pass; - } - - /** - * @return string path of the URI - */ - public function getPath() - { - return $this->_path; - } - - /** - * @return string query string of the URI - */ - public function getQuery() - { - return $this->_query; - } - - /** - * @return string fragment of the URI - */ - public function getFragment() - { - return $this->_fragment; - } -} - -/** - * THttpRequestUrlFormat class. - * THttpRequestUrlFormat defines the enumerable type for the possible URL formats - * that can be recognized by {@link THttpRequest}. - * - * The following enumerable values are defined: - * - Get: the URL format is like /path/to/index.php?name1=value1&name2=value2... - * - Path: the URL format is like /path/to/index.php/name1,value1/name2,value2... - * - * @author Qiang Xue - * @version $Id$ - * @package System.Web - * @since 3.0.4 - */ -class THttpRequestUrlFormat extends TEnumerable -{ - const Get='Get'; - const Path='Path'; -} - + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Web + */ + +Prado::using('System.Web.TUrlManager'); + +/** + * THttpRequest class + * + * THttpRequest provides storage and access scheme for user request sent via HTTP. + * It also encapsulates a uniform way to parse and construct URLs. + * + * User post data can be retrieved from THttpRequest by using it like an associative array. + * For example, to test if a user supplies a variable named 'param1', you can use, + * + * if(isset($request['param1'])) ... + * // equivalent to: + * // if($request->contains('param1')) ... + * + * To get the value of 'param1', use, + * + * $value=$request['param1']; + * // equivalent to: + * // $value=$request->itemAt('param1'); + * + * To traverse the user post data, use + * + * foreach($request as $name=>$value) ... + * + * Note, POST and GET variables are merged together in THttpRequest. + * If a variable name appears in both POST and GET data, then POST data + * takes precedence. + * + * To construct a URL that can be recognized by Prado, use {@link constructUrl()}. + * The format of the recognizable URLs is determined according to + * {@link setUrlManager UrlManager}. By default, the following two formats + * are recognized: + * + * /index.php?ServiceID=ServiceParameter&Name1=Value1&Name2=Value2 + * /index.php/ServiceID,ServiceParameter/Name1,Value1/Name2,Value2 + * + * The first format is called 'Get' while the second 'Path', which is specified + * via {@link setUrlFormat UrlFormat}. For advanced users who want to use + * their own URL formats, they can write customized URL management modules + * and install the managers as application modules and set {@link setUrlManager UrlManager}. + * + * The ServiceID in the above URLs is as defined in the application configuration + * (e.g. the default page service's service ID is 'page'). + * As a consequence, your GET variable names should not conflict with the service + * IDs that your application supports. + * + * THttpRequest also provides the cookies sent by the user, user information such + * as his browser capabilities, accepted languages, etc. + * + * By default, THttpRequest is registered with {@link TApplication} as the + * request module. It can be accessed via {@link TApplication::getRequest()}. + * + * @author Qiang Xue + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class THttpRequest extends TApplicationComponent implements IteratorAggregate,ArrayAccess,Countable,IModule +{ + /** + * @var TUrlManager the URL manager module + */ + private $_urlManager=null; + /** + * @var string the ID of the URL manager module + */ + private $_urlManagerID=''; + /** + * @var string Separator used to separate GET variable name and value when URL format is Path. + */ + private $_separator=','; + /** + * @var string requested service ID + */ + private $_serviceID=null; + /** + * @var string requested service parameter + */ + private $_serviceParam=null; + /** + * @var THttpCookieCollection cookies sent from user + */ + private $_cookies=null; + /** + * @var string requested URI (URL w/o host info) + */ + private $_requestUri; + /** + * @var string path info of URL + */ + private $_pathInfo; + /** + * @var boolean whether the session ID should be kept in cookie only + */ + private $_cookieOnly=false; + private $_urlFormat=THttpRequestUrlFormat::Get; + private $_services; + private $_requestResolved=false; + private $_enableCookieValidation=false; + private $_forceSecureConnection=null; + /** + * @var string request URL + */ + private $_url=null; + + /** + * @var string module id + */ + private $_id; + + /** + * @var array contains all request variables + */ + private $_items=array(); + + /** + * @return string id of this module + */ + public function getID() + { + return $this->_id; + } + + /** + * @param string id of this module + */ + public function setID($value) + { + $this->_id=$value; + } + + /** + * Initializes the module. + * This method is required by IModule and is invoked by application. + * @param TXmlElement module configuration + */ + public function init($config) + { + if(empty($this->_urlManagerID)) + { + $this->_urlManager=new TUrlManager; + $this->_urlManager->init(null); + } + else + { + $this->_urlManager=$this->getApplication()->getModule($this->_urlManagerID); + if($this->_urlManager===null) + throw new TConfigurationException('httprequest_urlmanager_inexist',$this->_urlManagerID); + if(!($this->_urlManager instanceof TUrlManager)) + throw new TConfigurationException('httprequest_urlmanager_invalid',$this->_urlManagerID); + } + + // Fill in default request info when the script is run in command line + if(php_sapi_name()==='cli') + { + $_SERVER['REMOTE_ADDR']='127.0.0.1'; + $_SERVER['REQUEST_METHOD']='GET'; + $_SERVER['SERVER_NAME']='localhost'; + $_SERVER['SERVER_PORT']=80; + $_SERVER['HTTP_USER_AGENT']=''; + } + + $this->_cookieOnly=(int)ini_get('session.use_cookies') && (int)ini_get('session.use_only_cookies'); + + // Info about server variables: + // PHP_SELF contains real URI (w/ path info, w/o query string) + // SCRIPT_NAME is the real URI for the requested script (w/o path info and query string) + // QUERY_STRING is the string following the '?' in the ur (eg the a=x part in http://foo/bar?a=x) + // REQUEST_URI contains the URI part entered in the browser address bar + // SCRIPT_FILENAME is the file path to the executing script + if(isset($_SERVER['REQUEST_URI'])) + $this->_requestUri=$_SERVER['REQUEST_URI']; + else // TBD: in this case, SCRIPT_NAME need to be escaped + $this->_requestUri=$_SERVER['SCRIPT_NAME'].(empty($_SERVER['QUERY_STRING'])?'':'?'.$_SERVER['QUERY_STRING']); + + if(isset($_SERVER['PATH_INFO'])) + $this->_pathInfo=$_SERVER['PATH_INFO']; + else if(strpos($_SERVER['PHP_SELF'],$_SERVER['SCRIPT_NAME'])===0) + $this->_pathInfo=substr($_SERVER['PHP_SELF'],strlen($_SERVER['SCRIPT_NAME'])); + else + $this->_pathInfo=''; + + if(get_magic_quotes_gpc()) + { + if(isset($_GET)) + $_GET=$this->stripSlashes($_GET); + if(isset($_POST)) + $_POST=$this->stripSlashes($_POST); + if(isset($_REQUEST)) + $_REQUEST=$this->stripSlashes($_REQUEST); + if(isset($_COOKIE)) + $_COOKIE=$this->stripSlashes($_COOKIE); + } + + $this->getApplication()->setRequest($this); + } + + /** + * Strips slashes from input data. + * This method is applied when magic quotes is enabled. + * @param mixed input data to be processed + * @return mixed processed data + */ + public function stripSlashes(&$data) + { + return is_array($data)?array_map(array($this,'stripSlashes'),$data):stripslashes($data); + } + + /** + * @return TUri the request URL + */ + public function getUrl() + { + if($this->_url===null) + { + $secure=$this->getIsSecureConnection(); + $url=$secure?'https://':'http://'; + if(empty($_SERVER['HTTP_HOST'])) + { + $url.=$_SERVER['SERVER_NAME']; + $port=$_SERVER['SERVER_PORT']; + if(($port!=80 && !$secure) || ($port!=443 && $secure)) + $url.=':'.$port; + } + else + $url.=$_SERVER['HTTP_HOST']; + $url.=$this->getRequestUri(); + $this->_url=new TUri($url); + } + return $this->_url; + } + + /** + * @return string the ID of the URL manager module + */ + public function getUrlManager() + { + return $this->_urlManagerID; + } + + /** + * Sets the URL manager module. + * By default, {@link TUrlManager} is used for managing URLs. + * You may specify a different module for URL managing tasks + * by loading it as an application module and setting this property + * with the module ID. + * @param string the ID of the URL manager module + */ + public function setUrlManager($value) + { + $this->_urlManagerID=$value; + } + + /** + * @return TUrlManager the URL manager module + */ + public function getUrlManagerModule() + { + return $this->_urlManager; + } + + /** + * @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get. + */ + public function getUrlFormat() + { + return $this->_urlFormat; + } + + /** + * Sets the format of URLs constructed and interpretted by the request module. + * A Get URL format is like index.php?name1=value1&name2=value2 + * while a Path URL format is like index.php/name1,value1/name2,value. + * Changing the UrlFormat will affect {@link constructUrl} and how GET variables + * are parsed. + * @param THttpRequestUrlFormat the format of URLs. + */ + public function setUrlFormat($value) + { + $this->_urlFormat=TPropertyValue::ensureEnum($value,'THttpRequestUrlFormat'); + } + + /** + * @return string separator used to separate GET variable name and value when URL format is Path. Defaults to comma ','. + */ + public function getUrlParamSeparator() + { + return $this->_separator; + } + + /** + * @param string separator used to separate GET variable name and value when URL format is Path. + * @throws TInvalidDataValueException if the separator is not a single character + */ + public function setUrlParamSeparator($value) + { + if(strlen($value)===1) + $this->_separator=$value; + else + throw new TInvalidDataValueException('httprequest_separator_invalid'); + } + + /** + * @return string request type, can be GET, POST, HEAD, or PUT + */ + public function getRequestType() + { + return $_SERVER['REQUEST_METHOD']; + } + + public function setForceSecureConnection($value) + { + $this->_forceSecureConnection=TPropertyValue::ensureBoolean($value); + } + + public function getForceSecureConnection() + { + return $this->_forceSecureConnection; + } + + /** + * @return boolean if the request is sent via secure channel (https) + */ + public function getIsSecureConnection() + { + return isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'],'off'); + } + + /** + * @return string part of the request URL after script name and before question mark. + */ + public function getPathInfo() + { + return $this->_pathInfo; + } + + /** + * @return string part of that request URL after the question mark + */ + public function getQueryString() + { + return isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:''; + } + + /** + * @return string part of that request URL after the host info (including pathinfo and query string) + */ + public function getRequestUri() + { + return $this->_requestUri; + } + + /** + * @return string schema and hostname of the requested URL + */ + public function getBaseUrl() + { + return ($this->getIsSecureConnection() || $this->getForceSecureConnection() ? "https://" : "http://") . $_SERVER ['HTTP_HOST']; + } + + /** + * @return string entry script URL (w/o host part) + */ + public function getApplicationUrl() + { + return $_SERVER['SCRIPT_NAME']; + } + + /** + * @return string entry script URL (w/ host part) + */ + public function getAbsoluteApplicationUrl() + { + return $this->getBaseUrl() . $this->getApplicationUrl(); + } + + /** + * @return string application entry script file path (processed w/ realpath()) + */ + public function getApplicationFilePath() + { + return realpath($_SERVER['SCRIPT_FILENAME']); + } + + /** + * @return string server name + */ + public function getServerName() + { + return $_SERVER['SERVER_NAME']; + } + + /** + * @return integer server port number + */ + public function getServerPort() + { + return $_SERVER['SERVER_PORT']; + } + + /** + * @return string URL referrer, null if not present + */ + public function getUrlReferrer() + { + return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null; + } + + /** + * @return array user browser capabilities + * @see get_browser + */ + public function getBrowser() + { + return get_browser(); + } + + /** + * @return string user agent + */ + public function getUserAgent() + { + return $_SERVER['HTTP_USER_AGENT']; + } + + /** + * @return string user IP address + */ + public function getUserHostAddress() + { + return $_SERVER['REMOTE_ADDR']; + } + + /** + * @return string user host name, null if cannot be determined + */ + public function getUserHost() + { + return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null; + } + + /** + * @return string user browser accept types + */ + public function getAcceptTypes() + { + // TBD: break it into array?? + return $_SERVER['HTTP_ACCEPT']; + } + + /** + * Returns a list of user preferred languages. + * The languages are returned as an array. Each array element + * represents a single language preference. The languages are ordered + * according to user preferences. The first language is the most preferred. + * @return array list of user preferred languages. + */ + public function getUserLanguages() + { + return Prado::getUserLanguages(); + } + + /** + * @return boolean whether cookies should be validated. Defaults to false. + */ + public function getEnableCookieValidation() + { + return $this->_enableCookieValidation; + } + + /** + * @param boolean whether cookies should be validated. + */ + public function setEnableCookieValidation($value) + { + $this->_enableCookieValidation=TPropertyValue::ensureBoolean($value); + } + + /** + * @return THttpCookieCollection list of cookies to be sent + */ + public function getCookies() + { + if($this->_cookies===null) + { + $this->_cookies=new THttpCookieCollection; + if($this->getEnableCookieValidation()) + { + $sm=$this->getApplication()->getSecurityManager(); + foreach($_COOKIE as $key=>$value) + { + if(($value=$sm->validateData($value))!==false) + $this->_cookies->add(new THttpCookie($key,$value)); + } + } + else + { + foreach($_COOKIE as $key=>$value) + $this->_cookies->add(new THttpCookie($key,$value)); + } + } + return $this->_cookies; + } + + /** + * @return array list of uploaded files. + */ + public function getUploadedFiles() + { + return $_FILES; + } + + /** + * @return array list of server variables. + */ + public function getServerVariables() + { + return $_SERVER; + } + + /** + * @return array list of environment variables. + */ + public function getEnvironmentVariables() + { + return $_ENV; + } + + /** + * Constructs a URL that can be recognized by PRADO. + * The actual construction work is done by the URL manager module. + * This method may append session information to the generated URL if needed. + * You may provide your own URL manager module by setting {@link setUrlManager UrlManager} + * to provide your own URL scheme. + * @param string service ID + * @param string service parameter + * @param array GET parameters, null if not needed + * @param boolean whether to encode the ampersand in URL, defaults to true. + * @param boolean whether to encode the GET parameters (their names and values), defaults to false. + * @return string URL + * @see TUrlManager::constructUrl + */ + public function constructUrl($serviceID,$serviceParam,$getItems=null,$encodeAmpersand=true,$encodeGetItems=true) + { + $url=$this->_urlManager->constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems); + if($this->getForceSecureConnection()!==null) + $url = $this->getBaseUrl().$url; + if(defined('SID') && SID != '' && !$this->_cookieOnly) + return $url . (strpos($url,'?')===false? '?' : ($encodeAmpersand?'&':'&')) . SID; + else + return $url; + } + + /** + * Parses the request URL and returns an array of input parameters (excluding GET variables). + * You may override this method to support customized URL format. + * @return array list of input parameters, indexed by parameter names + * @see TUrlManager::parseUrl + */ + protected function parseUrl() + { + return $this->_urlManager->parseUrl(); + } + + /** + * Resolves the requested service. + * This method implements a URL-based service resolution. + * A URL in the format of /index.php?sp=serviceID.serviceParameter + * will be resolved with the serviceID and the serviceParameter. + * You may override this method to provide your own way of service resolution. + * @param array list of valid service IDs + * @return string the currently requested service ID, null if no service ID is found + * @see constructUrl + */ + public function resolveRequest($serviceIDs) + { + Prado::trace("Resolving request from ".$_SERVER['REMOTE_ADDR'],'System.Web.THttpRequest'); + $this->_items=array_merge($_GET,$this->parseUrl(),$_POST); + $this->_requestResolved=true; + foreach($serviceIDs as $serviceID) + { + if($this->contains($serviceID)) + { + $this->setServiceID($serviceID); + $this->setServiceParameter($this->itemAt($serviceID)); + return $serviceID; + } + } + return null; + } + + /** + * @return boolean true if request is already resolved, false otherwise. + */ + public function getRequestResolved() + { + return $this->_requestResolved; + } + + /** + * @return string requested service ID + */ + public function getServiceID() + { + return $this->_serviceID; + } + + /** + * Sets the requested service ID. + * @param string requested service ID + */ + public function setServiceID($value) + { + $this->_serviceID=$value; + } + + /** + * @return string requested service parameter + */ + public function getServiceParameter() + { + return $this->_serviceParam; + } + + /** + * Sets the requested service parameter. + * @param string requested service parameter + */ + public function setServiceParameter($value) + { + $this->_serviceParam=$value; + } + + //------ The following methods enable THttpRequest to be TMap-like ----- + + /** + * Returns an iterator for traversing the items in the list. + * This method is required by the interface IteratorAggregate. + * @return Iterator an iterator for traversing the items in the list. + */ + public function getIterator() + { + return new TMapIterator($this->_items); + } + + /** + * @return integer the number of items in the request + */ + public function getCount() + { + return count($this->_items); + } + + /** + * Returns the number of items in the request. + * This method is required by Countable interface. + * @return integer number of items in the request. + */ + public function count() + { + return $this->getCount(); + } + + /** + * @return array the key list + */ + public function getKeys() + { + return array_keys($this->_items); + } + + /** + * Returns the item with the specified key. + * This method is exactly the same as {@link offsetGet}. + * @param mixed the key + * @return mixed the element at the offset, null if no element is found at the offset + */ + public function itemAt($key) + { + return isset($this->_items[$key]) ? $this->_items[$key] : null; + } + + /** + * Adds an item into the request. + * Note, if the specified key already exists, the old value will be overwritten. + * @param mixed key + * @param mixed value + */ + public function add($key,$value) + { + $this->_items[$key]=$value; + } + + /** + * Removes an item from the request by its key. + * @param mixed the key of the item to be removed + * @return mixed the removed value, null if no such key exists. + * @throws TInvalidOperationException if the item cannot be removed + */ + public function remove($key) + { + if(isset($this->_items[$key]) || array_key_exists($key,$this->_items)) + { + $value=$this->_items[$key]; + unset($this->_items[$key]); + return $value; + } + else + return null; + } + + /** + * Removes all items in the request. + */ + public function clear() + { + foreach(array_keys($this->_items) as $key) + $this->remove($key); + } + + /** + * @param mixed the key + * @return boolean whether the request contains an item with the specified key + */ + public function contains($key) + { + return isset($this->_items[$key]) || array_key_exists($key,$this->_items); + } + + /** + * @return array the list of items in array + */ + public function toArray() + { + return $this->_items; + } + + /** + * Returns whether there is an element at the specified offset. + * This method is required by the interface ArrayAccess. + * @param mixed the offset to check on + * @return boolean + */ + public function offsetExists($offset) + { + return $this->contains($offset); + } + + /** + * Returns the element at the specified offset. + * This method is required by the interface ArrayAccess. + * @param integer the offset to retrieve element. + * @return mixed the element at the offset, null if no element is found at the offset + */ + public function offsetGet($offset) + { + return $this->itemAt($offset); + } + + /** + * Sets the element at the specified offset. + * This method is required by the interface ArrayAccess. + * @param integer the offset to set element + * @param mixed the element value + */ + public function offsetSet($offset,$item) + { + $this->add($offset,$item); + } + + /** + * Unsets the element at the specified offset. + * This method is required by the interface ArrayAccess. + * @param mixed the offset to unset element + */ + public function offsetUnset($offset) + { + $this->remove($offset); + } +} + +/** + * THttpCookieCollection class. + * + * THttpCookieCollection implements a collection class to store cookies. + * Besides using all functionalities from {@link TList}, you can also + * retrieve a cookie by its name using either {@link findCookieByName} or + * simply: + * + * $cookie=$collection[$cookieName]; + * + * + * @author Qiang Xue + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class THttpCookieCollection extends TList +{ + /** + * @var mixed owner of this collection + */ + private $_o; + + /** + * Constructor. + * @param mixed owner of this collection. + */ + public function __construct($owner=null) + { + $this->_o=$owner; + } + + /** + * Inserts an item at the specified position. + * This overrides the parent implementation by performing additional + * operations for each newly added THttpCookie object. + * @param integer the specified position. + * @param mixed new item + * @throws TInvalidDataTypeException if the item to be inserted is not a THttpCookie object. + */ + public function insertAt($index,$item) + { + if($item instanceof THttpCookie) + { + parent::insertAt($index,$item); + if($this->_o instanceof THttpResponse) + $this->_o->addCookie($item); + } + else + throw new TInvalidDataTypeException('httpcookiecollection_httpcookie_required'); + } + + /** + * Removes an item at the specified position. + * This overrides the parent implementation by performing additional + * cleanup work when removing a TCookie object. + * @param integer the index of the item to be removed. + * @return mixed the removed item. + */ + public function removeAt($index) + { + $item=parent::removeAt($index); + if($this->_o instanceof THttpResponse) + $this->_o->removeCookie($item); + return $item; + } + + /** + * @param integer|string index of the cookie in the collection or the cookie's name + * @return THttpCookie the cookie found + */ + public function itemAt($index) + { + if(is_integer($index)) + return parent::itemAt($index); + else + return $this->findCookieByName($index); + } + + /** + * Finds the cookie with the specified name. + * @param string the name of the cookie to be looked for + * @return THttpCookie the cookie, null if not found + */ + public function findCookieByName($name) + { + foreach($this as $cookie) + if($cookie->getName()===$name) + return $cookie; + return null; + } +} + +/** + * THttpCookie class. + * + * A THttpCookie instance stores a single cookie, including the cookie name, value, + * domain, path, expire, and secure. + * + * @author Qiang Xue + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class THttpCookie extends TComponent +{ + /** + * @var string domain of the cookie + */ + private $_domain=''; + /** + * @var string name of the cookie + */ + private $_name; + /** + * @var string value of the cookie + */ + private $_value=0; + /** + * @var integer expire of the cookie + */ + private $_expire=0; + /** + * @var string path of the cookie + */ + private $_path='/'; + /** + * @var boolean whether cookie should be sent via secure connection + */ + private $_secure=false; + + /** + * Constructor. + * @param string name of this cookie + * @param string value of this cookie + */ + public function __construct($name,$value) + { + $this->_name=$name; + $this->_value=$value; + } + + /** + * @return string the domain to associate the cookie with + */ + public function getDomain() + { + return $this->_domain; + } + + /** + * @param string the domain to associate the cookie with + */ + public function setDomain($value) + { + $this->_domain=$value; + } + + /** + * @return integer the time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. + */ + public function getExpire() + { + return $this->_expire; + } + + /** + * @param integer the time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. + */ + public function setExpire($value) + { + $this->_expire=TPropertyValue::ensureInteger($value); + } + + /** + * @return string the name of the cookie + */ + public function getName() + { + return $this->_name; + } + + /** + * @param string the name of the cookie + */ + public function setName($value) + { + $this->_name=$value; + } + + /** + * @return string the value of the cookie + */ + public function getValue() + { + return $this->_value; + } + + /** + * @param string the value of the cookie + */ + public function setValue($value) + { + $this->_value=$value; + } + + /** + * @return string the path on the server in which the cookie will be available on, default is '/' + */ + public function getPath() + { + return $this->_path; + } + + /** + * @param string the path on the server in which the cookie will be available on + */ + public function setPath($value) + { + $this->_path=$value; + } + + /** + * @return boolean whether the cookie should only be transmitted over a secure HTTPS connection + */ + public function getSecure() + { + return $this->_secure; + } + + /** + * @param boolean ether the cookie should only be transmitted over a secure HTTPS connection + */ + public function setSecure($value) + { + $this->_secure=TPropertyValue::ensureBoolean($value); + } +} + +/** + * TUri class + * + * TUri represents a URI. Given a URI + * http://joe:whatever@example.com:8080/path/to/script.php?param=value#anchor + * it will be decomposed as follows, + * - scheme: http + * - host: example.com + * - port: 8080 + * - user: joe + * - password: whatever + * - path: /path/to/script.php + * - query: param=value + * - fragment: anchor + * + * @author Qiang Xue + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class TUri extends TComponent +{ + /** + * @var array list of default ports for known schemes + */ + private static $_defaultPort=array( + 'ftp'=>21, + 'gopher'=>70, + 'http'=>80, + 'https'=>443, + 'news'=>119, + 'nntp'=>119, + 'wais'=>210, + 'telnet'=>23 + ); + /** + * @var string scheme of the URI + */ + private $_scheme; + /** + * @var string host name of the URI + */ + private $_host; + /** + * @var integer port of the URI + */ + private $_port; + /** + * @var string user of the URI + */ + private $_user; + /** + * @var string password of the URI + */ + private $_pass; + /** + * @var string path of the URI + */ + private $_path; + /** + * @var string query string of the URI + */ + private $_query; + /** + * @var string fragment of the URI + */ + private $_fragment; + /** + * @var string the URI + */ + private $_uri; + + /** + * Constructor. + * Decomposes the specified URI into parts. + * @param string URI to be represented + * @throws TInvalidDataValueException if URI is of bad format + */ + public function __construct($uri) + { + if(($ret=@parse_url($uri))!==false) + { + // decoding??? + $this->_scheme=isset($ret['scheme'])?$ret['scheme']:''; + $this->_host=isset($ret['host'])?$ret['host']:''; + $this->_port=isset($ret['port'])?$ret['port']:''; + $this->_user=isset($ret['user'])?$ret['user']:''; + $this->_pass=isset($ret['pass'])?$ret['pass']:''; + $this->_path=isset($ret['path'])?$ret['path']:''; + $this->_query=isset($ret['query'])?$ret['query']:''; + $this->_fragment=isset($ret['fragment'])?$ret['fragment']:''; + $this->_uri=$uri; + } + else + { + throw new TInvalidDataValueException('uri_format_invalid',$uri); + } + } + + /** + * @return string URI + */ + public function getUri() + { + return $this->_uri; + } + + /** + * @return string scheme of the URI, such as 'http', 'https', 'ftp', etc. + */ + public function getScheme() + { + return $this->_scheme; + } + + /** + * @return string hostname of the URI + */ + public function getHost() + { + return $this->_host; + } + + /** + * @return integer port number of the URI + */ + public function getPort() + { + return $this->_port; + } + + /** + * @return string username of the URI + */ + public function getUser() + { + return $this->_user; + } + + /** + * @return string password of the URI + */ + public function getPassword() + { + return $this->_pass; + } + + /** + * @return string path of the URI + */ + public function getPath() + { + return $this->_path; + } + + /** + * @return string query string of the URI + */ + public function getQuery() + { + return $this->_query; + } + + /** + * @return string fragment of the URI + */ + public function getFragment() + { + return $this->_fragment; + } +} + +/** + * THttpRequestUrlFormat class. + * THttpRequestUrlFormat defines the enumerable type for the possible URL formats + * that can be recognized by {@link THttpRequest}. + * + * The following enumerable values are defined: + * - Get: the URL format is like /path/to/index.php?name1=value1&name2=value2... + * - Path: the URL format is like /path/to/index.php/name1,value1/name2,value2... + * + * @author Qiang Xue + * @version $Id$ + * @package System.Web + * @since 3.0.4 + */ +class THttpRequestUrlFormat extends TEnumerable +{ + const Get='Get'; + const Path='Path'; +} + ?> \ No newline at end of file -- cgit v1.2.3