2007-08-17 05:32:14 +02:00
< ? php
/**
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
* Represents a response returned by a controller .
2008-02-25 03:10:37 +01:00
*
2012-04-12 08:02:46 +02:00
* @ package framework
2008-02-25 03:10:37 +01:00
* @ subpackage control
2007-08-17 05:32:14 +02:00
*/
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
class SS_HTTPResponse {
2010-11-23 20:38:15 +01:00
/**
* @ var array
*/
2007-08-17 05:32:14 +02:00
protected static $status_codes = array (
100 => 'Continue' ,
101 => 'Switching Protocols' ,
200 => 'OK' ,
201 => 'Created' ,
202 => 'Accepted' ,
203 => 'Non-Authoritative Information' ,
204 => 'No Content' ,
205 => 'Reset Content' ,
206 => 'Partial Content' ,
301 => 'Moved Permanently' ,
302 => 'Found' ,
303 => 'See Other' ,
304 => 'Not Modified' ,
305 => 'Use Proxy' ,
307 => 'Temporary Redirect' ,
400 => 'Bad Request' ,
401 => 'Unauthorized' ,
403 => 'Forbidden' ,
404 => 'Not Found' ,
405 => 'Method Not Allowed' ,
406 => 'Not Acceptable' ,
407 => 'Proxy Authentication Required' ,
408 => 'Request Timeout' ,
409 => 'Conflict' ,
410 => 'Gone' ,
411 => 'Length Required' ,
412 => 'Precondition Failed' ,
413 => 'Request Entity Too Large' ,
414 => 'Request-URI Too Long' ,
415 => 'Unsupported Media Type' ,
416 => 'Request Range Not Satisfiable' ,
417 => 'Expectation Failed' ,
2010-10-15 01:56:33 +02:00
422 => 'Unprocessable Entity' ,
2007-08-17 05:32:14 +02:00
500 => 'Internal Server Error' ,
501 => 'Not Implemented' ,
502 => 'Bad Gateway' ,
503 => 'Service Unavailable' ,
504 => 'Gateway Timeout' ,
505 => 'HTTP Version Not Supported' ,
);
2010-11-23 20:38:15 +01:00
/**
* @ var array
*/
2008-04-22 03:45:55 +02:00
protected static $redirect_codes = array (
301 ,
302 ,
303 ,
304 ,
305 ,
2008-11-28 06:29:52 +01:00
307
2008-04-22 03:45:55 +02:00
);
2010-11-23 20:38:15 +01:00
/**
* @ var Int
*/
2007-08-17 05:32:14 +02:00
protected $statusCode = 200 ;
2010-11-23 20:38:15 +01:00
/**
* @ var String
*/
2008-09-12 03:47:39 +02:00
protected $statusDescription = " OK " ;
2008-08-09 09:03:24 +02:00
/**
* HTTP Headers like " Content-Type: text/xml "
*
* @ see http :// en . wikipedia . org / wiki / List_of_HTTP_headers
* @ var array
*/
2009-10-06 23:44:38 +02:00
protected $headers = array (
2011-07-15 07:05:50 +02:00
" Content-Type " => " text/html; charset=utf-8 " ,
2009-10-06 23:44:38 +02:00
);
2008-08-09 09:03:24 +02:00
/**
* @ var string
*/
2007-08-17 05:32:14 +02:00
protected $body = null ;
2008-09-12 03:47:39 +02:00
/**
* Create a new HTTP response
2010-11-23 20:38:15 +01:00
*
2008-09-12 03:47:39 +02:00
* @ param $body The body of the response
* @ param $statusCode The numeric status code - 200 , 404 , etc
2010-11-23 20:38:15 +01:00
* @ param $statusDescription The text to be given alongside the status code .
* See { @ link setStatusCode ()} for more information .
2008-09-12 03:47:39 +02:00
*/
2012-09-19 12:07:39 +02:00
public function __construct ( $body = null , $statusCode = null , $statusDescription = null ) {
2011-07-26 08:25:09 +02:00
$this -> setBody ( $body );
2008-09-12 03:47:39 +02:00
if ( $statusCode ) $this -> setStatusCode ( $statusCode , $statusDescription );
}
2010-11-23 20:38:15 +01:00
/**
* @ param String $code
* @ param String $description Optional . See { @ link setStatusDescription ()} .
* No newlines are allowed in the description .
* If omitted , will default to the standard HTTP description
* for the given $code value ( see { @ link $status_codes }) .
2012-09-22 00:20:12 +02:00
* @ return SS_HTTPRequest $this
2010-11-23 20:38:15 +01:00
*/
2012-09-19 12:07:39 +02:00
public function setStatusCode ( $code , $description = null ) {
2007-08-17 05:32:14 +02:00
if ( isset ( self :: $status_codes [ $code ])) $this -> statusCode = $code ;
else user_error ( " Unrecognised HTTP status code ' $code ' " , E_USER_WARNING );
2008-09-12 03:47:39 +02:00
if ( $description ) $this -> statusDescription = $description ;
else $this -> statusDescription = self :: $status_codes [ $code ];
2012-09-22 00:20:12 +02:00
return $this ;
2007-08-17 05:32:14 +02:00
}
2008-08-09 09:03:24 +02:00
2010-11-23 20:38:15 +01:00
/**
* The text to be given alongside the status code ( " reason phrase " ) .
* Caution : Will be overwritten by { @ link setStatusCode ()} .
*
2012-09-22 00:20:12 +02:00
* @ param String $description
* @ return SS_HTTPRequest $this
2010-11-23 20:38:15 +01:00
*/
2012-09-19 12:07:39 +02:00
public function setStatusDescription ( $description ) {
2010-11-23 20:38:15 +01:00
$this -> statusDescription = $description ;
2012-09-22 00:20:12 +02:00
return $this ;
2010-11-23 20:38:15 +01:00
}
/**
* @ return Int
*/
2012-09-19 12:07:39 +02:00
public function getStatusCode () {
2007-12-02 22:29:31 +01:00
return $this -> statusCode ;
}
2008-08-11 05:03:52 +02:00
/**
* @ return string Description for a HTTP status code
*/
2012-09-19 12:07:39 +02:00
public function getStatusDescription () {
2010-11-23 20:38:15 +01:00
return str_replace ( array ( " \r " , " \n " ), '' , $this -> statusDescription );
2008-08-11 05:03:52 +02:00
}
2007-08-17 05:32:14 +02:00
2008-08-11 02:03:57 +02:00
/**
* Returns true if this HTTP response is in error
2012-09-22 00:20:12 +02:00
*
* @ return bool
2008-08-11 02:03:57 +02:00
*/
2012-09-19 12:07:39 +02:00
public function isError () {
2008-08-11 02:03:57 +02:00
return $this -> statusCode && ( $this -> statusCode < 200 || $this -> statusCode > 399 );
}
2012-09-22 00:20:12 +02:00
/**
* @ param string $body
* @ return SS_HTTPRequest $this
*/
2012-09-19 12:07:39 +02:00
public function setBody ( $body ) {
2007-08-17 05:32:14 +02:00
$this -> body = $body ;
2011-07-26 08:25:09 +02:00
// Set content-length in bytes. Use mbstring to avoid problems with mb_internal_encoding() and mbstring.func_overload
2012-02-06 11:54:48 +01:00
$this -> headers [ 'Content-Length' ] = mb_strlen ( $this -> body , '8bit' );
2012-09-22 00:20:12 +02:00
return $this ;
2007-08-17 05:32:14 +02:00
}
2012-09-22 00:20:12 +02:00
/**
* @ return null | string
*/
2012-09-19 12:07:39 +02:00
public function getBody () {
2007-08-17 05:32:14 +02:00
return $this -> body ;
}
2007-08-27 07:09:54 +02:00
/**
2008-08-09 09:03:24 +02:00
* Add a HTTP header to the response , replacing any header of the same name .
*
* @ param string $header Example : " Content-Type "
2012-09-22 00:20:12 +02:00
* @ param string $value Example : " text/xml "
* @ return SS_HTTPRequest $this
2007-08-27 07:09:54 +02:00
*/
2012-09-19 12:07:39 +02:00
public function addHeader ( $header , $value ) {
2007-08-17 05:32:14 +02:00
$this -> headers [ $header ] = $value ;
2012-09-22 00:20:12 +02:00
return $this ;
2007-08-17 05:32:14 +02:00
}
2007-08-27 07:09:54 +02:00
/**
2008-08-09 09:03:24 +02:00
* Return the HTTP header of the given name .
*
* @ param string $header
2012-09-22 00:20:12 +02:00
* @ returns null | string
2007-08-27 07:09:54 +02:00
*/
2012-09-19 12:07:39 +02:00
public function getHeader ( $header ) {
2012-09-22 00:20:12 +02:00
if ( isset ( $this -> headers [ $header ]))
return $this -> headers [ $header ];
return null ;
2007-08-27 07:09:54 +02:00
}
2008-08-09 09:03:24 +02:00
/**
* @ return array
*/
2012-09-19 12:07:39 +02:00
public function getHeaders () {
2008-08-09 09:03:24 +02:00
return $this -> headers ;
}
/**
* Remove an existing HTTP header by its name ,
* e . g . " Content-Type " .
*
2012-09-22 00:20:12 +02:00
* @ param string $header
* @ return SS_HTTPRequest $this
2008-08-09 09:03:24 +02:00
*/
2012-09-19 12:07:39 +02:00
public function removeHeader ( $header ) {
2008-08-09 09:03:24 +02:00
if ( isset ( $this -> headers [ $header ])) unset ( $this -> headers [ $header ]);
2012-09-22 00:20:12 +02:00
return $this ;
2008-08-09 09:03:24 +02:00
}
2012-09-22 00:20:12 +02:00
/**
* @ param string $dest
* @ param int $code
* @ return SS_HTTPRequest $this
*/
2012-09-19 12:07:39 +02:00
public function redirect ( $dest , $code = 302 ) {
2008-04-22 03:45:55 +02:00
if ( ! in_array ( $code , self :: $redirect_codes )) $code = 302 ;
2011-03-16 10:18:57 +01:00
$this -> setStatusCode ( $code );
2007-08-17 05:32:14 +02:00
$this -> headers [ 'Location' ] = $dest ;
2012-09-22 00:20:12 +02:00
return $this ;
2007-08-17 05:32:14 +02:00
}
/**
* Send this HTTPReponse to the browser
*/
2012-09-19 12:07:39 +02:00
public function output () {
2008-11-12 05:31:33 +01:00
// Attach appropriate X-Include-JavaScript and X-Include-CSS headers
if ( Director :: is_ajax ()) {
Requirements :: include_in_response ( $this );
}
2008-11-28 06:29:52 +01:00
2008-04-22 03:45:55 +02:00
if ( in_array ( $this -> statusCode , self :: $redirect_codes ) && headers_sent ( $file , $line )) {
2007-08-17 05:32:14 +02:00
$url = $this -> headers [ 'Location' ];
2008-08-11 05:03:52 +02:00
echo
2007-08-17 05:32:14 +02:00
" <p>Redirecting to <a href= \" $url\ " title = \ " Please click this link if your browser does not redirect you \" > $url ... (output started on $file , line $line )</a></p>
< meta http - equiv = \ " refresh \" content= \" 1; url= $url\ " />
< script type = \ " text/javascript \" >setTimeout('window.location.href = \" $url\ " ' , 50 ); </ script > " ;
} else {
if ( ! headers_sent ()) {
2008-09-29 22:23:47 +02:00
header ( $_SERVER [ 'SERVER_PROTOCOL' ] . " $this->statusCode " . $this -> getStatusDescription ());
2007-08-17 05:32:14 +02:00
foreach ( $this -> headers as $header => $value ) {
2011-09-18 21:46:58 +02:00
header ( " $header : $value " , true , $this -> statusCode );
2007-08-17 05:32:14 +02:00
}
}
2009-04-03 20:57:17 +02:00
// Only show error pages or generic "friendly" errors if the status code signifies
// an error, and the response doesn't have any body yet that might contain
// a more specific error description.
if ( Director :: isLive () && $this -> isError () && ! $this -> body ) {
2008-10-01 16:43:43 +02:00
Debug :: friendlyError ( $this -> statusCode , $this -> getStatusDescription ());
} else {
echo $this -> body ;
}
2007-08-17 05:32:14 +02:00
}
}
/**
* Returns true if this response is " finished " , that is , no more script execution should be done .
* Specifically , returns true if a redirect has already been requested
2012-09-22 00:20:12 +02:00
*
* @ return bool
2007-08-17 05:32:14 +02:00
*/
2012-09-19 12:07:39 +02:00
public function isFinished () {
2009-03-20 00:04:48 +01:00
return in_array ( $this -> statusCode , array ( 301 , 302 , 401 , 403 ));
2007-08-17 05:32:14 +02:00
}
2009-10-11 02:06:53 +02:00
2009-03-10 23:17:26 +01:00
}
2009-06-27 10:48:44 +02:00
/**
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
* A { @ link SS_HTTPResponse } encapsulated in an exception , which can interrupt the processing flow and be caught by the
2009-06-27 10:48:44 +02:00
* { @ link RequestHandler } and returned to the user .
*
* Example Usage :
* < code >
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
* throw new SS_HTTPResponse_Exception ( 'This request was invalid.' , 400 );
* throw new SS_HTTPResponse_Exception ( new SS_HTTPResponse ( 'There was an internal server error.' , 500 ));
2009-06-27 10:48:44 +02:00
* </ code >
*
2012-04-12 08:02:46 +02:00
* @ package framework
2009-06-27 10:48:44 +02:00
* @ subpackage control
*/
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
class SS_HTTPResponse_Exception extends Exception {
2009-06-27 10:48:44 +02:00
protected $response ;
/**
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
* @ see SS_HTTPResponse :: __construct ();
2009-06-27 10:48:44 +02:00
*/
public function __construct ( $body = null , $statusCode = null , $statusDescription = null ) {
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
if ( $body instanceof SS_HTTPResponse ) {
2009-06-27 10:48:44 +02:00
$this -> setResponse ( $body );
} else {
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
$this -> setResponse ( new SS_HTTPResponse ( $body , $statusCode , $statusDescription ));
2009-06-27 10:48:44 +02:00
}
parent :: __construct ( $this -> getResponse () -> getBody (), $this -> getResponse () -> getStatusCode ());
}
/**
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
* @ return SS_HTTPResponse
2009-06-27 10:48:44 +02:00
*/
public function getResponse () {
return $this -> response ;
}
/**
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
* @ param SS_HTTPResponse $response
2009-06-27 10:48:44 +02:00
*/
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
public function setResponse ( SS_HTTPResponse $response ) {
2009-06-27 10:48:44 +02:00
$this -> response = $response ;
}
}