diff options
Diffstat (limited to 'thirdparty/libwebsockets/lib/core/dummy-callback.c')
-rw-r--r-- | thirdparty/libwebsockets/lib/core/dummy-callback.c | 611 |
1 files changed, 0 insertions, 611 deletions
diff --git a/thirdparty/libwebsockets/lib/core/dummy-callback.c b/thirdparty/libwebsockets/lib/core/dummy-callback.c deleted file mode 100644 index 8fd18be9c5..0000000000 --- a/thirdparty/libwebsockets/lib/core/dummy-callback.c +++ /dev/null @@ -1,611 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -#if defined(LWS_WITH_HTTP_PROXY) -static int -proxy_header(struct lws *wsi, struct lws *par, unsigned char *temp, - int temp_len, int index, unsigned char **p, unsigned char *end) -{ - int n = lws_hdr_total_length(par, index); - - if (n < 1) { - lwsl_debug("%s: no index %d:\n", __func__, index); - return 0; - } - - if (lws_hdr_copy(par, (char *)temp, temp_len, index) < 0) - return -1; - - lwsl_debug("%s: index %d: %s\n", __func__, index, (char *)temp); - - if (lws_add_http_header_by_token(wsi, index, temp, n, p, end)) - return -1; - - return 0; -} - -static int -stream_close(struct lws *wsi) -{ - char buf[LWS_PRE + 6], *out = buf + LWS_PRE; - - if (wsi->http.did_stream_close) - return 0; - - wsi->http.did_stream_close = 1; - - if (wsi->http2_substream) { - if (lws_write(wsi, (unsigned char *)buf + LWS_PRE, 0, - LWS_WRITE_HTTP_FINAL) < 0) { - lwsl_info("%s: COMPL_CLIENT_HTTP: h2 fin wr failed\n", - __func__); - - return -1; - } - } else { - *out++ = '0'; - *out++ = '\x0d'; - *out++ = '\x0a'; - *out++ = '\x0d'; - *out++ = '\x0a'; - - if (lws_write(wsi, (unsigned char *)buf + LWS_PRE, 5, - LWS_WRITE_HTTP_FINAL) < 0) { - lwsl_err("%s: COMPL_CLIENT_HTTP: " - "h2 final write failed\n", __func__); - - return -1; - } - } - - return 0; -} - -#endif - -LWS_VISIBLE int -lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct lws_ssl_info *si; -#ifdef LWS_WITH_CGI - struct lws_cgi_args *args; -#endif -#if defined(LWS_WITH_CGI) || defined(LWS_WITH_HTTP_PROXY) - char buf[8192]; - int n; -#endif -#if defined(LWS_WITH_HTTP_PROXY) - unsigned char **p, *end; - struct lws *parent; -#endif - - switch (reason) { -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - case LWS_CALLBACK_HTTP: -#ifndef LWS_NO_SERVER - if (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL)) - return -1; - - if (lws_http_transaction_completed(wsi)) -#endif - return -1; - break; -#if !defined(LWS_NO_SERVER) - case LWS_CALLBACK_HTTP_BODY_COMPLETION: - case LWS_CALLBACK_HTTP_FILE_COMPLETION: - if (lws_http_transaction_completed(wsi)) - return -1; - break; -#endif - - case LWS_CALLBACK_HTTP_WRITEABLE: -#ifdef LWS_WITH_CGI - if (wsi->reason_bf & (LWS_CB_REASON_AUX_BF__CGI_HEADERS | - LWS_CB_REASON_AUX_BF__CGI)) { - n = lws_cgi_write_split_stdout_headers(wsi); - if (n < 0) { - lwsl_debug("AUX_BF__CGI forcing close\n"); - return -1; - } - if (!n) - lws_rx_flow_control( - wsi->http.cgi->stdwsi[LWS_STDOUT], 1); - - if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__CGI_HEADERS) - wsi->reason_bf &= - ~LWS_CB_REASON_AUX_BF__CGI_HEADERS; - else - wsi->reason_bf &= ~LWS_CB_REASON_AUX_BF__CGI; - - if (wsi->http.cgi && wsi->http.cgi->cgi_transaction_over) - return -1; - break; - } - - if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__CGI_CHUNK_END) { - if (!wsi->http2_substream) { - memcpy(buf + LWS_PRE, "0\x0d\x0a\x0d\x0a", 5); - lwsl_debug("writing chunk term and exiting\n"); - n = lws_write(wsi, (unsigned char *)buf + - LWS_PRE, 5, LWS_WRITE_HTTP); - } else - n = lws_write(wsi, (unsigned char *)buf + - LWS_PRE, 0, - LWS_WRITE_HTTP_FINAL); - - /* always close after sending it */ - return -1; - } -#endif -#if defined(LWS_WITH_HTTP_PROXY) - - if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__PROXY_HEADERS) { - - wsi->reason_bf &= ~LWS_CB_REASON_AUX_BF__PROXY_HEADERS; - - lwsl_debug("%s: %p: issuing proxy headers\n", - __func__, wsi); - n = lws_write(wsi, wsi->http.pending_return_headers + - LWS_PRE, - wsi->http.pending_return_headers_len, - LWS_WRITE_HTTP_HEADERS); - - lws_free_set_NULL(wsi->http.pending_return_headers); - - if (n < 0) { - lwsl_err("%s: EST_CLIENT_HTTP: write failed\n", - __func__); - return -1; - } - lws_callback_on_writable(wsi); - break; - } - - if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__PROXY) { - char *px = buf + LWS_PRE; - int lenx = sizeof(buf) - LWS_PRE - 32; - - /* - * our sink is writeable and our source has something - * to read. So read a lump of source material of - * suitable size to send or what's available, whichever - * is the smaller. - */ - wsi->reason_bf &= ~LWS_CB_REASON_AUX_BF__PROXY; - if (!lws_get_child(wsi)) - break; - - /* this causes LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ */ - if (lws_http_client_read(lws_get_child(wsi), &px, - &lenx) < 0) { - lwsl_info("%s: LWS_CB_REASON_AUX_BF__PROXY: " - "client closed\n", __func__); - - stream_close(wsi); - - return -1; - } - break; - } - - if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__PROXY_TRANS_END) { - lwsl_info("%s: LWS_CB_REASON_AUX_BF__PROXY_TRANS_END\n", - __func__); - - wsi->reason_bf &= ~LWS_CB_REASON_AUX_BF__PROXY_TRANS_END; - - if (stream_close(wsi)) - return -1; - - if (lws_http_transaction_completed(wsi)) - return -1; - } -#endif - break; - -#if defined(LWS_WITH_HTTP_PROXY) - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - assert(lws_get_parent(wsi)); - if (!lws_get_parent(wsi)) - break; - lws_get_parent(wsi)->reason_bf |= LWS_CB_REASON_AUX_BF__PROXY; - lws_callback_on_writable(lws_get_parent(wsi)); - break; - - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: { - char *out = buf + LWS_PRE; - - assert(lws_get_parent(wsi)); - - if (wsi->http.proxy_parent_chunked) { - - if (len > sizeof(buf) - LWS_PRE - 16) { - lwsl_err("oversize buf %d %d\n", (int)len, - (int)sizeof(buf) - LWS_PRE - 16); - return -1; - } - - /* - * this only needs dealing with on http/1.1 to allow - * pipelining - */ - n = lws_snprintf(out, 14, "%X\x0d\x0a", (int)len); - out += n; - memcpy(out, in, len); - out += len; - *out++ = '\x0d'; - *out++ = '\x0a'; - - n = lws_write(lws_get_parent(wsi), - (unsigned char *)buf + LWS_PRE, - len + n + 2, LWS_WRITE_HTTP); - } else - n = lws_write(lws_get_parent(wsi), (unsigned char *)in, - len, LWS_WRITE_HTTP); - if (n < 0) - return -1; - break; } - - - /* this handles the proxy case... */ - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: { - unsigned char *start, *p, *end; - - /* - * We want to proxy these headers, but we are being called - * at the point the onward client was established, which is - * unrelated to the state or writability of our proxy - * connection. - * - * Therefore produce the headers using the onward client ah - * while we have it, and stick them on the output buflist to be - * written on the proxy connection as soon as convenient. - */ - - parent = lws_get_parent(wsi); - - if (!parent) - return 0; - - start = p = (unsigned char *)buf + LWS_PRE; - end = p + sizeof(buf) - LWS_PRE - 256; - - if (lws_add_http_header_status(lws_get_parent(wsi), - lws_http_client_http_response(wsi), &p, end)) - return 1; - - /* - * copy these headers from the client connection to the parent - */ - - proxy_header(parent, wsi, end, 256, - WSI_TOKEN_HTTP_CONTENT_LENGTH, &p, end); - proxy_header(parent, wsi, end, 256, - WSI_TOKEN_HTTP_CONTENT_TYPE, &p, end); - proxy_header(parent, wsi, end, 256, - WSI_TOKEN_HTTP_ETAG, &p, end); - proxy_header(parent, wsi, end, 256, - WSI_TOKEN_HTTP_ACCEPT_LANGUAGE, &p, end); - proxy_header(parent, wsi, end, 256, - WSI_TOKEN_HTTP_CONTENT_ENCODING, &p, end); - proxy_header(parent, wsi, end, 256, - WSI_TOKEN_HTTP_CACHE_CONTROL, &p, end); - - if (!parent->http2_substream) - if (lws_add_http_header_by_token(parent, - WSI_TOKEN_CONNECTION, (unsigned char *)"close", - 5, &p, end)) - return -1; - - /* - * We proxy using h1 only atm, and strip any chunking so it - * can go back out on h2 just fine. - * - * However if we are actually going out on h1, we need to add - * our own chunking since we still don't know the size. - */ - - if (!parent->http2_substream && - !lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) { - lwsl_debug("downstream parent chunked\n"); - if (lws_add_http_header_by_token(parent, - WSI_TOKEN_HTTP_TRANSFER_ENCODING, - (unsigned char *)"chunked", 7, &p, end)) - return -1; - - wsi->http.proxy_parent_chunked = 1; - } - - if (lws_finalize_http_header(parent, &p, end)) - return 1; - - parent->http.pending_return_headers_len = - lws_ptr_diff(p, start); - parent->http.pending_return_headers = - lws_malloc(parent->http.pending_return_headers_len + - LWS_PRE, "return proxy headers"); - if (!parent->http.pending_return_headers) - return -1; - - memcpy(parent->http.pending_return_headers + LWS_PRE, start, - parent->http.pending_return_headers_len); - - parent->reason_bf |= LWS_CB_REASON_AUX_BF__PROXY_HEADERS; - - lwsl_debug("%s: LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: " - "prepared headers\n", __func__); - lws_callback_on_writable(parent); - - break; } - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - lwsl_info("%s: COMPLETED_CLIENT_HTTP: %p (parent %p)\n", - __func__, wsi, lws_get_parent(wsi)); - if (!lws_get_parent(wsi)) - break; - lws_get_parent(wsi)->reason_bf |= - LWS_CB_REASON_AUX_BF__PROXY_TRANS_END; - lws_callback_on_writable(lws_get_parent(wsi)); - break; - - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - if (!lws_get_parent(wsi)) - break; - lwsl_err("%s: LWS_CALLBACK_CLOSED_CLIENT_HTTP\n", __func__); - lws_set_timeout(lws_get_parent(wsi), LWS_TO_KILL_ASYNC, - PENDING_TIMEOUT_KILLED_BY_PROXY_CLIENT_CLOSE); - break; - - case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: - parent = lws_get_parent(wsi); - - if (!parent) - break; - - p = (unsigned char **)in; - end = (*p) + len; - - /* - * copy these headers from the parent request to the client - * connection's request - */ - - proxy_header(wsi, parent, (unsigned char *)buf, sizeof(buf), - WSI_TOKEN_HOST, p, end); - proxy_header(wsi, parent, (unsigned char *)buf, sizeof(buf), - WSI_TOKEN_HTTP_ETAG, p, end); - proxy_header(wsi, parent, (unsigned char *)buf, sizeof(buf), - WSI_TOKEN_HTTP_IF_MODIFIED_SINCE, p, end); - proxy_header(wsi, parent, (unsigned char *)buf, sizeof(buf), - WSI_TOKEN_HTTP_ACCEPT_LANGUAGE, p, end); - proxy_header(wsi, parent, (unsigned char *)buf, sizeof(buf), - WSI_TOKEN_HTTP_ACCEPT_ENCODING, p, end); - proxy_header(wsi, parent, (unsigned char *)buf, sizeof(buf), - WSI_TOKEN_HTTP_CACHE_CONTROL, p, end); - - buf[0] = '\0'; - lws_get_peer_simple(parent, buf, sizeof(buf)); - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_X_FORWARDED_FOR, - (unsigned char *)buf, (int)strlen(buf), p, end)) - return -1; - - break; - -#endif - -#ifdef LWS_WITH_CGI - /* CGI IO events (POLLIN/OUT) appear here, our default policy is: - * - * - POST data goes on subprocess stdin - * - subprocess stdout goes on http via writeable callback - * - subprocess stderr goes to the logs - */ - case LWS_CALLBACK_CGI: - args = (struct lws_cgi_args *)in; - switch (args->ch) { /* which of stdin/out/err ? */ - case LWS_STDIN: - /* TBD stdin rx flow control */ - break; - case LWS_STDOUT: - /* quench POLLIN on STDOUT until MASTER got writeable */ - lws_rx_flow_control(args->stdwsi[LWS_STDOUT], 0); - wsi->reason_bf |= LWS_CB_REASON_AUX_BF__CGI; - /* when writing to MASTER would not block */ - lws_callback_on_writable(wsi); - break; - case LWS_STDERR: - n = lws_get_socket_fd(args->stdwsi[LWS_STDERR]); - if (n < 0) - break; - n = read(n, buf, sizeof(buf) - 2); - if (n > 0) { - if (buf[n - 1] != '\n') - buf[n++] = '\n'; - buf[n] = '\0'; - lwsl_notice("CGI-stderr: %s\n", buf); - } - break; - } - break; - - case LWS_CALLBACK_CGI_TERMINATED: - lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: %d %" PRIu64 "\n", - wsi->http.cgi->explicitly_chunked, - (uint64_t)wsi->http.cgi->content_length); - if (!wsi->http.cgi->explicitly_chunked && - !wsi->http.cgi->content_length) { - /* send terminating chunk */ - lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: ending\n"); - wsi->reason_bf |= LWS_CB_REASON_AUX_BF__CGI_CHUNK_END; - lws_callback_on_writable(wsi); - lws_set_timeout(wsi, PENDING_TIMEOUT_CGI, 3); - break; - } - return -1; - - case LWS_CALLBACK_CGI_STDIN_DATA: /* POST body for stdin */ - args = (struct lws_cgi_args *)in; - args->data[args->len] = '\0'; - if (!args->stdwsi[LWS_STDIN]) - return -1; - n = lws_get_socket_fd(args->stdwsi[LWS_STDIN]); - if (n < 0) - return -1; - -#if defined(LWS_WITH_ZLIB) - if (wsi->http.cgi->gzip_inflate) { - /* gzip handling */ - - if (!wsi->http.cgi->gzip_init) { - lwsl_info("inflating gzip\n"); - - memset(&wsi->http.cgi->inflate, 0, - sizeof(wsi->http.cgi->inflate)); - - if (inflateInit2(&wsi->http.cgi->inflate, - 16 + 15) != Z_OK) { - lwsl_err("%s: iniflateInit failed\n", - __func__); - return -1; - } - - wsi->http.cgi->gzip_init = 1; - } - - wsi->http.cgi->inflate.next_in = args->data; - wsi->http.cgi->inflate.avail_in = args->len; - - do { - - wsi->http.cgi->inflate.next_out = - wsi->http.cgi->inflate_buf; - wsi->http.cgi->inflate.avail_out = - sizeof(wsi->http.cgi->inflate_buf); - - n = inflate(&wsi->http.cgi->inflate, - Z_SYNC_FLUSH); - - switch (n) { - case Z_NEED_DICT: - case Z_STREAM_ERROR: - case Z_DATA_ERROR: - case Z_MEM_ERROR: - inflateEnd(&wsi->http.cgi->inflate); - wsi->http.cgi->gzip_init = 0; - lwsl_err("zlib error inflate %d\n", n); - return -1; - } - - if (wsi->http.cgi->inflate.avail_out != - sizeof(wsi->http.cgi->inflate_buf)) { - int written; - - written = write(args->stdwsi[LWS_STDIN]->desc.filefd, - wsi->http.cgi->inflate_buf, - sizeof(wsi->http.cgi->inflate_buf) - - wsi->http.cgi->inflate.avail_out); - - if (written != (int)( - sizeof(wsi->http.cgi->inflate_buf) - - wsi->http.cgi->inflate.avail_out)) { - lwsl_notice("LWS_CALLBACK_CGI_STDIN_DATA: " - "sent %d only %d went", n, args->len); - } - - if (n == Z_STREAM_END) { - lwsl_err("gzip inflate end\n"); - inflateEnd(&wsi->http.cgi->inflate); - wsi->http.cgi->gzip_init = 0; - break; - } - - } else - break; - - if (wsi->http.cgi->inflate.avail_out) - break; - - } while (1); - - return args->len; - } -#endif /* WITH_ZLIB */ - - n = write(n, args->data, args->len); -// lwsl_hexdump_notice(args->data, args->len); - if (n < args->len) - lwsl_notice("LWS_CALLBACK_CGI_STDIN_DATA: " - "sent %d only %d went", n, args->len); - - if (wsi->http.cgi->post_in_expected && args->stdwsi[LWS_STDIN] && - args->stdwsi[LWS_STDIN]->desc.filefd > 0) { - wsi->http.cgi->post_in_expected -= n; - if (!wsi->http.cgi->post_in_expected) { - struct lws *siwsi = args->stdwsi[LWS_STDIN]; - - lwsl_debug("%s: expected POST in end: " - "closing stdin wsi %p, fd %d\n", - __func__, siwsi, siwsi->desc.sockfd); - - __remove_wsi_socket_from_fds(siwsi); - lwsi_set_state(siwsi, LRS_DEAD_SOCKET); - siwsi->socket_is_permanently_unusable = 1; - lws_remove_child_from_any_parent(siwsi); - if (wsi->context->event_loop_ops-> - close_handle_manually) { - wsi->context->event_loop_ops-> - close_handle_manually(siwsi); - siwsi->told_event_loop_closed = 1; - } else { - compatible_close(siwsi->desc.sockfd); - __lws_free_wsi(siwsi); - } - wsi->http.cgi->pipe_fds[LWS_STDIN][1] = -1; - - args->stdwsi[LWS_STDIN] = NULL; - } - } - - return n; -#endif /* WITH_CGI */ -#endif /* ROLE_ H1 / H2 */ - case LWS_CALLBACK_SSL_INFO: - si = in; - - (void)si; - lwsl_notice("LWS_CALLBACK_SSL_INFO: where: 0x%x, ret: 0x%x\n", - si->where, si->ret); - break; - -#if LWS_MAX_SMP > 1 - case LWS_CALLBACK_GET_THREAD_ID: - return (int)(unsigned long long)pthread_self(); -#endif - - default: - break; - } - - return 0; -} |