From 9e0e585aae4d32378e2af043294a2129367279a5 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 13 Mar 2023 00:24:51 -0400 Subject: [PATCH] Implemented RFC4918 MOVE and COPY methods for individual messages. We need these to be able to move messages between rooms, so of course it makes sense to use HTTP methods that are already standardized. --- webcit-ng/server/messages.c | 32 +++++++++++++++++++++++++++++++- webcit-ng/server/webcit.h | 8 +++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/webcit-ng/server/messages.c b/webcit-ng/server/messages.c index 7250fe87c..c5dda5bbc 100644 --- a/webcit-ng/server/messages.c +++ b/webcit-ng/server/messages.c @@ -48,7 +48,37 @@ void dav_delete_message(struct http_transaction *h, struct ctdlsession *c, long // DAV move or copy an object in a room. void dav_move_or_copy_message(struct http_transaction *h, struct ctdlsession *c, long msgnum, int move_or_copy) { - do_404(h); + char target_room[ROOMNAMELEN]; + char buf[1024]; + + // HTTP "Destination" header will tell us the target collection + char *target_collection = header_val(h, "Destination"); + syslog(LOG_DEBUG, "dest coll: \"%s\"", target_collection); + + // Translate the target WebDAV Collection name to a Citadel Room name. + // Note that some clients will supply a fully-qualified URL such as "http://example.com/ctdl/r/roomname/999" + // so we're just going to search for "/ctdl/r/" and work from there. + char *ctdlr = strstr(target_collection, "/ctdl/r/"); + if (ctdlr == NULL) { + do_412(h); // badly formed target collection; fail out. + return; + } + safestrncpy(target_room, ctdlr+8, sizeof target_room); + char *slash = strchr(target_room, '/'); + if (slash) { + *slash = 0; // lop off the "filename" we don't need it + } + unescape_input(target_room); + syslog(LOG_DEBUG, "dest room: \"%s\"", target_room); + + // Perform the move or copy operation + ctdl_printf(c, "MOVE %ld|%s|%d", msgnum, target_room, move_or_copy); // Citadel Server: 0=move, 1=copy + ctdl_readline(c, buf, sizeof buf); + if (buf[0] == '2') { + do_204(h); // succeed (no content) + return; + } + do_412(h); // fail (precondition failed) } diff --git a/webcit-ng/server/webcit.h b/webcit-ng/server/webcit.h index e5a4f8e1f..d8009ddca 100644 --- a/webcit-ng/server/webcit.h +++ b/webcit-ng/server/webcit.h @@ -108,11 +108,6 @@ enum { WEBSERVER_UDS }; -enum { - DAV_MOVE, - DAV_COPY -}; - #define TRACE syslog(LOG_DEBUG, "\033[3%dmCHECKPOINT: %s:%d\033[0m", ((__LINE__%6)+1), __FILE__, __LINE__) #define SLEEPING 180 // TCP connection timeout #define MAX_WORKER_THREADS 32 // Maximum number of worker threads permitted to exist @@ -123,6 +118,9 @@ enum { #define DEVELOPER_ID 0 #define CLIENT_ID 4 #define TARGET "webcit02" /* Window target for inline URL's */ +#define ROOMNAMELEN 128 // The size of a roomname string +#define DAV_MOVE 0 // MOVE=0 COPY=1 don't change these! +#define DAV_COPY 1 // they are the values used in the Citadel Server MOVE command void worker_entry(int *); void perform_one_http_transaction(struct client_handle *ch); -- 2.39.2