summaryrefslogtreecommitdiff
path: root/contrib/examples/httpd/ssi_example/ssi_example.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-10-16 08:10:14 -0600
committerTom Rini <trini@konsulko.com>2024-10-16 08:10:14 -0600
commitf3f86fd1fe0fb288356bff78f8a6fa2edf89e3fc (patch)
treef0a99ea87d92f63895a6d053e3185838ebecf2d0 /contrib/examples/httpd/ssi_example/ssi_example.c
Squashed 'lib/lwip/lwip/' content from commit 0a0452b2c39b
git-subtree-dir: lib/lwip/lwip git-subtree-split: 0a0452b2c39bdd91e252aef045c115f88f6ca773
Diffstat (limited to 'contrib/examples/httpd/ssi_example/ssi_example.c')
-rw-r--r--contrib/examples/httpd/ssi_example/ssi_example.c264
1 files changed, 264 insertions, 0 deletions
diff --git a/contrib/examples/httpd/ssi_example/ssi_example.c b/contrib/examples/httpd/ssi_example/ssi_example.c
new file mode 100644
index 00000000000..2024e2ead01
--- /dev/null
+++ b/contrib/examples/httpd/ssi_example/ssi_example.c
@@ -0,0 +1,264 @@
+/**
+ * @file
+ * HTTPD simple SSI example
+ *
+ * This file demonstrates how to add support for SSI.
+ * It does this in a very simple way by providing the three tags 'HelloWorld'
+ * 'counter', and 'MultiPart'.
+ *
+ * This file also demonstrates how to integrate CGI with SSI.
+ */
+
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "ssi_example.h"
+
+#include "lwip/apps/httpd.h"
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE to 1 to enable this ssi example*/
+#ifndef LWIP_HTTPD_EXAMPLE_SSI_SIMPLE
+#define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE 0
+#endif
+
+/** define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION to 1 to show how to
+ * integrate CGI into SSI (LWIP_HTTPD_CGI_SSI) */
+#ifndef LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+#define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+#if !LWIP_HTTPD_FILE_STATE
+#error LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION needs LWIP_HTTPD_FILE_STATE
+#endif
+#if !LWIP_HTTPD_CGI_SSI
+#error LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION needs LWIP_HTTPD_CGI_SSI
+#endif
+
+#define MAX_CGI_LEN 16
+#endif
+
+const char * ssi_example_tags[] = {
+ "HellWorl",
+ "counter",
+ "MultPart"
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+ ,"CgiParam"
+#endif
+};
+
+u16_t ssi_example_ssi_handler(
+#if LWIP_HTTPD_SSI_RAW
+ const char* ssi_tag_name,
+#else /* LWIP_HTTPD_SSI_RAW */
+ int iIndex,
+#endif /* LWIP_HTTPD_SSI_RAW */
+ char *pcInsert, int iInsertLen
+#if LWIP_HTTPD_SSI_MULTIPART
+ , u16_t current_tag_part, u16_t *next_tag_part
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+ , void *connection_state
+#endif /* LWIP_HTTPD_FILE_STATE */
+ )
+{
+ size_t printed;
+#if LWIP_HTTPD_SSI_RAW
+ /* a real application could use if(!strcmp) blocks here, but we want to keep
+ the differences between configurations small, so translate string to index here */
+ int iIndex;
+ for (iIndex = 0; iIndex < LWIP_ARRAYSIZE(ssi_example_tags); iIndex++) {
+ if(!strcmp(ssi_tag_name, ssi_example_tags[iIndex])) {
+ break;
+ }
+ }
+#endif
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+ LWIP_UNUSED_ARG(connection_state);
+#endif
+
+ switch (iIndex) {
+ case 0: /* "HelloWorld" */
+ printed = snprintf(pcInsert, iInsertLen, "Hello World!");
+ break;
+ case 1: /* "counter" */
+ {
+ static int counter;
+ counter++;
+ printed = snprintf(pcInsert, iInsertLen, "%d", counter);
+ }
+ break;
+ case 2: /* "MultPart" */
+#if LWIP_HTTPD_SSI_MULTIPART
+ switch (current_tag_part) {
+ case 0:
+ printed = snprintf(pcInsert, iInsertLen, "part0");
+ *next_tag_part = 1;
+ break;
+ case 1:
+ printed = snprintf(pcInsert, iInsertLen, "part1");
+ *next_tag_part = 2;
+ break;
+ case 2:
+ printed = snprintf(pcInsert, iInsertLen, "part2");
+ break;
+ default:
+ printed = snprintf(pcInsert, iInsertLen, "unhandled part: %d", (int)current_tag_part);
+ break;
+ }
+#else
+ printed = snprintf(pcInsert, iInsertLen, "LWIP_HTTPD_SSI_MULTIPART disabled");
+#endif
+ break;
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+ case 3:
+ if (connection_state) {
+ char *params = (char *)connection_state;
+ if (*params) {
+ printed = snprintf(pcInsert, iInsertLen, "%s", (char *)params);
+ } else {
+ printed = snprintf(pcInsert, iInsertLen, "none");
+ }
+ } else {
+ printed = snprintf(pcInsert, iInsertLen, "NULL");
+ }
+ break;
+#endif
+ default: /* unknown tag */
+ printed = 0;
+ break;
+ }
+ LWIP_ASSERT("sane length", printed <= 0xFFFF);
+ return (u16_t)printed;
+}
+
+void
+ssi_ex_init(void)
+{
+ int i;
+ for (i = 0; i < LWIP_ARRAYSIZE(ssi_example_tags); i++) {
+ LWIP_ASSERT("tag too long for LWIP_HTTPD_MAX_TAG_NAME_LEN",
+ strlen(ssi_example_tags[i]) <= LWIP_HTTPD_MAX_TAG_NAME_LEN);
+ }
+
+ http_set_ssi_handler(ssi_example_ssi_handler,
+#if LWIP_HTTPD_SSI_RAW
+ NULL, 0
+#else
+ ssi_example_tags, LWIP_ARRAYSIZE(ssi_example_tags)
+#endif
+ );
+}
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+void *
+fs_state_init(struct fs_file *file, const char *name)
+{
+ char *ret;
+ LWIP_UNUSED_ARG(file);
+ LWIP_UNUSED_ARG(name);
+ ret = (char *)mem_malloc(MAX_CGI_LEN);
+ if (ret) {
+ *ret = 0;
+ }
+ return ret;
+}
+
+void
+fs_state_free(struct fs_file *file, void *state)
+{
+ LWIP_UNUSED_ARG(file);
+ if (state != NULL) {
+ mem_free(state);
+ }
+}
+
+void
+httpd_cgi_handler(struct fs_file *file, const char* uri, int iNumParams,
+ char **pcParam, char **pcValue
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+ , void *connection_state
+#endif /* LWIP_HTTPD_FILE_STATE */
+ )
+{
+ LWIP_UNUSED_ARG(file);
+ LWIP_UNUSED_ARG(uri);
+ if (connection_state != NULL) {
+ char *start = (char *)connection_state;
+ char *end = start + MAX_CGI_LEN;
+ int i;
+ memset(start, 0, MAX_CGI_LEN);
+ /* print a string of the arguments: */
+ for (i = 0; i < iNumParams; i++) {
+ size_t len;
+ len = end - start;
+ if (len) {
+ size_t inlen = strlen(pcParam[i]);
+ size_t copylen = LWIP_MIN(inlen, len);
+ memcpy(start, pcParam[i], copylen);
+ start += copylen;
+ len -= copylen;
+ }
+ if (len) {
+ *start = '=';
+ start++;
+ len--;
+ }
+ if (len) {
+ size_t inlen = strlen(pcValue[i]);
+ size_t copylen = LWIP_MIN(inlen, len);
+ memcpy(start, pcValue[i], copylen);
+ start += copylen;
+ len -= copylen;
+ }
+ if (len) {
+ *start = ';';
+ len--;
+ }
+ /* ensure NULL termination */
+ end--;
+ *end = 0;
+ }
+ }
+}
+#endif /* LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION */
+
+#endif /* LWIP_HTTPD_EXAMPLE_SSI_SIMPLE */