summaryrefslogtreecommitdiff
path: root/src/mod_postgresql_vhost.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_postgresql_vhost.c')
-rw-r--r--src/mod_postgresql_vhost.c371
1 files changed, 0 insertions, 371 deletions
diff --git a/src/mod_postgresql_vhost.c b/src/mod_postgresql_vhost.c
deleted file mode 100644
index 2e0f4a7f..00000000
--- a/src/mod_postgresql_vhost.c
+++ /dev/null
@@ -1,371 +0,0 @@
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdbool.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_LIBPQ_FE_H
-# ifdef HAVE_LIBPQ
-# define HAVE_POSTGRESQL
-# endif
-#endif
-
-#ifdef HAVE_POSTGRESQL
-#include <glib.h>
-#include <libpq-fe.h>
-#include <time.h>
-#endif
-
-#include "plugin.h"
-#include "log.h"
-
-#include "stat_cache.h"
-#include "sys-files.h"
-
-#include "mod_sql_vhost_core.h"
-
-#ifdef HAVE_POSTGRESQL
-// Define a couple constants so the cache expires and we
-// do a countdown for when to do some cleanup.
-
-typedef struct {
- PGconn **pconn;
- PGconn *conn;
-
- buffer *postgresql_pre;
- buffer *postgresql_post;
-
- buffer *conninfo;
-
- mod_sql_vhost_core_plugin_config *core;
-} plugin_config;
-
-/* global plugin data */
-typedef struct {
- PLUGIN_DATA;
-
- buffer *tmp_buf;
-
- plugin_config **config_storage;
-
- plugin_config conf;
-} plugin_data;
-
-#define CORE_PLUGIN "mod_sql_vhost_core"
-
-SQLVHOST_BACKEND_GETVHOST(mod_postgresql_vhost_get_vhost);
-
-/* init the plugin data */
-INIT_FUNC(mod_postgresql_vhost_init) {
- plugin_data *p;
- UNUSED(srv);
-
- p = calloc(1, sizeof(*p));
-
- p->tmp_buf = buffer_init();
-
- return p;
-}
-
-/* cleanup the plugin data */
-SERVER_FUNC(mod_postgresql_vhost_cleanup) {
- plugin_data *p = p_d;
-
- UNUSED(srv);
-
- if (!p) return HANDLER_GO_ON;
-
- if (p->config_storage) {
- size_t i;
- for (i = 0; i < srv->config_context->used; i++) {
- plugin_config *s = p->config_storage[i];
-
- if (!s) continue;
-
- PQfinish(s->conn);
- buffer_free(s->postgresql_pre);
- buffer_free(s->postgresql_post);
- buffer_free(s->conninfo);
-
- free(s);
- }
- free(p->config_storage);
- }
- buffer_free(p->tmp_buf);
-
- free(p);
-
- return HANDLER_GO_ON;
-}
-
-
-/* set configuration values */
-SERVER_FUNC(mod_postgresql_vhost_set_defaults) {
- plugin_data *p = p_d;
- mod_sql_vhost_core_plugin_data *core_config;
-
- size_t i = 0;
-
- /* our very own plugin storage, one entry for each conditional
- *
- * srv->config_context->used is the number of conditionals
- * */
- p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
-
- /* get the config of the core-plugin */
- core_config = plugin_get_config(srv, CORE_PLUGIN);
-
- /* walk through all conditionals and check for assignments */
- for (i = 0; i < srv->config_context->used; i++) {
- plugin_config *s;
- buffer *sel;
- char *qmark;
-
- /* get the config from the core plugin for this conditional-context */
- s = calloc(1, sizeof(plugin_config));
-
- s->core = core_config->config_storage[i];
- s->conn = NULL;
- s->pconn = &(s->conn);
-
- s->postgresql_pre = buffer_init();
- s->postgresql_post = buffer_init();
- s->conninfo = buffer_init();
-
- p->config_storage[i] = s;
-
- /* check if we are the plugin for this backend */
- if (!buffer_is_equal_string(s->core->backend, CONST_STR_LEN("postgresql"))) continue;
-
- /* attach us to the core-plugin */
- s->core->backend_data = p;
- s->core->get_vhost = mod_postgresql_vhost_get_vhost;
-
- sel = buffer_init();
- buffer_copy_string_buffer(sel, s->core->select_vhost);
-
- if (sel->used && (qmark = strchr(sel->ptr, '?'))) {
- *qmark = '\0';
- buffer_copy_string(s->postgresql_pre, sel->ptr);
- buffer_copy_string(s->postgresql_post, qmark+1);
- } else {
- buffer_copy_string_buffer(s->postgresql_pre, sel);
- }
- buffer_free(sel);
-
- /* see if we can build our connection string based on the parts we know from the config
- *
- * "host=/tmp dbname=lighttpd user=lighttpd"
- * */
-
- if (!buffer_is_empty(s->core->hostname)) {
- buffer_append_string_len(s->conninfo, CONST_STR_LEN("host="));
- buffer_append_string_buffer(s->conninfo, s->core->hostname);
- if (s->core->port) {
- buffer_append_string_len(s->conninfo, CONST_STR_LEN(" "));
- buffer_append_string_len(s->conninfo, CONST_STR_LEN("port="));
- buffer_append_long(s->conninfo, s->core->port);
- }
- } else if (!buffer_is_empty(s->core->sock)) {
- buffer_append_string_len(s->conninfo, CONST_STR_LEN("host="));
- buffer_append_string_buffer(s->conninfo, s->core->sock);
- }
-
- if (!buffer_is_empty(s->core->db)) {
- if (!buffer_is_empty(s->conninfo)) buffer_append_string_len(s->conninfo, CONST_STR_LEN(" "));
- buffer_append_string_len(s->conninfo, CONST_STR_LEN("dbname="));
- buffer_append_string_buffer(s->conninfo, s->core->db);
- }
-
- if (!buffer_is_empty(s->core->user)) {
- if (!buffer_is_empty(s->conninfo)) buffer_append_string_len(s->conninfo, CONST_STR_LEN(" "));
- buffer_append_string_len(s->conninfo, CONST_STR_LEN("user="));
- buffer_append_string_buffer(s->conninfo, s->core->user);
- }
-
- if (!buffer_is_empty(s->core->pass)) {
- if (!buffer_is_empty(s->conninfo)) buffer_append_string_len(s->conninfo, CONST_STR_LEN(" "));
- buffer_append_string_len(s->conninfo, CONST_STR_LEN("password="));
- buffer_append_string_buffer(s->conninfo, s->core->pass);
- }
-
- }
-
- return HANDLER_GO_ON;
-}
-
-
-static int mod_postgresql_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
- size_t i;
- plugin_config *s = p->config_storage[0];
-
- PATCH_OPTION(postgresql_pre);
- PATCH_OPTION(postgresql_post);
- PATCH_OPTION(conn);
- PATCH_OPTION(pconn);
- PATCH_OPTION(conninfo);
- PATCH_OPTION(core);
-
- /* skip the first, the global context */
- for (i = 1; i < srv->config_context->used; i++) {
- data_config *dc = (data_config *)srv->config_context->data[i];
- s = p->config_storage[i];
-
- /* condition didn't match */
- if (!config_check_cond(srv, con, dc)) continue;
-
- if (!buffer_is_equal_string(s->core->backend, CONST_STR_LEN("postgresql"))) continue;
-
- PATCH_OPTION(pconn);
- PATCH_OPTION(conn);
- PATCH_OPTION(conninfo);
- PATCH_OPTION(postgresql_pre);
- PATCH_OPTION(postgresql_post);
- PATCH_OPTION(core);
- }
-
- return 0;
-}
-
-/*
- * get the vhost info from the database
- */
-SQLVHOST_BACKEND_GETVHOST(mod_postgresql_vhost_get_vhost) {
- plugin_data *p = p_d;
- int nFields;
- PGresult *result;
- gchar *field;
-
- UNUSED(host);
-
- /* no host specified? */
- if (buffer_is_empty(con->uri.authority)) return HANDLER_ERROR;
-
- mod_postgresql_vhost_patch_connection(srv, con, p);
-
- if (buffer_is_empty(p->conf.conninfo)) return HANDLER_ERROR;
-
- /**
- * try to connect the pg-server
- */
- if (p->conf.conn == NULL) {
- if (p->conf.core->debug) TRACE("connecting to postgres: %s", SAFE_BUF_STR(p->conf.conninfo));
-
- if (NULL == (p->conf.conn = PQconnectdb(BUF_STR(p->conf.conninfo)))) {
- ERROR("%s", "postgresql malloc failure");
-
- return HANDLER_ERROR;
- }
-
- /* we have to update the pointer in the conditional cache too */
- *(p->conf.pconn) = p->conf.conn;
-
- /* For when we move to Async requests
- * PQsetnonblocking(s->conn,1);
- */
-
- if (CONNECTION_BAD == PQstatus(p->conf.conn)) {
- /* Even if bad connection. maybe next time it can be fixed
- */
- ERROR("Bad connection for '%s': %s", SAFE_BUF_STR(p->conf.conninfo), PQerrorMessage(p->conf.conn));
-
- PQfinish(p->conf.conn);
-
- p->conf.conn = NULL;
-
- return HANDLER_ERROR;
- }
-
- if (PQstatus(p->conf.conn) != CONNECTION_OK){
- ERROR("PQconnectdb() failed: %i", PQstatus(p->conf.conn));
-
- PQfinish(p->conf.conn);
-
- p->conf.conn = NULL;
-
- return HANDLER_ERROR;
- }
- }
-
- /**
- * TODO: Change to a stored proc to simiplify this
- * build and run SQL query
- */
- if (PQstatus(p->conf.conn) != CONNECTION_OK) {
- PQreset(p->conf.conn);
- }
-
- buffer_copy_string_buffer(p->tmp_buf, p->conf.postgresql_pre);
- if (p->conf.postgresql_post->used) {
- buffer_append_string_buffer(p->tmp_buf, con->uri.authority);
- buffer_append_string_buffer(p->tmp_buf, p->conf.postgresql_post);
- }
-
- result = PQexec(p->conf.conn, p->tmp_buf->ptr);
-
- /**
- * For Async requests. Database will block/slow down your daemon
- * result = PQsendQuery(p->conf.conn, p->tmp_buf->ptr);
- */
- if (result == NULL) {
- ERROR("PQexec(%s) failed: %s", SAFE_BUF_STR(p->tmp_buf), PQerrorMessage(p->conf.conn));
- return HANDLER_ERROR;
- }
-
- if (PQresultStatus(result) != PGRES_TUPLES_OK) {
- ERROR("PQresultStatus(%s): %s", SAFE_BUF_STR(p->tmp_buf), PQerrorMessage(p->conf.conn));
-
- PQclear(result);
-
- return HANDLER_ERROR;
- }
- /**
- * FIXME:
- * We checked for tupels already, but will add more sanity
- */
- nFields = PQnfields(result);
- if (PQntuples(result) < 1 || nFields < 1 ||
- (field = PQgetvalue(result, 0, 0)) == NULL || !*field) {
- /* no such virtual host */
- PQclear(result);
-
- return HANDLER_ERROR;
- }
-
- buffer_copy_string(docroot, field);
-
- PQclear(result);
-
- return HANDLER_GO_ON;
-}
-
-/* this function is called at dlopen() time and inits the callbacks */
-LI_EXPORT int mod_postgresql_vhost_plugin_init(plugin *p);
-LI_EXPORT int mod_postgresql_vhost_plugin_init(plugin *p) {
- data_string *ds;
- p->version = LIGHTTPD_VERSION_ID;
- p->name = buffer_init_string("postgresql_vhost");
- p->init = mod_postgresql_vhost_init;
- p->cleanup = mod_postgresql_vhost_cleanup;
- p->set_defaults = mod_postgresql_vhost_set_defaults;
-
- ds = data_string_init();
-
- buffer_copy_string_len(ds->value, CONST_STR_LEN(CORE_PLUGIN));
- array_insert_unique(p->required_plugins, (data_unset *)ds);
-
- return 0;
-}
-#else
-/* we don't have postgresql support, this plugin does nothing */
-LI_EXPORT int mod_postgresql_vhost_plugin_init(plugin *p);
-LI_EXPORT int mod_postgresql_vhost_plugin_init(plugin *p) {
- p->version = LIGHTTPD_VERSION_ID;
- p->name = buffer_init_string("postgresql_vhost");
-
- return 0;
-}
-#endif