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.
163 lines
3.5 KiB
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;
|
|
}
|
|
|