ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: worker process xxxx exited on signal 11, отдача файлов



Падения повторились на "железной" машине
Без вирутозы.
Исходник в аттаче, версия 0.6.32
Подскажите, плиз, куда копать?

2008/10/9 Mikhail Eremin <meremin@xxxxxxxxx>
Запрос бы пошел в другой локэйшн...на стадии nginx.conf


On Thu, Oct 9, 2008 at 2:05 PM, Kirill A. Korinskiy <catap@xxxxxxxx> wrote:

>       // get position of hash ending slash
>       p = (u_char*)ngx_strchr(&baseURI.data[4], '/');
                                        ^^^^^^^
А где вы проверяете что выделили столько память? Может r->uri.len был вообще 1 символ?




/**
* @file ngx_http_ulink_module.c
**
* Custom module for processing unique links
*/

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

#include <openssl/rsa.h>
#include <openssl/md5.h>

static ngx_int_t
ngx_http_ulink_init(ngx_conf_t *cf);

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

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

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

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

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

static void*
ngx_http_ulink_create_loc_conf(ngx_conf_t *cf);

static char *
ngx_http_ulink_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);

static ngx_int_t
ngx_http_ulink_handler(ngx_http_request_t *r);


static ngx_int_t
ulink_userid_index;

static ngx_int_t
ulink_user_ip_index;

static ngx_int_t
ulink_user_agent_index;

//static int str_alloc_count = 0;
//static size_t str_alloc_size = 0;

int b64_decode( const char* str, unsigned char* space, int size );
int check_url_signature(char* signature, size_t size, size_t restsize, 
ngx_http_request_t *r);


typedef struct
{
        /// module enabled
        ngx_flag_t      enable;
        /// download host
        ngx_str_t downloadhost;
        /// database host
        ngx_str_t       logpath;
        /// database user
        ngx_str_t lockpath;
        // ASID
        ngx_str_t cookiename;
} ngx_http_ulink_loc_conf_t;

static ngx_http_module_t ngx_http_ulink_module_ctx =
{
        NULL,                          /* preconfiguration */
        NULL, //ngx_http_ulink_init,           /* postconfiguration */

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

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

        ngx_http_ulink_create_loc_conf,  /* create location configuration */
        ngx_http_ulink_merge_loc_conf /* merge location configuration */
};

static ngx_command_t  ngx_http_ulink_commands[] =
{
        { ngx_string("ulink"),
                NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
                ngx_http_ulink,
                NGX_HTTP_LOC_CONF_OFFSET,
                0,
                NULL },

        { ngx_string("ulink_downloadhost"),
                NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
                ngx_http_ulink_downloadhost,
                NGX_HTTP_LOC_CONF_OFFSET,
                0,
                NULL },

        { ngx_string("ulink_cookiename"),
                NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
                ngx_http_ulink_downloadhost,
                NGX_HTTP_LOC_CONF_OFFSET,
                0,
                NULL },


        { ngx_string("ulink_logpath"),
                NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
                ngx_http_ulink_logpath,
                NGX_HTTP_LOC_CONF_OFFSET,
                0,
                NULL },

        { ngx_string("ulink_lockpath"),
                NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
                ngx_http_ulink_lockpath,
                NGX_HTTP_LOC_CONF_OFFSET,
                0,
                NULL },

        ngx_null_command
};

ngx_module_t ngx_http_ulink_module =
{
        NGX_MODULE_V1,
        &ngx_http_ulink_module_ctx, /* module context */
        ngx_http_ulink_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 char *
ngx_http_ulink(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
        ngx_http_core_loc_conf_t  *clcf;
        ngx_http_ulink_loc_conf_t *cglcf = conf;

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

        cglcf->enable = 1;

        return NGX_CONF_OK;
}


static char *
ngx_http_ulink_cookiename( ngx_conf_t *cf, ngx_command_t *cmd, void *conf )
{
        ngx_http_ulink_loc_conf_t *cglcf = conf;
        ngx_str_t   *value;

        value = cf->args->elts;

        cglcf->cookiename = value[1];

        return NGX_CONF_OK;
}


static char *
ngx_http_ulink_downloadhost( ngx_conf_t *cf, ngx_command_t *cmd, void *conf )
{
        ngx_http_ulink_loc_conf_t *cglcf = conf;
        ngx_str_t   *value;

        value = cf->args->elts;

        cglcf->downloadhost = value[1];

        return NGX_CONF_OK;
}


static char *
ngx_http_ulink_logpath(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
        ngx_http_ulink_loc_conf_t *cglcf = conf;
        ngx_str_t   *value;

        value = cf->args->elts;

        cglcf->logpath = value[1];

        return NGX_CONF_OK;
}

static char *
ngx_http_ulink_lockpath(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
        ngx_http_ulink_loc_conf_t *cglcf = conf;
        ngx_str_t   *value;

        value = cf->args->elts;

        cglcf->lockpath = value[1];

        return NGX_CONF_OK;
}



/**
* Create local module configuration
* @param cf configuration
*/
static void *
ngx_http_ulink_create_loc_conf(ngx_conf_t *cf)
{
        ngx_http_ulink_loc_conf_t  *conf;

        conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ulink_loc_conf_t));

        if (conf == NULL)
        {
                return NGX_CONF_ERROR;
        }

        // disable by default
        conf->enable = 0;

        return conf;
}

static char *
ngx_http_ulink_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
        ngx_http_ulink_loc_conf_t *prev = parent;
        ngx_http_ulink_loc_conf_t *conf = child;

        ngx_conf_merge_str_value(conf->downloadhost, prev->downloadhost, 
"/private/");
        ngx_conf_merge_str_value(conf->logpath, prev->logpath, 
"/opt/nginx_ul/log/");
        ngx_conf_merge_str_value(conf->lockpath, prev->lockpath, 
"/tmp/nginx/lock/");
        ngx_conf_merge_str_value(conf->cookiename, prev->cookiename, "ASID");

        // userid variable for stats
        ngx_str_t uuid = ngx_string("ulink_userid");
        ulink_userid_index  = ngx_http_get_variable_index(cf, &uuid);

        if (ulink_userid_index == NGX_ERROR)
        {
                return NGX_CONF_ERROR;
        }

        // user ip variable
        ngx_str_t uuip = ngx_string("ulink_user_ip");

        ulink_user_ip_index  = ngx_http_get_variable_index(cf, &uuip);

        if (ulink_user_ip_index == NGX_ERROR)
        {
                return NGX_CONF_ERROR;
        }

        // User Agent variable
        ngx_str_t ulinkuseragent = ngx_string("ulink_user_agent");

        ulink_user_agent_index  = ngx_http_get_variable_index(cf, 
&ulinkuseragent);

        if (ulink_user_agent_index  == NGX_ERROR)
        {
                return NGX_CONF_ERROR;
        }

        return NGX_CONF_OK;
}

static ngx_int_t
ngx_http_ulink_error_404(ngx_http_request_t *r)
{
        r->headers_out.status = NGX_HTTP_NOT_FOUND;
        return NGX_HTTP_NOT_FOUND;
}

static ngx_int_t
ngx_http_ulink_init(ngx_conf_t *cf)
{
        return NGX_OK;
}


#define DUMP_STR(str, name) ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, 
name ": %s (%d, %d)", str.data, str.len, ngx_strlen(str.data))


static ngx_int_t
ngx_http_ulink_handler(ngx_http_request_t *r)
{
        ngx_http_ulink_loc_conf_t *ulink_config = NULL;
        ngx_http_variable_value_t *UlinkUserId = NULL;
        ngx_http_variable_value_t *UlinkUserIp = NULL;
        ngx_http_variable_value_t *UlinkUserAgent = NULL;

        u_char* p = NULL;

        ngx_str_t hash = {0, NULL};
        ngx_str_t file = {0, NULL};
        ngx_str_t uri = {0, NULL};
        
        ngx_str_t baseURI  = {0, NULL};

        ngx_str_t redirect_uri = {0, NULL};
        ngx_str_t redirect_test = {0, NULL};
        ngx_str_t args = {0, NULL};

        // userid
        ngx_str_t userid = {0, NULL};
        //user ip
        ngx_str_t userip = {0, NULL};
        // user agent
        ngx_str_t useragent = {0, NULL};
        ngx_int_t       n = 0;
        ngx_str_t cook = {0, NULL};


        ngx_str_t ngx_location = ngx_string("/opt/nginx");

        DUMP_STR(r->uri, "URI");
        
        baseURI.len = r->uri.len;
        
        baseURI.data = ngx_palloc(r->pool, baseURI.len + 1);
        
        if (baseURI.data == NULL)
        {
            return ngx_http_ulink_error_404(r);
        }
        
        ngx_memcpy(baseURI.data, r->uri.data, baseURI.len);
        
        DUMP_STR(baseURI, "baseURI");

        // get config
        ulink_config = ngx_http_get_module_loc_conf(r, ngx_http_ulink_module);
        UlinkUserId = ngx_http_get_indexed_variable(r, ulink_userid_index);
        UlinkUserIp = ngx_http_get_indexed_variable(r, ulink_user_ip_index);
        UlinkUserAgent = ngx_http_get_indexed_variable(r, 
ulink_user_agent_index);

        // process uri
        
        if (ngx_strlen(baseURI.data) < 4) 
        {
            return ngx_http_ulink_error_404(r);
        } 

        if (ngx_strncmp(baseURI.data, "/sl/", 4) != 0)
        {
                return ngx_http_ulink_error_404(r);
        }

        // get position of hash ending slash
        p = (u_char*)ngx_strchr(&baseURI.data[4], '/');

        if (p == NULL)
        {
                return ngx_http_ulink_error_404(r);
        }

        // calculate hash length
        hash.len = p - &baseURI.data[4];

        if (hash.len <= 0)
        {
                return ngx_http_ulink_error_404(r);
        }

        // get hash value
        hash.data = ngx_palloc(r->pool, hash.len + 1);

        if (hash.data == NULL)
        {
                return ngx_http_ulink_error_404(r);
        }

        ngx_memcpy(hash.data, &baseURI.data[4], hash.len);

        hash.data[hash.len] = 0x00;
        DUMP_STR(hash, "Hash");

        // calculate file name length
        file.len = (baseURI.data + baseURI.len - 1) - p;

        if (file.len <= 0)
        {
                return ngx_http_ulink_error_404(r);
        }

        // get file name
        file.data = ngx_palloc(r->pool, file.len + 1);

        if (file.data == NULL)
        {
                return ngx_http_ulink_error_404(r);
        }

        ngx_memcpy(file.data, p + 1, file.len);

        file.data[file.len] = 0x00;
        DUMP_STR(file, "File");

        p = NULL;

        // making URI with hash and file
        uri.len = hash.len + file.len + 1;
        uri.data = ngx_palloc(r->pool, uri.len + 1);

        if (uri.data == NULL)
        {
            return ngx_http_ulink_error_404(r);
        }

        p = ngx_cpymem(uri.data, hash.data, hash.len);
        p = ngx_cpymem(p, (u_char*)"/", 1);
        p = ngx_cpymem(p, file.data, file.len);
        
        uri.data[uri.len] = 0x00;       
//      *p = 0x00;

        p = NULL;

        //userid
        userid.len = UlinkUserId->len;

        if (userid.len <= 0)
        {
                userid.len=0;
        }

        userid.data = ngx_palloc(r->pool, userid.len + 1);

        if (userid.data == NULL)
        {
                return ngx_http_ulink_error_404(r);
        }

        ngx_memcpy(userid.data, UlinkUserId->data, userid.len);

        userid.data[userid.len] = 0x00;
        
        p = NULL;

        // lookup for cookie ASID
        n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, 
&ulink_config->cookiename, &cook);

        if (n != NGX_DECLINED)
        {
        
                userid.len = 32;
                userid.data = ngx_palloc(r->pool, 33);
                
                if (userid.data == NULL)
                {
                    return ngx_http_ulink_error_404(r);
                }
                
                ngx_memcpy(userid.data, &cook.data[0], userid.len);
                userid.data[userid.len] = 0x00;

        }

        DUMP_STR(userid, "USER ID");

        //user ip
        userip.len = UlinkUserIp->len;

        if (userip.len <= 0)
        {
                userip.len = 0;
        }

        userip.data = ngx_palloc(r->pool, userip.len + 1);

        if (userip.data == NULL)
        {
                return ngx_http_ulink_error_404(r);
        }

        ngx_memcpy(userip.data, UlinkUserIp->data, userip.len);

        userip.data[userip.len] = 0x00;

        DUMP_STR(userip, "User Ip");

        // user agent
        useragent.len = UlinkUserAgent->len;

        if (useragent.len <= 0)
        {
                useragent.len = 0;
        }

        useragent.data = ngx_palloc(r->pool, useragent.len + 1);

        if (useragent.data == NULL)
        {
                return ngx_http_ulink_error_404(r);;
        }

        ngx_memcpy(useragent.data, UlinkUserAgent->data, useragent.len);

        useragent.data[useragent.len] = 0x00;


        // create redirect uri
        redirect_uri.len = ulink_config->downloadhost.len + file.len;

        //redirect_uri.len = file.len + 10;
        redirect_uri.data = ngx_palloc(r->pool, redirect_uri.len + 1);

        if (redirect_uri.data == NULL) return ngx_http_ulink_error_404(r);

        p = ngx_cpymem(redirect_uri.data, ulink_config->downloadhost.data, 
ulink_config->downloadhost.len);

        p = ngx_cpymem(p , file.data, file.len);
        
        redirect_uri.data[redirect_uri.len] = 0x00;

        //*p = 0x00;
        p = NULL;

        args.len = 0;

        args.data = NULL;

        DUMP_STR(redirect_uri, "Redirecting");


        // must test for file exists
        redirect_test.len  = ngx_location.len + redirect_uri.len;

        redirect_test.data = ngx_palloc(r->pool, redirect_test.len + 1);

        if (redirect_test.data == NULL) return ngx_http_ulink_error_404(r);

        p = ngx_cpymem(redirect_test.data, ngx_location.data, ngx_location.len);

        p = ngx_cpymem(p , redirect_uri.data, redirect_uri.len);
        
        redirect_test.data[redirect_test.len] = 0x00;

        //*p = 0x00;
        
        p = NULL;

        DUMP_STR(redirect_test, "Real file path");

        FILE *testdnld = fopen((char *)redirect_test.data, "r");

        if (testdnld)
        {
                fclose(testdnld);
                ngx_http_internal_redirect(r, &redirect_uri, &args);
        }
        else
        {
                ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0,  "File not 
found! (%s)", redirect_test.data);
//              unlink((char *)lockfileName.data);
                return ngx_http_ulink_error_404(r);
        }

        return NGX_OK;
}





 




Copyright © Lexa Software, 1996-2009.