1d7fbf95676ae64710160d03b7753ccb4a3acd41
[citadel.git] / webcit-ng / server / upload.c
1 // Upload handler
2 //
3 // Copyright (c) 1996-2022 by the citadel.org team
4 //
5 // This program is open source software.  Use, duplication, or
6 // disclosure are subject to the GNU General Public License v3.
7
8 #include "webcit.h"
9
10
11 // This function is called by the MIME parser to handle data uploaded by the browser.
12 void upload_handler(char *name, char *filename, char *partnum, char *disp,
13                     void *content, char *cbtype, char *cbcharset,
14                     size_t length, char *encoding, char *cbid, void *userdata)
15 {
16         syslog(LOG_DEBUG, "upload_handler()");
17         syslog(LOG_DEBUG, "        name: %s", name);
18         syslog(LOG_DEBUG, "    filename: %s", filename);
19         syslog(LOG_DEBUG, " part number: %s", partnum);
20         syslog(LOG_DEBUG, " disposition: %s", disp);
21         syslog(LOG_DEBUG, "content type: %s", cbtype);
22         syslog(LOG_DEBUG, "    char set: %s", cbcharset);
23         syslog(LOG_DEBUG, "      length: %ld", length);
24         syslog(LOG_DEBUG, "    encoding: %s", encoding);
25         syslog(LOG_DEBUG, "          id: %s", cbid);
26
27         // Write the upload to a file that we can pull later when the user saves the message.
28         char tempfile[PATH_MAX];
29         snprintf(tempfile, sizeof tempfile, "/tmp/ctdl_upload_XXXXXX");
30         int fd = mkstemp(tempfile);
31         if (fd < 0) {
32                 syslog(LOG_ERR, "upload: %s: %m", tempfile);
33                 return;
34         }
35         write(fd, content, length);
36         close(fd);
37
38         // Create a JSON object describing this upload
39         JsonValue *j_one_upload = NewJsonObject(HKEY(""));
40         JsonObjectAppend(j_one_upload, NewJsonPlainString(HKEY("ref"), &tempfile[strlen(tempfile)-6], -1));
41         JsonObjectAppend(j_one_upload, NewJsonPlainString(HKEY("uploadfilename"), filename, -1));
42         JsonObjectAppend(j_one_upload, NewJsonPlainString(HKEY("contenttype"), cbtype, -1));
43         JsonObjectAppend(j_one_upload, NewJsonNumber(HKEY("contentlength"), length));
44
45         // ...and attach it to the array of uploads
46         JsonValue *j_uploads = (JsonValue *) userdata;
47         JsonArrayAppend(j_uploads, j_one_upload);
48 }
49
50 // upload handler
51 void upload_files(struct http_transaction *h, struct ctdlsession *c) {
52         // FIXME reject uploads if we're not logged in
53
54         // This will be a JSON Array of all files that were uploaded during this HTTP transaction.
55         // Normally the browser will upload only one file per transaction, but that behavior is not guaranteed.
56         JsonValue *j_uploads = NewJsonArray(HKEY(""));
57
58         // h->request_body will contain the upload(s) in MIME format
59         mime_parser(h->request_body, (h->request_body + h->request_body_length), *upload_handler, NULL, NULL, j_uploads, 0);
60
61         // probably do something more clever here
62         h->response_code = 200;
63         h->response_string = strdup("OK");
64
65         // send back a JSON array of all files uploaded
66         StrBuf *sj = NewStrBuf();
67         SerializeJson(sj, j_uploads, 1);        // '1' == free the source object
68         add_response_header(h, strdup("Content-type"), strdup("application/json"));
69         h->response_code = 200;
70         h->response_string = strdup("OK");
71         h->response_body_length = StrLength(sj);
72         h->response_body = SmashStrBuf(&sj);
73 }