aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/dav/lib/Sabre/HTTP
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/dav/lib/Sabre/HTTP')
-rw-r--r--vendor/sabre/dav/lib/Sabre/HTTP/AWSAuth.php227
-rw-r--r--vendor/sabre/dav/lib/Sabre/HTTP/AbstractAuth.php111
-rw-r--r--vendor/sabre/dav/lib/Sabre/HTTP/BasicAuth.php67
-rw-r--r--vendor/sabre/dav/lib/Sabre/HTTP/DigestAuth.php240
-rw-r--r--vendor/sabre/dav/lib/Sabre/HTTP/Request.php284
-rw-r--r--vendor/sabre/dav/lib/Sabre/HTTP/Response.php175
-rw-r--r--vendor/sabre/dav/lib/Sabre/HTTP/Util.php82
-rw-r--r--vendor/sabre/dav/lib/Sabre/HTTP/Version.php24
8 files changed, 1210 insertions, 0 deletions
diff --git a/vendor/sabre/dav/lib/Sabre/HTTP/AWSAuth.php b/vendor/sabre/dav/lib/Sabre/HTTP/AWSAuth.php
new file mode 100644
index 000000000..f697f23f1
--- /dev/null
+++ b/vendor/sabre/dav/lib/Sabre/HTTP/AWSAuth.php
@@ -0,0 +1,227 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * HTTP AWS Authentication handler
+ *
+ * Use this class to leverage amazon's AWS authentication header
+ *
+ * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class AWSAuth extends 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 = 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;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/Sabre/HTTP/AbstractAuth.php b/vendor/sabre/dav/lib/Sabre/HTTP/AbstractAuth.php
new file mode 100644
index 000000000..886e34737
--- /dev/null
+++ b/vendor/sabre/dav/lib/Sabre/HTTP/AbstractAuth.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * HTTP Authentication baseclass
+ *
+ * This class has the common functionality for BasicAuth and DigestAuth
+ *
+ * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+abstract class 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 Response();
+ $this->httpRequest = new Request();
+
+ }
+
+ /**
+ * Sets an alternative HTTP response object
+ *
+ * @param Response $response
+ * @return void
+ */
+ public function setHTTPResponse(Response $response) {
+
+ $this->httpResponse = $response;
+
+ }
+
+ /**
+ * Sets an alternative HTTP request object
+ *
+ * @param Request $request
+ * @return void
+ */
+ public function setHTTPRequest(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();
+
+}
diff --git a/vendor/sabre/dav/lib/Sabre/HTTP/BasicAuth.php b/vendor/sabre/dav/lib/Sabre/HTTP/BasicAuth.php
new file mode 100644
index 000000000..36aa31cbc
--- /dev/null
+++ b/vendor/sabre/dav/lib/Sabre/HTTP/BasicAuth.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * HTTP Basic Authentication handler
+ *
+ * Use this class for easy http authentication setup
+ *
+ * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class BasicAuth extends 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)),2);
+
+ }
+
+ /**
+ * 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);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/Sabre/HTTP/DigestAuth.php b/vendor/sabre/dav/lib/Sabre/HTTP/DigestAuth.php
new file mode 100644
index 000000000..19b58eba3
--- /dev/null
+++ b/vendor/sabre/dav/lib/Sabre/HTTP/DigestAuth.php
@@ -0,0 +1,240 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * 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.
+ *
+ *
+ * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class DigestAuth extends 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;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/Sabre/HTTP/Request.php b/vendor/sabre/dav/lib/Sabre/HTTP/Request.php
new file mode 100644
index 000000000..b0f1e62bf
--- /dev/null
+++ b/vendor/sabre/dav/lib/Sabre/HTTP/Request.php
@@ -0,0 +1,284 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * 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'.
+ *
+ * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class 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;
+
+ }
+
+ /**
+ * Returns the HTTP version specified within the request.
+ *
+ * @return string
+ */
+ public function getHTTPVersion() {
+
+ $protocol = $this->getRawServerValue('SERVER_PROTOCOL');
+ if ($protocol==='HTTP/1.0') {
+ return '1.0';
+ } else {
+ return '1.1';
+ }
+
+ }
+
+}
+
diff --git a/vendor/sabre/dav/lib/Sabre/HTTP/Response.php b/vendor/sabre/dav/lib/Sabre/HTTP/Response.php
new file mode 100644
index 000000000..fd7c0bc38
--- /dev/null
+++ b/vendor/sabre/dav/lib/Sabre/HTTP/Response.php
@@ -0,0 +1,175 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * This class represents a HTTP response.
+ *
+ * It contains the HTTP status code, response headers and a message body.
+ *
+ * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Response {
+
+ /**
+ * The HTTP version to return in the header() line.
+ *
+ * By default you will definitely want this to be HTTP/1.1, but in some
+ * edge cases (most notably pre 1.2 nginx servers acting as a proxy), you
+ * want to force this to 1.0.
+ *
+ * @var string
+ */
+ public $defaultHttpVersion = '1.1';
+
+ /**
+ * Returns a full HTTP status message for an HTTP status code
+ *
+ * @param int $code
+ * @return string
+ */
+ public function getStatusMessage($code, $httpVersion = '1.1') {
+
+ $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/' . $httpVersion . ' ' . $code . ' ' . $msg[$code];
+
+ }
+
+ // @codeCoverageIgnoreStart
+ // We cannot reasonably test header() related methods.
+
+ /**
+ * 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, $this->defaultHttpVersion));
+ 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;
+
+
+ }
+ // @codeCoverageIgnoreEnd
+
+ /**
+ * 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;
+
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/Sabre/HTTP/Util.php b/vendor/sabre/dav/lib/Sabre/HTTP/Util.php
new file mode 100644
index 000000000..42fd0a003
--- /dev/null
+++ b/vendor/sabre/dav/lib/Sabre/HTTP/Util.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * HTTP utility methods
+ *
+ * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @author Paul Voegler
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class 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');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/Sabre/HTTP/Version.php b/vendor/sabre/dav/lib/Sabre/HTTP/Version.php
new file mode 100644
index 000000000..f4b70437f
--- /dev/null
+++ b/vendor/sabre/dav/lib/Sabre/HTTP/Version.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Sabre\HTTP;
+
+/**
+ * This class contains the Sabre\HTTP version constants.
+ *
+ * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Version {
+
+ /**
+ * Full version number
+ */
+ const VERSION = '1.8.1';
+
+ /**
+ * Stability : alpha, beta, stable
+ */
+ const STABILITY = 'stable';
+
+}