Added server config

This commit is contained in:
2014-07-27 22:19:08 +01:00
parent cf81743970
commit 17693097a5
22 changed files with 680 additions and 80 deletions

142
src/config.c Normal file
View 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
View 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 */

View File

@@ -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;
}

View File

@@ -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
View File

@@ -0,0 +1,6 @@
#include <stdlib.h>
#include <stdio.h>
#include "http.h"
#include "main.h"

26
src/http-server.h Normal file
View 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 */

View File

@@ -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);

View File

@@ -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) {
}
}
}

View File

@@ -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;

View File

@@ -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;