From f4fc33d1114d8a6901029ab69f48fa09395e2dc1 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Fri, 17 Jun 2022 16:35:02 -0300 Subject: [PATCH] brought back 7.5 file-upload as file-upload-multiple-posts; updated to latest API renamed form-upload to file-upload-html-form renamed file-upload to file-upload-single-post --- .../Makefile | 0 .../README.md | 0 .../main.c | 0 .../web_root/index.html | 0 .../Makefile | 0 .../README.md | 0 examples/file-upload-multiple-posts/main.c | 33 +++++++++++++++ .../web_root/app.js | 41 +++++++++++++++++++ .../web_root/index.html | 36 ++++++++++++++++ examples/file-upload-single-post/Makefile | 10 +++++ examples/file-upload-single-post/README.md | 1 + .../main.c | 0 .../web_root/index.html | 0 13 files changed, 121 insertions(+) rename examples/{file-upload => file-upload-html-form}/Makefile (100%) rename examples/{file-upload => file-upload-html-form}/README.md (100%) rename examples/{form-upload => file-upload-html-form}/main.c (100%) rename examples/{form-upload => file-upload-html-form}/web_root/index.html (100%) rename examples/{form-upload => file-upload-multiple-posts}/Makefile (100%) rename examples/{form-upload => file-upload-multiple-posts}/README.md (100%) create mode 100644 examples/file-upload-multiple-posts/main.c create mode 100644 examples/file-upload-multiple-posts/web_root/app.js create mode 100644 examples/file-upload-multiple-posts/web_root/index.html create mode 100644 examples/file-upload-single-post/Makefile create mode 100644 examples/file-upload-single-post/README.md rename examples/{file-upload => file-upload-single-post}/main.c (100%) rename examples/{file-upload => file-upload-single-post}/web_root/index.html (100%) diff --git a/examples/file-upload/Makefile b/examples/file-upload-html-form/Makefile similarity index 100% rename from examples/file-upload/Makefile rename to examples/file-upload-html-form/Makefile diff --git a/examples/file-upload/README.md b/examples/file-upload-html-form/README.md similarity index 100% rename from examples/file-upload/README.md rename to examples/file-upload-html-form/README.md diff --git a/examples/form-upload/main.c b/examples/file-upload-html-form/main.c similarity index 100% rename from examples/form-upload/main.c rename to examples/file-upload-html-form/main.c diff --git a/examples/form-upload/web_root/index.html b/examples/file-upload-html-form/web_root/index.html similarity index 100% rename from examples/form-upload/web_root/index.html rename to examples/file-upload-html-form/web_root/index.html diff --git a/examples/form-upload/Makefile b/examples/file-upload-multiple-posts/Makefile similarity index 100% rename from examples/form-upload/Makefile rename to examples/file-upload-multiple-posts/Makefile diff --git a/examples/form-upload/README.md b/examples/file-upload-multiple-posts/README.md similarity index 100% rename from examples/form-upload/README.md rename to examples/file-upload-multiple-posts/README.md diff --git a/examples/file-upload-multiple-posts/main.c b/examples/file-upload-multiple-posts/main.c new file mode 100644 index 00000000..4389e851 --- /dev/null +++ b/examples/file-upload-multiple-posts/main.c @@ -0,0 +1,33 @@ +// Copyright (c) 2020 Cesanta Software Limited +// All rights reserved + +#include "mongoose.h" + +// HTTP request handler function. It implements the following endpoints: +// /upload - Saves the next file chunk +// all other URI - serves web_root/ directory +static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { + if (ev == MG_EV_HTTP_MSG) { + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_http_match_uri(hm, "/upload")) { + mg_http_upload(c, hm, &mg_fs_posix, "/tmp"); + } else { + struct mg_http_serve_opts opts = {.root_dir = "web_root"}; + mg_http_serve_dir(c, ev_data, &opts); + } + } +} + +int main(void) { + struct mg_mgr mgr; + struct mg_timer t1; + + mg_mgr_init(&mgr); + mg_log_set("3"); + mg_http_listen(&mgr, "http://localhost:8000", cb, NULL); + + for (;;) mg_mgr_poll(&mgr, 50); + mg_mgr_free(&mgr); + + return 0; +} diff --git a/examples/file-upload-multiple-posts/web_root/app.js b/examples/file-upload-multiple-posts/web_root/app.js new file mode 100644 index 00000000..f90c01d6 --- /dev/null +++ b/examples/file-upload-multiple-posts/web_root/app.js @@ -0,0 +1,41 @@ +// Copyright (c) 2020 Cesanta Software Limited +// All rights reserved + +// Helper function to display upload status +var setStatus = function(text) { + document.getElementById('el3').innerText = text; +}; + +// When user clicks on a button, trigger file selection dialog +var button = document.getElementById('el2'); +button.onclick = function(ev) { + input.click(); +}; + +// Send a large blob of data chunk by chunk +var sendFileData = function(name, data, chunkSize) { + var sendChunk = function(offset) { + var chunk = data.subarray(offset, offset + chunkSize) || ''; + var opts = {method: 'POST', body: chunk}; + var url = '/upload?offset=' + offset + '&name=' + encodeURIComponent(name); + setStatus( + 'sending bytes ' + offset + '..' + (offset + chunk.length) + ' of ' + + data.length); + fetch(url, opts).then(function(res) { + if (chunk.length > 0) sendChunk(offset + chunk.length); + }); + }; + sendChunk(0); +}; + +// If user selected a file, read it into memory and trigger sendFileData() +var input = document.getElementById('el1'); +input.onchange = function(ev) { + if (!ev.target.files[0]) return; + var f = ev.target.files[0], r = new FileReader(); + r.readAsArrayBuffer(f); + r.onload = function() { + ev.target.value = ''; + sendFileData(f.name, new Uint8Array(r.result), 4096); + }; +}; diff --git a/examples/file-upload-multiple-posts/web_root/index.html b/examples/file-upload-multiple-posts/web_root/index.html new file mode 100644 index 00000000..3d55a26e --- /dev/null +++ b/examples/file-upload-multiple-posts/web_root/index.html @@ -0,0 +1,36 @@ + + + + example + + + + + + +
+
+ Mongoose always buffers a full HTTP message before invoking + the MG_EV_HTTP_MSG event. A big POST request would require a lot + of RAM to buffer everything. Therefore, in order to upload large + files on memory-constrained systems, a large file should be sent + in small chunks. +

+ In this example, the JavaScript code on this page sends the chosen + file in 4K chunks using the /upload endpoint. + The uploaded file is stored in the /tmp directory by + the helper API function mg_http_upload() +
+
+ + +
+
+
+ + + diff --git a/examples/file-upload-single-post/Makefile b/examples/file-upload-single-post/Makefile new file mode 100644 index 00000000..eaa5aa25 --- /dev/null +++ b/examples/file-upload-single-post/Makefile @@ -0,0 +1,10 @@ +PROG ?= example + +all: $(PROG) + $(DEBUGGER) ./$(PROG) + +$(PROG): + $(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c + +clean: + rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt diff --git a/examples/file-upload-single-post/README.md b/examples/file-upload-single-post/README.md new file mode 100644 index 00000000..d1ea184a --- /dev/null +++ b/examples/file-upload-single-post/README.md @@ -0,0 +1 @@ +See detailed tutorial at https://mongoose.ws/tutorials/file-uploads/ diff --git a/examples/file-upload/main.c b/examples/file-upload-single-post/main.c similarity index 100% rename from examples/file-upload/main.c rename to examples/file-upload-single-post/main.c diff --git a/examples/file-upload/web_root/index.html b/examples/file-upload-single-post/web_root/index.html similarity index 100% rename from examples/file-upload/web_root/index.html rename to examples/file-upload-single-post/web_root/index.html