mirror of
https://git.friendi.ca/friendica/friendica-addons.git
synced 2025-07-07 17:08:48 +00:00
Initial Release of the calendar plugin
This commit is contained in:
parent
45cc9885fc
commit
7115197a33
561 changed files with 189494 additions and 0 deletions
227
dav/SabreDAV/lib/Sabre/HTTP/AWSAuth.php
Normal file
227
dav/SabreDAV/lib/Sabre/HTTP/AWSAuth.php
Normal file
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* HTTP AWS Authentication handler
|
||||
*
|
||||
* Use this class to leverage amazon's AWS authentication header
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
|
||||
|
||||
/**
|
||||
* The signature supplied by the HTTP client
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $signature = null;
|
||||
|
||||
/**
|
||||
* The accesskey supplied by the HTTP client
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $accessKey = null;
|
||||
|
||||
/**
|
||||
* An error code, if any
|
||||
*
|
||||
* This value will be filled with one of the ERR_* constants
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $errorCode = 0;
|
||||
|
||||
const ERR_NOAWSHEADER = 1;
|
||||
const ERR_MD5CHECKSUMWRONG = 2;
|
||||
const ERR_INVALIDDATEFORMAT = 3;
|
||||
const ERR_REQUESTTIMESKEWED = 4;
|
||||
const ERR_INVALIDSIGNATURE = 5;
|
||||
|
||||
/**
|
||||
* Gathers all information from the headers
|
||||
*
|
||||
* This method needs to be called prior to anything else.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
$authHeader = $this->httpRequest->getHeader('Authorization');
|
||||
$authHeader = explode(' ',$authHeader);
|
||||
|
||||
if ($authHeader[0]!='AWS' || !isset($authHeader[1])) {
|
||||
$this->errorCode = self::ERR_NOAWSHEADER;
|
||||
return false;
|
||||
}
|
||||
|
||||
list($this->accessKey,$this->signature) = explode(':',$authHeader[1]);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username for the request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAccessKey() {
|
||||
|
||||
return $this->accessKey;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the signature based on the secretKey
|
||||
*
|
||||
* @param string $secretKey
|
||||
* @return bool
|
||||
*/
|
||||
public function validate($secretKey) {
|
||||
|
||||
$contentMD5 = $this->httpRequest->getHeader('Content-MD5');
|
||||
|
||||
if ($contentMD5) {
|
||||
// We need to validate the integrity of the request
|
||||
$body = $this->httpRequest->getBody(true);
|
||||
$this->httpRequest->setBody($body,true);
|
||||
|
||||
if ($contentMD5!=base64_encode(md5($body,true))) {
|
||||
// content-md5 header did not match md5 signature of body
|
||||
$this->errorCode = self::ERR_MD5CHECKSUMWRONG;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!$requestDate = $this->httpRequest->getHeader('x-amz-date'))
|
||||
$requestDate = $this->httpRequest->getHeader('Date');
|
||||
|
||||
if (!$this->validateRFC2616Date($requestDate))
|
||||
return false;
|
||||
|
||||
$amzHeaders = $this->getAmzHeaders();
|
||||
|
||||
$signature = base64_encode(
|
||||
$this->hmacsha1($secretKey,
|
||||
$this->httpRequest->getMethod() . "\n" .
|
||||
$contentMD5 . "\n" .
|
||||
$this->httpRequest->getHeader('Content-type') . "\n" .
|
||||
$requestDate . "\n" .
|
||||
$amzHeaders .
|
||||
$this->httpRequest->getURI()
|
||||
)
|
||||
);
|
||||
|
||||
if ($this->signature != $signature) {
|
||||
|
||||
$this->errorCode = self::ERR_INVALIDSIGNATURE;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an HTTP 401 header, forcing login
|
||||
*
|
||||
* This should be called when username and password are incorrect, or not supplied at all
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function requireLogin() {
|
||||
|
||||
$this->httpResponse->setHeader('WWW-Authenticate','AWS');
|
||||
$this->httpResponse->sendStatus(401);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the supplied value is a valid RFC2616 date.
|
||||
*
|
||||
* If we would just use strtotime to get a valid timestamp, we have no way of checking if a
|
||||
* user just supplied the word 'now' for the date header.
|
||||
*
|
||||
* This function also makes sure the Date header is within 15 minutes of the operating
|
||||
* system date, to prevent replay attacks.
|
||||
*
|
||||
* @param string $dateHeader
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateRFC2616Date($dateHeader) {
|
||||
|
||||
$date = Sabre_HTTP_Util::parseHTTPDate($dateHeader);
|
||||
|
||||
// Unknown format
|
||||
if (!$date) {
|
||||
$this->errorCode = self::ERR_INVALIDDATEFORMAT;
|
||||
return false;
|
||||
}
|
||||
|
||||
$min = new DateTime('-15 minutes');
|
||||
$max = new DateTime('+15 minutes');
|
||||
|
||||
// We allow 15 minutes around the current date/time
|
||||
if ($date > $max || $date < $min) {
|
||||
$this->errorCode = self::ERR_REQUESTTIMESKEWED;
|
||||
return false;
|
||||
}
|
||||
|
||||
return $date;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of AMZ headers
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAmzHeaders() {
|
||||
|
||||
$amzHeaders = array();
|
||||
$headers = $this->httpRequest->getHeaders();
|
||||
foreach($headers as $headerName => $headerValue) {
|
||||
if (strpos(strtolower($headerName),'x-amz-')===0) {
|
||||
$amzHeaders[strtolower($headerName)] = str_replace(array("\r\n"),array(' '),$headerValue) . "\n";
|
||||
}
|
||||
}
|
||||
ksort($amzHeaders);
|
||||
|
||||
$headerStr = '';
|
||||
foreach($amzHeaders as $h=>$v) {
|
||||
$headerStr.=$h.':'.$v;
|
||||
}
|
||||
|
||||
return $headerStr;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an HMAC-SHA1 signature
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $message
|
||||
* @return string
|
||||
*/
|
||||
private function hmacsha1($key, $message) {
|
||||
|
||||
$blocksize=64;
|
||||
if (strlen($key)>$blocksize)
|
||||
$key=pack('H*', sha1($key));
|
||||
$key=str_pad($key,$blocksize,chr(0x00));
|
||||
$ipad=str_repeat(chr(0x36),$blocksize);
|
||||
$opad=str_repeat(chr(0x5c),$blocksize);
|
||||
$hmac = pack('H*',sha1(($key^$opad).pack('H*',sha1(($key^$ipad).$message))));
|
||||
return $hmac;
|
||||
|
||||
}
|
||||
|
||||
}
|
111
dav/SabreDAV/lib/Sabre/HTTP/AbstractAuth.php
Normal file
111
dav/SabreDAV/lib/Sabre/HTTP/AbstractAuth.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* HTTP Authentication baseclass
|
||||
*
|
||||
* This class has the common functionality for BasicAuth and DigestAuth
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
abstract class Sabre_HTTP_AbstractAuth {
|
||||
|
||||
/**
|
||||
* The realm will be displayed in the dialog boxes
|
||||
*
|
||||
* This identifier can be changed through setRealm()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $realm = 'SabreDAV';
|
||||
|
||||
/**
|
||||
* HTTP response helper
|
||||
*
|
||||
* @var Sabre_HTTP_Response
|
||||
*/
|
||||
protected $httpResponse;
|
||||
|
||||
|
||||
/**
|
||||
* HTTP request helper
|
||||
*
|
||||
* @var Sabre_HTTP_Request
|
||||
*/
|
||||
protected $httpRequest;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->httpResponse = new Sabre_HTTP_Response();
|
||||
$this->httpRequest = new Sabre_HTTP_Request();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alternative HTTP response object
|
||||
*
|
||||
* @param Sabre_HTTP_Response $response
|
||||
* @return void
|
||||
*/
|
||||
public function setHTTPResponse(Sabre_HTTP_Response $response) {
|
||||
|
||||
$this->httpResponse = $response;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alternative HTTP request object
|
||||
*
|
||||
* @param Sabre_HTTP_Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function setHTTPRequest(Sabre_HTTP_Request $request) {
|
||||
|
||||
$this->httpRequest = $request;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the realm
|
||||
*
|
||||
* The realm is often displayed in authentication dialog boxes
|
||||
* Commonly an application name displayed here
|
||||
*
|
||||
* @param string $realm
|
||||
* @return void
|
||||
*/
|
||||
public function setRealm($realm) {
|
||||
|
||||
$this->realm = $realm;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the realm
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRealm() {
|
||||
|
||||
return $this->realm;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTTP 401 header, forcing login
|
||||
*
|
||||
* This should be called when username and password are incorrect, or not supplied at all
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function requireLogin();
|
||||
|
||||
}
|
67
dav/SabreDAV/lib/Sabre/HTTP/BasicAuth.php
Normal file
67
dav/SabreDAV/lib/Sabre/HTTP/BasicAuth.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* HTTP Basic Authentication handler
|
||||
*
|
||||
* Use this class for easy http authentication setup
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth {
|
||||
|
||||
/**
|
||||
* Returns the supplied username and password.
|
||||
*
|
||||
* The returned array has two values:
|
||||
* * 0 - username
|
||||
* * 1 - password
|
||||
*
|
||||
* If nothing was supplied, 'false' will be returned
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserPass() {
|
||||
|
||||
// Apache and mod_php
|
||||
if (($user = $this->httpRequest->getRawServerValue('PHP_AUTH_USER')) && ($pass = $this->httpRequest->getRawServerValue('PHP_AUTH_PW'))) {
|
||||
|
||||
return array($user,$pass);
|
||||
|
||||
}
|
||||
|
||||
// Most other webservers
|
||||
$auth = $this->httpRequest->getHeader('Authorization');
|
||||
|
||||
// Apache could prefix environment variables with REDIRECT_ when urls
|
||||
// are passed through mod_rewrite
|
||||
if (!$auth) {
|
||||
$auth = $this->httpRequest->getRawServerValue('REDIRECT_HTTP_AUTHORIZATION');
|
||||
}
|
||||
|
||||
if (!$auth) return false;
|
||||
|
||||
if (strpos(strtolower($auth),'basic')!==0) return false;
|
||||
|
||||
return explode(':', base64_decode(substr($auth, 6)));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTTP 401 header, forcing login
|
||||
*
|
||||
* This should be called when username and password are incorrect, or not supplied at all
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function requireLogin() {
|
||||
|
||||
$this->httpResponse->setHeader('WWW-Authenticate','Basic realm="' . $this->realm . '"');
|
||||
$this->httpResponse->sendStatus(401);
|
||||
|
||||
}
|
||||
|
||||
}
|
240
dav/SabreDAV/lib/Sabre/HTTP/DigestAuth.php
Normal file
240
dav/SabreDAV/lib/Sabre/HTTP/DigestAuth.php
Normal file
|
@ -0,0 +1,240 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* HTTP Digest Authentication handler
|
||||
*
|
||||
* Use this class for easy http digest authentication.
|
||||
* Instructions:
|
||||
*
|
||||
* 1. Create the object
|
||||
* 2. Call the setRealm() method with the realm you plan to use
|
||||
* 3. Call the init method function.
|
||||
* 4. Call the getUserName() function. This function may return false if no
|
||||
* authentication information was supplied. Based on the username you
|
||||
* should check your internal database for either the associated password,
|
||||
* or the so-called A1 hash of the digest.
|
||||
* 5. Call either validatePassword() or validateA1(). This will return true
|
||||
* or false.
|
||||
* 6. To make sure an authentication prompt is displayed, call the
|
||||
* requireLogin() method.
|
||||
*
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
|
||||
|
||||
/**
|
||||
* These constants are used in setQOP();
|
||||
*/
|
||||
const QOP_AUTH = 1;
|
||||
const QOP_AUTHINT = 2;
|
||||
|
||||
protected $nonce;
|
||||
protected $opaque;
|
||||
protected $digestParts;
|
||||
protected $A1;
|
||||
protected $qop = self::QOP_AUTH;
|
||||
|
||||
/**
|
||||
* Initializes the object
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->nonce = uniqid();
|
||||
$this->opaque = md5($this->realm);
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers all information from the headers
|
||||
*
|
||||
* This method needs to be called prior to anything else.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
$digest = $this->getDigest();
|
||||
$this->digestParts = $this->parseDigest($digest);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the quality of protection value.
|
||||
*
|
||||
* Possible values are:
|
||||
* Sabre_HTTP_DigestAuth::QOP_AUTH
|
||||
* Sabre_HTTP_DigestAuth::QOP_AUTHINT
|
||||
*
|
||||
* Multiple values can be specified using logical OR.
|
||||
*
|
||||
* QOP_AUTHINT ensures integrity of the request body, but this is not
|
||||
* supported by most HTTP clients. QOP_AUTHINT also requires the entire
|
||||
* request body to be md5'ed, which can put strains on CPU and memory.
|
||||
*
|
||||
* @param int $qop
|
||||
* @return void
|
||||
*/
|
||||
public function setQOP($qop) {
|
||||
|
||||
$this->qop = $qop;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user.
|
||||
*
|
||||
* The A1 parameter should be md5($username . ':' . $realm . ':' . $password);
|
||||
*
|
||||
* @param string $A1
|
||||
* @return bool
|
||||
*/
|
||||
public function validateA1($A1) {
|
||||
|
||||
$this->A1 = $A1;
|
||||
return $this->validate();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates authentication through a password. The actual password must be provided here.
|
||||
* It is strongly recommended not store the password in plain-text and use validateA1 instead.
|
||||
*
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
public function validatePassword($password) {
|
||||
|
||||
$this->A1 = md5($this->digestParts['username'] . ':' . $this->realm . ':' . $password);
|
||||
return $this->validate();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username for the request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername() {
|
||||
|
||||
return $this->digestParts['username'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the digest challenge
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate() {
|
||||
|
||||
$A2 = $this->httpRequest->getMethod() . ':' . $this->digestParts['uri'];
|
||||
|
||||
if ($this->digestParts['qop']=='auth-int') {
|
||||
// Making sure we support this qop value
|
||||
if (!($this->qop & self::QOP_AUTHINT)) return false;
|
||||
// We need to add an md5 of the entire request body to the A2 part of the hash
|
||||
$body = $this->httpRequest->getBody(true);
|
||||
$this->httpRequest->setBody($body,true);
|
||||
$A2 .= ':' . md5($body);
|
||||
} else {
|
||||
|
||||
// We need to make sure we support this qop value
|
||||
if (!($this->qop & self::QOP_AUTH)) return false;
|
||||
}
|
||||
|
||||
$A2 = md5($A2);
|
||||
|
||||
$validResponse = md5("{$this->A1}:{$this->digestParts['nonce']}:{$this->digestParts['nc']}:{$this->digestParts['cnonce']}:{$this->digestParts['qop']}:{$A2}");
|
||||
|
||||
return $this->digestParts['response']==$validResponse;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTTP 401 header, forcing login
|
||||
*
|
||||
* This should be called when username and password are incorrect, or not supplied at all
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function requireLogin() {
|
||||
|
||||
$qop = '';
|
||||
switch($this->qop) {
|
||||
case self::QOP_AUTH : $qop = 'auth'; break;
|
||||
case self::QOP_AUTHINT : $qop = 'auth-int'; break;
|
||||
case self::QOP_AUTH | self::QOP_AUTHINT : $qop = 'auth,auth-int'; break;
|
||||
}
|
||||
|
||||
$this->httpResponse->setHeader('WWW-Authenticate','Digest realm="' . $this->realm . '",qop="'.$qop.'",nonce="' . $this->nonce . '",opaque="' . $this->opaque . '"');
|
||||
$this->httpResponse->sendStatus(401);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the full digest string.
|
||||
*
|
||||
* It should be compatibile with mod_php format and other webservers.
|
||||
*
|
||||
* If the header could not be found, null will be returned
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDigest() {
|
||||
|
||||
// mod_php
|
||||
$digest = $this->httpRequest->getRawServerValue('PHP_AUTH_DIGEST');
|
||||
if ($digest) return $digest;
|
||||
|
||||
// most other servers
|
||||
$digest = $this->httpRequest->getHeader('Authorization');
|
||||
|
||||
// Apache could prefix environment variables with REDIRECT_ when urls
|
||||
// are passed through mod_rewrite
|
||||
if (!$digest) {
|
||||
$digest = $this->httpRequest->getRawServerValue('REDIRECT_HTTP_AUTHORIZATION');
|
||||
}
|
||||
|
||||
if ($digest && strpos(strtolower($digest),'digest')===0) {
|
||||
return substr($digest,7);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the different pieces of the digest string into an array.
|
||||
*
|
||||
* This method returns false if an incomplete digest was supplied
|
||||
*
|
||||
* @param string $digest
|
||||
* @return mixed
|
||||
*/
|
||||
protected function parseDigest($digest) {
|
||||
|
||||
// protect against missing data
|
||||
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
|
||||
$data = array();
|
||||
|
||||
preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $digest, $matches, PREG_SET_ORDER);
|
||||
|
||||
foreach ($matches as $m) {
|
||||
$data[$m[1]] = $m[2] ? $m[2] : $m[3];
|
||||
unset($needed_parts[$m[1]]);
|
||||
}
|
||||
|
||||
return $needed_parts ? false : $data;
|
||||
|
||||
}
|
||||
|
||||
}
|
268
dav/SabreDAV/lib/Sabre/HTTP/Request.php
Normal file
268
dav/SabreDAV/lib/Sabre/HTTP/Request.php
Normal file
|
@ -0,0 +1,268 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* HTTP Request information
|
||||
*
|
||||
* This object can be used to easily access information about an HTTP request.
|
||||
* It can additionally be used to create 'mock' requests.
|
||||
*
|
||||
* This class mostly operates independent, but because of the nature of a single
|
||||
* request per run it can operate as a singleton. For more information check out
|
||||
* the behaviour around 'defaultInputStream'.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_HTTP_Request {
|
||||
|
||||
/**
|
||||
* PHP's $_SERVER data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_SERVER;
|
||||
|
||||
/**
|
||||
* PHP's $_POST data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_POST;
|
||||
|
||||
/**
|
||||
* The request body, if any.
|
||||
*
|
||||
* This is stored in the form of a stream resource.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $body = null;
|
||||
|
||||
/**
|
||||
* This will be set as the 'default' inputStream for a specific HTTP request
|
||||
* We sometimes need to retain, or rebuild this if we need multiple runs
|
||||
* of parsing the original HTTP request.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
static $defaultInputStream=null;
|
||||
|
||||
/**
|
||||
* Sets up the object
|
||||
*
|
||||
* The serverData and postData array can be used to override usage of PHP's
|
||||
* global _SERVER and _POST variable respectively.
|
||||
*
|
||||
* @param array $serverData
|
||||
* @param array $postData
|
||||
*/
|
||||
public function __construct(array $serverData = null, array $postData = null) {
|
||||
|
||||
if ($serverData) $this->_SERVER = $serverData;
|
||||
else $this->_SERVER =& $_SERVER;
|
||||
|
||||
if ($postData) $this->_POST = $postData;
|
||||
else $this->_POST =& $_POST;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for a specific http header.
|
||||
*
|
||||
* This method returns null if the header did not exist.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getHeader($name) {
|
||||
|
||||
$name = strtoupper(str_replace(array('-'),array('_'),$name));
|
||||
if (isset($this->_SERVER['HTTP_' . $name])) {
|
||||
return $this->_SERVER['HTTP_' . $name];
|
||||
}
|
||||
|
||||
// There's a few headers that seem to end up in the top-level
|
||||
// server array.
|
||||
switch($name) {
|
||||
case 'CONTENT_TYPE' :
|
||||
case 'CONTENT_LENGTH' :
|
||||
if (isset($this->_SERVER[$name])) {
|
||||
return $this->_SERVER[$name];
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all (known) HTTP headers.
|
||||
*
|
||||
* All headers are converted to lower-case, and additionally all underscores
|
||||
* are automatically converted to dashes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders() {
|
||||
|
||||
$hdrs = array();
|
||||
foreach($this->_SERVER as $key=>$value) {
|
||||
|
||||
switch($key) {
|
||||
case 'CONTENT_LENGTH' :
|
||||
case 'CONTENT_TYPE' :
|
||||
$hdrs[strtolower(str_replace('_','-',$key))] = $value;
|
||||
break;
|
||||
default :
|
||||
if (strpos($key,'HTTP_')===0) {
|
||||
$hdrs[substr(strtolower(str_replace('_','-',$key)),5)] = $value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $hdrs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP request method
|
||||
*
|
||||
* This is for example POST or GET
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod() {
|
||||
|
||||
return $this->_SERVER['REQUEST_METHOD'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested uri
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUri() {
|
||||
|
||||
return $this->_SERVER['REQUEST_URI'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return protocol + the hostname + the uri
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAbsoluteUri() {
|
||||
|
||||
// Checking if the request was made through HTTPS. The last in line is for IIS
|
||||
$protocol = isset($this->_SERVER['HTTPS']) && ($this->_SERVER['HTTPS']) && ($this->_SERVER['HTTPS']!='off');
|
||||
return ($protocol?'https':'http') . '://' . $this->getHeader('Host') . $this->getUri();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns everything after the ? from the current url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryString() {
|
||||
|
||||
return isset($this->_SERVER['QUERY_STRING'])?$this->_SERVER['QUERY_STRING']:'';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP request body body
|
||||
*
|
||||
* This method returns a readable stream resource.
|
||||
* If the asString parameter is set to true, a string is sent instead.
|
||||
*
|
||||
* @param bool $asString
|
||||
* @return resource
|
||||
*/
|
||||
public function getBody($asString = false) {
|
||||
|
||||
if (is_null($this->body)) {
|
||||
if (!is_null(self::$defaultInputStream)) {
|
||||
$this->body = self::$defaultInputStream;
|
||||
} else {
|
||||
$this->body = fopen('php://input','r');
|
||||
self::$defaultInputStream = $this->body;
|
||||
}
|
||||
}
|
||||
if ($asString) {
|
||||
$body = stream_get_contents($this->body);
|
||||
return $body;
|
||||
} else {
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the contents of the HTTP request body
|
||||
*
|
||||
* This method can either accept a string, or a readable stream resource.
|
||||
*
|
||||
* If the setAsDefaultInputStream is set to true, it means for this run of the
|
||||
* script the supplied body will be used instead of php://input.
|
||||
*
|
||||
* @param mixed $body
|
||||
* @param bool $setAsDefaultInputStream
|
||||
* @return void
|
||||
*/
|
||||
public function setBody($body,$setAsDefaultInputStream = false) {
|
||||
|
||||
if(is_resource($body)) {
|
||||
$this->body = $body;
|
||||
} else {
|
||||
|
||||
$stream = fopen('php://temp','r+');
|
||||
fputs($stream,$body);
|
||||
rewind($stream);
|
||||
// String is assumed
|
||||
$this->body = $stream;
|
||||
}
|
||||
if ($setAsDefaultInputStream) {
|
||||
self::$defaultInputStream = $this->body;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns PHP's _POST variable.
|
||||
*
|
||||
* The reason this is in a method is so it can be subclassed and
|
||||
* overridden.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPostVars() {
|
||||
|
||||
return $this->_POST;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific item from the _SERVER array.
|
||||
*
|
||||
* Do not rely on this feature, it is for internal use only.
|
||||
*
|
||||
* @param string $field
|
||||
* @return string
|
||||
*/
|
||||
public function getRawServerValue($field) {
|
||||
|
||||
return isset($this->_SERVER[$field])?$this->_SERVER[$field]:null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
157
dav/SabreDAV/lib/Sabre/HTTP/Response.php
Normal file
157
dav/SabreDAV/lib/Sabre/HTTP/Response.php
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Sabre_HTTP_Response
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_HTTP_Response {
|
||||
|
||||
/**
|
||||
* Returns a full HTTP status message for an HTTP status code
|
||||
*
|
||||
* @param int $code
|
||||
* @return string
|
||||
*/
|
||||
public function getStatusMessage($code) {
|
||||
|
||||
$msg = array(
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
102 => 'Processing',
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authorative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
207 => 'Multi-Status', // RFC 4918
|
||||
208 => 'Already Reported', // RFC 5842
|
||||
226 => 'IM Used', // RFC 3229
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found',
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
306 => 'Reserved',
|
||||
307 => 'Temporary Redirect',
|
||||
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 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
418 => 'I\'m a teapot', // RFC 2324
|
||||
422 => 'Unprocessable Entity', // RFC 4918
|
||||
423 => 'Locked', // RFC 4918
|
||||
424 => 'Failed Dependency', // RFC 4918
|
||||
426 => 'Upgrade required',
|
||||
428 => 'Precondition required', // draft-nottingham-http-new-status
|
||||
429 => 'Too Many Requests', // draft-nottingham-http-new-status
|
||||
431 => 'Request Header Fields Too Large', // draft-nottingham-http-new-status
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version not supported',
|
||||
506 => 'Variant Also Negotiates',
|
||||
507 => 'Insufficient Storage', // RFC 4918
|
||||
508 => 'Loop Detected', // RFC 5842
|
||||
509 => 'Bandwidth Limit Exceeded', // non-standard
|
||||
510 => 'Not extended',
|
||||
511 => 'Network Authentication Required', // draft-nottingham-http-new-status
|
||||
);
|
||||
|
||||
return 'HTTP/1.1 ' . $code . ' ' . $msg[$code];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HTTP status header to the client
|
||||
*
|
||||
* @param int $code HTTP status code
|
||||
* @return bool
|
||||
*/
|
||||
public function sendStatus($code) {
|
||||
|
||||
if (!headers_sent())
|
||||
return header($this->getStatusMessage($code));
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an HTTP header for the response
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param bool $replace
|
||||
* @return bool
|
||||
*/
|
||||
public function setHeader($name, $value, $replace = true) {
|
||||
|
||||
$value = str_replace(array("\r","\n"),array('\r','\n'),$value);
|
||||
if (!headers_sent())
|
||||
return header($name . ': ' . $value, $replace);
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a bunch of HTTP Headers
|
||||
*
|
||||
* headersnames are specified as keys, value in the array value
|
||||
*
|
||||
* @param array $headers
|
||||
* @return void
|
||||
*/
|
||||
public function setHeaders(array $headers) {
|
||||
|
||||
foreach($headers as $key=>$value)
|
||||
$this->setHeader($key, $value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the entire response body
|
||||
*
|
||||
* This method can accept either an open filestream, or a string.
|
||||
*
|
||||
* @param mixed $body
|
||||
* @return void
|
||||
*/
|
||||
public function sendBody($body) {
|
||||
|
||||
if (is_resource($body)) {
|
||||
|
||||
fpassthru($body);
|
||||
|
||||
} else {
|
||||
|
||||
// We assume a string
|
||||
echo $body;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
82
dav/SabreDAV/lib/Sabre/HTTP/Util.php
Normal file
82
dav/SabreDAV/lib/Sabre/HTTP/Util.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* HTTP utility methods
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @author Paul Voegler
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_HTTP_Util {
|
||||
|
||||
/**
|
||||
* Parses a RFC2616-compatible date string
|
||||
*
|
||||
* This method returns false if the date is invalid
|
||||
*
|
||||
* @param string $dateHeader
|
||||
* @return bool|DateTime
|
||||
*/
|
||||
static function parseHTTPDate($dateHeader) {
|
||||
|
||||
//RFC 2616 section 3.3.1 Full Date
|
||||
//Only the format is checked, valid ranges are checked by strtotime below
|
||||
$month = '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)';
|
||||
$weekday = '(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)';
|
||||
$wkday = '(Mon|Tue|Wed|Thu|Fri|Sat|Sun)';
|
||||
$time = '[0-2]\d(\:[0-5]\d){2}';
|
||||
$date3 = $month . ' ([1-3]\d| \d)';
|
||||
$date2 = '[0-3]\d\-' . $month . '\-\d\d';
|
||||
//4-digit year cannot begin with 0 - unix timestamp begins in 1970
|
||||
$date1 = '[0-3]\d ' . $month . ' [1-9]\d{3}';
|
||||
|
||||
//ANSI C's asctime() format
|
||||
//4-digit year cannot begin with 0 - unix timestamp begins in 1970
|
||||
$asctime_date = $wkday . ' ' . $date3 . ' ' . $time . ' [1-9]\d{3}';
|
||||
//RFC 850, obsoleted by RFC 1036
|
||||
$rfc850_date = $weekday . ', ' . $date2 . ' ' . $time . ' GMT';
|
||||
//RFC 822, updated by RFC 1123
|
||||
$rfc1123_date = $wkday . ', ' . $date1 . ' ' . $time . ' GMT';
|
||||
//allowed date formats by RFC 2616
|
||||
$HTTP_date = "($rfc1123_date|$rfc850_date|$asctime_date)";
|
||||
|
||||
//allow for space around the string and strip it
|
||||
$dateHeader = trim($dateHeader, ' ');
|
||||
if (!preg_match('/^' . $HTTP_date . '$/', $dateHeader))
|
||||
return false;
|
||||
|
||||
//append implicit GMT timezone to ANSI C time format
|
||||
if (strpos($dateHeader, ' GMT') === false)
|
||||
$dateHeader .= ' GMT';
|
||||
|
||||
|
||||
$realDate = strtotime($dateHeader);
|
||||
//strtotime can return -1 or false in case of error
|
||||
if ($realDate !== false && $realDate >= 0)
|
||||
return new DateTime('@' . $realDate, new DateTimeZone('UTC'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a DateTime object to HTTP's most common date format.
|
||||
*
|
||||
* We're serializing it as the RFC 1123 date, which, for HTTP must be
|
||||
* specified as GMT.
|
||||
*
|
||||
* @param DateTime $dateTime
|
||||
* @return string
|
||||
*/
|
||||
static function toHTTPDate(DateTime $dateTime) {
|
||||
|
||||
// We need to clone it, as we don't want to affect the existing
|
||||
// DateTime.
|
||||
$dateTime = clone $dateTime;
|
||||
$dateTime->setTimeZone(new DateTimeZone('GMT'));
|
||||
return $dateTime->format('D, d M Y H:i:s \G\M\T');
|
||||
|
||||
}
|
||||
|
||||
}
|
24
dav/SabreDAV/lib/Sabre/HTTP/Version.php
Normal file
24
dav/SabreDAV/lib/Sabre/HTTP/Version.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This class contains the Sabre_HTTP version constants.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_HTTP_Version {
|
||||
|
||||
/**
|
||||
* Full version number
|
||||
*/
|
||||
const VERSION = '1.6.2';
|
||||
|
||||
/**
|
||||
* Stability : alpha, beta, stable
|
||||
*/
|
||||
const STABILITY = 'stable';
|
||||
|
||||
}
|
27
dav/SabreDAV/lib/Sabre/HTTP/includes.php
Normal file
27
dav/SabreDAV/lib/Sabre/HTTP/includes.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Sabre_HTTP includes file
|
||||
*
|
||||
* Including this file will automatically include all files from the Sabre_HTTP
|
||||
* package.
|
||||
*
|
||||
* This often allows faster loadtimes, as autoload-speed is often quite slow.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage HTTP
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
|
||||
// Begin includes
|
||||
include __DIR__ . '/AbstractAuth.php';
|
||||
include __DIR__ . '/AWSAuth.php';
|
||||
include __DIR__ . '/BasicAuth.php';
|
||||
include __DIR__ . '/DigestAuth.php';
|
||||
include __DIR__ . '/Request.php';
|
||||
include __DIR__ . '/Response.php';
|
||||
include __DIR__ . '/Util.php';
|
||||
include __DIR__ . '/Version.php';
|
||||
// End includes
|
Loading…
Add table
Add a link
Reference in a new issue