diff --git a/lib/misc/lwsac/lwsac.c b/lib/misc/lwsac/lwsac.c index 07e0fa282..f3059bbe4 100644 --- a/lib/misc/lwsac/lwsac.c +++ b/lib/misc/lwsac/lwsac.c @@ -136,6 +136,8 @@ lwsac_free(struct lwsac **head) { struct lwsac *it = *head; + lwsl_debug("%s: head %p\n", __func__, *head); + while (it) { struct lwsac *tmp = it->next; @@ -149,8 +151,8 @@ lwsac_free(struct lwsac **head) void lwsac_info(struct lwsac *head) { - lwsl_notice("%s: lac %p: %dKiB in %d blocks\n", __func__, head, - (int)(head->total_alloc_size >> 10), head->total_blocks); + lwsl_debug("%s: lac %p: %dKiB in %d blocks\n", __func__, head, + (int)(head->total_alloc_size >> 10), head->total_blocks); } uint64_t @@ -163,6 +165,8 @@ void lwsac_reference(struct lwsac *head) { head->refcount++; + lwsl_debug("%s: head %p: (det %d) refcount -> %d\n", + __func__, head, head->detached, head->refcount); } void @@ -170,15 +174,29 @@ lwsac_unreference(struct lwsac **head) { if (!(*head)) return; + + if (!(*head)->refcount) + lwsl_warn("%s: refcount going below zero\n", __func__); + (*head)->refcount--; - if ((*head)->detached && !(*head)->refcount) + + lwsl_debug("%s: head %p: (det %d) refcount -> %d\n", + __func__, *head, (*head)->detached, (*head)->refcount); + + if ((*head)->detached && !(*head)->refcount) { + lwsl_debug("%s: head %p: FREED\n", __func__, *head); lwsac_free(head); + } } void lwsac_detach(struct lwsac **head) { (*head)->detached = 1; - if (!(*head)->refcount) + if (!(*head)->refcount) { + lwsl_debug("%s: head %p: FREED\n", __func__, *head); lwsac_free(head); + } else + lwsl_debug("%s: head %p: refcount %d: Marked as detached\n", + __func__, *head, (*head)->refcount); } diff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c index 7dae16f8d..4205cface 100644 --- a/lib/roles/http/server/server.c +++ b/lib/roles/http/server/server.c @@ -1552,7 +1552,7 @@ deal_body: (uint8_t **)&ebuf.token); if (!ebuf.len) break; - lwsl_notice("%s: consuming %d\n", __func__, + lwsl_debug("%s: consuming %d\n", __func__, (int)ebuf.len); m = lws_read_h1(wsi, (uint8_t *)ebuf.token, ebuf.len); diff --git a/minimal-examples/http-server/README.md b/minimal-examples/http-server/README.md index 6d5f84807..48644bc8e 100644 --- a/minimal-examples/http-server/README.md +++ b/minimal-examples/http-server/README.md @@ -1,6 +1,7 @@ |Example|Demonstrates| ---|--- minimal-http-server-basicauth|Shows how to protect a mount using a password file and basic auth +minimal-http-server-deaddrop|Shows how to use the deaddrop drag and drop file upload + sharing plugin minimal-http-server-dynamic|Serves both static and dynamically generated http content minimal-http-server-eventlib-foreign|Demonstrates integrating lws with a foreign event library minimal-http-server-eventlib-demos|Using the demo plugins with event libraries diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/CMakeLists.txt b/minimal-examples/http-server/minimal-http-server-deaddrop/CMakeLists.txt new file mode 100644 index 000000000..d5f518803 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/CMakeLists.txt @@ -0,0 +1,86 @@ +cmake_minimum_required(VERSION 2.8) +include(CheckCSourceCompiles) + +set(SAMP lws-minimal-http-server-deaddrop) +set(SRCS minimal-http-server-deaddrop.c) + +# NOTE... if you are building this standalone, you must point LWS_PLUGINS_DIR +# to the lws plugins dir so it can pick up the plugin source. Eg, +# cmake . -DLWS_PLUGINS_DIR=~/libwebsockets/plugins + +# If we are being built as part of lws, confirm current build config supports +# reqconfig, else skip building ourselves. +# +# If we are being built externally, confirm installed lws was configured to +# support reqconfig, else error out with a helpful message about the problem. +# +MACRO(require_lws_config reqconfig _val result) + + if (DEFINED ${reqconfig}) + if (${reqconfig}) + set (rq 1) + else() + set (rq 0) + endif() + else() + set(rq 0) + endif() + + if (${_val} EQUAL ${rq}) + set(SAME 1) + else() + set(SAME 0) + endif() + + if (LWS_WITH_MINIMAL_EXAMPLES AND NOT ${SAME}) + if (${_val}) + message("${SAMP}: skipping as lws being built without ${reqconfig}") + else() + message("${SAMP}: skipping as lws built with ${reqconfig}") + endif() + set(${result} 0) + else() + if (LWS_WITH_MINIMAL_EXAMPLES) + set(MET ${SAME}) + else() + CHECK_C_SOURCE_COMPILES("#include \nint main(void) {\n#if defined(${reqconfig})\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_${reqconfig}) + if (NOT DEFINED HAS_${reqconfig} OR NOT HAS_${reqconfig}) + set(HAS_${reqconfig} 0) + else() + set(HAS_${reqconfig} 1) + endif() + if ((HAS_${reqconfig} AND ${_val}) OR (NOT HAS_${reqconfig} AND NOT ${_val})) + set(MET 1) + else() + set(MET 0) + endif() + endif() + if (NOT MET) + if (${_val}) + message(FATAL_ERROR "This project requires lws must have been configured with ${reqconfig}") + else() + message(FATAL_ERROR "Lws configuration of ${reqconfig} is incompatible with this project") + endif() + endif() + endif() +ENDMACRO() + +set(requirements 1) +require_lws_config(LWS_ROLE_H1 1 requirements) +require_lws_config(LWS_ROLE_WS 1 requirements) +require_lws_config(LWS_WITHOUT_SERVER 0 requirements) + +if (requirements) + add_executable(${SAMP} ${SRCS}) + + if (LWS_PLUGINS_DIR) + include_directories(${LWS_PLUGINS_DIR}) + endif() + + if (websockets_shared) + target_link_libraries(${SAMP} websockets_shared) + add_dependencies(${SAMP} websockets_shared) + else() + target_link_libraries(${SAMP} websockets) + endif() +endif() diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/README.md b/minimal-examples/http-server/minimal-http-server-deaddrop/README.md new file mode 100644 index 000000000..4a07ad4be --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/README.md @@ -0,0 +1,49 @@ +# lws minimal http server deaddrop + +This demonstrates how you can leverage the lws deaddrop plugin to make a +secure, modern html5 file upload and sharing application. + +The demo is protected by basic auth credentials defined in the file at +./ba-passwords - by default the credentials are user: user1, password: password; +and user: user2, password: password again. + +You can upload files and have them appear on a shared, downloadable list that +is dynamically updated to all clients open on the page. Only the authenticated +uploader is able to delete the files he uploaded. + +Multiple simultaneous ongoing file uploads are supported. + +## build + +To build this standalone, you must tell cmake where the lws source tree +./plugins directory can be found, since it relies on including the source +of the raw-proxy plugin. + +``` + $ cmake . -DLWS_PLUGINS_DIR=~/libwebsockets/plugins && make +``` + +## usage + +``` + $ ./lws-minimal-http-server-deaddrop +[2018/12/01 10:31:09:7108] USER: LWS minimal http server deaddrop | visit https://localhost:7681 +[2018/12/01 10:31:09:8511] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 off +[2018/12/01 10:31:09:8522] NOTICE: Using SSL mode +[2018/12/01 10:31:10:0755] NOTICE: SSL ECDH curve 'prime256v1' +[2018/12/01 10:31:10:2562] NOTICE: lws_tls_client_create_vhost_context: doing cert filepath localhost-100y.cert +[2018/12/01 10:31:10:2581] NOTICE: Loaded client cert localhost-100y.cert +[2018/12/01 10:31:10:2583] NOTICE: lws_tls_client_create_vhost_context: doing private key filepath +[2018/12/01 10:31:10:2593] NOTICE: Loaded client cert private key localhost-100y.key +[2018/12/01 10:31:10:2596] NOTICE: created client ssl context for default +[2018/12/01 10:31:10:5290] NOTICE: deaddrop: vh default, upload dir ./uploads, max size 10000000 +[2018/12/01 10:31:10:5376] NOTICE: vhost default: cert expiry: 730203d +... +``` + +Visit https://localhost:7681, and follow the link there to the secret area. + +Give your browser "user1" and "password" as the credentials. For testing to +confirm what a different user sees, you can also log in as "user2" and +"password". + diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/ba-passwords b/minimal-examples/http-server/minimal-http-server-deaddrop/ba-passwords new file mode 100644 index 000000000..cd9feb014 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/ba-passwords @@ -0,0 +1,2 @@ +user1:password +user2:password diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/localhost-100y.cert b/minimal-examples/http-server/minimal-http-server-deaddrop/localhost-100y.cert new file mode 100644 index 000000000..6f372db40 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/localhost-100y.cert @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +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 +e2Hl/7M0c/lbZ4FvXgARlex2rkgS0Ka06HE= +-----END CERTIFICATE----- diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/localhost-100y.key b/minimal-examples/http-server/minimal-http-server-deaddrop/localhost-100y.key new file mode 100644 index 000000000..148f8598e --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/localhost-100y.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +fBrpEY1IATtPq1taBZZogRqI3rOkkPk= +-----END PRIVATE KEY----- diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/minimal-http-server-deaddrop.c b/minimal-examples/http-server/minimal-http-server-deaddrop/minimal-http-server-deaddrop.c new file mode 100644 index 000000000..341918355 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/minimal-http-server-deaddrop.c @@ -0,0 +1,171 @@ +/* + * lws-minimal-http-server-deaddrop + * + * Copyright (C) 2018 Andy Green + * + * This file is made available under the Creative Commons CC0 1.0 + * Universal Public Domain Dedication. + * + * This demonstrates how you can leverage the lws deaddrop plugin to make a + * secure, modern html5 file upload and sharing application. + * + * Because the guts are in a plugin, you can avoid all this setup by using the + * plugin from lwsws and do the config in JSON. + */ + +#include +#include +#include +#include + +#define LWS_PLUGIN_STATIC +#include "../plugins/deaddrop/protocol_lws_deaddrop.c" + +static struct lws_protocols protocols[] = { + LWS_PLUGIN_PROTOCOL_DEADDROP, + { NULL, NULL, 0, 0 } /* terminator */ +}; + + +static int interrupted; + +/* + * teach the /get mount how to present various filetypes to the client... + * lws won't serve files it doesn't know the mimetype for as a security + * measure. + */ + +static struct lws_protocol_vhost_options em3 = { + NULL, NULL, ".zip", "application/zip" +}, em2 = { + &em3, NULL, ".pdf", "application/pdf" +}, extra_mimetypes = { + &em2, NULL, ".tar.gz", "application/x-gzip" +}; + +/* wire up /upload URLs to the plugin (protected by basic auth) */ + +static const struct lws_http_mount mount_upload = { + /* .mount_next */ NULL, + /* .mountpoint */ "/upload", /* mountpoint URL */ + /* .origin */ "lws-deaddrop", + /* .def */ "", + /* .protocol */ NULL, + /* .cgienv */ NULL, + /* .extra_mimetypes */ NULL, + /* .interpret */ NULL, + /* .cgi_timeout */ 0, + /* .cache_max_age */ 0, + /* .auth_mask */ 0, + /* .cache_reusable */ 0, + /* .cache_revalidate */ 0, + /* .cache_intermediaries */ 0, + /* .origin_protocol */ LWSMPRO_CALLBACK, + /* .mountpoint_len */ 7, /* char count */ + /* .basic_auth_login_file */ "./ba-passwords", +}; + +/* wire up /get URLs to the upload directory (protected by basic auth) */ + +static const struct lws_http_mount mount_get = { + /* .mount_next */ &mount_upload, /* linked-list "next" */ + /* .mountpoint */ "/get", /* mountpoint URL */ + /* .origin */ "./uploads", + /* .def */ "", + /* .protocol */ NULL, + /* .cgienv */ NULL, + /* .extra_mimetypes */ &extra_mimetypes, + /* .interpret */ NULL, + /* .cgi_timeout */ 0, + /* .cache_max_age */ 0, + /* .auth_mask */ 0, + /* .cache_reusable */ 0, + /* .cache_revalidate */ 0, + /* .cache_intermediaries */ 0, + /* .origin_protocol */ LWSMPRO_FILE, /* dynamic */ + /* .mountpoint_len */ 4, /* char count */ + /* .basic_auth_login_file */ "./ba-passwords", +}; + +/* wire up / to serve from ./mount-origin (protected by basic auth) */ + +static const struct lws_http_mount mount = { + /* .mount_next */ &mount_get, /* linked-list "next" */ + /* .mountpoint */ "/", /* mountpoint URL */ + /* .origin */ "./mount-origin", /* serve from dir */ + /* .def */ "index.html", /* default filename */ + /* .protocol */ NULL, + /* .cgienv */ NULL, + /* .extra_mimetypes */ NULL, + /* .interpret */ NULL, + /* .cgi_timeout */ 0, + /* .cache_max_age */ 0, + /* .auth_mask */ 0, + /* .cache_reusable */ 0, + /* .cache_revalidate */ 0, + /* .cache_intermediaries */ 0, + /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */ + /* .mountpoint_len */ 1, /* char count */ + /* .basic_auth_login_file */ "./ba-passwords", +}; + +/* pass config options to the deaddrop plugin using pvos */ + +static struct lws_protocol_vhost_options pvo3 = { + /* make the wss also require to pass basic auth */ + NULL, NULL, "basic-auth", "./ba-passwords" +}, pvo2 = { + &pvo3, NULL, "max-size", "10000000" +}, pvo1 = { + &pvo2, NULL, "upload-dir", "./uploads" /* would be an absolute path */ +}, pvo = { + NULL, /* "next" pvo linked-list */ + &pvo1, /* "child" pvo linked-list */ + "lws-deaddrop", /* protocol name we belong to on this vhost */ + "" /* ignored */ +}; + +void sigint_handler(int sig) +{ + interrupted = 1; +} + +int main(int argc, const char **argv) +{ + struct lws_context_creation_info info; + struct lws_context *context; + const char *p; + int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE; + + signal(SIGINT, sigint_handler); + + if ((p = lws_cmdline_option(argc, argv, "-d"))) + logs = atoi(p); + + lws_set_log_level(logs, NULL); + lwsl_user("LWS minimal http server deaddrop | visit https://localhost:7681\n"); + + memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ + info.port = 7681; + info.mounts = &mount; + info.pvo = &pvo; + info.protocols = protocols; + info.error_document_404 = "/404.html"; + info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | + LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; + info.ssl_cert_filepath = "localhost-100y.cert"; + info.ssl_private_key_filepath = "localhost-100y.key"; + + context = lws_create_context(&info); + if (!context) { + lwsl_err("lws init failed\n"); + return 1; + } + + while (n >= 0 && !interrupted) + n = lws_service(context, 1000); + + lws_context_destroy(context); + + return 0; +} diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/404.html b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/404.html new file mode 100644 index 000000000..3e5a14b9f --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/404.html @@ -0,0 +1,9 @@ + + + +
+

404

+ Sorry, that file doesn't exist. + + + diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/deaddrop.css b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/deaddrop.css new file mode 100644 index 000000000..549e36236 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/deaddrop.css @@ -0,0 +1,70 @@ +.td { padding: 8px } +.h1 { } +.dd-fileinfo { font-size: 8pt; } +table td { + display: table-cell; + vertical-align: top; + background-color: rgba(247, 247, 232, 0.6); + text-align: center +} +table { + border: 2px solid #ccc; + padding: 4px; + border-radius: 12px; + transition: background-color 0.5s ease; +} +table.nb { border: 0px; border-radius: 0px; transition: opacity 0.5s; } +table.noconn { background-color: #ddd; } + +div { transition: opacity 0.5s; } +div.da { padding-left: 20px; padding-right:20px; } +div.trot { + animation: scale 0.5s linear infinite; +} +div.uplbox { padding-bottom: 8px; } +div.disa { opacity: 0.2; } + +td.ogn { text-align:left; font-size: 8pt; padding-left: 4px; padding-right: 4px;} +td.dow { text-align:left; font-size: 9pt; padding-left: 4px; padding-right: 4px;} +td.r { text-align: right; } +td.err { color: red; font-weight: bold; } +td.vm { display: table-cell; vertical-align: middle; padding-top: 12px; padding-bottom: 12px; } + +h3 { font-size: 12pt; margin-bottom: 6px; } +span { font-size: 9pt; } +a { font-size: 9pt; } + +input.ubtn { font-size: 16pt; margin-top: 4px; text-align: center } + +img.working { + display: inline-block; + float:left; + background: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKICAgICB3aWR0aD0iMjRweCIgaGVpZ2h0PSIzMHB4IiB2aWV3Qm94PSIwIDAgMjQgMzAiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUwIDUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CiAgICA8cmVjdCB4PSIwIiB5PSIxMCIgd2lkdGg9IjQiIGhlaWdodD0iMTAiIGZpbGw9IiMzMzMiIG9wYWNpdHk9IjAuMiI+CiAgICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9Im9wYWNpdHkiIGF0dHJpYnV0ZVR5cGU9IlhNTCIgdmFsdWVzPSIwLjI7IDE7IC4yIiBiZWdpbj0iMHMiIGR1cj0iMC42cyIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIC8+CiAgICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImhlaWdodCIgYXR0cmlidXRlVHlwZT0iWE1MIiB2YWx1ZXM9IjEwOyAyMDsgMTAiIGJlZ2luPSIwcyIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICAgICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0ieSIgYXR0cmlidXRlVHlwZT0iWE1MIiB2YWx1ZXM9IjEwOyA1OyAxMCIgYmVnaW49IjBzIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0iOCIgeT0iMTAiIHdpZHRoPSI0IiBoZWlnaHQ9IjEwIiBmaWxsPSIjMzMzIiAgb3BhY2l0eT0iMC4yIj4KICAgICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0ib3BhY2l0eSIgYXR0cmlidXRlVHlwZT0iWE1MIiB2YWx1ZXM9IjAuMjsgMTsgLjIiIGJlZ2luPSIwLjE1cyIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICAgICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iaGVpZ2h0IiBhdHRyaWJ1dGVUeXBlPSJYTUwiIHZhbHVlcz0iMTA7IDIwOyAxMCIgYmVnaW49IjAuMTVzIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJ5IiBhdHRyaWJ1dGVUeXBlPSJYTUwiIHZhbHVlcz0iMTA7IDU7IDEwIiBiZWdpbj0iMC4xNXMiIGR1cj0iMC42cyIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIC8+CiAgICA8L3JlY3Q+CiAgICA8cmVjdCB4PSIxNiIgeT0iMTAiIHdpZHRoPSI0IiBoZWlnaHQ9IjEwIiBmaWxsPSIjMzMzIiAgb3BhY2l0eT0iMC4yIj4KICAgICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0ib3BhY2l0eSIgYXR0cmlidXRlVHlwZT0iWE1MIiB2YWx1ZXM9IjAuMjsgMTsgLjIiIGJlZ2luPSIwLjNzIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJoZWlnaHQiIGF0dHJpYnV0ZVR5cGU9IlhNTCIgdmFsdWVzPSIxMDsgMjA7IDEwIiBiZWdpbj0iMC4zcyIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICAgICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0ieSIgYXR0cmlidXRlVHlwZT0iWE1MIiB2YWx1ZXM9IjEwOyA1OyAxMCIgYmVnaW49IjAuM3MiIGR1cj0iMC42cyIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIC8+CiAgICA8L3JlY3Q+Cjwvc3ZnPg=="); + width:0px; + height:0px; + cursor:pointer; + padding:0.6em 1em; + background-repeat: no-repeat; + vertical-align:middle; + color: rgba(0, 0, 0, 0); +} + +img.delbtn { + display: inline-block; + float:left; + background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzNC4yMTcxMzMgMzQuMTQ0MjQ5IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KCTxkZWZzPgoJCTxyYWRpYWxHcmFkaWVudCBpZD0iYSIgY3g9IjEzNTguNSIgY3k9Ijk3Ny43MiIgcj0iNC4xMTYiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS41MDM1IDAgMCAyLjQ5NDQgLTI1NzcuNCAtMTgyMy44KSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjZmZmIiBvZmZzZXQ9IjAiLz4KCQkJPHN0b3Agc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjEiLz4KCQk8L3JhZGlhbEdyYWRpZW50PgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iYiIgeDE9IjEzNjYuMyIgeDI9IjEzNDQuOCIgeTE9Ijk3OC4xOSIgeTI9Ijk1OC43MyIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgtMjE3NCAtMTA3Ni4xKSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgoJCQk8c3RvcCBzdG9wLWNvbG9yPSIjOWM5NzlkIiBvZmZzZXQ9IjAiLz4KCQkJPHN0b3Agc3RvcC1jb2xvcj0iI2Y0ZmVmMyIgc3RvcC1vcGFjaXR5PSIuNzQwMTYiIG9mZnNldD0iMSIvPgoJCTwvbGluZWFyR3JhZGllbnQ+Cgk8L2RlZnM+Cgk8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4MzQuMjkgMTIzLjc1KSI+CgkJPGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj4KCQkJPGNpcmNsZSBjeD0iLTgxNy4yMiIgY3k9Ii0xMDYuNjgiIHI9IjE2LjA5IiBmaWxsPSJ1cmwoI2IpIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMS45NjUiLz4KCQkJPHBhdGggZD0ibS04MjUuNjctMTE0LjcxYzE3LjMzIDE3LjMzIDE3IDE2Ljk5OSAxNyAxNi45OTkiIGZpbGw9IiNmNTUiIHN0cm9rZT0iI2EwMCIgc3Ryb2tlLXdpZHRoPSIxLjY2NSIvPgoJCQk8cGF0aCBkPSJtLTgwOC45Ni0xMTQuNjFjLTE3LjMzIDE3LjMzLTE3IDE2Ljk5OS0xNyAxNi45OTkiIGZpbGw9IiNmNTUiIHN0cm9rZT0iI2EwMCIgc3Ryb2tlLXdpZHRoPSIxLjY2NSIvPgoJCTwvZz4KCQk8ZWxsaXBzZSB0cmFuc2Zvcm09InJvdGF0ZSg1NS44ODUpIiBjeD0iLTUzNC45NiIgY3k9IjYxNS4wNyIgcng9IjYuMTg4MyIgcnk9IjEwLjI2NyIgZmlsbD0idXJsKCNhKSIvPgoJPC9nPgo8L3N2Zz4="); + width:0px; + height:0px; + cursor:pointer; + padding:0.45em; + background-repeat: no-repeat; + vertical-align:middle; + color: rgba(0, 0, 0, 0); +} + +@keyframes scale { + 50% { + opacity: 0.5; + transform:scale(1.1) rotate(2deg); + } +} diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/deaddrop.js b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/deaddrop.js new file mode 100644 index 000000000..9bd3d7f7f --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/deaddrop.js @@ -0,0 +1,300 @@ +(function() { + + var server_max_size = 0, ws; + + function san(s) + { + if (!s) + return ""; + + return s.replace(/&/g, "&"). + replace(/\/g, ">"). + replace(/\"/g, """). + replace(/%/g, "%"); + } + + function lws_urlencode(s) + { + return encodeURI(s).replace(/@/g, "%40"); + } + + function trim(num) + { + var s = num.toString(); + + if (!s.indexOf(".")) + return s; + + while (s.length && s[s.length - 1] == "0") + s = s.substring(0, s.length - 1); + + if (s[s.length - 1] == ".") + s = s.substring(0, s.length - 1); + + return s; + } + + function humanize(n) + { + if (n < 1024) + return n + "B"; + + if (n < 1024 * 1024) + return trim((n / 1024).toFixed(2)) + "KiB"; + + if (n < 1024 * 1024 * 1024) + return trim((n / (1024 * 1024)).toFixed(2)) + "MiB"; + + return trim((n / (1024 * 1024 * 1024)).toFixed(2)) + "GiB"; + } + + function da_enter(e) + { + var da = document.getElementById("da"); + + e.preventDefault(); + da.classList.add("trot"); + } + + function da_leave(e) + { + var da = document.getElementById("da"); + + e.preventDefault(); + da.classList.remove("trot"); + } + + function da_over(e) + { + var da = document.getElementById("da"); + + e.preventDefault(); + da.classList.add("trot"); + } + + function clear_errors() { + var t = document.getElementById("ongoing"); + + for (n = 0; n < t.rows.length; n++) + if (t.rows[n].cells[0].classList.contains("err")) + t.deleteRow(n); + } + + function do_upload(file) { + var formData = new FormData(); + var t = document.getElementById("ongoing"); + + formData.append('file', file); + + var row = t.insertRow(0), c1 = row.insertCell(0), + c2 = row.insertCell(1), c3 = row.insertCell(2); + + c1.classList.add("ogn"); + c1.classList.add("r"); + + if (file.size > server_max_size) { + c1.innerHTML = "Too Large"; + c1.classList.add("err"); + } else + c1.innerHTML = ""; + + c2.classList.add("ogn"); + c2.classList.add("r"); + c2.innerHTML = humanize(file.size); + + c3.classList.add("ogn"); + c3.innerHTML = file.name; + + if (file.size > server_max_size) + return; + + fetch("upload/" + lws_urlencode(file.name), { + method: 'POST', + body: formData + }) + .then((e) => { /* this just means we got a response code */ + var us = e.url.split("/"), ul = us[us.length - 1], n; + + for (n = 0; n < t.rows.length; n++) + if (ul === lws_urlencode( + t.rows[n].cells[2].textContent)) { + if (e.ok === true) { + t.deleteRow(n); + } else { + t.rows[n].cells[0].textContent = + "Failed " + san(e.status.toString()); + t.rows[n].cells[0]. + classList.add("err"); + } + break; + } + }) + .catch((e) => { + var us = e.url.split("/"), ul = us[us.length - 1], n; + + for (n = 0; n < t.rows.length; n++) + if (ul === lws_urlencode( + t.rows[n].cells[2].textContent)) { + t.rows[n].cells[0] = "FAIL"; + break; + } + }) + } + + function da_drop(e) { + var da = document.getElementById("da"); + + e.preventDefault(); + da.classList.remove("trot"); + + clear_errors(); + + ([...e.dataTransfer.files]).forEach(do_upload) + } + + function upl_button(e) { + var fi = document.getElementById("file"), + da = document.getElementById("da"); + + clear_errors(); + e.preventDefault(); + + ([...fi.files]).forEach(do_upload) + } + + function body_drop(e) { + e.preventDefault(); + } + + function inp() { + var fi = document.getElementById("file"), + upl = document.getElementById("upl"); + console.log("inp"); + upl.disabled = !fi.files.length; + } + + function delfile(e) + { + e.stopPropagation(); + e.preventDefault(); + + ws.send("{\"del\":\"" + decodeURI(e.target.getAttribute("file")) + + "\"}"); + } + + function get_appropriate_ws_url(extra_url) + { + var pcol; + var u = document.URL; + + /* + * We open the websocket encrypted if this page came on an + * https:// url itself, otherwise unencrypted + */ + + if (u.substring(0, 5) === "https") { + pcol = "wss://"; + u = u.substr(8); + } else { + pcol = "ws://"; + if (u.substring(0, 4) === "http") + u = u.substr(7); + } + + u = u.split("/"); + + /* + "/xxx" bit is for IE10 workaround */ + + return pcol + u[0] + "/" + extra_url; + } + + function new_ws(urlpath, protocol) + { + if (typeof MozWebSocket != "undefined") + return new MozWebSocket(urlpath, protocol); + + return new WebSocket(urlpath, protocol); + } + + document.addEventListener("DOMContentLoaded", function() { + var da = document.getElementById("da"), + fi = document.getElementById("file"), + upl = document.getElementById("upl"); + + da.addEventListener("dragenter", da_enter, false); + da.addEventListener("dragleave", da_leave, false); + da.addEventListener("dragover", da_over, false); + da.addEventListener("drop", da_drop, false); + + upl.addEventListener("click", upl_button, false); + fi.addEventListener("change", inp, false); + + window.addEventListener("dragover", body_drop, false); + window.addEventListener("drop", body_drop, false); + + ws = new_ws(get_appropriate_ws_url(""), "lws-deaddrop"); + try { + ws.onopen = function() { + var dd = document.getElementById("ddrop"), + da = document.getElementById("da"); + + dd.classList.remove("noconn"); + da.classList.remove("disa"); + }; + + ws.onmessage = function got_packet(msg) { + var j = JSON.parse(msg.data), s = "", n, + t = document.getElementById("dd-list"); + + server_max_size = j.max_size; + document.getElementById("size").innerHTML = + "Server maximum file size " + + humanize(j.max_size); + + s += ""; + for (n = 0; n < j.files.length; n++) { + var date = new Date(j.files[n].mtime * 1000); + s += ""; + } + s += "
" + + humanize(j.files[n].size) + + "" + + date.toDateString() + " " + + date.toLocaleTimeString() + + ""; + if (j.files[n].yours === 1) + s += ""; + else + s += " "; + + s += "" + + san(j.files[n].name) + "
"; + + t.innerHTML = s; + + for (n = 0; n < j.files.length; n++) { + var d = document.getElementById("d" + n); + if (d) + d.addEventListener("click", + delfile, false); + } + }; + + ws.onclose = function() { + var dd = document.getElementById("ddrop"), + da = document.getElementById("da"); + + dd.classList.add("noconn"); + da.classList.add("disa"); + }; + } catch(exception) { + alert("

Error " + exception); + } + + }); +}()); \ No newline at end of file diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/drop.svg b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/drop.svg new file mode 100644 index 000000000..f413cf054 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/drop.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/favicon.ico b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/favicon.ico new file mode 100644 index 000000000..c0cc2e3df Binary files /dev/null and b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/favicon.ico differ diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/index.html b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/index.html new file mode 100644 index 000000000..67885727a --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/index.html @@ -0,0 +1,35 @@ + + + + + + + + +  
+

+ + + +
+
+
+

...or select files to upload:

+
+
+ + +
+ +
+
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/libwebsockets.org-logo.svg b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/libwebsockets.org-logo.svg new file mode 100644 index 000000000..7baea649f --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/libwebsockets.org-logo.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/strict-csp.svg b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/strict-csp.svg new file mode 100644 index 000000000..cd128f1d2 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/mount-origin/strict-csp.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/minimal-examples/http-server/minimal-http-server-deaddrop/uploads/user1/placeholder.txt b/minimal-examples/http-server/minimal-http-server-deaddrop/uploads/user1/placeholder.txt new file mode 100644 index 000000000..2d1be9ef0 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-deaddrop/uploads/user1/placeholder.txt @@ -0,0 +1 @@ +git doesn't support empty dirs... diff --git a/plugins/deaddrop/protocol_lws_deaddrop.c b/plugins/deaddrop/protocol_lws_deaddrop.c index f0ac456e4..bd12cad68 100644 --- a/plugins/deaddrop/protocol_lws_deaddrop.c +++ b/plugins/deaddrop/protocol_lws_deaddrop.c @@ -390,7 +390,7 @@ callback_deaddrop(struct lws *wsi, enum lws_callback_reasons reason, break; case LWS_CALLBACK_PROTOCOL_DESTROY: - lwsac_reference(vhd->lwsac_head); + lwsac_free(&vhd->lwsac_head); break; /* WS-related */ @@ -405,7 +405,8 @@ callback_deaddrop(struct lws *wsi, enum lws_callback_reasons reason, m = lws_hdr_copy(wsi, pss->user, sizeof(pss->user), WSI_TOKEN_HTTP_AUTHORIZATION); if (m > 0) - lwsl_info("basic auth user: %s\n", pss->user); + lwsl_info("%s: basic auth user: %s\n", + __func__, pss->user); else pss->user[0] = '\0'; @@ -440,7 +441,8 @@ callback_deaddrop(struct lws *wsi, enum lws_callback_reasons reason, if ((int)strlen(pss->user) != n || memcmp(pss->user, ((const char *)in) + 8, n)) { - lwsl_notice("%s: del: auth mismatch '%s' '%s' (%d)\n", + lwsl_notice("%s: del: auth mismatch " + " '%s' '%s' (%d)\n", __func__, pss->user, ((const char *)in) + 8, n); break; @@ -497,7 +499,10 @@ callback_deaddrop(struct lws *wsi, enum lws_callback_reasons reason, if (!pss->dire) { p += lws_snprintf((char *)p, lws_ptr_diff(end, p), "]}"); - lwsac_unreference(&pss->lwsac_head); + if (pss->lwsac_head) { + lwsac_unreference(&pss->lwsac_head); + pss->lwsac_head = NULL; + } } n = lws_write(wsi, start, lws_ptr_diff(p, start), @@ -516,7 +521,7 @@ callback_deaddrop(struct lws *wsi, enum lws_callback_reasons reason, /* ie, we finished */ if (pss->filelist_version != pss->vhd->filelist_version) { - lwsl_notice("restart send\n"); + lwsl_info("%s: restart send\n", __func__); /* what we just sent is already out of date */ start_sending_dir(pss); lws_callback_on_writable(wsi);