@@ -42,6 +42,10 @@ public function initialize(\Sabre\DAV\Server $server): void {
4242 }
4343
4444 public function onMkcol (RequestInterface $ request , ResponseInterface $ response ) {
45+ if ($ this ->isChunkedUpload ($ request )) {
46+ return ;
47+ }
48+
4549 if (!$ this ->enabled || $ this ->share === null ) {
4650 return ;
4751 }
@@ -58,7 +62,18 @@ public function onMkcol(RequestInterface $request, ResponseInterface $response)
5862 return false ;
5963 }
6064
65+ private function isChunkedUpload (RequestInterface $ request ): bool {
66+ return str_starts_with (substr ($ request ->getUrl (), strlen ($ request ->getBaseUrl ()) - 1 ), '/uploads/ ' );
67+ }
68+
6169 public function beforeMethod (RequestInterface $ request , ResponseInterface $ response ) {
70+ $ isChunkedUpload = $ this ->isChunkedUpload ($ request );
71+
72+ // For the final MOVE request of a chunked upload it is necessary to modify the Destination header.
73+ if ($ isChunkedUpload && $ request ->getMethod () !== 'MOVE ' ) {
74+ return ;
75+ }
76+
6277 if (!$ this ->enabled || $ this ->share === null ) {
6378 return ;
6479 }
@@ -68,21 +83,8 @@ public function beforeMethod(RequestInterface $request, ResponseInterface $respo
6883 return ;
6984 }
7085
71- // Retrieve the nickname from the request
72- $ nickname = $ request ->hasHeader ('X-NC-Nickname ' )
73- ? trim (urldecode ($ request ->getHeader ('X-NC-Nickname ' )))
74- : null ;
75-
76- if ($ request ->getMethod () !== 'PUT ' ) {
77- // If uploading subfolders we need to ensure they get created
78- // within the nickname folder
79- if ($ request ->getMethod () === 'MKCOL ' ) {
80- if (!$ nickname ) {
81- throw new BadRequest ('A nickname header is required when uploading subfolders ' );
82- }
83- } else {
84- throw new MethodNotAllowed ('Only PUT is allowed on files drop ' );
85- }
86+ if ($ request ->getMethod () !== 'PUT ' && $ request ->getMethod () !== 'MKCOL ' && (!$ isChunkedUpload || $ request ->getMethod () !== 'MOVE ' )) {
87+ throw new MethodNotAllowed ('Only PUT, MKCOL and MOVE are allowed on files drop ' );
8688 }
8789
8890 // If this is a folder creation request
@@ -95,8 +97,16 @@ public function beforeMethod(RequestInterface $request, ResponseInterface $respo
9597 // full path along the way. We'll only handle conflict
9698 // resolution on file conflicts, but not on folders.
9799
98- // e.g files/dCP8yn3N86EK9sL/Folder/image.jpg
99- $ path = $ request ->getPath ();
100+ if ($ isChunkedUpload ) {
101+ $ destination = $ request ->getHeader ('destination ' );
102+ $ baseUrl = $ request ->getBaseUrl ();
103+ // e.g files/dCP8yn3N86EK9sL/Folder/image.jpg
104+ $ path = substr ($ destination , strpos ($ destination , $ baseUrl ) + strlen ($ baseUrl ));
105+ } else {
106+ // e.g files/dCP8yn3N86EK9sL/Folder/image.jpg
107+ $ path = $ request ->getPath ();
108+ }
109+
100110 $ token = $ this ->share ->getToken ();
101111
102112 // e.g files/dCP8yn3N86EK9sL
@@ -112,6 +122,11 @@ public function beforeMethod(RequestInterface $request, ResponseInterface $respo
112122 $ isFileRequest = $ attributes ->getAttribute ('fileRequest ' , 'enabled ' ) === true ;
113123 }
114124
125+ // Retrieve the nickname from the request
126+ $ nickname = $ request ->hasHeader ('X-NC-Nickname ' )
127+ ? trim (urldecode ($ request ->getHeader ('X-NC-Nickname ' )))
128+ : null ;
129+
115130 // We need a valid nickname for file requests
116131 if ($ isFileRequest && !$ nickname ) {
117132 throw new BadRequest ('A nickname header is required for file requests ' );
@@ -187,7 +202,11 @@ public function beforeMethod(RequestInterface $request, ResponseInterface $respo
187202 $ relativePath = substr ($ folder ->getPath (), strlen ($ node ->getPath ()));
188203 $ path = '/files/ ' . $ token . '/ ' . $ relativePath . '/ ' . $ uniqueName ;
189204 $ url = rtrim ($ request ->getBaseUrl (), '/ ' ) . str_replace ('// ' , '/ ' , $ path );
190- $ request ->setUrl ($ url );
205+ if ($ isChunkedUpload ) {
206+ $ request ->setHeader ('destination ' , $ url );
207+ } else {
208+ $ request ->setUrl ($ url );
209+ }
191210 }
192211
193212 private function getPathSegments (string $ path ): array {
0 commit comments