
/*
 * Copyright (C) Igor Sysoev
 */

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_mysql.h>
#include <ngx_http.h>


typedef struct {
    ngx_peers_t  *peers;
} ngx_http_mysql_test_conf_t;


static void ngx_http_mysql_auth(ngx_mysql_t *m);
static void ngx_http_mysql_done(ngx_mysql_t *m);
static void *ngx_http_mysql_test_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_mysql_test(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);

static ngx_command_t  ngx_http_mysql_test_commands[] = {

    { ngx_string("mysql_test"),
      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
      ngx_http_mysql_test,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },

      ngx_null_command
};


static ngx_http_module_t  ngx_http_mysql_test_module_ctx = {
    NULL,                          /* preconfiguration */
    NULL,                          /* postconfiguration */

    NULL,                          /* create main configuration */
    NULL,                          /* init main configuration */

    NULL,                          /* create server configuration */
    NULL,                          /* merge server configuration */

    ngx_http_mysql_test_create_loc_conf,  /* create location configuration */
    NULL                           /* merge location configuration */
};


ngx_module_t  ngx_http_mysql_test_module = {
    NGX_MODULE_V1,
    &ngx_http_mysql_test_module_ctx, /* module context */
    ngx_http_mysql_test_commands,   /* module directives */
    NGX_HTTP_MODULE,               /* module type */
    NULL,                          /* init master */
    NULL,                          /* init module */
    NULL,                          /* init process */
    NULL,                          /* init thread */
    NULL,                          /* exit thread */
    NULL,                          /* exit process */
    NULL,                          /* exit master */
    NGX_MODULE_V1_PADDING
};


static ngx_str_t  ngx_mysql_login = ngx_string("root");
static ngx_str_t  ngx_mysql_passwd = ngx_string("tp");
static ngx_str_t  ngx_mysql_database = ngx_string("mysql");
static ngx_str_t  ngx_mysql_command_query =
    ngx_string("select * from user");


static ngx_int_t
ngx_http_mysql_test_handler(ngx_http_request_t *r)
{
    ngx_int_t                    rc;
    ngx_mysql_t                 *m;
    ngx_http_mysql_test_conf_t  *mtcf;

    mtcf = ngx_http_get_module_loc_conf(r, ngx_http_mysql_test_module);

    m = ngx_pcalloc(r->pool, sizeof(ngx_mysql_t));

    if (m == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    m->pool = r->pool;
    m->handler = ngx_http_mysql_auth;
    m->data = r;

    m->login = &ngx_mysql_login;
    m->passwd = &ngx_mysql_passwd;
    m->database = &ngx_mysql_database;

    m->peer.log = r->connection->log;
    m->peer.log_error = NGX_ERROR_ERR;
    m->peer.peers = mtcf->peers;
    m->peer.tries = mtcf->peers->number;

    rc = ngx_mysql_connect(m);

    if (rc == NGX_OK || rc == NGX_AGAIN) {
        return NGX_DONE;
    }

    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}


static void
ngx_http_mysql_auth(ngx_mysql_t *m)
{
    ngx_http_request_t  *r;

    r = m->data;

    if (m->state != NGX_OK) {
        ngx_http_finalize_request(r, NGX_HTTP_NO_CONTENT);
        return;
    }

    m->query.len = NGX_MYSQL_CMDPKT_LEN + ngx_mysql_command_query.len;

    m->query.data = ngx_palloc(r->pool, m->query.len);
    if (m->query.data == NULL) {
        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
        return;
    }

    ngx_memcpy(m->query.data + NGX_MYSQL_CMDPKT_LEN,
               ngx_mysql_command_query.data, ngx_mysql_command_query.len);

    m->handler = ngx_http_mysql_done;

    ngx_mysql_query(m);
}


static void
ngx_http_mysql_done(ngx_mysql_t *m)
{
    ngx_http_request_t  *r;

    r = m->data;

    ngx_http_finalize_request(r, NGX_HTTP_NO_CONTENT);
}


static void *
ngx_http_mysql_test_create_loc_conf(ngx_conf_t *cf)
{
    ngx_http_mysql_test_conf_t  *conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_mysql_test_conf_t));
    if (conf == NULL) {
        return NGX_CONF_ERROR;
    }

    return conf;
}

static char *
ngx_http_mysql_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_mysql_test_conf_t  *mtcf = conf;

    ngx_str_t                 *value;
    ngx_url_t                  u;
    ngx_http_core_loc_conf_t  *clcf;

    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    clcf->handler = ngx_http_mysql_test_handler;

    value = cf->args->elts;

    ngx_memzero(&u, sizeof(ngx_url_t));

    u.url = value[1];
    u.default_portn = 3306;

    if (ngx_parse_url(cf, &u) != NGX_OK) {
        if (u.err) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "%s in upstream \"%V\"", u.err, &u.url);
        }

        return NGX_CONF_ERROR;
    }

    mtcf->peers = u.peers;

    return NGX_CONF_OK;
}
