More work on WWW Server
This commit is contained in:
parent
f214eb2faf
commit
ce15bedcde
2
bbs.h
2
bbs.h
@ -200,8 +200,10 @@ extern void lua_push_cfunctions(lua_State *L);
|
|||||||
|
|
||||||
extern void load_strings();
|
extern void load_strings();
|
||||||
extern char *get_string(int offset);
|
extern char *get_string(int offset);
|
||||||
|
extern void chomp(char *string);
|
||||||
|
|
||||||
#if defined(ENABLE_WWW)
|
#if defined(ENABLE_WWW)
|
||||||
|
extern void www_init();
|
||||||
extern int www_handler(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version, const char * upload_data, size_t * upload_data_size, void ** ptr);
|
extern int www_handler(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version, const char * upload_data, size_t * upload_data_size, void ** ptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
1
main.c
1
main.c
@ -696,6 +696,7 @@ void server(int port) {
|
|||||||
|
|
||||||
#if defined(ENABLE_WWW)
|
#if defined(ENABLE_WWW)
|
||||||
if (conf.www_server && conf.www_path != NULL) {
|
if (conf.www_server && conf.www_path != NULL) {
|
||||||
|
www_init();
|
||||||
www_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_END);
|
www_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_END);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
223
www.c
223
www.c
@ -4,10 +4,176 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include "bbs.h"
|
#include "bbs.h"
|
||||||
|
|
||||||
extern struct bbs_config conf;
|
extern struct bbs_config conf;
|
||||||
|
|
||||||
|
struct mime_type {
|
||||||
|
char *ext;
|
||||||
|
char *mime;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mime_type **mime_types;
|
||||||
|
static int mime_types_count;
|
||||||
|
|
||||||
|
void www_init() {
|
||||||
|
FILE *fptr;
|
||||||
|
char buffer[4096];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mime_types_count = 0;
|
||||||
|
|
||||||
|
sprintf(buffer, "%s/mime.types", conf.www_path);
|
||||||
|
|
||||||
|
fptr = fopen(buffer, "r");
|
||||||
|
if (!fptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fgets(buffer, 4096, fptr);
|
||||||
|
while (!feof(fptr)) {
|
||||||
|
chomp(buffer);
|
||||||
|
|
||||||
|
for (i=0;i<strlen(buffer);i++) {
|
||||||
|
if (buffer[i] == ' ') {
|
||||||
|
buffer[i] = '\0';
|
||||||
|
if (mime_types_count == 0) {
|
||||||
|
mime_types = (struct mime_type **)malloc(sizeof(struct mime_type *));
|
||||||
|
} else {
|
||||||
|
mime_types = (struct mime_type **)realloc(mime_types, sizeof(struct mime_type *) * (mime_types_count + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
mime_types[mime_types_count] = (struct mime_type *)malloc(sizeof(struct mime_type));
|
||||||
|
|
||||||
|
mime_types[mime_types_count]->mime = strdup(buffer);
|
||||||
|
mime_types[mime_types_count]->ext = strdup(&buffer[i+1]);
|
||||||
|
|
||||||
|
mime_types_count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fgets(buffer, 4096, fptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *www_get_mime_type(const char *extension) {
|
||||||
|
int i;
|
||||||
|
static char default_mime_type[] = "application/octet-stream";
|
||||||
|
|
||||||
|
|
||||||
|
for (i=0;i<mime_types_count;i++) {
|
||||||
|
if (strcasecmp(extension, mime_types[i]->ext) == 0) {
|
||||||
|
return mime_types[i]->mime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return default_mime_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int www_404(char *header, char *footer, struct MHD_Connection * connection) {
|
||||||
|
char buffer[4096];
|
||||||
|
char *page;
|
||||||
|
struct stat s;
|
||||||
|
char *whole_page;
|
||||||
|
struct MHD_Response *response;
|
||||||
|
int ret;
|
||||||
|
FILE *fptr;
|
||||||
|
|
||||||
|
snprintf(buffer, 4096, "%s/404.tpl", conf.www_path);
|
||||||
|
|
||||||
|
page = NULL;
|
||||||
|
|
||||||
|
if (stat(buffer, &s) == 0) {
|
||||||
|
page = (char *)malloc(s.st_size + 1);
|
||||||
|
if (page == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(page, 0, s.st_size + 1);
|
||||||
|
fptr = fopen(buffer, "r");
|
||||||
|
if (fptr) {
|
||||||
|
fread(page, s.st_size, 1, fptr);
|
||||||
|
fclose(fptr);
|
||||||
|
} else {
|
||||||
|
free(page);
|
||||||
|
page = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page == NULL) {
|
||||||
|
page = (char *)malloc(16);
|
||||||
|
if (page == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sprintf(page, "Missing Content");
|
||||||
|
}
|
||||||
|
|
||||||
|
whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1);
|
||||||
|
|
||||||
|
sprintf(whole_page, "%s%s%s", header, page, footer);
|
||||||
|
|
||||||
|
response = MHD_create_response_from_buffer (strlen(whole_page), (void*)whole_page, MHD_RESPMEM_PERSISTENT);
|
||||||
|
|
||||||
|
ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
|
||||||
|
MHD_destroy_response (response);
|
||||||
|
free(whole_page);
|
||||||
|
free(page);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int www_403(char *header, char *footer, struct MHD_Connection * connection) {
|
||||||
|
char buffer[4096];
|
||||||
|
char *page;
|
||||||
|
struct stat s;
|
||||||
|
char *whole_page;
|
||||||
|
struct MHD_Response *response;
|
||||||
|
int ret;
|
||||||
|
FILE *fptr;
|
||||||
|
|
||||||
|
snprintf(buffer, 4096, "%s/403.tpl", conf.www_path);
|
||||||
|
|
||||||
|
page = NULL;
|
||||||
|
|
||||||
|
if (stat(buffer, &s) == 0) {
|
||||||
|
page = (char *)malloc(s.st_size + 1);
|
||||||
|
if (page == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(page, 0, s.st_size + 1);
|
||||||
|
fptr = fopen(buffer, "r");
|
||||||
|
if (fptr) {
|
||||||
|
fread(page, s.st_size, 1, fptr);
|
||||||
|
fclose(fptr);
|
||||||
|
} else {
|
||||||
|
free(page);
|
||||||
|
page = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page == NULL) {
|
||||||
|
page = (char *)malloc(16);
|
||||||
|
if (page == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sprintf(page, "Missing Content");
|
||||||
|
}
|
||||||
|
|
||||||
|
whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1);
|
||||||
|
|
||||||
|
sprintf(whole_page, "%s%s%s", header, page, footer);
|
||||||
|
|
||||||
|
response = MHD_create_response_from_buffer (strlen(whole_page), (void*)whole_page, MHD_RESPMEM_PERSISTENT);
|
||||||
|
|
||||||
|
ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
|
||||||
|
MHD_destroy_response (response);
|
||||||
|
free(whole_page);
|
||||||
|
free(page);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int www_handler(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version, const char * upload_data, size_t * upload_data_size, void ** ptr) {
|
int www_handler(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version, const char * upload_data, size_t * upload_data_size, void ** ptr) {
|
||||||
struct MHD_Response *response;
|
struct MHD_Response *response;
|
||||||
|
|
||||||
@ -19,6 +185,9 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
|
|||||||
char *footer;
|
char *footer;
|
||||||
char *whole_page;
|
char *whole_page;
|
||||||
FILE *fptr;
|
FILE *fptr;
|
||||||
|
char *mime;
|
||||||
|
int i;
|
||||||
|
int fno;
|
||||||
|
|
||||||
snprintf(buffer, 4096, "%s/header.tpl", conf.www_path);
|
snprintf(buffer, 4096, "%s/header.tpl", conf.www_path);
|
||||||
|
|
||||||
@ -29,6 +198,7 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
|
|||||||
if (header == NULL) {
|
if (header == NULL) {
|
||||||
return MHD_NO;
|
return MHD_NO;
|
||||||
}
|
}
|
||||||
|
memset(header, 0, s.st_size + 1);
|
||||||
fptr = fopen(buffer, "r");
|
fptr = fopen(buffer, "r");
|
||||||
if (fptr) {
|
if (fptr) {
|
||||||
fread(header, s.st_size, 1, fptr);
|
fread(header, s.st_size, 1, fptr);
|
||||||
@ -57,6 +227,7 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
|
|||||||
free(header);
|
free(header);
|
||||||
return MHD_NO;
|
return MHD_NO;
|
||||||
}
|
}
|
||||||
|
memset(footer, 0, s.st_size + 1);
|
||||||
fptr = fopen(buffer, "r");
|
fptr = fopen(buffer, "r");
|
||||||
if (fptr) {
|
if (fptr) {
|
||||||
fread(footer, s.st_size, 1, fptr);
|
fread(footer, s.st_size, 1, fptr);
|
||||||
@ -90,6 +261,7 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
|
|||||||
free(footer);
|
free(footer);
|
||||||
return MHD_NO;
|
return MHD_NO;
|
||||||
}
|
}
|
||||||
|
memset(page, 0, s.st_size + 1);
|
||||||
fptr = fopen(buffer, "r");
|
fptr = fopen(buffer, "r");
|
||||||
if (fptr) {
|
if (fptr) {
|
||||||
fread(page, s.st_size, 1, fptr);
|
fread(page, s.st_size, 1, fptr);
|
||||||
@ -115,12 +287,59 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url
|
|||||||
sprintf(whole_page, "%s%s%s", header, page, footer);
|
sprintf(whole_page, "%s%s%s", header, page, footer);
|
||||||
} else if (strncasecmp(url, "/static/", 8) == 0) {
|
} else if (strncasecmp(url, "/static/", 8) == 0) {
|
||||||
// sanatize path
|
// sanatize path
|
||||||
|
if (strstr(url, "/..") != NULL) {
|
||||||
|
return MHD_NO;
|
||||||
|
}
|
||||||
|
// get mimetype
|
||||||
|
for (i=strlen(url);i>0;--i) {
|
||||||
|
if (url[i] == '.') {
|
||||||
|
mime = www_get_mime_type(&url[i+1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// load file
|
// load file
|
||||||
|
|
||||||
|
sprintf(buffer, "%s%s", conf.www_path, url);
|
||||||
|
if (stat(buffer, &s) == 0 && S_ISREG(s.st_mode)) {
|
||||||
|
fno = open(buffer, O_RDONLY);
|
||||||
|
if (fno != -1) {
|
||||||
|
response = MHD_create_response_from_fd(s.st_size, fno);
|
||||||
|
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime);
|
||||||
|
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
|
||||||
|
MHD_destroy_response (response);
|
||||||
|
free(header);
|
||||||
|
free(footer);
|
||||||
|
return MHD_YES;
|
||||||
|
} else {
|
||||||
|
if (www_403(header, footer, connection) != 0) {
|
||||||
|
free(header);
|
||||||
|
free(footer);
|
||||||
|
return MHD_NO;
|
||||||
|
}
|
||||||
|
free(header);
|
||||||
|
free(footer);
|
||||||
|
return MHD_YES;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (www_404(header, footer, connection) != 0) {
|
||||||
|
free(header);
|
||||||
|
free(footer);
|
||||||
|
return MHD_NO;
|
||||||
|
}
|
||||||
|
free(header);
|
||||||
|
free(footer);
|
||||||
|
return MHD_YES;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (www_404(header, footer, connection) != 0) {
|
||||||
|
free(header);
|
||||||
|
free(footer);
|
||||||
|
return MHD_NO;
|
||||||
|
}
|
||||||
free(header);
|
free(header);
|
||||||
free(footer);
|
free(footer);
|
||||||
return MHD_NO;
|
return MHD_YES;
|
||||||
}
|
}
|
||||||
} else if (strcmp(method, "POST") == 0) {
|
} else if (strcmp(method, "POST") == 0) {
|
||||||
free(header);
|
free(header);
|
||||||
|
2
www/403.tpl
Normal file
2
www/403.tpl
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>403 - Forbidden</h1>
|
||||||
|
The page you are looking for can not be accessed.
|
2
www/404.tpl
Normal file
2
www/404.tpl
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>404 - Page not found</h1>
|
||||||
|
The page you are looking for can not be found.
|
@ -1,2 +1,4 @@
|
|||||||
|
<hr />
|
||||||
|
<div class="footer">Powered By Magicka BBS</div>
|
||||||
</BODY>
|
</BODY>
|
||||||
</HTML>
|
</HTML>
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
<HTML>
|
<HTML>
|
||||||
<HEAD>
|
<HEAD>
|
||||||
|
<TITLE>Magicka BBS</TITLE>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/style.css">
|
||||||
</HEAD>
|
</HEAD>
|
||||||
<BODY>
|
<BODY>
|
||||||
|
<div class="header">
|
||||||
|
<img src="/static/header.png" alt="Magicka BBS" />
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<h2>Welcome to another Magicka BBS!</h2>
|
<h2>Welcome to another Magicka BBS!</h2>
|
||||||
|
|
||||||
The sysop should customize this file with what he wants on the front page!
|
The sysop should customize this file with what he/she wants on the front page!
|
||||||
|
1
www/mime.types
Normal file
1
www/mime.types
Normal file
@ -0,0 +1 @@
|
|||||||
|
image/png png
|
BIN
www/static/header.png
Normal file
BIN
www/static/header.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
3
www/static/style.css
Normal file
3
www/static/style.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.footer {
|
||||||
|
font-size: small;
|
||||||
|
}
|
Reference in New Issue
Block a user