@@ -161,180 +161,171 @@ static const char slash = '/';
161161// ._* (metadata for the file *)
162162// .hidden
163163
164- std::map<int , String> reqNames = {
165- { 1 , " GET" }, { 2 , " POST" }, { 4 , " DELETE" }, { 8 , " PUT" }, { 16 , " PATCH" },
166- { 32 , " HEAD" }, { 64 , " OPTIONS" }, { 128 , " PROPFIND" }, { 256 , " LOCK" }, { 512 , " UNLOCK" },
167- { 1024 , " PROPATCH" }, { 2048 , " MKCOL" }, { 4096 , " MOVE" }, { 8192 , " COPY" }, { 16384 , " RESERVED" },
168- };
164+ void WebDAV::handleRequest (AsyncWebServerRequest *request) {
165+ // If request->_tempObject is not null, handleBody already
166+ // did the necessary work for a PUT operation
167+ auto state = static_cast <RequestState *>(request->_tempObject );
168+ if (state) {
169+ if (state->outFile ) {
170+ // The file was already opened and written in handleBody so
171+ // we are done. We will handle PUT without body data below.
172+ state->outFile .close ();
173+ request->send (201 ); // Created
174+ }
175+ delete state;
176+ request->_tempObject = nullptr ;
177+ return ;
178+ }
169179
170- void WebDAV::handleRequest (AsyncWebServerRequest *request) {
171- // If request->_tempObject is not null, handleBody already
172- // did the necessary work for a PUT operation
173- auto state = static_cast <RequestState *>(request->_tempObject );
174- if (state) {
175- if (state->outFile ) {
176- // The file was already opened and written in handleBody so
177- // we are done. We will handle PUT without body data below.
178- state->outFile .close ();
179- request->send (201 ); // Created
180- }
181- delete state;
182- request->_tempObject = nullptr ;
183- return ;
184- }
180+ String path = request->url ();
185181
186- String path = request->url ();
187-
188- Serial.print (reqNames.find (request->method ())->second );
189- Serial.print (" " );
190- Serial.println (path);
191-
192- if (request->method () == HTTP_MKCOL) {
193- Serial.println (" MKCOL" );
194- // does the file/dir already exist?
195- int status;
196- if (_fs.exists (path)) {
197- // Already exists
198- // I think there is an "Overwrite: {T,F}" header; we should handle it
199- request->send (405 );
200- } else {
201- request->send (_fs.mkdir (path) ? 201 : 405 );
202- }
203- return ;
204- }
205-
206- if (request->method () == HTTP_PUT) {
207- // This PUT code executes if the body was empty, which
208- // can happen if the client creates a zero-length file.
209- // MacOS WebDAVFS does that, then later LOCKs the file
210- // and issues a subsequent PUT with body contents.
211-
212- File file = _fs.open (path, FILE_WRITE, true );
213- if (file) {
214- file.close ();
215- request->send (201 ); // Created
216- return ;
217- }
218- request->send (403 );
219- return ;
220- }
182+ Serial.print (request->methodToString ());
183+ Serial.print (" " );
184+ Serial.println (path);
185+
186+ if (request->method () == HTTP_MKCOL) {
187+ // does the file/dir already exist?
188+ int status;
189+ if (_fs.exists (path)) {
190+ // Already exists
191+ // I think there is an "Overwrite: {T,F}" header; we should handle it
192+ request->send (405 );
193+ } else {
194+ request->send (_fs.mkdir (path) ? 201 : 405 );
195+ }
196+ return ;
197+ }
221198
222- if (request->method () == HTTP_OPTIONS) {
223- AsyncWebServerResponse *response = request->beginResponse (200 );
224- response->addHeader (" Dav" , " 1,2" );
225- response->addHeader (" Ms-Author-Via" , " DAV" );
226- response->addHeader (" Allow" , " PROPFIND,OPTIONS,DELETE,MOVE,HEAD,POST,PUT,GET" );
227- request->send (response);
228- return ;
229- }
199+ if (request->method () == HTTP_PUT) {
200+ // This PUT code executes if the body was empty, which
201+ // can happen if the client creates a zero-length file.
202+ // MacOS WebDAVFS does that, then later LOCKs the file
203+ // and issues a subsequent PUT with body contents.
204+
205+ File file = _fs.open (path, FILE_WRITE, true );
206+ if (file) {
207+ file.close ();
208+ request->send (201 ); // Created
209+ return ;
210+ }
211+ request->send (403 );
212+ return ;
213+ }
230214
231- // If we are not creating the resource it must already exist
232- if (!_fs.exists (path)) {
233- Serial.printf (" %s does not exist\n " , path.c_str ());
234- request->send (404 , " Resource does not exist" );
235- return ;
236- }
215+ if (request->method () == HTTP_OPTIONS) {
216+ AsyncWebServerResponse *response = request->beginResponse (200 );
217+ response->addHeader (" Dav" , " 1,2" );
218+ response->addHeader (" Ms-Author-Via" , " DAV" );
219+ response->addHeader (" Allow" , " PROPFIND,OPTIONS,DELETE,MOVE,HEAD,POST,PUT,GET" );
220+ request->send (response);
221+ return ;
222+ }
237223
238- if (request->method () == HTTP_HEAD) {
239- File file = _fs.open (path);
224+ // If we are not creating the resource it must already exist
225+ if (!_fs.exists (path)) {
226+ Serial.printf (" %s does not exist\n " , path.c_str ());
227+ request->send (404 , " Resource does not exist" );
228+ return ;
229+ }
240230
241- // HEAD is like GET without a body, but with Content-Length
242- AsyncWebServerResponse *response = request->beginResponse (200 , getContentType (path), " " ); // AsyncBasicResponse
243- response->setContentLength (file.size ());
231+ if (request->method () == HTTP_HEAD) {
232+ File file = _fs.open (path);
244233
245- request-> send (response);
246- return ;
247- }
234+ // HEAD is like GET without a body, but with Content-Length
235+ AsyncWebServerResponse *response = request-> beginResponse ( 200 , getContentType (path), " " ); // AsyncBasicResponse
236+ response-> setContentLength (file. size ());
248237
249- if ( request->method () == HTTP_GET) {
250- return handleGet (path, request) ;
251- }
238+ request->send (response);
239+ return ;
240+ }
252241
253- if (request->method () == HTTP_PROPFIND) {
254- handlePropfind (path, request);
255- return ;
256- }
242+ if (request->method () == HTTP_GET) {
243+ return handleGet (path, request);
244+ }
257245
258- if (request->method () == HTTP_LOCK) {
259- Serial.println (" LOCK" );
260-
261- String lockroot (" http://" );
262- lockroot += request->host ();
263- lockroot += path;
264-
265- AsyncResponseStream *response = request->beginResponseStream (" application/xml; charset=utf-8" );
266- response->setCode (200 );
267- response->addHeader (" Lock-Token" , " urn:uuid:26e57cb3-834d-191a-00de-000042bdecf9" );
268-
269- response->print (" <?xml version=\" 1.0\" encoding=\" utf-8\" ?>" );
270- response->print (" <D:prop xmlns:D=\" DAV:\" >" );
271- response->print (" <D:lockdiscovery>" );
272- response->print (" <D:activelock>" );
273- response->print (" <D:locktype><write/></D:locktype>" );
274- response->print (" <D:lockscope><exclusive/></D:lockscope>" );
275- response->print (" <D:locktoken><D:href>urn:uuid:26e57cb3-834d-191a-00de-000042bdecf9</D:href></D:locktoken>" );
276- response->printf (" <D:lockroot><D:href>%s</D:href></D:lockroot>" , lockroot.c_str ());
277- response->print (" <D:depth>infinity</D:depth>" );
278- response->printf (" <D:owner><a:href xmlns:a=\" DAV:\" >%s</a:href></D:owner>" , " todo" );
279- response->print (" <D:timeout>Second-3600</D:timeout>" );
280- response->print (" </D:activelock>" );
281- response->print (" </D:lockdiscovery>" );
282- response->print (" </D:prop>" );
283-
284- request->send (response);
285- return ;
286- }
287- if (request->method () == HTTP_UNLOCK) {
288- request->send (204 ); // No Content
289- return ;
290- }
291- if (request->method () == HTTP_MOVE) {
292- const AsyncWebHeader *destinationHeader = request->getHeader (" destination" );
293- if (!destinationHeader || destinationHeader->value ().isEmpty ()) {
294- request->send (400 , " text/plain" , " Missing destination header" );
295- return ;
296- }
246+ if (request->method () == HTTP_PROPFIND) {
247+ handlePropfind (path, request);
248+ return ;
249+ }
297250
298- // Should handle "Overwrite: {T,F}" header
299- String newpath = urlToUri (destinationHeader->value ());
300- Serial.printf (" Renaming %s to %s\n " , path.c_str (), newpath.c_str ());
301-
302- if (_fs.exists (newpath)) {
303- Serial.printf (" Destination file %s already exists\n " , newpath.c_str ());
304- request->send (500 , " text/plain" , " Destination file exists" );
305- } else {
306- if (_fs.rename (path, newpath)) {
307- Serial.println (" Rename succeeded" );
308- request->send (201 );
309- } else {
310- Serial.println (" Rename failed" );
311- request->send (500 , " text/plain" , " Unable to move" );
312- }
313- }
251+ if (request->method () == HTTP_LOCK) {
252+ String lockroot (" http://" );
253+ lockroot += request->host ();
254+ lockroot += path;
255+
256+ AsyncResponseStream *response = request->beginResponseStream (" application/xml; charset=utf-8" );
257+ response->setCode (200 );
258+ response->addHeader (" Lock-Token" , " urn:uuid:26e57cb3-834d-191a-00de-000042bdecf9" );
259+
260+ response->print (" <?xml version=\" 1.0\" encoding=\" utf-8\" ?>" );
261+ response->print (" <D:prop xmlns:D=\" DAV:\" >" );
262+ response->print (" <D:lockdiscovery>" );
263+ response->print (" <D:activelock>" );
264+ response->print (" <D:locktype><write/></D:locktype>" );
265+ response->print (" <D:lockscope><exclusive/></D:lockscope>" );
266+ response->print (" <D:locktoken><D:href>urn:uuid:26e57cb3-834d-191a-00de-000042bdecf9</D:href></D:locktoken>" );
267+ response->printf (" <D:lockroot><D:href>%s</D:href></D:lockroot>" , lockroot.c_str ());
268+ response->print (" <D:depth>infinity</D:depth>" );
269+ response->printf (" <D:owner><a:href xmlns:a=\" DAV:\" >%s</a:href></D:owner>" , " todo" );
270+ response->print (" <D:timeout>Second-3600</D:timeout>" );
271+ response->print (" </D:activelock>" );
272+ response->print (" </D:lockdiscovery>" );
273+ response->print (" </D:prop>" );
274+
275+ request->send (response);
276+ return ;
277+ }
278+ if (request->method () == HTTP_UNLOCK) {
279+ request->send (204 ); // No Content
280+ return ;
281+ }
282+ if (request->method () == HTTP_MOVE) {
283+ const AsyncWebHeader *destinationHeader = request->getHeader (" destination" );
284+ if (!destinationHeader || destinationHeader->value ().isEmpty ()) {
285+ request->send (400 , " text/plain" , " Missing destination header" );
286+ return ;
287+ }
314288
315- return ;
316- }
317- if (request->method () == HTTP_DELETE) {
318- // delete file or dir
319- bool result;
320- File file = _fs.open (path);
321-
322- if (!file) {
323- request->send (404 );
324- } else {
325- if (file.isDirectory ()) {
326- file.close ();
327- request->send (_fs.rmdir (path) ? 200 : 201 );
328- } else {
329- file.close ();
330- request->send (_fs.remove (path) ? 200 : 201 );
331- }
332- }
333- return ;
289+ // Should handle "Overwrite: {T,F}" header
290+ String newpath = urlToUri (destinationHeader->value ());
291+ Serial.printf (" Renaming %s to %s\n " , path.c_str (), newpath.c_str ());
292+
293+ if (_fs.exists (newpath)) {
294+ Serial.printf (" Destination file %s already exists\n " , newpath.c_str ());
295+ request->send (500 , " text/plain" , " Destination file exists" );
296+ } else {
297+ if (_fs.rename (path, newpath)) {
298+ Serial.println (" Rename succeeded" );
299+ request->send (201 );
300+ } else {
301+ Serial.println (" Rename failed" );
302+ request->send (500 , " text/plain" , " Unable to move" );
334303 }
304+ }
335305
336- handleNotFound (request);
306+ return ;
307+ }
308+ if (request->method () == HTTP_DELETE) {
309+ // delete file or dir
310+ bool result;
311+ File file = _fs.open (path);
312+
313+ if (!file) {
314+ request->send (404 );
315+ } else {
316+ if (file.isDirectory ()) {
317+ file.close ();
318+ request->send (_fs.rmdir (path) ? 200 : 201 );
319+ } else {
320+ file.close ();
321+ request->send (_fs.remove (path) ? 200 : 201 );
322+ }
337323 }
324+ return ;
325+ }
326+
327+ handleNotFound (request);
328+ }
338329
339330 void WebDAV::handleBody (AsyncWebServerRequest *request, unsigned char *data, size_t len, size_t index, size_t total) {
340331 // The other requests with a body are LOCK and PROPFIND, where the body data is the XML
0 commit comments