Completed
Push — stable8.2 ( b38580...8fddaa )
by Thomas
80:57
created

QuotaPlugin::getLength()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 6
nop 0
dl 0
loc 15
ccs 10
cts 10
cp 1
crap 5
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Felix Moeller <[email protected]>
4
 * @author Morris Jobke <[email protected]>
5
 * @author Robin Appelman <[email protected]>
6
 * @author Robin McCorkell <[email protected]>
7
 * @author scambra <[email protected]>
8
 * @author Scrutinizer Auto-Fixer <[email protected]>
9
 * @author Thomas Müller <[email protected]>
10
 * @author Vincent Petry <[email protected]>
11
 *
12
 * @copyright Copyright (c) 2015, ownCloud, Inc.
13
 * @license AGPL-3.0
14
 *
15
 * This code is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License, version 3,
17
 * as published by the Free Software Foundation.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License, version 3,
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
26
 *
27
 */
28
namespace OC\Connector\Sabre;
29
30
/**
31
 * This plugin check user quota and deny creating files when they exceeds the quota.
32
 *
33
 * @author Sergio Cambra
34
 * @copyright Copyright (C) 2012 entreCables S.L. All rights reserved.
35
 * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
36
 */
37
class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
38
39
	/**
40
	 * @var \OC\Files\View
41
	 */
42
	private $view;
43
44
	/**
45
	 * Reference to main server object
46
	 *
47
	 * @var \Sabre\DAV\Server
48
	 */
49
	private $server;
50
51
	/**
52
	 * @param \OC\Files\View $view
53
	 */
54 30
	public function __construct($view) {
55 30
		$this->view = $view;
56 30
	}
57
58
	/**
59
	 * This initializes the plugin.
60
	 *
61
	 * This function is called by \Sabre\DAV\Server, after
62
	 * addPlugin is called.
63
	 *
64
	 * This method should set up the requires event subscriptions.
65
	 *
66
	 * @param \Sabre\DAV\Server $server
67
	 * @return void
68
	 */
69 30
	public function initialize(\Sabre\DAV\Server $server) {
70
71 30
		$this->server = $server;
72
73 30
		$server->on('beforeWriteContent', array($this, 'checkQuota'), 10);
74 30
		$server->on('beforeCreateFile', array($this, 'checkQuota'), 10);
75 30
	}
76
77
	/**
78
	 * This method is called before any HTTP method and validates there is enough free space to store the file
79
	 *
80
	 * @param string $uri
81
	 * @param null $data
82
	 * @throws \Sabre\DAV\Exception\InsufficientStorage
83
	 * @return bool
84
	 */
85 22
	public function checkQuota($uri, $data = null) {
86 22
		$length = $this->getLength();
87 22
		if ($length) {
88 9
			if (substr($uri, 0, 1) !== '/') {
89 9
				$uri = '/' . $uri;
90 9
			}
91 9
			list($parentUri, $newName) = \Sabre\HTTP\URLUtil::splitPath($uri);
92 9
			if(is_null($parentUri)) {
93 9
				$parentUri = '';
94 9
			}
95 9
			$req = $this->server->httpRequest;
96 9
			if ($req->getHeader('OC-Chunked')) {
97
				$info = \OC_FileChunking::decodeName($newName);
98
				$chunkHandler = new \OC_FileChunking($info);
99
				// subtract the already uploaded size to see whether
100
				// there is still enough space for the remaining chunks
101
				$length -= $chunkHandler->getCurrentSize();
102
			}
103 9
			$freeSpace = $this->getFreeSpace($parentUri);
104 9
			if ($freeSpace !== \OCP\Files\FileInfo::SPACE_UNKNOWN && $length > $freeSpace) {
105 3
				if (isset($chunkHandler)) {
106
					$chunkHandler->cleanup();
107
				}
108 3
				throw new \Sabre\DAV\Exception\InsufficientStorage();
109
			}
110 6
		}
111 19
		return true;
112
	}
113
114 27
	public function getLength() {
115 27
		$req = $this->server->httpRequest;
116 27
		$length = $req->getHeader('X-Expected-Entity-Length');
117 27
		if (!is_numeric($length)) {
118 22
			$length = $req->getHeader('Content-Length');
119 22
			$length = is_numeric($length) ? $length : null;
120
		}
121 27
122 27
		$ocLength = $req->getHeader('OC-Total-Length');
123 5
		if (is_numeric($length) && is_numeric($ocLength)) {
124
			return max($length, $ocLength);
125
		}
126 22
127
		return $length;
128
	}
129
130
	/**
131
	 * @param string $parentUri
132
	 * @return mixed
133 9
	 */
134
	public function getFreeSpace($parentUri) {
135 9
		try {
136 9
			$freeSpace = $this->view->free_space($parentUri);
137
			return $freeSpace;
138
		} catch (\OCP\Files\StorageNotAvailableException $e) {
139
			throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
140
		}
141
	}
142
}
143