/* this shows how to override the lws file operations. You don't need * to do any of this unless you have a reason (eg, want to serve * compressed files without decompressing the whole archive) */ static lws_filefd_type test_server_fops_open(struct lws *wsi, const char *filename, unsigned long *filelen, int flags) { lws_filefd_type n; /* call through to original platform implementation */ n = fops_plat.open(wsi, filename, filelen, flags); lwsl_notice("%s: opening %s, ret %ld, len %lu\n", __func__, filename, (long)n, *filelen); return n; }
int lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type, union lws_tls_cert_info_results *buf, size_t len) { #if defined(LWS_HAVE_SSL_CTX_get0_certificate) X509 *x509 = SSL_CTX_get0_certificate(vhost->tls.ssl_ctx); return lws_tls_openssl_cert_info(x509, type, buf, len); #else lwsl_notice("openssl is too old to support %s\n", __func__); return -1; #endif }
LWS_VISIBLE int lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len) { int n, m; if (!wsi->ssl) return lws_ssl_capable_write_no_ssl(wsi, buf, len); n = SSL_write(wsi->ssl, buf, len); if (n > 0) return n; m = lws_ssl_get_error(wsi, n); if (m != SSL_ERROR_SYSCALL) { if (SSL_want_read(wsi->ssl)) { lwsl_notice("%s: want read\n", __func__); return LWS_SSL_CAPABLE_MORE_SERVICE; } if (SSL_want_write(wsi->ssl)) { lws_set_blocking_send(wsi); lwsl_notice("%s: want write\n", __func__); return LWS_SSL_CAPABLE_MORE_SERVICE; } } lwsl_debug("%s failed: %s\n",__func__, ERR_error_string(m, NULL)); lws_ssl_elaborate_error(); wsi->socket_is_permanently_unusable = 1; return LWS_SSL_CAPABLE_ERROR; }
size_t get_gen_server_key_25519(struct per_session_data__sshd *pss, uint8_t *b, size_t len) { size_t s, mylen; mylen = pss->vhd->ops->get_server_key(b, len); if (mylen) return mylen; /* create one then */ lwsl_notice("Generating server hostkey\n"); s = lws_gen_server_key_ed25519(pss->vhd->context, b, len); lwsl_notice(" gen key len %ld\n", (long)s); if (!s) return 0; /* set the key */ if (!pss->vhd->ops->set_server_key(b, s)) return 0; /* new key stored OK */ return s; }
static void lwsgs_email_on_connect(uv_connect_t *req, int status) { struct lws_email *email = (struct lws_email *)req->data; lwsl_notice("%s\n", __func__); if (status == -1) { lwsl_err("%s: failed\n", __func__); return; } uv_read_start(req->handle, alloc_buffer, lwsgs_email_read); email->estate = LGSSMTP_CONNECTED; }
static int lws_context_ssl_init_ecdh_curve(struct lws_context_creation_info *info, struct lws_vhost *vhost) { #if defined(LWS_HAVE_OPENSSL_ECDH_H) && !defined(LWS_WITH_MBEDTLS) EC_KEY *ecdh; int ecdh_nid; const char *ecdh_curve = "prime256v1"; if (info->ecdh_curve) ecdh_curve = info->ecdh_curve; ecdh_nid = OBJ_sn2nid(ecdh_curve); if (NID_undef == ecdh_nid) { lwsl_err("SSL: Unknown curve name '%s'", ecdh_curve); return 1; } ecdh = EC_KEY_new_by_curve_name(ecdh_nid); if (NULL == ecdh) { lwsl_err("SSL: Unable to create curve '%s'", ecdh_curve); return 1; } SSL_CTX_set_tmp_ecdh(vhost->ssl_ctx, ecdh); EC_KEY_free(ecdh); SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_SINGLE_ECDH_USE); lwsl_notice(" SSL ECDH curve '%s'\n", ecdh_curve); #else #if !defined(LWS_WITH_MBEDTLS) lwsl_notice(" OpenSSL doesn't support ECDH\n"); #endif #endif return 0; }
void signal_cb(struct ev_loop *loop, struct ev_signal* watcher, int revents) { lwsl_notice("Signal caught, exiting...\n"); force_exit = 1; switch (watcher->signum) { case SIGTERM: case SIGINT: ev_break(loop, EVBREAK_ALL); break; default: signal(SIGABRT, SIG_DFL); abort(); break; } }
static void signal_cb(int signum) { lwsl_notice("Signal %d caught, exiting...\n", signum); switch (signum) { case SIGTERM: case SIGINT: break; default: break; } lws_context_destroy(context); }
int lws_ws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len) { if ((lwsi_state(wsi) != LRS_WAITING_PROXY_REPLY) && (lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE) && (lwsi_state(wsi) != LRS_WAITING_SERVER_REPLY) && !lwsi_role_client(wsi)) return 0; // lwsl_notice("%s: hs client gets %d in\n", __func__, (int)len); while (len) { /* * we were accepting input but now we stopped doing so */ if (lws_is_flowcontrolled(wsi)) { //lwsl_notice("%s: caching %ld\n", __func__, (long)len); lws_rxflow_cache(wsi, *buf, 0, (int)len); *buf += len; return 0; } #if !defined(LWS_WITHOUT_EXTENSIONS) if (wsi->ws->rx_draining_ext) { int m; //lwsl_notice("%s: draining ext\n", __func__); if (lwsi_role_client(wsi)) m = lws_ws_client_rx_sm(wsi, 0); else m = lws_ws_rx_sm(wsi, 0, 0); if (m < 0) return -1; continue; } #endif /* caller will account for buflist usage */ if (lws_ws_client_rx_sm(wsi, *(*buf)++)) { lwsl_notice("%s: client_rx_sm exited, DROPPING %d\n", __func__, (int)len); return -1; } len--; } // lwsl_notice("%s: finished with %ld\n", __func__, (long)len); return 0; }
LWS_VISIBLE void lws_server_get_canonical_hostname(struct lws_context *context, struct lws_context_creation_info *info) { if (info->options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME) return; #if LWS_POSIX /* find canonical hostname */ gethostname((char *)context->canonical_hostname, sizeof(context->canonical_hostname) - 1); lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname); #else (void)context; #endif }
enum lws_ssl_capable_status lws_tls_server_accept(struct lws *wsi) { union lws_tls_cert_info_results ir; int m, n = SSL_accept(wsi->ssl); if (n == 1) { n = lws_tls_peer_cert_info(wsi, LWS_TLS_CERT_INFO_COMMON_NAME, &ir, sizeof(ir.ns.name)); if (!n) lwsl_notice("%s: client cert CN '%s'\n", __func__, ir.ns.name); else lwsl_info("%s: couldn't get client cert CN\n", __func__); return LWS_SSL_CAPABLE_DONE; } m = SSL_get_error(wsi->ssl, n); // mbedtls wrapper only if (m == SSL_ERROR_SYSCALL && errno == 11) return LWS_SSL_CAPABLE_MORE_SERVICE_READ; if (m == SSL_ERROR_SYSCALL || m == SSL_ERROR_SSL) return LWS_SSL_CAPABLE_ERROR; if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl)) { if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) { lwsl_info("%s: WANT_READ change_pollfd failed\n", __func__); return LWS_SSL_CAPABLE_ERROR; } lwsl_info("SSL_ERROR_WANT_READ\n"); return LWS_SSL_CAPABLE_MORE_SERVICE_READ; } if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) { lwsl_debug("%s: WANT_WRITE\n", __func__); if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) { lwsl_info("%s: WANT_WRITE change_pollfd failed\n", __func__); return LWS_SSL_CAPABLE_ERROR; } return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE; } return LWS_SSL_CAPABLE_ERROR; }
LWS_VISIBLE void lws_plat_delete_socket_from_fds(struct lws_context *context, struct lws *wsi, int m) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; int n; for (n = 0; n < wsi->context->max_fds; n++) if (wsi->context->connpool[n] == wsi->desc.sockfd) { wsi->context->connpool[n] = NULL; wsi->context->connpool[n + wsi->context->max_fds] = NULL; lwsl_notice(" freed connpool %d\n", n); } wsi->desc.sockfd->reverse = NULL; pt->fds_count--; }
LWS_VISIBLE int lws_plat_init(struct lws_context *context, struct lws_context_creation_info *info) { context->lws_lookup = lws_zalloc(sizeof(struct lws *) * context->max_fds); if (context->lws_lookup == NULL) { lwsl_err( "Unable to allocate lws_lookup array for %d connections\n", context->max_fds); return 1; } lwsl_notice(" mem: platform fd map: %5u bytes\n", sizeof(struct lws *) * context->max_fds); context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY); if (context->fd_random < 0) { lwsl_err("Unable to open random device %s %d\n", SYSTEM_RANDOM_FILEPATH, context->fd_random); return 1; } if (!lws_libev_init_fd_table(context)) { /* otherwise libev handled it instead */ if (pipe(context->dummy_pipe_fds)) { lwsl_err("Unable to create pipe\n"); return 1; } } /* use the read end of pipe as first item */ context->fds[0].fd = context->dummy_pipe_fds[0]; context->fds[0].events = LWS_POLLIN; context->fds[0].revents = 0; context->fds_count = 1; context->fops.open = _lws_plat_file_open; context->fops.close = _lws_plat_file_close; context->fops.seek_cur = _lws_plat_file_seek_cur; context->fops.read = _lws_plat_file_read; context->fops.write = _lws_plat_file_write; return 0; }
int lws_service_timeout_check(struct lws *wsi, unsigned int sec) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; /* * if extensions want in on it (eg, we are a mux parent) * give them a chance to service child timeouts */ if (lws_ext_cb_active(wsi, LWS_EXT_CB_1HZ, NULL, sec) < 0) return 0; if (!wsi->pending_timeout) return 0; /* * if we went beyond the allowed time, kill the * connection */ if ((time_t)sec > wsi->pending_timeout_limit) { #if LWS_POSIX /* no need to log normal idle keepalive timeout */ if (wsi->pending_timeout != PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE) lwsl_notice("wsi %p: TIMEDOUT WAITING on %d (did hdr %d, ah %p, wl %d, pfd events %d)\n", (void *)wsi, wsi->pending_timeout, wsi->hdr_parsing_completed, wsi->u.hdr.ah, pt->ah_wait_list_length, pt->fds[wsi->sock].events); #endif /* * Since he failed a timeout, he already had a chance to do * something and was unable to... that includes situations like * half closed connections. So process this "failed timeout" * close as a violent death and don't try to do protocol * cleanup like flush partials. */ wsi->socket_is_permanently_unusable = 1; lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); return 1; } return 0; }
//============================================================================== // WsInput //------------------------------------------------------------------------------ void WsInput::wsConnect(WsInput* wsinput) { libwebsocket_context *context; lws_context_creation_info info; int debug_level = 7; memset(&info,0,sizeof info); info.port = 7681; lws_set_log_level(debug_level,da); lwsl_notice("libwebsockets chat server -\n"); libwebsocket_protocols protocols[] = { { "input", WsInput::wsCallBackData, 0, 128 }, {NULL,NULL,0,0} /* terminator */ }; info.iface = nullptr; info.protocols = protocols; info.ssl_cert_filepath = nullptr; info.ssl_private_key_filepath = nullptr; info.gid = -1; info.uid = -1; info.options = 0; info.user = nullptr; context = libwebsocket_create_context(&info); for(;;) { int n = libwebsocket_service(context,10); if(n >= 0 && wsinput->_isend) { break; } } libwebsocket_context_destroy(context); wsinput->_isend = false; }
static int lws_mbedtls_sni_cb(void *arg, mbedtls_ssl_context *mbedtls_ctx, const unsigned char *servername, size_t len) { SSL *ssl = SSL_SSL_from_mbedtls_ssl_context(mbedtls_ctx); struct lws_context *context = (struct lws_context *)arg; struct lws_vhost *vhost, *vh; lwsl_notice("%s: %s\n", __func__, servername); /* * We can only get ssl accepted connections by using a vhost's ssl_ctx * find out which listening one took us and only match vhosts on the * same port. */ vh = context->vhost_list; while (vh) { if (!vh->being_destroyed && vh->ssl_ctx == SSL_get_SSL_CTX(ssl)) break; vh = vh->vhost_next; } if (!vh) { assert(vh); /* can't match the incoming vh? */ return 0; } vhost = lws_select_vhost(context, vh->listen_port, (const char *)servername); if (!vhost) { lwsl_info("SNI: none: %s:%d\n", servername, vh->listen_port); return 0; } lwsl_info("SNI: Found: %s:%d at vhost '%s'\n", servername, vh->listen_port, vhost->name); /* select the ssl ctx from the selected vhost for this conn */ SSL_set_SSL_CTX(ssl, vhost->ssl_ctx); return 0; }
int lws_tls_server_vhost_backend_init(struct lws_context_creation_info *info, struct lws_vhost *vhost, struct lws *wsi) { const SSL_METHOD *method = TLS_server_method(); uint8_t *p; lws_filepos_t flen; vhost->ssl_ctx = SSL_CTX_new(method); /* create context */ if (!vhost->ssl_ctx) { lwsl_err("problem creating ssl context\n"); return 1; } if (!vhost->use_ssl || !info->ssl_cert_filepath) return 0; if (info->ssl_ca_filepath) { lwsl_notice("%s: vh %s: loading CA filepath %s\n", __func__, vhost->name, info->ssl_ca_filepath); if (lws_tls_alloc_pem_to_der_file(vhost->context, info->ssl_ca_filepath, NULL, 0, &p, &flen)) { lwsl_err("couldn't find client CA file %s\n", info->ssl_ca_filepath); return 1; } if (SSL_CTX_add_client_CA_ASN1(vhost->ssl_ctx, (int)flen, p) != 1) { lwsl_err("%s: SSL_CTX_add_client_CA_ASN1 unhappy\n", __func__); free(p); return 1; } free(p); } return lws_tls_server_certs_load(vhost, wsi, info->ssl_cert_filepath, info->ssl_private_key_filepath, NULL, 0, NULL, 0); }
int ws_start(short port){ struct lws_context_creation_info info; memset(&info, 0, sizeof info); info.port = port; lwsl_notice("libwebsockets test server - " "(C) Copyright 2010-2013 Andy Green <*****@*****.**> - " "licensed under LGPL2.1\n"); info.protocols = protocols; info.extensions = libwebsocket_get_internal_extensions(); /*this is critical. otherwise UTF-8 error in client.*/ info.gid = -1; info.uid = -1; info.ka_time=100; context = libwebsocket_create_context(&info); if (!context){ lwsl_err("libwebsocket init failed\n"); return -1; } return 0; }
LWS_VISIBLE void lws_plat_drop_app_privileges(struct lws_context_creation_info *info) { if (info->gid != -1) if (setgid(info->gid)) lwsl_warn("setgid: %s\n", strerror(LWS_ERRNO)); if (info->uid != -1) { struct passwd *p = getpwuid(info->uid); if (p) { initgroups(p->pw_name, info->gid); if (setuid(info->uid)) lwsl_warn("setuid: %s\n", strerror(LWS_ERRNO)); else lwsl_notice("Set privs to user '%s'\n", p->pw_name); } else lwsl_warn("getpwuid: unable to find uid %d", info->uid); } }
LWS_VISIBLE int lws_plat_plugins_destroy(struct lws_context * context) { struct lws_plugin *plugin = context->plugin_list, *p; lws_plugin_destroy_func func; char path[256]; void *v; int m; if (!plugin) return 0; lwsl_notice("%s\n", __func__); while (plugin) { p = plugin; m = snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + 3); path[m - 3] = '\0'; if (uv_dlsym(&plugin->lib, path, &v)) { uv_dlerror(&plugin->lib); lwsl_err("Failed to get init on %s: %s", plugin->name, plugin->lib.errmsg); } else { func = (lws_plugin_destroy_func)v; m = func(context); if (m) lwsl_err("Destroying %s failed %d\n", plugin->name, m); } uv_dlclose(&p->lib); plugin = p->list; p->list = NULL; free(p); } context->plugin_list = NULL; return 0; }
/* * Notice: trashes i and url */ static struct lws * lws_acme_client_connect(struct lws_context *context, struct lws_vhost *vh, struct lws **pwsi, struct lws_client_connect_info *i, char *url, const char *method) { const char *prot, *p; char path[200], _url[256]; struct lws *wsi; memset(i, 0, sizeof(*i)); i->port = 443; lws_strncpy(_url, url, sizeof(_url)); if (lws_parse_uri(_url, &prot, &i->address, &i->port, &p)) { lwsl_err("unable to parse uri %s\n", url); return NULL; } /* add back the leading / on path */ path[0] = '/'; lws_strncpy(path + 1, p, sizeof(path) - 1); i->path = path; i->context = context; i->vhost = vh; i->ssl_connection = 1; i->host = i->address; i->origin = i->address; i->method = method; i->pwsi = pwsi; i->protocol = "lws-acme-client"; wsi = lws_client_connect_via_info(i); if (!wsi) { lws_snprintf(path, sizeof(path) - 1, "Unable to connect to %s", url); lwsl_notice("%s: %s\n", __func__, path); lws_acme_report_status(vh, LWS_CUS_FAILED, path); } return wsi; }
static void *_realloc(void *ptr, size_t size, const char *reason) { if (size) { #if defined(LWS_WITH_ESP32) lwsl_notice("%s: size %lu: %s\n", __func__, (unsigned long)size, reason); #else lwsl_debug("%s: size %lu: %s\n", __func__, (unsigned long)size, reason); #endif #if defined(LWS_PLAT_OPTEE) return (void *)TEE_Realloc(ptr, size); #else return (void *)realloc(ptr, size); #endif } if (ptr) free(ptr); return NULL; }
LWS_VISIBLE int lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi, struct lws_pollfd *pfd) { void *p; //lwsl_notice("%s: %p: wsi->pift=%d, events %d\n", // __func__, wsi, wsi->position_in_fds_table, pfd->events); if (pfd->events & LWS_POLLIN) { if (wsi->premature_rx) { lwsl_notice("replaying buffered rx: wsi %p\n", wsi); p = wsi->premature_rx; wsi->premature_rx = NULL; esp8266_cb_rx(wsi->desc.sockfd, (char *)p + wsi->prem_rx_pos, wsi->prem_rx_size - wsi->prem_rx_pos); wsi->prem_rx_size = 0; wsi->prem_rx_pos = 0; lws_free(p); } if (espconn_recv_unhold(wsi->desc.sockfd) < 0) return -1; } else if (espconn_recv_hold(wsi->desc.sockfd) < 0) return -1; if (!(pfd->events & LWS_POLLOUT)) return 0; if (!wsi->pending_send_completion) { pfd->revents |= LWS_POLLOUT; // lwsl_notice("doing POLLOUT\n"); lws_service_fd(lws_get_context(wsi), pfd); } //else //lwsl_notice("pending sc\n"); return 0; }
signed char lws_struct_schema_only_lejp_cb(struct lejp_ctx *ctx, char reason) { lws_struct_args_t *a = (lws_struct_args_t *)ctx->user; const lws_struct_map_t *map = a->map_st[ctx->pst_sp]; int n = a->map_entries_st[ctx->pst_sp]; lejp_callback cb = map->lejp_cb; if (reason != LEJPCB_VAL_STR_END || ctx->path_match != 1) return 0; while (n--) { if (strcmp(ctx->buf, map->colname)) { map++; continue; } a->dest = lwsac_use_zero(&a->ac, map->aux, a->ac_block_size); if (!a->dest) { lwsl_err("%s: OOT\n", __func__); return 1; } a->dest_len = map->aux; if (!cb) cb = lws_struct_default_lejp_cb; lejp_parser_push(ctx, a->dest, &map->child_map[0].colname, (uint8_t)map->child_map_size, cb); a->map_st[ctx->pst_sp] = map->child_map; a->map_entries_st[ctx->pst_sp] = map->child_map_size; return 0; } lwsl_notice("%s: unknown schema %s\n", __func__, ctx->buf); return 1; }
int lws_context_init_ssl_library(struct lws_context_creation_info *info) { #ifdef USE_WOLFSSL #ifdef USE_OLD_CYASSL lwsl_notice(" Compiled with CyaSSL support\n"); #else lwsl_notice(" Compiled with wolfSSL support\n"); #endif #else #if defined(LWS_USE_POLARSSL) lwsl_notice(" Compiled with PolarSSL support\n"); #else #if defined(LWS_USE_MBEDTLS) lwsl_notice(" Compiled with mbedTLS support\n"); #else lwsl_notice(" Compiled with OpenSSL support\n"); #endif #endif #endif if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) { lwsl_notice(" SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n"); return 0; } /* basic openssl init */ #if defined(LWS_USE_POLARSSL) #else #if defined(LWS_USE_MBEDTLS) #else SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); openssl_websocket_private_data_index = SSL_get_ex_new_index(0, "lws", NULL, NULL, NULL); openssl_SSL_CTX_private_data_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); #endif #endif return 0; }
int lws_create_client_ws_object(const struct lws_client_connect_info *i, struct lws *wsi) { int v = SPEC_LATEST_SUPPORTED; /* allocate the ws struct for the wsi */ wsi->ws = lws_zalloc(sizeof(*wsi->ws), "client ws struct"); if (!wsi->ws) { lwsl_notice("OOM\n"); return 1; } /* -1 means just use latest supported */ if (i->ietf_version_or_minus_one != -1 && i->ietf_version_or_minus_one) v = i->ietf_version_or_minus_one; wsi->ws->ietf_spec_revision = v; return 0; }
/** * lws_client_reset() - retarget a connected wsi to start over with a new connection (ie, redirect) * this only works if still in HTTP, ie, not upgraded yet * wsi: connection to reset * address: network address of the new server * port: port to connect to * path: uri path to connect to on the new server * host: host header to send to the new server */ LWS_VISIBLE struct lws * lws_client_reset(struct lws *wsi, int ssl, const char *address, int port, const char *path, const char *host) { if (wsi->u.hdr.redirects == 3) { lwsl_err("%s: Too many redirects\n", __func__); return NULL; } wsi->u.hdr.redirects++; #ifdef LWS_OPENSSL_SUPPORT wsi->use_ssl = ssl; #else if (ssl) { lwsl_err("%s: not configured for ssl\n", __func__); return NULL; } #endif lwsl_notice("redirect ads='%s', port=%d, path='%s'\n", address, port, path); if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address)) return NULL; if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, path)) return NULL; if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host)) return NULL; compatible_close(wsi->sock); remove_wsi_socket_from_fds(wsi); wsi->sock = LWS_SOCK_INVALID; wsi->state = LWSS_CLIENT_UNCONNECTED; wsi->protocol = NULL; wsi->pending_timeout = NO_PENDING_TIMEOUT; wsi->u.hdr.ah->c_port = port; return lws_client_connect_2(wsi); }
static int file_upload_cb(void *data, const char *name, const char *filename, char *buf, int len, enum lws_urldecode_fileupload_states state) { struct per_session_data__post_demo *pss = (struct per_session_data__post_demo *)data; int n; switch (state) { case LWS_UFS_OPEN: strncpy(pss->filename, filename, sizeof(pss->filename) - 1); /* we get the original filename in @filename arg, but for * simple demo use a fixed name so we don't have to deal with * attacks */ pss->fd = open("/tmp/post-file", O_CREAT | O_TRUNC | O_RDWR, 0600); break; case LWS_UFS_FINAL_CONTENT: case LWS_UFS_CONTENT: if (len) { pss->file_length += len; /* if the file length is too big, drop it */ if (pss->file_length > 100000) return 1; n = write(pss->fd, buf, len); lwsl_notice("%s: write %d says %d\n", __func__, len, n); } if (state == LWS_UFS_CONTENT) break; close(pss->fd); pss->fd = LWS_INVALID_FILE; break; } return 0; }
LWS_VISIBLE int lws_plat_plugins_destroy(struct lws_context * context) { struct lws_plugin *plugin = context->plugin_list, *p; lws_plugin_destroy_func func; char path[256]; int m; if (!plugin) return 0; lwsl_notice("%s\n", __func__); while (plugin) { p = plugin; m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + 3); path[m - 3] = '\0'; func = dlsym(plugin->l, path); if (!func) { lwsl_err("Failed to get destroy on %s: %s", plugin->name, dlerror()); goto next; } m = func(context); if (m) lwsl_err("Initializing %s failed %d\n", plugin->name, m); next: dlclose(p->l); plugin = p->list; p->list = NULL; free(p); } context->plugin_list = NULL; return 0; }
static void * _realloc(void *ptr, size_t size, const char *reason) { void *v; if (size) { #if defined(LWS_WITH_ESP32) lwsl_notice("%s: size %lu: %s (free heap %d)\n", __func__, (unsigned long)size, reason, (unsigned int)esp_get_free_heap_size() - (int)size); #else lwsl_debug("%s: size %lu: %s\n", __func__, (unsigned long)size, reason); #endif #if defined(LWS_HAVE_MALLOC_USABLE_SIZE) if (ptr) allocated -= malloc_usable_size(ptr); #endif #if defined(LWS_PLAT_OPTEE) v = (void *)TEE_Realloc(ptr, size); #else v = (void *)realloc(ptr, size); #endif #if defined(LWS_HAVE_MALLOC_USABLE_SIZE) allocated += malloc_usable_size(v); #endif return v; } if (ptr) { #if defined(LWS_HAVE_MALLOC_USABLE_SIZE) allocated -= malloc_usable_size(ptr); #endif free(ptr); } return NULL; }