From d333c3c09e16d9719560d13b7706ab8ad50df0d4 Mon Sep 17 00:00:00 2001 From: Alexander Alashkin Date: Mon, 11 Jan 2016 12:52:35 +0200 Subject: [PATCH] Implement fake DAV LOCK PUBLISHED_FROM=0ea0d8623ab3f59de8996f6b18712d1b3fb120f8 --- examples/simplest_web_server/Makefile | 3 +- mongoose.c | 55 ++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/examples/simplest_web_server/Makefile b/examples/simplest_web_server/Makefile index dd3e4109..f792e4c7 100644 --- a/examples/simplest_web_server/Makefile +++ b/examples/simplest_web_server/Makefile @@ -1,6 +1,7 @@ PROG = simplest_web_server SOURCES = $(PROG).c ../../mongoose.c -CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA) -DMG_DISABLE_DAV_AUTH +CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA) -DMG_DISABLE_DAV_AUTH \ + -DMG_ENABLE_FAKE_DAVLOCK all: $(PROG) diff --git a/mongoose.c b/mongoose.c index 1ee0cb67..e6bb87a9 100644 --- a/mongoose.c +++ b/mongoose.c @@ -5532,6 +5532,40 @@ static void handle_propfind(struct mg_connection *nc, const char *path, } } +#ifdef MG_ENABLE_FAKE_DAVLOCK +/* + * Windows explorer (probably there are another WebDav clients like it) + * requires LOCK support in webdav. W/out this, it still works, but fails + * to save file: shows error message and offers "Save As". + * "Save as" works, but this message is very annoying. + * This is fake lock, which doesn't lock something, just returns LOCK token, + * UNLOCK always answers "OK". + * With this fake LOCK Windows Explorer looks happy and saves file. + * NOTE: that is not DAV LOCK imlementation, it is just a way to shut up + * Windows native DAV client. This is why FAKE LOCK is not enabed by default + */ +static void handle_lock(struct mg_connection *nc, const char *path) { + static const char *reply = + "HTTP/1.1 207 Multi-Status\r\n" + "Connection: close\r\n" + "Content-Type: text/xml; charset=utf-8\r\n\r\n" + "" + "\n" + "\n" + "\n" + "\n" + "\n" + "opaquelocktoken:%s%u" + "" + "" + "\n" + "" + "\n"; + mg_printf(nc, reply, path, (unsigned int) time(NULL)); + nc->flags |= MG_F_SEND_AND_CLOSE; +} +#endif + static void handle_mkcol(struct mg_connection *nc, const char *path, struct http_message *hm) { int status_code = 500; @@ -5679,8 +5713,21 @@ static void handle_put(struct mg_connection *nc, const char *path, #endif /* MG_DISABLE_DAV */ static int is_dav_request(const struct mg_str *s) { - return !mg_vcmp(s, "PUT") || !mg_vcmp(s, "DELETE") || !mg_vcmp(s, "MKCOL") || - !mg_vcmp(s, "PROPFIND") || !mg_vcmp(s, "MOVE"); + static const char *methods[] = {"PUT", "DELETE", "MKCOL", "PROPFIND", "MOVE" +#ifdef MG_ENABLE_FAKE_DAVLOCK + , + "LOCK", "UNLOCK" +#endif + }; + size_t i; + + for (i = 0; i < ARRAY_SIZE(methods); i++) { + if (mg_vcmp(s, methods[i]) == 0) { + return 1; + } + } + + return 0; } /* @@ -6374,6 +6421,10 @@ void mg_send_http_file(struct mg_connection *nc, char *path, handle_put(nc, path, hm); } else if (!mg_vcmp(&hm->method, "MOVE")) { handle_move(nc, opts, path, hm); +#ifdef MG_ENABLE_FAKE_DAVLOCK + } else if (!mg_vcmp(&hm->method, "LOCK")) { + handle_lock(nc, path); +#endif #endif } else if (!mg_vcmp(&hm->method, "OPTIONS")) { send_options(nc);