2929use OC \Files \View ;
3030use OCA \DAV \Connector \Sabre \Directory ;
3131use OCA \DAV \Connector \Sabre \FilesPlugin ;
32+ use OCP \Files \ObjectStore \IObjectStoreMultiPartUpload ;
3233use OCP \Files \Storage \IChunkedFileWrite ;
34+ use OCP \Files \Storage \IProcessingCallbackStorage ;
3335use OCP \Files \Storage \IStorage ;
3436use OCP \Files \StorageInvalidException ;
3537use Sabre \DAV \Exception \BadRequest ;
@@ -118,6 +120,10 @@ public function beforeMkcol(RequestInterface $request, ResponseInterface $respon
118120
119121 public function beforePut (RequestInterface $ request , ResponseInterface $ response ): bool {
120122 $ this ->uploadFolder = $ this ->server ->tree ->getNodeForPath (dirname ($ request ->getPath ()));
123+ if (!$ this ->uploadFolder instanceof UploadFolder) {
124+ return true ;
125+ }
126+
121127 try {
122128 $ this ->checkPrerequisites ();
123129 $ storage = $ this ->getStorage ();
@@ -143,7 +149,7 @@ public function beforePut(RequestInterface $request, ResponseInterface $response
143149
144150 $ additionalSize = (int )$ request ->getHeader ('Content-Length ' );
145151 if ($ this ->uploadFolder ->childExists (self ::TEMP_TARGET )) {
146- // FIXME Quota checking will not work for existing files that way
152+ /** @var UploadFile $tempTargetFile */
147153 $ tempTargetFile = $ this ->uploadFolder ->getChild (self ::TEMP_TARGET );
148154 $ tempTargetCache = $ storage ->getCache ()->get ($ tempTargetFile ->getInternalPath ());
149155
@@ -159,7 +165,6 @@ public function beforePut(RequestInterface $request, ResponseInterface $response
159165
160166 $ stream = $ request ->getBodyAsStream ();
161167 $ storage ->putChunkedFilePart ($ targetFile ->getInternalPath (), $ uploadId , (string )$ partId , $ stream , $ additionalSize );
162- // FIXME add return value to putChunkedFilePart to validate against size
163168
164169 $ storage ->getCache ()->update ($ cacheEntry ->getId (), ['size ' => $ cacheEntry ->getSize () + $ additionalSize ]);
165170 if ($ tempTargetFile ) {
@@ -211,6 +216,22 @@ public function beforeMove($sourcePath, $destination): bool {
211216
212217 $ rootView = new View ();
213218 if ($ storage ->instanceOfStorage (ObjectStoreStorage::class)) {
219+ /** @var ObjectStoreStorage $storage */
220+ $ objectStore = $ storage ->getObjectStore ();
221+ if ($ objectStore instanceof IObjectStoreMultiPartUpload) {
222+ $ parts = $ objectStore ->getMultipartUploads ($ storage ->getURN ($ targetFile ->getId ()), $ uploadId );
223+ $ size = 0 ;
224+ foreach ($ parts as $ part ) {
225+ $ size += $ part ['Size ' ];
226+ }
227+ $ free = $ storage ->free_space ($ destinationParent ->getInternalPath ());
228+ if ($ free >= 0 && ($ size > $ free )) {
229+ throw new InsufficientStorage ("Insufficient space in $ targetPath " );
230+ }
231+ }
232+ }
233+ if ($ storage ->instanceOfStorage (IProcessingCallbackStorage::class)) {
234+ /** @var IProcessingCallbackStorage $storage */
214235 $ lastTick = time ();
215236 $ storage ->processingCallback ('writeChunkedFile ' , function () use ($ lastTick ) {
216237 if ($ lastTick < time ()) {
@@ -245,7 +266,7 @@ public function beforeMove($sourcePath, $destination): bool {
245266 ['200 ' => [
246267 FilesPlugin::SIZE_PROPERTYNAME => $ rootView ->filesize ($ destinationInView )
247268 ]],
248- $ destinationExists ? 204 : 201
269+ $ destinationExists ? ' 204 ' : ' 201 '
249270 );
250271 echo $ this ->server ->xml ->write (
251272 '{DAV:}multistatus ' ,
0 commit comments