From 9219fc4eda5db85122cec6d4c7ed85e41021cd42 Mon Sep 17 00:00:00 2001 From: Jan Kneschke Date: Mon, 28 Feb 2005 08:42:47 +0000 Subject: [PATCH] moved external functions to *-glue.c this simplifies the linkage on windows and macosx which can't reference the binary for symbols git-svn-id: svn+ssh://svn.lighttpd.net/lighttpd/trunk@49 152afb58-edef-0310-8abb-c4023f1b3aa9 --- src/.cvsignore | 5 +- src/Makefile.am | 17 ++-- src/config.c | 197 ------------------------------------- src/configfile-glue.c | 216 +++++++++++++++++++++++++++++++++++++++++ src/connections-glue.c | 44 +++++++++ src/connections.c | 42 -------- src/http-header-glue.c | 136 ++++++++++++++++++++++++++ src/response.c | 128 ------------------------ 8 files changed, 410 insertions(+), 375 deletions(-) create mode 100644 src/configfile-glue.c create mode 100644 src/connections-glue.c create mode 100644 src/http-header-glue.c diff --git a/src/.cvsignore b/src/.cvsignore index 82d670f2..52e599d1 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -1,9 +1,10 @@ -lemon -lighttpd Makefile.in Makefile spawn-fcgi chunk +lemon +lighttpd +*.exe .deps .libs array diff --git a/src/Makefile.am b/src/Makefile.am index c4d275fc..dff793cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,21 +28,26 @@ config.c: configparser.h mod_ssi_expr.c: mod_ssi_exprparser.h common_src=buffer.c log.c \ - keyvalue.c response.c request.c chunk.c \ - http_chunk.c stream.c fdevent.c connections.c \ + keyvalue.c chunk.c \ + http_chunk.c stream.c fdevent.c \ file_cache.c plugin.c joblist.c etag.c array.c \ data_string.c data_count.c data_array.c \ data_integer.c md5.c data_fastcgi.c \ fdevent_select.c fdevent_linux_rtsig.c \ fdevent_poll.c fdevent_linux_sysepoll.c \ fdevent_solaris_devpoll.c fdevent_freebsd_kqueue.c \ + data_config.c bitset.c configparser.c \ + inet_ntop_cache.c \ + connections-glue.c \ + configfile-glue.c \ + http-header-glue.c + +src = server.c response.c connections.c network.c \ network_write.c network_linux_sendfile.c \ network_freebsd_sendfile.c network_writev.c \ network_solaris_sendfilev.c network_openssl.c \ - data_config.c bitset.c configparser.c config.c \ - inet_ntop_cache.c network.c - -src = server.c + config.c request.c + spawn_fcgi_SOURCES=spawn-fcgi.c diff --git a/src/config.c b/src/config.c index 80dd8f9a..cbc32c08 100644 --- a/src/config.c +++ b/src/config.c @@ -20,136 +20,6 @@ #include "configparser.h" #include "configfile.h" -/* handle global options */ - -int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) { - size_t i; - data_unset *du; - - for (i = 0; cv[i].key; i++) { - data_string *touched; - - if (NULL == (du = array_get_element(ca, cv[i].key))) { - /* no found */ - - continue; - } - - /* touched */ - touched = data_string_init(); - - buffer_copy_string(touched->value, ""); - buffer_copy_string_buffer(touched->key, du->key); - - array_insert_unique(srv->config_touched, (data_unset *)touched); - } - - return config_insert_values_internal(srv, ca, cv); -} - -/* parse config array */ - -int config_insert_values_internal(server *srv, array *ca, const config_values_t cv[]) { - size_t i; - data_unset *du; - - for (i = 0; cv[i].key; i++) { - - if (NULL == (du = array_get_element(ca, cv[i].key))) { - /* no found */ - - continue; - } - - switch (cv[i].type) { - case T_CONFIG_ARRAY: - if (du->type == TYPE_ARRAY) { - size_t j; - data_array *da = (data_array *)du; - - for (j = 0; j < da->value->used; j++) { - if (da->value->data[j]->type == TYPE_STRING) { - data_string *ds = data_string_init(); - - buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value); - buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key); - - array_insert_unique(cv[i].destination, (data_unset *)ds); - } else { - log_error_write(srv, __FILE__, __LINE__, "sssbs", "unexpected type for key: ", cv[i].key, "[", da->value->data[i]->key, "](string)"); - - return -1; - } - } - } else { - log_error_write(srv, __FILE__, __LINE__, "sss", "unexpected type for key: ", cv[i].key, "array of strings"); - - return -1; - } - break; - case T_CONFIG_STRING: - if (du->type == TYPE_STRING) { - data_string *ds = (data_string *)du; - - buffer_copy_string_buffer(cv[i].destination, ds->value); - } else { - log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\""); - - return -1; - } - break; - case T_CONFIG_SHORT: - switch(du->type) { - case TYPE_INTEGER: { - data_integer *di = (data_integer *)du; - - *((unsigned short *)(cv[i].destination)) = di->value; - break; - } - case TYPE_STRING: { - data_string *ds = (data_string *)du; - - log_error_write(srv, __FILE__, __LINE__, "ssbss", "unexpected type for key: ", cv[i].key, ds->value, "(short)", "0 ... 65535"); - - return -1; - } - default: - log_error_write(srv, __FILE__, __LINE__, "ssdss", "unexpected type for key: ", cv[i].key, du->type, "(short)", "0 ... 65535"); - return -1; - } - break; - case T_CONFIG_BOOLEAN: - if (du->type == TYPE_STRING) { - data_string *ds = (data_string *)du; - - if (0 == strcmp(ds->value->ptr, "enable")) { - *((unsigned short *)(cv[i].destination)) = 1; - } else if (0 == strcmp(ds->value->ptr, "disable")) { - *((unsigned short *)(cv[i].destination)) = 0; - } else { - log_error_write(srv, __FILE__, __LINE__, "ssbs", "ERROR: unexpected value for key:", cv[i].key, ds->value, "(enable|disable)"); - - return -1; - } - } else { - log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: unexpected type for key:", cv[i].key, "(string)", "\"(enable|disable)\""); - - return -1; - } - break; - case T_CONFIG_LOCAL: - case T_CONFIG_UNSET: - break; - case T_CONFIG_DEPRECATED: - log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found deprecated key:", cv[i].key, "-", (char *)(cv[i].destination)); - - srv->config_deprecated = 1; - - break; - } - } - return 0; -} static int config_insert(server *srv) { size_t i; @@ -309,73 +179,6 @@ static int config_insert(server *srv) { } -int config_check_cond(server *srv, connection *con, data_config *dc) { - buffer *l; - server_socket *srv_sock = con->srv_socket; - /* pass the rules */ - - l = srv->empty_string; - - if (0 == strcmp(dc->comp_key->ptr, "HTTPhost")) { - l = con->uri.authority; - } else if (0 == strcmp(dc->comp_key->ptr, "HTTPurl")) { - l = con->uri.path; - } else if (0 == strcmp(dc->comp_key->ptr, "SERVERsocket")) { - l = srv_sock->srv_token; - } else if (0 == strcmp(dc->comp_key->ptr, "HTTPreferer")) { - data_string *ds; - - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) { - l = ds->value; - } - } else if (0 == strcmp(dc->comp_key->ptr, "HTTPcookie")) { - data_string *ds; - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) { - l = ds->value; - } - } else if (0 == strcmp(dc->comp_key->ptr, "HTTPuseragent")) { - data_string *ds; - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "User-Agent"))) { - l = ds->value; - } - } else { - return 0; - } - - switch(dc->cond) { - case CONFIG_COND_NE: - case CONFIG_COND_EQ: - if (buffer_is_equal(l, dc->match.string)) { - return (dc->cond == CONFIG_COND_EQ) ? 1 : 0; - } else { - return (dc->cond == CONFIG_COND_EQ) ? 0 : 1; - } - break; -#ifdef HAVE_PCRE_H - case CONFIG_COND_NOMATCH: - case CONFIG_COND_MATCH: { -#define N 10 - int ovec[N * 3]; - int n; - - n = pcre_exec(dc->match.regex, NULL, l->ptr, l->used - 1, 0, 0, ovec, N * 3); - - if (n > 0) { - return (dc->cond == CONFIG_COND_MATCH) ? 1 : 0; - } else { - return (dc->cond == CONFIG_COND_MATCH) ? 0 : 1; - } - - break; - } -#endif - default: - /* no way */ - break; - } - - return 0; -} #define PATCH(x) con->conf.x = s->x int config_setup_connection(server *srv, connection *con) { diff --git a/src/configfile-glue.c b/src/configfile-glue.c new file mode 100644 index 00000000..05befa31 --- /dev/null +++ b/src/configfile-glue.c @@ -0,0 +1,216 @@ + +#include "base.h" +#include "buffer.h" +#include "array.h" +#include "log.h" + +/** + * like all glue code this file contains functions which + * are the external interface of lighttpd. The functions + * are used by the server itself and the plugins. + * + * The main-goal is to have a small library in the end + * which is linked against both and which will define + * the interface itself in the end. + * + */ + + +/* handle global options */ + +/* parse config array */ +int config_insert_values_internal(server *srv, array *ca, const config_values_t cv[]) { + size_t i; + data_unset *du; + + for (i = 0; cv[i].key; i++) { + + if (NULL == (du = array_get_element(ca, cv[i].key))) { + /* no found */ + + continue; + } + + switch (cv[i].type) { + case T_CONFIG_ARRAY: + if (du->type == TYPE_ARRAY) { + size_t j; + data_array *da = (data_array *)du; + + for (j = 0; j < da->value->used; j++) { + if (da->value->data[j]->type == TYPE_STRING) { + data_string *ds = data_string_init(); + + buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value); + buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key); + + array_insert_unique(cv[i].destination, (data_unset *)ds); + } else { + log_error_write(srv, __FILE__, __LINE__, "sssbs", "unexpected type for key: ", cv[i].key, "[", da->value->data[i]->key, "](string)"); + + return -1; + } + } + } else { + log_error_write(srv, __FILE__, __LINE__, "sss", "unexpected type for key: ", cv[i].key, "array of strings"); + + return -1; + } + break; + case T_CONFIG_STRING: + if (du->type == TYPE_STRING) { + data_string *ds = (data_string *)du; + + buffer_copy_string_buffer(cv[i].destination, ds->value); + } else { + log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\""); + + return -1; + } + break; + case T_CONFIG_SHORT: + switch(du->type) { + case TYPE_INTEGER: { + data_integer *di = (data_integer *)du; + + *((unsigned short *)(cv[i].destination)) = di->value; + break; + } + case TYPE_STRING: { + data_string *ds = (data_string *)du; + + log_error_write(srv, __FILE__, __LINE__, "ssbss", "unexpected type for key: ", cv[i].key, ds->value, "(short)", "0 ... 65535"); + + return -1; + } + default: + log_error_write(srv, __FILE__, __LINE__, "ssdss", "unexpected type for key: ", cv[i].key, du->type, "(short)", "0 ... 65535"); + return -1; + } + break; + case T_CONFIG_BOOLEAN: + if (du->type == TYPE_STRING) { + data_string *ds = (data_string *)du; + + if (buffer_is_equal_string(ds->value, CONST_STR_LEN("enable"))) { + *((unsigned short *)(cv[i].destination)) = 1; + } else if (buffer_is_equal_string(ds->value, CONST_STR_LEN("disable"))) { + *((unsigned short *)(cv[i].destination)) = 0; + } else { + log_error_write(srv, __FILE__, __LINE__, "ssbs", "ERROR: unexpected value for key:", cv[i].key, ds->value, "(enable|disable)"); + + return -1; + } + } else { + log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: unexpected type for key:", cv[i].key, "(string)", "\"(enable|disable)\""); + + return -1; + } + break; + case T_CONFIG_LOCAL: + case T_CONFIG_UNSET: + break; + case T_CONFIG_DEPRECATED: + log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found deprecated key:", cv[i].key, "-", (char *)(cv[i].destination)); + + srv->config_deprecated = 1; + + break; + } + } + return 0; +} + +int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) { + size_t i; + data_unset *du; + + for (i = 0; cv[i].key; i++) { + data_string *touched; + + if (NULL == (du = array_get_element(ca, cv[i].key))) { + /* no found */ + + continue; + } + + /* touched */ + touched = data_string_init(); + + buffer_copy_string(touched->value, ""); + buffer_copy_string_buffer(touched->key, du->key); + + array_insert_unique(srv->config_touched, (data_unset *)touched); + } + + return config_insert_values_internal(srv, ca, cv); +} + +int config_check_cond(server *srv, connection *con, data_config *dc) { + buffer *l; + server_socket *srv_sock = con->srv_socket; + /* pass the rules */ + + l = srv->empty_string; + + if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPhost"))) { + l = con->uri.authority; + } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPurl"))) { + l = con->uri.path; + } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("SERVERsocket"))) { + l = srv_sock->srv_token; + } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPreferer"))) { + data_string *ds; + + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) { + l = ds->value; + } + } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPcookie"))) { + data_string *ds; + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) { + l = ds->value; + } + } else if (buffer_is_equal_string(dc->comp_key, CONST_STR_LEN("HTTPuseragent"))) { + data_string *ds; + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "User-Agent"))) { + l = ds->value; + } + } else { + return 0; + } + + switch(dc->cond) { + case CONFIG_COND_NE: + case CONFIG_COND_EQ: + if (buffer_is_equal(l, dc->match.string)) { + return (dc->cond == CONFIG_COND_EQ) ? 1 : 0; + } else { + return (dc->cond == CONFIG_COND_EQ) ? 0 : 1; + } + break; +#ifdef HAVE_PCRE_H + case CONFIG_COND_NOMATCH: + case CONFIG_COND_MATCH: { +#define N 10 + int ovec[N * 3]; + int n; + + n = pcre_exec(dc->match.regex, NULL, l->ptr, l->used - 1, 0, 0, ovec, N * 3); + + if (n > 0) { + return (dc->cond == CONFIG_COND_MATCH) ? 1 : 0; + } else { + return (dc->cond == CONFIG_COND_MATCH) ? 0 : 1; + } + + break; + } +#endif + default: + /* no way */ + break; + } + + return 0; +} + diff --git a/src/connections-glue.c b/src/connections-glue.c new file mode 100644 index 00000000..ac6d267a --- /dev/null +++ b/src/connections-glue.c @@ -0,0 +1,44 @@ +#include "base.h" + +const char *connection_get_state(connection_state_t state) { + switch (state) { + case CON_STATE_CONNECT: return "connect"; + case CON_STATE_READ: return "read"; + case CON_STATE_READ_POST: return "readpost"; + case CON_STATE_WRITE: return "write"; + case CON_STATE_CLOSE: return "close"; + case CON_STATE_ERROR: return "error"; + case CON_STATE_HANDLE_REQUEST: return "handle-req"; + case CON_STATE_REQUEST_START: return "req-start"; + case CON_STATE_REQUEST_END: return "req-end"; + case CON_STATE_RESPONSE_START: return "resp-start"; + case CON_STATE_RESPONSE_END: return "resp-end"; + default: return "(unknown)"; + } +} + +const char *connection_get_short_state(connection_state_t state) { + switch (state) { + case CON_STATE_CONNECT: return "."; + case CON_STATE_READ: return "r"; + case CON_STATE_READ_POST: return "R"; + case CON_STATE_WRITE: return "W"; + case CON_STATE_CLOSE: return "C"; + case CON_STATE_ERROR: return "E"; + case CON_STATE_HANDLE_REQUEST: return "h"; + case CON_STATE_REQUEST_START: return "q"; + case CON_STATE_REQUEST_END: return "Q"; + case CON_STATE_RESPONSE_START: return "s"; + case CON_STATE_RESPONSE_END: return "S"; + default: return "x"; + } +} + +int connection_set_state(server *srv, connection *con, connection_state_t state) { + UNUSED(srv); + + con->state = state; + + return 0; +} + diff --git a/src/connections.c b/src/connections.c index 5f1ff544..2f816441 100644 --- a/src/connections.c +++ b/src/connections.c @@ -34,40 +34,6 @@ #include "sys-socket.h" -const char *connection_get_state(connection_state_t state) { - switch (state) { - case CON_STATE_CONNECT: return "connect"; - case CON_STATE_READ: return "read"; - case CON_STATE_READ_POST: return "readpost"; - case CON_STATE_WRITE: return "write"; - case CON_STATE_CLOSE: return "close"; - case CON_STATE_ERROR: return "error"; - case CON_STATE_HANDLE_REQUEST: return "handle-req"; - case CON_STATE_REQUEST_START: return "req-start"; - case CON_STATE_REQUEST_END: return "req-end"; - case CON_STATE_RESPONSE_START: return "resp-start"; - case CON_STATE_RESPONSE_END: return "resp-end"; - default: return "(unknown)"; - } -} - -const char *connection_get_short_state(connection_state_t state) { - switch (state) { - case CON_STATE_CONNECT: return "."; - case CON_STATE_READ: return "r"; - case CON_STATE_READ_POST: return "R"; - case CON_STATE_WRITE: return "W"; - case CON_STATE_CLOSE: return "C"; - case CON_STATE_ERROR: return "E"; - case CON_STATE_HANDLE_REQUEST: return "h"; - case CON_STATE_REQUEST_START: return "q"; - case CON_STATE_REQUEST_END: return "Q"; - case CON_STATE_RESPONSE_START: return "s"; - case CON_STATE_RESPONSE_END: return "S"; - default: return "x"; - } -} - static connection *connections_get_new_connection(server *srv) { connections *conns = srv->conns; size_t i; @@ -1168,14 +1134,6 @@ connection *connection_accept(server *srv, server_socket *srv_socket) { } } -int connection_set_state(server *srv, connection *con, connection_state_t state) { - UNUSED(srv); - - con->state = state; - - return 0; -} - int connection_state_machine(server *srv, connection *con) { int done = 0, r; diff --git a/src/http-header-glue.c b/src/http-header-glue.c new file mode 100644 index 00000000..d9bef500 --- /dev/null +++ b/src/http-header-glue.c @@ -0,0 +1,136 @@ +#include +#include + +#include "base.h" +#include "array.h" +#include "buffer.h" +#include "log.h" + +int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) { + data_string *ds; + + UNUSED(srv); + + if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { + ds = data_response_init(); + } + buffer_copy_string_len(ds->key, key, keylen); + buffer_copy_string_len(ds->value, value, vallen); + + array_insert_unique(con->response.headers, (data_unset *)ds); + + return 0; +} + +int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) { + data_string *ds; + + UNUSED(srv); + + /* if there already is a key by this name overwrite the value */ + if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) { + buffer_copy_string(ds->value, value); + + return 0; + } + + return response_header_insert(srv, con, key, keylen, value, vallen); +} + +int http_response_redirect_to_directory(server *srv, connection *con) { + buffer *o; + + o = buffer_init(); + + if (con->conf.is_ssl) { + buffer_copy_string(o, "https://"); + } else { + buffer_copy_string(o, "http://"); + } + if (con->uri.authority->used) { + buffer_append_string_buffer(o, con->uri.authority); + } else { + /* get the name of the currently connected socket */ + struct hostent *he; +#ifdef HAVE_IPV6 + char hbuf[256]; +#endif + sock_addr our_addr; + socklen_t our_addr_len; + + our_addr_len = sizeof(our_addr); + + if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) { + con->http_status = 500; + + log_error_write(srv, __FILE__, __LINE__, "ss", + "can't get sockname", strerror(errno)); + + buffer_free(o); + return 0; + } + + + /* Lookup name: secondly try to get hostname for bind address */ + switch(our_addr.plain.sa_family) { +#ifdef HAVE_IPV6 + case AF_INET6: + if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6), + SA_LEN((const struct sockaddr *)&our_addr.ipv6), + hbuf, sizeof(hbuf), NULL, 0, 0)) { + + char dst[INET6_ADDRSTRLEN]; + + log_error_write(srv, __FILE__, __LINE__, + "SSSS", "NOTICE: getnameinfo failed: ", + strerror(errno), ", using ip-address instead"); + + buffer_append_string(o, + inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr, + dst, sizeof(dst))); + } else { + buffer_append_string(o, hbuf); + } + break; +#endif + case AF_INET: + if (NULL == (he = gethostbyaddr((char *)&our_addr.ipv4.sin_addr, sizeof(struct in_addr), AF_INET))) { + log_error_write(srv, __FILE__, __LINE__, + "SSSS", "NOTICE: gethostbyaddr failed: ", + hstrerror(h_errno), ", using ip-address instead"); + + buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr)); + } else { + buffer_append_string(o, he->h_name); + } + break; + default: + log_error_write(srv, __FILE__, __LINE__, + "S", "ERROR: unsupported address-type"); + + buffer_free(o); + return -1; + } + + if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) || + (con->conf.is_ssl == 1 && srv->srvconf.port == 443))) { + buffer_append_string(o, ":"); + buffer_append_long(o, srv->srvconf.port); + } + } + buffer_append_string_buffer(o, con->uri.path); + buffer_append_string(o, "/"); + if (!buffer_is_empty(con->uri.query)) { + buffer_append_string(o, "?"); + buffer_append_string_buffer(o, con->uri.query); + } + + response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(o)); + + con->http_status = 301; + + buffer_free(o); + + return 0; +} + diff --git a/src/response.c b/src/response.c index 1f67d70e..36146737 100644 --- a/src/response.c +++ b/src/response.c @@ -91,38 +91,6 @@ static size_t get_sa_len(const struct sockaddr *addr) { -int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) { - data_string *ds; - - UNUSED(srv); - - if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { - ds = data_response_init(); - } - buffer_copy_string_len(ds->key, key, keylen); - buffer_copy_string_len(ds->value, value, vallen); - - array_insert_unique(con->response.headers, (data_unset *)ds); - - return 0; -} - -int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) { - data_string *ds; - - UNUSED(srv); - - /* if there already is a key by this name overwrite the value */ - if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) { - buffer_copy_string(ds->value, value); - - return 0; - } - - return response_header_insert(srv, con, key, keylen, value, vallen); -} - - int http_response_write_basic_header(server *srv, connection *con) { size_t i; buffer *b; @@ -754,102 +722,6 @@ static int http_list_directory(server *srv, connection *con, buffer *dir) { return 0; } -int http_response_redirect_to_directory(server *srv, connection *con) { - buffer *o; - - o = buffer_init(); - - if (con->conf.is_ssl) { - buffer_copy_string(o, "https://"); - } else { - buffer_copy_string(o, "http://"); - } - if (con->uri.authority->used) { - buffer_append_string_buffer(o, con->uri.authority); - } else { - /* get the name of the currently connected socket */ - struct hostent *he; -#ifdef HAVE_IPV6 - char hbuf[256]; -#endif - sock_addr our_addr; - socklen_t our_addr_len; - - our_addr_len = sizeof(our_addr); - - if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) { - con->http_status = 500; - - log_error_write(srv, __FILE__, __LINE__, "ss", - "can't get sockname", strerror(errno)); - - buffer_free(o); - return 0; - } - - - /* Lookup name: secondly try to get hostname for bind address */ - switch(our_addr.plain.sa_family) { -#ifdef HAVE_IPV6 - case AF_INET6: - if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6), - SA_LEN((const struct sockaddr *)&our_addr.ipv6), - hbuf, sizeof(hbuf), NULL, 0, 0)) { - - char dst[INET6_ADDRSTRLEN]; - - log_error_write(srv, __FILE__, __LINE__, - "SSSS", "NOTICE: getnameinfo failed: ", - strerror(errno), ", using ip-address instead"); - - buffer_append_string(o, - inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr, - dst, sizeof(dst))); - } else { - buffer_append_string(o, hbuf); - } - break; -#endif - case AF_INET: - if (NULL == (he = gethostbyaddr((char *)&our_addr.ipv4.sin_addr, sizeof(struct in_addr), AF_INET))) { - log_error_write(srv, __FILE__, __LINE__, - "SSSS", "NOTICE: gethostbyaddr failed: ", - hstrerror(h_errno), ", using ip-address instead"); - - buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr)); - } else { - buffer_append_string(o, he->h_name); - } - break; - default: - log_error_write(srv, __FILE__, __LINE__, - "S", "ERROR: unsupported address-type"); - - buffer_free(o); - return -1; - } - - if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) || - (con->conf.is_ssl == 1 && srv->srvconf.port == 443))) { - buffer_append_string(o, ":"); - buffer_append_long(o, srv->srvconf.port); - } - } - buffer_append_string_buffer(o, con->uri.path); - buffer_append_string(o, "/"); - if (!buffer_is_empty(con->uri.query)) { - buffer_append_string(o, "?"); - buffer_append_string_buffer(o, con->uri.query); - } - - response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(o)); - - con->http_status = 301; - - buffer_free(o); - - return 0; -} handler_t http_response_prepare(server *srv, connection *con) {