Commit 53a75a7a authored by Alain Vagner's avatar Alain Vagner

No commit message

No commit message
parent 8d4a3af2
- securiser les variables get et les paramètres de l'url, et les variables en post si form-urlencoded
- intégration dans front controller framework sur base du préfixe
- gérer les TODO et les FIXME
- cache (p.244)
- doc
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of libReviens.
# Copyright (c) 2007 Luc Dehand and Alain Vagner.
# All rights reserved.
#
# libReviens is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# libReviens is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with libReviens; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
/**
* root resource class
* lists all services
* @package REST
* @author Luc Dehand - Alain Vagner
*/
class DefaultRootResource implements RESTRootResource {
/**
* list of resources
*/
private $listResources;
/**
* reference to the request object
*/
private $request;
/**
* Constructor
* @param HttpRequest $pReq request
*/
public function __construct(HttpRequest $pReq) {
$this->request = $pReq;
}
/**
* list of items (this method is optional)
* @param string $pLogin login
* @param string $pPass password
* @return boolean true if the login is successful or if it is a public resource
*/
public function auth($pLogin, $pPass) {
return true;
}
/**
* list of services
* GET /
* or HEAD /
* @param boolean $pHead true if we return only headers
*/
public function index($pHead = false) {
if ($pHead) {
return;
}
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
echo '<html><head><title>List of services</title></head><body><ul>';
foreach (ServiceEnumerator::listDefinedResources() as $i) {
echo '<li><a href="./'.$i.'/">'.$i.'</a></li>';
}
echo '</ul></body></html>';
}
}
?>
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of libReviens.
# Copyright (c) 2007 Luc Dehand and Alain Vagner.
# All rights reserved.
#
# libReviens is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# libReviens is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with libReviens; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
/**
* Http Request class
* @package REST
* @author Luc Dehand - Alain Vagner
*/
class HttpRequest {
/**
* data passed to the REST web service
*/
private $input;
/**
* http method used on the resource (get, put post, delete, ...)
*/
private $method;
/**
* path of the resource
*/
private $path;
/**
* content_type of the input data
*/
private $content_type;
/**
* basic auth login
*/
private $login;
/**
* basic auth password
*/
private $password;
/**
* Constructor
* @param string $pPathInfo overrides server path_info (optional)
*/
function __construct($pPathInfo = null) {
$this->input = file_get_contents('php://input');
$this->method = strtoupper($_SERVER['REQUEST_METHOD']);
$headers = apache_request_headers();
$this->content_type = (isset($headers['Content-Type']))?$headers['Content-Type']:'';
// http basic auth handling
if (isset($headers['Authorization'])) {
$matches = array();
preg_match('/^Basic (.+)/', $headers['Authorization'], $matches);
if (isset($matches[1])) {
$str = base64_decode($matches[1], true);
if ($str !== false) {
$credentials = explode(':', $str);
if (count($credentials) == 2) {
$this->login = $credentials[0];
$this->password = $credentials[1];
} else {
throw new RESTException('Invalid Authorization token', 409);
}
} else {
throw new RESTException('Invalid Authorization token', 409);
}
} else {
throw new RESTException('Authorization type not handled', 409);
}
} else {
$this->login = '';
$this->password = '';
}
// TODO sécuriser path, GET et si possible POST (quand input n'est pas du xml)
if ($pPathInfo != null) {
$this->path = $pPathInfo;
} else {
if (isset($_SERVER['PATH_INFO'])) {
$this->path = $_SERVER['PATH_INFO'];
} else {
$this->path = '';
}
}
}
/**
* Returns raw input data
* @return string raw input data
*/
public function getInput() {
return $this->input;
}
/**
* Returns http method
* @return string http method
*/
public function getMethod() {
return $this->method;
}
/**
* Returns resource path
* @return string path
*/
public function getPath() {
return $this->path;
}
/**
* Returns input content type
* @return string Content Type
*/
public function getContentType() {
return $this->content_type;
}
/**
* Returns basic auth login
* @return string login
*/
public function getLogin() {
return $this->login;
}
/**
* Returns basic auth password
* @return string password
*/
public function getPassword() {
return $this->password;
}
/**
* This function gives you access to the parsed and validated input DOMDocument
* @param string $pSchema path to the schema file used to validate the input document
* @return DOMDocument dom of the input document
*/
public function getInputDOM($pSchema = null)
{
/* Enable user error handling */
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
/* load the XML Schema using our own Error Handler */
if(!@$doc->loadXML($this->input))
{
$message = ": ";
$errors = libxml_get_errors();
foreach ($errors as $error) {
$message .= "(" . $error->code . ")" . trim($error->message) . " on line " . $error->line . "; ";
}
libxml_clear_errors();
/* there is a problem with the XML, throw a 400 BAD REQUEST*/
throw new RESTException("XML Parse Error".$message, 400);
}
/* validate the XML Schema using our own Error Handler */
if(isset($pSchema) && !@$doc->schemaValidate($pSchema))
{
$message = ": ";
$errors = libxml_get_errors();
foreach ($errors as $error) {
$message .= "(" . $error->code . ")" . trim($error->message) . " on line " . $error->line . "; ";
}
libxml_clear_errors();
/* there is a problem with the XML, throw a 400 BAD REQUEST*/
throw new RESTException("XML Validation Error".$message, 400);
}
return $doc;
}
}
?>
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of libReviens.
# Copyright (c) 2007 Luc Dehand and Alain Vagner.
# All rights reserved.
#
# libReviens is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# libReviens is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with libReviens; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
/**
* Http Status
* @package REST
* @author Luc Dehand - Alain Vagner
*/
class HttpStatus {
// from http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
public static $http_status_codes = array(
# 1xx informational
100 => 'Continue',
101 => 'Switching Protocols',
# 2xx Successful
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
203 => 'Non-Authoritative Information',
204 => 'No Content',
205 => 'Reset Content',
206 => 'Partial Content',
# 3xx Redirection
300 => 'Multiple Choices',
301 => 'Moved Permanently',
302 => 'Found',
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
307 => 'Temporary Redirect',
# 4xx Client Error
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
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',
# 5xx Server Error
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
505 => 'HTTP Version Not Supported'
);
public static function getMessage($pId) {
$msg = self::$http_status_codes[$pId];
return $pId.' '.$msg;
}
}
?>
This diff is collapsed.
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of libReviens.
# Copyright (c) 2007 Luc Dehand and Alain Vagner.
# All rights reserved.
#
# libReviens is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# libReviens is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with libReviens; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
/**
* REST Exception, handles http error codes
* @package REST
* @author Luc Dehand - Alain Vagner
*/
class RESTException extends Exception
{
/**
* http status code
* we do not use directly the error code which is in the Exception class,
* because it can be used for other things
*/
public $code;
/**
* additional headers
*/
public $additional_headers;
/**
* Constructor
* @param string $pMsg Error message
* @param string $pErrorCode HTTP Error Code
* @param array $pAddHeaders additional headers
*/
function __construct($pMsg, $pErrorCode = 500, $pAddHeaders = array()) {
parent::__construct($pMsg);
$this->code = $pErrorCode;
$this->additional_headers = $pAddHeaders;
}
public function getStatusCode() {
return $this->code;
}
public function getAdditionalHeaders() {
return $this->additional_headers;
}
public function sendError() {
$message = $this->getMessage();
$code = $this->getStatusCode();
header("HTTP/1.0 ".httpStatus::getMessage($code));
foreach ($this->getAdditionalHeaders() as $k => $v) {
header($k.': '.$v, false);
}
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
echo '<html>';
echo '<head><title>Error</title></head>';
echo '<body><p>Error '.httpStatus::getMessage($code).'</p>';
echo '<p>'.$this->getMessage().'</p></body>';
echo '</html>';
}
}
?>
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of libReviens.
# Copyright (c) 2007 Luc Dehand and Alain Vagner.
# All rights reserved.
#
# libReviens is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# libReviens is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with libReviens; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
/**
* REST resource interface
* @package REST
* @author Luc Dehand - Alain Vagner
*/
interface restresource {
/**
* Constructor
* @param HttpRequest $pReq request
* @param string $pExt extension
* @param array $pConstraints list of constraints on this resource
*/
public function __construct(HttpRequest $pReq, $pExt = null, $pConstraints = array());
/**
* authentication
* @param string $pLogin login
* @param string $pPass password
* @return boolean true if the login is successful or if it is a public resource
*/
public function auth($pLogin, $pPass);
}
?>
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of libReviens.
# Copyright (c) 2007 Luc Dehand and Alain Vagner.
# All rights reserved.
#
# libReviens is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# libReviens is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with libReviens; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
/**
* REST root resource interface
* @package REST
* @author Luc Dehand - Alain Vagner
*/
interface RESTRootResource {
/**
* Constructor
* @param HttpRequest $pReq request
*/
public function __construct(HttpRequest $pReq);
/**
* authentication
* @param string $pLogin login
* @param string $pPass password
* @return boolean true if the login is successful or if it is a public resource
*/
public function auth($pLogin, $pPass);
/**
* list of services
* @param boolean $pHead true if we return only headers
*/
public function index($pHead = false);
}
?>
<?php
require_once dirname(__FILE__) ."/../includes/common.php";
$app_name = 'test web service';
try {
$re = new HttpRequest();
$root = new DefaultRootResource($re);
$fc = new RESTC($re, $root, $app_name);
$fc->dispatch();
} catch (RESTException $e) {
$e->sendError();
} catch (Exception $e) {
$ne = new RESTException($e->getMessage(), 500);
$ne->sendError();
}
?>
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of libReviens.
# Copyright (c) 2007 Luc Dehand and Alain Vagner.
# All rights reserved.
#
# libReviens is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# libReviens is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with libReviens; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
/**
* Service Enumerator, lists the resources classes
* @package REST
* @author Luc Dehand - Alain Vagner
*/
class ServiceEnumerator
{
private static $listResources = null;
/**
* get the list of resources implemented in the folder rest/resources
* @return array list of resources
*/
public static function listDefinedResources() {
$resources = array();
if (self::$listResources === null) {
$dir = new DirectoryIterator(RESOURCES_PATH);
foreach ($dir as $file) {
$filename = $file->getFileName();
$matches = array();
$res = preg_match('/(.*)\.class\.php$/', $filename, &$matches);
if (isset($matches[1])) {
$resources[] = $matches[1];
}
}
self::$listResources = $resources;
} else {
$resources = self::$listResources;
}
return $resources;
}
}
?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment