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