SpriteHTTPD - embedded HTTP server with read-only filesystem and templating, originally developed for ESP8266, now stand-alone and POSIX compatible.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
spritehttpd/demo/server_demo.c

163 lines
3.5 KiB

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include "httpd.h"
#include "httpd-utils.h"
#include "cgi-espfs.h"
#include "httpd-heap.h"
extern unsigned char espfs_image[];
extern unsigned int espfs_image_len;
httpd_thread_handle_t *s_serverHandle = NULL;
struct SharedData {
int visits;
};
static struct SharedData shared = {};
struct RequestData {
int counter;
};
/** "About" page */
httpd_cgi_state templateReplacer(HttpdConnData *conn, const char *token)
{
struct RequestData *rd;
if (!token) {
if (conn->userData) {
httpdFree(conn->userData);
conn->userData = NULL;
}
return HTTPD_CGI_DONE;
}
if (!conn->userData) {
rd = httpdMalloc(sizeof(struct RequestData));
conn->userData = rd;
rd->counter = 0;
shared.visits++;
} else {
rd = conn->userData;
}
char buf[100];
if (streq(token, "visits")) {
sprintf(buf, "%d", shared.visits);
tplSend(conn, buf);
}
else if (streq(token, "html1")) {
tplSend(conn, "<a href=\"foo\">foo</a>");
}
else if (streq(token, "html2")) {
tplSend(conn, "<a href=\"bar\">bar</a>");
}
else if (streq(token, "json1")) {
tplSend(conn, "\"hello\":\"foo<angle>'' and backslash\\ \" also crlf \r\n");
}
else if (streq(token, "multipart")) {
if (rd->counter < 100) {
sprintf(buf, "HELLO %d, ", rd->counter);
tplSend(conn, buf);
rd->counter++;
return HTTPD_CGI_MORE;
}
tplSend(conn, "and that's it.");
}
else {
return HTTPD_CGI_NOTFOUND;
}
return HTTPD_CGI_DONE;
}
httpd_cgi_state cgiStartSession(HttpdConnData *conn)
{
httpdQueueHeader(conn, "X-Foo", "FOO");
httpdQueueHeader(conn, "X-Bar", "Bar");
char cbuf[100] = {};
httpdGetCookie(conn, "testCookie", cbuf, 100);
printf("Cookie val = %s\n", cbuf);
httpdSetCookie(conn, &(SetCookie) {
.name = "testCookie",
.value = "lala-lele",
// .domain = "localhost",
// .expires = "BABABABAx",
// .httponly = true,
.maxAge = 0,
// .path = "foo/bar/baz",
// .sameSite = COOKIE_SAMESITE_LAX,
// .secure = true,
});
return HTTPD_CGI_NOTFOUND;
}
/**
* Application routes
*/
const HttpdBuiltInUrl routes[] = {
// TODO password lock ...
ROUTE_CGI("*", cgiStartSession),
// --- Web pages ---
// ROUTE_TPL_FILE("/", tplIndex, "/index.tpl"),
ROUTE_FILE("/", "index.html"),
ROUTE_TPL_FILE("/tpl", templateReplacer, "template.tpl.txt"),
ROUTE_FILESYSTEM(),
ROUTE_END(),
};
void sigpipe_handler(int signum)
{
(void) signum;
}
void handle_sigint(int signum)
{
(void) signum;
fprintf(stderr, " SIGINT detected, shutting down HTTPD\n");
httpdShutdown(s_serverHandle);
}
int main(void)
{
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = handle_sigint;
sigaction(SIGINT, &action, NULL);
// prevent abort on sigpipe
sigaction(SIGPIPE, &(struct sigaction) {{sigpipe_handler},.sa_mask={}}, NULL);
struct httpd_init_options opts = {
.port = 8080,
};
s_serverHandle = httpdStart(routes, &opts);
httpdSetName("SpriteHTTPD Server Demo");
httpdJoin(s_serverHandle);
return 0;
}
int httpdPlatEspfsRead(void *dest, size_t offset, size_t len)
{
if (offset + len > espfs_image_len) {
return -1;
}
memcpy(dest, &espfs_image[offset], len);
return 0;
}