nginx/src/http/modules/ngx_http_uwsgi_module.c


/*
 * Copyright (C) Unbit S.a.s. 2009-2010
 * Copyright (C) 2008 Manlio Perillo ([email protected])
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 */


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


ngx_http_uwsgi_main_conf_t;


ngx_http_uwsgi_params_t;


ngx_http_uwsgi_loc_conf_t;


static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r,
    ngx_http_uwsgi_loc_conf_t *uwcf);
static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
static ngx_int_t ngx_http_uwsgi_input_filter_init(void *data);
static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
    ngx_int_t rc);

static void *ngx_http_uwsgi_create_main_conf(ngx_conf_t *cf);
static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
    void *child);
static ngx_int_t ngx_http_uwsgi_init_params(ngx_conf_t *cf,
    ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_params_t *params,
    ngx_keyval_t *default_params);

static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);
static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);

#if (NGX_HTTP_CACHE)
static ngx_int_t ngx_http_uwsgi_create_key(ngx_http_request_t *r);
static char *ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);
static char *ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);
#endif

#if (NGX_HTTP_SSL)
static char *ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf,
    ngx_command_t *cmd, void *conf);
static char *ngx_http_uwsgi_ssl_conf_command_check(ngx_conf_t *cf, void *post,
    void *data);
static ngx_int_t ngx_http_uwsgi_merge_ssl(ngx_conf_t *cf,
    ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_loc_conf_t *prev);
static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
    ngx_http_uwsgi_loc_conf_t *uwcf);
#endif


static ngx_conf_num_bounds_t  ngx_http_uwsgi_modifier_bounds =;


static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] =;


#if (NGX_HTTP_SSL)

static ngx_conf_bitmask_t  ngx_http_uwsgi_ssl_protocols[] = {
    { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
    { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
    { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
    { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
    { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
    { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
    { ngx_null_string, 0 }
};

static ngx_conf_post_t  ngx_http_uwsgi_ssl_conf_command_post =
    { ngx_http_uwsgi_ssl_conf_command_check };

#endif


ngx_module_t  ngx_http_uwsgi_module;


static ngx_command_t ngx_http_uwsgi_commands[] =;


static ngx_http_module_t ngx_http_uwsgi_module_ctx =;


ngx_module_t ngx_http_uwsgi_module =;


static ngx_str_t ngx_http_uwsgi_hide_headers[] =;


#if (NGX_HTTP_CACHE)

static ngx_keyval_t  ngx_http_uwsgi_cache_headers[] =;

#endif


static ngx_path_init_t ngx_http_uwsgi_temp_path =;


static ngx_int_t
ngx_http_uwsgi_handler(ngx_http_request_t *r)
{}


static ngx_int_t
ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
{}


#if (NGX_HTTP_CACHE)

static ngx_int_t
ngx_http_uwsgi_create_key(ngx_http_request_t *r)
{}

#endif


static ngx_int_t
ngx_http_uwsgi_create_request(ngx_http_request_t *r)
{}


static ngx_int_t
ngx_http_uwsgi_reinit_request(ngx_http_request_t *r)
{}


static ngx_int_t
ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
{}


static ngx_int_t
ngx_http_uwsgi_process_header(ngx_http_request_t *r)
{}


static ngx_int_t
ngx_http_uwsgi_input_filter_init(void *data)
{}


static void
ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
{}


static void
ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
{}


static void *
ngx_http_uwsgi_create_main_conf(ngx_conf_t *cf)
{}


static void *
ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
{}


static char *
ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{}


static ngx_int_t
ngx_http_uwsgi_init_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
    ngx_http_uwsgi_params_t *params, ngx_keyval_t *default_params)
{}


static char *
ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{}


static char *
ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{}


#if (NGX_HTTP_CACHE)

static char *
ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{}


static char *
ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{}

#endif


#if (NGX_HTTP_SSL)

static char *
ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_uwsgi_loc_conf_t *uwcf = conf;

    ngx_str_t  *value;

    if (uwcf->upstream.ssl_passwords != NGX_CONF_UNSET_PTR) {
        return "is duplicate";
    }

    value = cf->args->elts;

    uwcf->upstream.ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);

    if (uwcf->upstream.ssl_passwords == NULL) {
        return NGX_CONF_ERROR;
    }

    return NGX_CONF_OK;
}


static char *
ngx_http_uwsgi_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
{
#ifndef SSL_CONF_FLAG_FILE
    return "is not supported on this platform";
#else
    return NGX_CONF_OK;
#endif
}


static ngx_int_t
ngx_http_uwsgi_merge_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
    ngx_http_uwsgi_loc_conf_t *prev)
{
    ngx_uint_t  preserve;

    if (conf->ssl_protocols == 0
        && conf->ssl_ciphers.data == NULL
        && conf->upstream.ssl_certificate == NGX_CONF_UNSET_PTR
        && conf->upstream.ssl_certificate_key == NGX_CONF_UNSET_PTR
        && conf->upstream.ssl_passwords == NGX_CONF_UNSET_PTR
        && conf->upstream.ssl_verify == NGX_CONF_UNSET
        && conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
        && conf->ssl_trusted_certificate.data == NULL
        && conf->ssl_crl.data == NULL
        && conf->upstream.ssl_session_reuse == NGX_CONF_UNSET
        && conf->ssl_conf_commands == NGX_CONF_UNSET_PTR)
    {
        if (prev->upstream.ssl) {
            conf->upstream.ssl = prev->upstream.ssl;
            return NGX_OK;
        }

        preserve = 1;

    } else {
        preserve = 0;
    }

    conf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
    if (conf->upstream.ssl == NULL) {
        return NGX_ERROR;
    }

    conf->upstream.ssl->log = cf->log;

    /*
     * special handling to preserve conf->upstream.ssl
     * in the "http" section to inherit it to all servers
     */

    if (preserve) {
        prev->upstream.ssl = conf->upstream.ssl;
    }

    return NGX_OK;
}


static ngx_int_t
ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
{
    ngx_pool_cleanup_t  *cln;

    if (uwcf->upstream.ssl->ctx) {
        return NGX_OK;
    }

    if (ngx_ssl_create(uwcf->upstream.ssl, uwcf->ssl_protocols, NULL)
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    cln = ngx_pool_cleanup_add(cf->pool, 0);
    if (cln == NULL) {
        ngx_ssl_cleanup_ctx(uwcf->upstream.ssl);
        return NGX_ERROR;
    }

    cln->handler = ngx_ssl_cleanup_ctx;
    cln->data = uwcf->upstream.ssl;

    if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers, 0)
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    if (uwcf->upstream.ssl_certificate
        && uwcf->upstream.ssl_certificate->value.len)
    {
        if (uwcf->upstream.ssl_certificate_key == NULL) {
            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                          "no \"uwsgi_ssl_certificate_key\" is defined "
                          "for certificate \"%V\"",
                          &uwcf->upstream.ssl_certificate->value);
            return NGX_ERROR;
        }

        if (uwcf->upstream.ssl_certificate->lengths
            || uwcf->upstream.ssl_certificate_key->lengths)
        {
            uwcf->upstream.ssl_passwords =
                  ngx_ssl_preserve_passwords(cf, uwcf->upstream.ssl_passwords);
            if (uwcf->upstream.ssl_passwords == NULL) {
                return NGX_ERROR;
            }

        } else {
            if (ngx_ssl_certificate(cf, uwcf->upstream.ssl,
                                    &uwcf->upstream.ssl_certificate->value,
                                    &uwcf->upstream.ssl_certificate_key->value,
                                    uwcf->upstream.ssl_passwords)
                != NGX_OK)
            {
                return NGX_ERROR;
            }
        }
    }

    if (uwcf->upstream.ssl_verify) {
        if (uwcf->ssl_trusted_certificate.len == 0) {
            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                      "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify");
            return NGX_ERROR;
        }

        if (ngx_ssl_trusted_certificate(cf, uwcf->upstream.ssl,
                                        &uwcf->ssl_trusted_certificate,
                                        uwcf->ssl_verify_depth)
            != NGX_OK)
        {
            return NGX_ERROR;
        }

        if (ngx_ssl_crl(cf, uwcf->upstream.ssl, &uwcf->ssl_crl) != NGX_OK) {
            return NGX_ERROR;
        }
    }

    if (ngx_ssl_client_session_cache(cf, uwcf->upstream.ssl,
                                     uwcf->upstream.ssl_session_reuse)
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    if (ngx_ssl_conf_commands(cf, uwcf->upstream.ssl, uwcf->ssl_conf_commands)
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    return NGX_OK;
}

#endif