Added server config
This commit is contained in:
142
src/config.c
Normal file
142
src/config.c
Normal file
@@ -0,0 +1,142 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "config.h"
|
||||
#include "ini.h"
|
||||
|
||||
const char *default_servername = "localhost";
|
||||
const char *default_administrator = "root@localhost";
|
||||
|
||||
config_server* config_server_new() {
|
||||
config_server* config = calloc(1, sizeof(config_server));
|
||||
config->host_count = 0;
|
||||
config->listen_port = 80;
|
||||
|
||||
config->servername = calloc(128, sizeof(char));
|
||||
if (gethostname(config->servername, 128) < 0) {
|
||||
warning("failed to get server hostname", true);
|
||||
free(config->servername);
|
||||
config->servername = strdup(default_servername);
|
||||
}
|
||||
config->servername = realloc(config->servername, (strlen(config->servername)+1)*sizeof(char));
|
||||
|
||||
config->administrator = strdup(default_servername);
|
||||
|
||||
return config;
|
||||
}
|
||||
void config_server_addhost(config_server *config, config_host *host) {
|
||||
if (config->host_count == 0) {
|
||||
config->hosts = calloc(1, sizeof(config_server*));
|
||||
config->host_count++;
|
||||
} else {
|
||||
config->hosts = realloc(config->hosts, ++config->host_count * sizeof(config_server*));
|
||||
}
|
||||
config->hosts[config->host_count-1] = host;
|
||||
}
|
||||
config_host* config_server_gethost(config_server *config, char *name) {
|
||||
config_host *defaulthost=NULL;
|
||||
config_host *host=NULL;
|
||||
CONFIG_SERVER_FOREACH_HOST(config, host) {
|
||||
if (strcasecmp(name, host->hostname) == 0) {
|
||||
return host;
|
||||
}
|
||||
if (host->default_host == true) {
|
||||
defaulthost = host;
|
||||
}
|
||||
}
|
||||
return defaulthost;
|
||||
}
|
||||
void config_server_delete(config_server* config) {
|
||||
if (config->administrator != NULL) free(config->administrator);
|
||||
if (config->servername != NULL) free(config->servername);
|
||||
config_host *host;
|
||||
CONFIG_SERVER_FOREACH_HOST(config, host) {
|
||||
config_host_delete(host);
|
||||
}
|
||||
if (config->hosts != NULL) free(config->hosts);
|
||||
free(config);
|
||||
}
|
||||
|
||||
config_host* config_host_new() {
|
||||
config_host *host = calloc(1, sizeof(config_host));
|
||||
host->default_host = false;
|
||||
host->enabled = true;
|
||||
host->hostname = NULL;
|
||||
host->serve_dir = NULL;
|
||||
|
||||
return host;
|
||||
}
|
||||
void config_host_delete(config_host *host) {
|
||||
if (host->hostname != NULL) free(host->hostname);
|
||||
if (host->serve_dir != NULL) free(host->serve_dir);
|
||||
free(host);
|
||||
}
|
||||
|
||||
static int config_read_ini_cb(void* _config, const char* section, const char* name,
|
||||
const char* value) {
|
||||
config_server *config = (config_server*)_config;
|
||||
static config_host *host = NULL;
|
||||
|
||||
#define MATCH(s, n) strcasecmp(s, section) == 0 && strcasecmp(n, name) == 0
|
||||
|
||||
if (name == NULL && strcasecmp(section, "Host") == 0) {
|
||||
host = config_host_new();
|
||||
config_server_addhost(config, host);
|
||||
} else if (strcasecmp("Host", section) == 0 && host == NULL) {
|
||||
return -1;
|
||||
} else if (name != NULL) {
|
||||
if (MATCH("Server", "name")) {
|
||||
config->servername = strdup(value);
|
||||
} else if (MATCH("Server", "admin")) {
|
||||
config->administrator = strdup(value);
|
||||
} else if (MATCH("Server", "listen")) {
|
||||
errno = 0;
|
||||
config->listen_port = (uint16_t)strtol(value, NULL, 10);
|
||||
if (errno != 0) {
|
||||
warning("Config: Invalid port number for [Server]listen", true);
|
||||
}
|
||||
return -1;
|
||||
} else if (MATCH("Host", "name")) {
|
||||
host->hostname = strdup(value);
|
||||
} else if (MATCH("Host", "enabled")) {
|
||||
if (strcasecmp(value, "yes") == 0) {
|
||||
host->enabled = true;
|
||||
} else if (strcasecmp(value, "no") == 0) {
|
||||
host->enabled = false;
|
||||
}
|
||||
} else if (MATCH("Host", "default")) {
|
||||
|
||||
if (strcasecmp(value, "yes") == 0) {
|
||||
//Ensure there is only one default host
|
||||
config_host *tmp;
|
||||
CONFIG_SERVER_FOREACH_HOST(config, tmp) {
|
||||
tmp->default_host = false;
|
||||
}
|
||||
host->default_host = true;
|
||||
} else if (strcasecmp(value, "no") == 0) {
|
||||
host->default_host = false;
|
||||
}
|
||||
} else if (MATCH("Host", "serve")) {
|
||||
DIR *dir = opendir(value);
|
||||
if (dir == NULL) {
|
||||
warning("Config: host serve directory is invalid", true);
|
||||
return -1;
|
||||
}
|
||||
closedir(dir);
|
||||
host->serve_dir = strdup(value);
|
||||
}
|
||||
}
|
||||
#undef MATCH
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int config_read_ini(const char* filename, config_server *config) {
|
||||
return ini_parse(filename, config_read_ini_cb, config);
|
||||
}
|
||||
53
src/config.h
Normal file
53
src/config.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* File: config.h
|
||||
* Author: sam
|
||||
*
|
||||
* Created on 27 July 2014, 18:47
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "main.h"
|
||||
|
||||
#define CONFIG_SERVER_FOREACH_HOST(config, elem) \
|
||||
elem = config->hosts[0]; \
|
||||
for(int i=0; i < config->host_count; elem=config->hosts[i++])
|
||||
|
||||
typedef struct config_host {
|
||||
char *hostname;
|
||||
bool default_host;
|
||||
bool enabled;
|
||||
char* serve_dir;
|
||||
} config_host;
|
||||
|
||||
typedef struct config_server {
|
||||
char *servername;
|
||||
char *administrator;
|
||||
uint16_t listen_port;
|
||||
|
||||
config_host **hosts;
|
||||
size_t host_count;
|
||||
} config_server;
|
||||
|
||||
config_server* config_server_new();
|
||||
void config_server_addhost(config_server *config, config_host *host);
|
||||
config_host* config_server_gethost(config_server *config, char* name);
|
||||
void config_server_delete(config_server* config);
|
||||
|
||||
config_host* config_host_new();
|
||||
void config_host_delete(config_host *host);
|
||||
|
||||
int config_read_ini(const char* filename, config_server *config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <http_parser.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../main.h"
|
||||
#include "main.h"
|
||||
#include "http.h"
|
||||
#include "parse.h"
|
||||
#include "http_parser.h"
|
||||
#include "http-reader.h"
|
||||
|
||||
#define GET_CB_STR(str, at, length) do { \
|
||||
str = calloc(length+1, sizeof(char));\
|
||||
@@ -30,6 +30,12 @@ http_parser_settings* parser_get_settings(skt_elem *elem) {
|
||||
}
|
||||
return parser_settings;
|
||||
}
|
||||
void parser_free_settings() {
|
||||
if (parser_settings != NULL) {
|
||||
free(parser_settings);
|
||||
parser_settings = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int parser_cb_on_message_begin(http_parser* parser) {
|
||||
if (SKT(parser)->current_request != NULL) {
|
||||
@@ -83,6 +89,7 @@ int parser_cb_on_header_field(http_parser* parser, const char *at, size_t length
|
||||
http_header* header = SKT(parser)->parser_current_header;
|
||||
size_t newlen = strlen(header->name) + length +1;
|
||||
header->name = realloc(header->name, newlen * sizeof(char));
|
||||
strcat(header->name, str);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
@@ -14,12 +14,10 @@ extern "C" {
|
||||
|
||||
#include "http_parser.h"
|
||||
#include "http.h"
|
||||
#include "../main.h"
|
||||
|
||||
|
||||
void parser_set_currentskt(skt_elem *elem);
|
||||
#include "main.h"
|
||||
|
||||
http_parser_settings* parser_get_settings(skt_elem *elem);
|
||||
void parser_free_settings();
|
||||
|
||||
int parser_cb_on_message_begin(http_parser* parser);
|
||||
int parser_cb_on_url(http_parser* parser, const char *at, size_t length);
|
||||
6
src/http-server.c
Normal file
6
src/http-server.c
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "http.h"
|
||||
#include "main.h"
|
||||
|
||||
26
src/http-server.h
Normal file
26
src/http-server.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* File: http-server.h
|
||||
* Author: sam
|
||||
*
|
||||
* Created on 26 July 2014, 15:32
|
||||
*/
|
||||
|
||||
#ifndef HTTP_SERVER_H
|
||||
#define HTTP_SERVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "http.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HTTP_SERVER_H */
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include "../main.h"
|
||||
#include "main.h"
|
||||
#include "ut/utarray.h"
|
||||
#include "ut/utstring.h"
|
||||
#include "http.h"
|
||||
@@ -360,7 +360,7 @@ http_response* http_response_create_builtin(uint16_t code, char* errmsg) {
|
||||
|
||||
http_header_list_add(resp->headers, http_header_new(HEADER_CONTENT_TYPE, "text/html"), false);
|
||||
|
||||
file_map* errorpage = file_map_new("content/error.html");
|
||||
file_map* errorpage = file_map_new("error.html");
|
||||
if (errorpage != NULL) {
|
||||
http_response_append_body(resp, errorpage->map);
|
||||
file_map_delete(errorpage);
|
||||
41
src/main.c
41
src/main.c
@@ -21,16 +21,22 @@
|
||||
#include "ut/utarray.h"
|
||||
#include "main.h"
|
||||
#include "socket.h"
|
||||
#include "http/http.h"
|
||||
#include "http/parse.h"
|
||||
#include "http.h"
|
||||
#include "http-reader.h"
|
||||
#include "config.h"
|
||||
|
||||
int serverfd = 0;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
config_server *config = config_server_new();
|
||||
if (config_read_ini("khttpd.ini", config) < 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
skt_elem *connections = NULL;
|
||||
|
||||
serverfd = svr_create();
|
||||
svr_listen(serverfd, 1234);
|
||||
svr_listen(serverfd, config->listen_port);
|
||||
|
||||
while(1) {
|
||||
uint32_t counter;
|
||||
@@ -55,34 +61,35 @@ int main(int argc, char** argv) {
|
||||
//Process sockets
|
||||
LL_FOREACH(connections, elem) {
|
||||
if (utstring_len(elem->info->read) > 0) {
|
||||
//Parse the incoming data
|
||||
int parsedcount = http_parser_execute(
|
||||
elem->parser,
|
||||
parser_get_settings(elem),
|
||||
utstring_body(elem->info->read),
|
||||
utstring_len(elem->info->read));
|
||||
//Check that all data was read
|
||||
if (parsedcount != utstring_len(elem->info->read)) {
|
||||
//emit warning
|
||||
char warningmsg[2048] = {0};
|
||||
snprintf(warningmsg, 2048,
|
||||
"error parsing request (%s: %s). closing connection",
|
||||
http_errno_name(elem->parser->http_errno),
|
||||
http_errno_description(elem->parser->http_errno));
|
||||
warning(warningmsg, false);
|
||||
elem->info->close = true;
|
||||
}
|
||||
utstring_clear(elem->info->read);
|
||||
if (elem->request_complete == true) {
|
||||
char* reqstr = http_request_write(elem->current_request);
|
||||
info("\n%s\n", reqstr);
|
||||
free(reqstr);
|
||||
|
||||
http_response* resp = http_response_create_builtin(200, elem->current_request->req->uri);
|
||||
utstring_printf(elem->info->write, "%s", http_response_write(resp));
|
||||
http_response_delete(resp);
|
||||
elem->request_complete = false;
|
||||
http_request_delete(elem->current_request);
|
||||
elem->current_request = NULL;
|
||||
//send 400 back and close connection
|
||||
http_response *resp400 = http_response_create_builtin(400, "Request was invalid or could not be read");
|
||||
char *resp400str = http_response_write(resp400);
|
||||
utstring_printf(elem->info->write, "%s", resp400str);
|
||||
http_response_delete(resp400);
|
||||
free(resp400str);
|
||||
elem->info->close_afterwrite = true;
|
||||
}
|
||||
//Clear read data now that we have processed it
|
||||
utstring_clear(elem->info->read);
|
||||
//Process request if received
|
||||
if (elem->request_complete == true) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
#include "http_parser.h"
|
||||
#include "socket.h"
|
||||
#include "http/http.h"
|
||||
#include "http.h"
|
||||
|
||||
typedef struct file_map {
|
||||
char* map;
|
||||
|
||||
@@ -17,7 +17,7 @@ extern "C" {
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <time.h>
|
||||
#include "http/http.h"
|
||||
#include "http.h"
|
||||
#include "ut/utstring.h"
|
||||
|
||||
typedef struct skt_info skt_info;
|
||||
|
||||
Reference in New Issue
Block a user