diff options
author | Bart Visscher <bartv@thisnet.nl> | 2012-07-27 11:40:51 +0200 |
---|---|---|
committer | Bart Visscher <bartv@thisnet.nl> | 2012-07-27 11:40:51 +0200 |
commit | a7a54331082c41c5b05cd7982c058caf1556f777 (patch) | |
tree | bc51551c2430837856cdb1f3a1e04c46e0f664cb /lib/connector | |
parent | e8010209bb1ec8ef9ecc1cff7ac2b2d4d414bd74 (diff) | |
parent | d26f87e738314db7820f39f74f42865ff20f7bd7 (diff) | |
download | nextcloud-server-a7a54331082c41c5b05cd7982c058caf1556f777.tar.gz nextcloud-server-a7a54331082c41c5b05cd7982c058caf1556f777.zip |
Merge branch 'master' into chunked_upload
Conflicts:
lib/connector/sabre/directory.php
Diffstat (limited to 'lib/connector')
-rw-r--r-- | lib/connector/sabre/auth.php | 17 | ||||
-rw-r--r-- | lib/connector/sabre/client.php | 83 | ||||
-rw-r--r-- | lib/connector/sabre/directory.php | 47 | ||||
-rw-r--r-- | lib/connector/sabre/file.php | 34 | ||||
-rw-r--r-- | lib/connector/sabre/locks.php | 2 | ||||
-rw-r--r-- | lib/connector/sabre/node.php | 54 |
6 files changed, 182 insertions, 55 deletions
diff --git a/lib/connector/sabre/auth.php b/lib/connector/sabre/auth.php index ee680391626..99f696e3a07 100644 --- a/lib/connector/sabre/auth.php +++ b/lib/connector/sabre/auth.php @@ -31,13 +31,18 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic { * @return bool */ protected function validateUserPass($username, $password){ - OC_Util::setUpFS();//login hooks may need early access to the filesystem - if(OC_User::login($username,$password)){ - OC_Util::setUpFS($username); + if (OC_User::isLoggedIn()) { + OC_Util::setupFS($username); return true; - } - else{ - return false; + } else { + OC_Util::setUpFS();//login hooks may need early access to the filesystem + if(OC_User::login($username,$password)){ + OC_Util::setUpFS($username); + return true; + } + else{ + return false; + } } } } diff --git a/lib/connector/sabre/client.php b/lib/connector/sabre/client.php index b799b541a05..7e8f21264f9 100644 --- a/lib/connector/sabre/client.php +++ b/lib/connector/sabre/client.php @@ -23,29 +23,18 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client {
- protected $curlSettings;
-
- public function __construct(array $settings) {
- //set default curl settings
- $this->curlSettings = array(
- CURLOPT_RETURNTRANSFER => true,
- // Return headers as part of the response
- CURLOPT_HEADER => true,
- // Automatically follow redirects
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_MAXREDIRS => 5,
- CURLOPT_SSL_VERIFYPEER => true,
- //CURLOPT_SSL_VERIFYPEER => false,
- );
- parent::__construct($settings);
- }
-
- public function setCurlSettings($settings) {
- if (is_array($settings)) {
- foreach ($settings as $k => $v) {
- $this->curlSettings[$k] = $v;
- }
- }
+ protected $trustedCertificates;
+
+ /**
+ * Add trusted root certificates to the webdav client.
+ *
+ * The parameter certificates should be a absulute path to a file which contains
+ * all trusted certificates
+ *
+ * @param string $certificates
+ */
+ public function addTrustedCertificates($certificates) {
+ $this->trustedCertificates = $certificates;
}
/**
@@ -68,14 +57,24 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client { * @return array
*/
public function request($method, $url = '', $body = null, $headers = array()) {
-
- $this->curlSettings[CURLOPT_POSTFIELDS] = $body;
+
$url = $this->getAbsoluteUrl($url);
+ $curlSettings = array(
+ CURLOPT_RETURNTRANSFER => true,
+ // Return headers as part of the response
+ CURLOPT_HEADER => true,
+ CURLOPT_POSTFIELDS => $body,
+ // Automatically follow redirects
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ );
+
+ if($this->trustedCertificates) {
+ $curlSettings[CURLOPT_CAINFO] = $this->trustedCertificates;
+ }
+
switch ($method) {
- case 'PUT':
- $this->curlSettings[CURLOPT_PUT] = true;
- break;
case 'HEAD' :
// do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD
@@ -83,12 +82,12 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client { // specs...) cURL does unfortunately return an error in this case ("transfer closed transfer closed with
// ... bytes remaining to read") this can be circumvented by explicitly telling cURL to ignore the
// response body
- $this->curlSettings[CURLOPT_NOBODY] = true;
- $this->curlSettings[CURLOPT_CUSTOMREQUEST] = 'HEAD';
+ $curlSettings[CURLOPT_NOBODY] = true;
+ $curlSettings[CURLOPT_CUSTOMREQUEST] = 'HEAD';
break;
default:
- $this->curlSettings[CURLOPT_CUSTOMREQUEST] = $method;
+ $curlSettings[CURLOPT_CUSTOMREQUEST] = $method;
break;
}
@@ -100,15 +99,22 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client { $nHeaders[] = $key . ': ' . $value;
}
- $this->curlSettings[CURLOPT_HTTPHEADER] = $nHeaders;
+ $curlSettings[CURLOPT_HTTPHEADER] = $nHeaders;
if ($this->proxy) {
- $this->curlSettings[CURLOPT_PROXY] = $this->proxy;
+ $curlSettings[CURLOPT_PROXY] = $this->proxy;
}
- if ($this->userName) {
- $this->curlSettings[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC | CURLAUTH_DIGEST;
- $this->curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password;
+ if ($this->userName && $this->authType) {
+ $curlType = 0;
+ if ($this->authType & self::AUTH_BASIC) {
+ $curlType |= CURLAUTH_BASIC;
+ }
+ if ($this->authType & self::AUTH_DIGEST) {
+ $curlType |= CURLAUTH_DIGEST;
+ }
+ $curlSettings[CURLOPT_HTTPAUTH] = $curlType;
+ $curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password;
}
list(
@@ -116,7 +122,7 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client { $curlInfo,
$curlErrNo,
$curlError
- ) = $this->curlRequest($url, $this->curlSettings);
+ ) = $this->curlRequest($url, $curlSettings);
$headerBlob = substr($response, 0, $curlInfo['header_size']);
$response = substr($response, $curlInfo['header_size']);
@@ -163,6 +169,5 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client { return $response;
- }
-
+ }
}
\ No newline at end of file diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 894256d5b2a..bed75015aef 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -26,11 +26,26 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa /** * Creates a new file in the directory * - * data is a readable stream resource + * Data will either be supplied as a stream resource, or in certain cases + * as a string. Keep in mind that you may have to support either. + * + * After succesful creation of the file, you may choose to return the ETag + * of the new file here. + * + * The returned ETag must be surrounded by double-quotes (The quotes should + * be part of the actual string). + * + * If you cannot accurately determine the ETag, you should not return it. + * If you don't store the file exactly as-is (you're transforming it + * somehow) you should also not return an ETag. + * + * This means that if a subsequent GET to this new file does not exactly + * return the same contents of what was submitted here, you are strongly + * recommended to omit the ETag. * * @param string $name Name of the file - * @param resource $data Initial payload - * @return void + * @param resource|string $data Initial payload + * @return null|string */ public function createFile($name, $data = null) { if (isset($_SERVER['HTTP_OC_CHUNKED'])) { @@ -53,11 +68,15 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa fwrite($f,$chunk); } fclose($f); + return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); } } else { $newPath = $this->path . '/' . $name; OC_Filesystem::file_put_contents($newPath,$data); + return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); } + + return null; } /** @@ -167,7 +186,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * @return array */ public function getQuotaInfo() { - $rootInfo=OC_FileCache::get(''); + $rootInfo=OC_FileCache_Cached::get(''); return array( $rootInfo['size'], OC_Filesystem::free_space() @@ -175,5 +194,25 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa } + /** + * Returns a list of properties for this nodes.; + * + * The properties list is a list of propertynames the client requested, + * encoded as xmlnamespace#tagName, for example: + * http://www.example.org/namespace#author + * If the array is empty, all properties should be returned + * + * @param array $properties + * @return void + */ + public function getProperties($properties) { + $props = parent::getProperties($properties); + if (in_array(self::GETETAG_PROPERTYNAME, $properties) + && !isset($props[self::GETETAG_PROPERTYNAME])) { + $props[self::GETETAG_PROPERTYNAME] = + OC_Connector_Sabre_Node::getETagPropertyForPath($this->path); + } + return $props; + } } diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index dd25df78c29..9d571fceb0d 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -26,13 +26,28 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D /** * Updates the data * + * The data argument is a readable stream resource. + * + * After a succesful put operation, you may choose to return an ETag. The + * etag must always be surrounded by double-quotes. These quotes must + * appear in the actual string you're returning. + * + * Clients may use the ETag from a PUT request to later on make sure that + * when they update the file, the contents haven't changed in the mean + * time. + * + * If you don't plan to store the file byte-by-byte, and you return a + * different object on a subsequent GET you are strongly recommended to not + * return an ETag, and just return null. + * * @param resource $data - * @return void + * @return string|null */ public function put($data) { OC_Filesystem::file_put_contents($this->path,$data); + return OC_Connector_Sabre_Node::getETagPropertyForPath($this->path); } /** @@ -42,7 +57,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function get() { - return OC_Filesystem::fopen($this->path,'r'); + return OC_Filesystem::fopen($this->path,'rb'); } @@ -79,9 +94,20 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * @return mixed */ public function getETag() { + $properties = $this->getProperties(array(self::GETETAG_PROPERTYNAME)); + if (isset($properties[self::GETETAG_PROPERTYNAME])) { + return $properties[self::GETETAG_PROPERTYNAME]; + } + return $this->getETagPropertyForPath($this->path); + } - return null; - + /** + * Creates a ETag for this path. + * @param string $path Path of the file + * @return string|null Returns null if the ETag can not effectively be determined + */ + static protected function createETag($path) { + return OC_Filesystem::hash('md5', $path); } /** diff --git a/lib/connector/sabre/locks.php b/lib/connector/sabre/locks.php index 94382e68a1a..e95dcf02d27 100644 --- a/lib/connector/sabre/locks.php +++ b/lib/connector/sabre/locks.php @@ -108,7 +108,7 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { $locks = $this->getLocks($uri,false); $exists = false; - foreach($locks as $k=>$lock) { + foreach($locks as $lock) { if ($lock->token == $lockInfo->token) $exists = true; } diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index be315a0ffd9..f268f8b57c4 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -22,6 +22,7 @@ */ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties { + const GETETAG_PROPERTYNAME = '{DAV:}getetag'; /** * The path to the current node @@ -141,6 +142,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr public function updateProperties($properties) { $existing = $this->getProperties(array()); foreach($properties as $propertyName => $propertyValue) { + $propertyName = preg_replace("/^{.*}/", "", $propertyName); // remove leading namespace from property name // If it was null, we need to delete the property if (is_null($propertyValue)) { if(array_key_exists( $propertyName, $existing )){ @@ -178,7 +180,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * @param array $properties * @return void */ - function getProperties($properties) { + public function getProperties($properties) { if (is_null($this->property_cache)) { $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); $result = $query->execute( array( OC_User::getUser(), $this->path )); @@ -200,4 +202,54 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } return $props; } + + /** + * Creates a ETag for this path. + * @param string $path Path of the file + * @return string|null Returns null if the ETag can not effectively be determined + */ + static protected function createETag($path) { + return uniqid('', true); + } + + /** + * Returns the ETag surrounded by double-quotes for this path. + * @param string $path Path of the file + * @return string|null Returns null if the ETag can not effectively be determined + */ + static public function getETagPropertyForPath($path) { + $tag = self::createETag($path); + if (empty($tag)) { + return null; + } + $etag = '"'.$tag.'"'; + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' ); + $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag )); + return $etag; + } + + /** + * Remove the ETag from the cache. + * @param string $path Path of the file + */ + static public function removeETagPropertyForPath($path) { + // remove tags from this and parent paths + $paths = array(); + while ($path != '/' && $path != '') { + $paths[] = $path; + $path = dirname($path); + } + if (empty($paths)) { + return; + } + $paths[] = $path; + $path_placeholders = join(',', array_fill(0, count($paths), '?')); + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties' + .' WHERE userid = ?' + .' AND propertyname = ?' + .' AND propertypath IN ('.$path_placeholders.')' + ); + $vals = array( OC_User::getUser(), self::GETETAG_PROPERTYNAME ); + $query->execute(array_merge( $vals, $paths )); + } } |