Updated TODO hints

personal/stbuehler/wip
Stefan Bühler 15 years ago
parent 1ed36c93b9
commit 03458817cc

@ -47,6 +47,7 @@ static gboolean condition_ip_from_socket(condition_rvalue *val, sock_addr *addr)
condition_lvalue* condition_lvalue_new(cond_lvalue_t type, GString *key) {
condition_lvalue *lvalue = g_slice_new0(condition_lvalue);
if (type == COMP_REQUEST_HEADER) g_string_ascii_down(key);
lvalue->type = type;
lvalue->key = key;
lvalue->refcount = 1;
@ -89,7 +90,7 @@ static condition* cond_new_string(comp_operator_t op, condition_lvalue *lvalue,
static condition* cond_new_match(server *srv, comp_operator_t op, condition_lvalue *lvalue, GString *str) {
UNUSED(op); UNUSED(lvalue); UNUSED(str);
ERROR(srv, "%s", "pcre not supported for now");
/* TODO */
/* TODO: pcre */
return NULL;
}
#endif
@ -237,13 +238,11 @@ const char* cond_lvalue_to_string(cond_lvalue_t t) {
/* COND_VALUE_STRING and COND_VALUE_REGEXP only */
static gboolean condition_check_eval_string(server *srv, connection *con, condition *cond) {
const char *value = "";
GString *tmp = NULL;
gboolean result = FALSE;
UNUSED(srv);
UNUSED(con);
switch (cond->lvalue->type) {
/* TODO: get values */
case COMP_REQUEST_LOCALIP:
value = con->local_addr_str->str;
break;
@ -266,21 +265,23 @@ static gboolean condition_check_eval_string(server *srv, connection *con, condit
value = con->request.http_method_str->str;
break;
case COMP_PHYSICAL_PATH:
value = con->physical.path->str;
break;
case COMP_PHYSICAL_PATH_EXISTS:
/* TODO */
/* TODO: physical path exists */
break;
case COMP_REQUEST_HEADER:
/* TODO */
http_header_get_fast(srv->tmp_str, con->request.headers, GSTR_LEN(cond->lvalue->key));
value = srv->tmp_str->str;
break;
case COMP_PHYSICAL_SIZE:
/* TODO */
g_string_printf((tmp = g_string_sized_new(0)), "%"L_GOFFSET_FORMAT, (goffset) 0);
value = tmp->str;
/* TODO: physical size */
g_string_printf(srv->tmp_str, "%"L_GOFFSET_FORMAT, (goffset) 0);
value = srv->tmp_str->str;
break;
case COMP_REQUEST_CONTENT_LENGTH:
/* TODO */
g_string_printf((tmp = g_string_sized_new(0)), "%"L_GOFFSET_FORMAT, (goffset) 0);
value = tmp->str;
g_string_printf(srv->tmp_str, "%"L_GOFFSET_FORMAT, con->request.content_length);
value = srv->tmp_str->str;
break;
}
@ -310,7 +311,6 @@ static gboolean condition_check_eval_string(server *srv, connection *con, condit
break;
}
if (tmp) g_string_free(tmp, TRUE);
return result;
}
@ -327,6 +327,7 @@ static gboolean condition_check_eval_int(server *srv, connection *con, condition
value = con->physical.size;
break;
default:
CON_ERROR(srv, con, "couldn't get int value for '%s', using -1", cond_lvalue_to_string(cond->lvalue->type));
value = -1;
}
@ -349,8 +350,6 @@ static gboolean condition_check_eval_int(server *srv, connection *con, condition
case CONFIG_COND_NOTIP:
ERROR(srv, "cannot compare int with '%s'", comp_op_to_string(cond->op));
return FALSE;
} else {
ERROR(srv, "couldn't get int value for '%s'", cond_lvalue_to_string(cond->lvalue->type));
}
return FALSE;
@ -408,7 +407,6 @@ static gboolean condition_check_eval_ip(server *srv, connection *con, condition
ipval.type = COND_VALUE_INT;
switch (cond->lvalue->type) {
/* TODO: get values */
case COMP_REQUEST_LOCALIP:
if (!condition_ip_from_socket(&ipval, &con->local_addr))
return (cond->op == CONFIG_COND_NOTIP);
@ -418,7 +416,8 @@ static gboolean condition_check_eval_ip(server *srv, connection *con, condition
return (cond->op == CONFIG_COND_NOTIP);
break;
case COMP_REQUEST_PATH:
value = con->request.uri.path->str;
ERROR(srv, "%s", "Cannot parse request.path as ip");
return (cond->op == CONFIG_COND_NOTIP);
break;
case COMP_REQUEST_HOST:
value = con->request.host->str;
@ -430,14 +429,17 @@ static gboolean condition_check_eval_ip(server *srv, connection *con, condition
value = con->request.uri.query->str;
break;
case COMP_REQUEST_METHOD:
value = con->request.http_method_str->str;
ERROR(srv, "%s", "Cannot request.method as ip");
return (cond->op == CONFIG_COND_NOTIP);
break;
case COMP_PHYSICAL_PATH:
case COMP_PHYSICAL_PATH_EXISTS:
/* TODO */
ERROR(srv, "%s", "Cannot physical.path(-exists) as ip");
return (cond->op == CONFIG_COND_NOTIP);
break;
case COMP_REQUEST_HEADER:
/* TODO */
http_header_get_fast(srv->tmp_str, con->request.headers, GSTR_LEN(cond->lvalue->key));
value = srv->tmp_str->str;
break;
case COMP_PHYSICAL_SIZE:
case COMP_REQUEST_CONTENT_LENGTH:

@ -51,7 +51,7 @@ typedef enum {
COMP_PHYSICAL_SIZE,
/* needs a key */
COMP_REQUEST_HEADER
COMP_REQUEST_HEADER /**< needs lowercase key, enforced by condition_lvalue_new */
} cond_lvalue_t;
#define COND_LVALUE_FIRST_WITH_KEY COMP_REQUEST_HEADER

@ -78,11 +78,11 @@ static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) {
case NETWORK_STATUS_WAIT_FOR_EVENT:
break;
case NETWORK_STATUS_WAIT_FOR_AIO_EVENT:
/* TODO ? */
/* TODO: aio */
ev_io_rem_events(loop, w, EV_READ);
break;
case NETWORK_STATUS_WAIT_FOR_FD:
/* TODO */
/* TODO: wait for fd */
ev_io_rem_events(loop, w, EV_READ);
break;
}
@ -106,11 +106,11 @@ static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) {
case NETWORK_STATUS_WAIT_FOR_EVENT:
break;
case NETWORK_STATUS_WAIT_FOR_AIO_EVENT:
/* TODO ? */
/* TODO: aio */
ev_io_rem_events(loop, w, EV_WRITE);
break;
case NETWORK_STATUS_WAIT_FOR_FD:
/* TODO */
/* TODO: wait for fd */
ev_io_rem_events(loop, w, EV_WRITE);
break;
}
@ -149,6 +149,7 @@ connection* connection_new(server *srv) {
action_stack_init(&con->action_stack);
request_init(&con->request, con->raw_in);
physical_init(&con->physical);
response_init(&con->response);
return con;
@ -177,6 +178,7 @@ void connection_reset(server *srv, connection *con) {
action_stack_reset(srv, &con->action_stack);
request_reset(&con->request);
physical_reset(&con->physical);
response_reset(&con->response);
}
@ -197,6 +199,7 @@ void connection_reset_keep_alive(server *srv, connection *con) {
action_stack_reset(srv, &con->action_stack);
request_reset(&con->request);
physical_reset(&con->physical);
response_reset(&con->response);
}
@ -223,6 +226,7 @@ void connection_free(server *srv, connection *con) {
action_stack_clear(srv, &con->action_stack);
request_clear(&con->request);
physical_clear(&con->physical);
response_clear(&con->response);
g_slice_free(connection, con);
@ -241,7 +245,6 @@ void connection_state_machine(server *srv, connection *con) {
do {
switch (con->state) {
case CON_STATE_REQUEST_START:
/* TODO: reset some values after keep alive - or do it in CON_STATE_REQUEST_END */
connection_set_state(srv, con, CON_STATE_READ_REQUEST_HEADER);
action_enter(con, srv->mainaction);
break;
@ -253,7 +256,7 @@ void connection_state_machine(server *srv, connection *con) {
connection_set_state(srv, con, CON_STATE_VALIDATE_REQUEST_HEADER);
break;
case HANDLER_WAIT_FOR_FD:
/* TODO */
/* TODO: wait for fd */
done = TRUE;
break;
case HANDLER_WAIT_FOR_EVENT:
@ -285,9 +288,7 @@ void connection_state_machine(server *srv, connection *con) {
connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE);
break;
case ACTION_ERROR:
/* action return error */
/* TODO: return 500 instead ? */
connection_set_state(srv, con, CON_STATE_ERROR);
internal_error(srv, con);
break;
}
break;
@ -305,9 +306,7 @@ void connection_state_machine(server *srv, connection *con) {
connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE);
break;
case ACTION_ERROR:
/* action return error */
/* TODO: return 500 instead ? */
connection_set_state(srv, con, CON_STATE_ERROR);
internal_error(srv, con);
break;
}
break;

@ -67,6 +67,7 @@ struct connection {
guint idx; /** index in connection table */
connection_state_t state;
gboolean response_headers_sent, expect_100_cont;
/* TODO: implement expect_100 */
chunkqueue *raw_in, *raw_out;
chunkqueue *in, *out;
@ -78,7 +79,7 @@ struct connection {
action_stack action_stack;
gpointer *options; /* TODO */
gpointer *options; /* TODO: options */
request request;
physical physical;

@ -1,4 +1,5 @@
#include "base.h"
#include "http_headers.h"
static void _string_free(gpointer p) {
@ -154,3 +155,15 @@ gboolean http_header_is(http_headers *headers, const gchar *key, size_t keylen,
}
return FALSE;
}
void http_header_get_fast(GString *dest, http_headers *headers, const gchar *key, size_t keylen) {
http_header *h = http_header_lookup_fast(headers, key, keylen);
GList *iter;
g_string_truncate(dest, 0);
if (!h) return;
for (iter = g_queue_peek_head_link(&h->values); NULL != iter; iter = g_list_next(iter)) {
if (dest->len) g_string_append_len(dest, CONST_STR_LEN(", "));
g_string_append_len(dest, GSTR_LEN((GString*)iter->data));
}
}

@ -41,4 +41,7 @@ LI_API http_header* http_header_lookup_fast(http_headers *headers, const gchar *
/** Use lowercase keys! values are compared case-insensitive */
LI_API gboolean http_header_is(http_headers *headers, const gchar *key, size_t keylen, const gchar *value, size_t valuelen);
/** concats all headers with key with ', ' - empty if no header exists - use lowercase key*/
LI_API void http_header_get_fast(GString *dest, http_headers *headers, const gchar *key, size_t keylen);
#endif

@ -65,7 +65,7 @@ static action* core_when(server *srv, plugin* p, option *opt) {
static action_result core_handle_static(server *srv, connection *con, gpointer param) {
UNUSED(param);
/* TODO */
/* TODO: handle static files */
CON_ERROR(srv, con, "%s", "Not implemented yet");
return ACTION_ERROR;
}

@ -68,9 +68,15 @@ static void bad_request(server *srv, connection *con, int status) {
connection_handle_direct(srv, con);
}
gboolean request_parse_url(server *srv, connection *con) {
request *req = &con->request;
/* TODO: parse url */
return TRUE;
}
void request_validate_header(server *srv, connection *con) {
request *req = &con->request;
response *resp = &con->response;
http_header *hh;
switch (req->http_version) {
@ -99,9 +105,12 @@ void request_validate_header(server *srv, connection *con) {
return;
} else if (hh) {
g_string_append_len(req->host, GSTR_LEN((GString*) g_queue_peek_head(&hh->values)));
// CON_TRACE(srv, con, "hostname: '%s'", req->host->str);
}
/* may override hostname */
if (!request_parse_url(srv, con))
return;
/* content-length */
hh = http_header_lookup_fast(req->headers, CONST_STR_LEN("content-length"));
if (hh) {
@ -195,4 +204,33 @@ void request_validate_header(server *srv, connection *con) {
/* the may have a content-length */
break;
}
/* TODO: check hostname */
}
void physical_init(physical *phys) {
phys->path = g_string_sized_new(512);
phys->basedir = g_string_sized_new(256);
phys->doc_root = g_string_sized_new(256);
phys->rel_path = g_string_sized_new(256);
phys->pathinfo = g_string_sized_new(256);
phys->size = -1;
}
void physical_reset(physical *phys) {
g_string_truncate(phys->path, 0);
g_string_truncate(phys->basedir, 0);
g_string_truncate(phys->doc_root, 0);
g_string_truncate(phys->rel_path, 0);
g_string_truncate(phys->pathinfo, 0);
phys->size = -1;
}
void physical_clear(physical *phys) {
g_string_free(phys->path, TRUE);
g_string_free(phys->basedir, TRUE);
g_string_free(phys->doc_root, TRUE);
g_string_free(phys->rel_path, TRUE);
g_string_free(phys->pathinfo, TRUE);
phys->size = -1;
}

@ -63,7 +63,7 @@ struct physical {
GString *pathinfo;
guint64 size;
gint64 size;
};
struct request {
@ -87,4 +87,8 @@ LI_API void request_clear(request *req);
LI_API void request_validate_header(server *srv, connection *con);
LI_API void physical_init(physical *phys);
LI_API void physical_reset(physical *phys);
LI_API void physical_clear(physical *phys);
#endif

@ -2,6 +2,8 @@
#include "base.h"
#include "utils.h"
void con_put(server *srv, connection *con);
static void server_option_free(gpointer _so) {
g_slice_free(server_option, _so);
}
@ -48,12 +50,31 @@ server* server_new() {
void server_free(server* srv) {
if (!srv) return;
/* TODO */
srv->exiting = TRUE;
server_stop(srv);
{ /* close connections */
guint i;
if (srv->connections_active > 0) {
ERROR(srv, "Server shutdown with unclosed connections: %u", srv->connections_active);
for (i = srv->connections_active; i-- > 0;) {
connection *con = g_array_index(srv->connections, connection*, i);
connection_set_state(srv, con, CON_STATE_ERROR);
connection_state_machine(srv, con); /* cleanup plugins */
con_put(srv, con);
}
}
for (i = 0; i < srv->connections->len; i++) {
connection_free(srv, g_array_index(srv->connections, connection*, i));
}
g_array_free(srv->connections, TRUE);
}
g_hash_table_destroy(srv->plugins);
g_hash_table_destroy(srv->options);
g_hash_table_destroy(srv->actions);
g_hash_table_destroy(srv->setups);
g_hash_table_destroy(srv->plugins);
action_release(srv, srv->mainaction);

@ -36,7 +36,7 @@ struct server {
GHashTable *actions; /**< const gchar* => (server_action*) */
GHashTable *setups; /**< const gchar* => (server_setup*) */
gpointer *option_def_values; /* TODO */
gpointer *option_def_values; /* TODO: options */
struct action *mainaction;
gboolean exiting;

Loading…
Cancel
Save