summaryrefslogtreecommitdiff
path: root/framework/Web/THttpRequest.php
diff options
context:
space:
mode:
authorcarl <>2007-08-04 16:21:24 +0000
committercarl <>2007-08-04 16:21:24 +0000
commit8c964555633510dd85def6836f4b720366dce5ef (patch)
tree8cff91d456e1ce3e196cb045dca23f8ea717fe50 /framework/Web/THttpRequest.php
parent6875b48357e96b98a3c21794bb553ffad83ed0ab (diff)
Fixed #672
Diffstat (limited to 'framework/Web/THttpRequest.php')
-rw-r--r--framework/Web/THttpRequest.php2437
1 files changed, 1225 insertions, 1212 deletions
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 @@
-<?php
-/**
- * THttpRequest, THttpCookie, THttpCookieCollection, TUri class file
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 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,
- * <code>
- * if(isset($request['param1'])) ...
- * // equivalent to:
- * // if($request->contains('param1')) ...
- * </code>
- * To get the value of 'param1', use,
- * <code>
- * $value=$request['param1'];
- * // equivalent to:
- * // $value=$request->itemAt('param1');
- * </code>
- * To traverse the user post data, use
- * <code>
- * foreach($request as $name=>$value) ...
- * </code>
- * 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:
- * <code>
- * /index.php?ServiceID=ServiceParameter&Name1=Value1&Name2=Value2
- * /index.php/ServiceID,ServiceParameter/Name1,Value1/Name2,Value2
- * </code>
- * 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 <qiang.xue@gmail.com>
- * @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?'&amp;':'&')) . 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:
- * <code>
- * $cookie=$collection[$cookieName];
- * </code>
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @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 <qiang.xue@gmail.com>
- * @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 <qiang.xue@gmail.com>
- * @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 <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web
- * @since 3.0.4
- */
-class THttpRequestUrlFormat extends TEnumerable
-{
- const Get='Get';
- const Path='Path';
-}
-
+<?php
+/**
+ * THttpRequest, THttpCookie, THttpCookieCollection, TUri class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 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,
+ * <code>
+ * if(isset($request['param1'])) ...
+ * // equivalent to:
+ * // if($request->contains('param1')) ...
+ * </code>
+ * To get the value of 'param1', use,
+ * <code>
+ * $value=$request['param1'];
+ * // equivalent to:
+ * // $value=$request->itemAt('param1');
+ * </code>
+ * To traverse the user post data, use
+ * <code>
+ * foreach($request as $name=>$value) ...
+ * </code>
+ * 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:
+ * <code>
+ * /index.php?ServiceID=ServiceParameter&Name1=Value1&Name2=Value2
+ * /index.php/ServiceID,ServiceParameter/Name1,Value1/Name2,Value2
+ * </code>
+ * 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 <qiang.xue@gmail.com>
+ * @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?'&amp;':'&')) . 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:
+ * <code>
+ * $cookie=$collection[$cookieName];
+ * </code>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @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 <qiang.xue@gmail.com>
+ * @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 <qiang.xue@gmail.com>
+ * @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 <qiang.xue@gmail.com>
+ * @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