示例#1
0
static u_char *
ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
    ngx_http_log_op_t *op)
{
    ngx_time_t      *tp;
    ngx_msec_int_t   ms;

    tp = ngx_timeofday();

    ms = (ngx_msec_int_t)
             ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
    ms = ngx_max(ms, 0);

    return ngx_sprintf(buf, "%T.%03M", ms / 1000, ms % 1000);
}
示例#2
0
static void ngx_http_sla_init_quantiles (const ngx_http_sla_pool_t* pool, ngx_http_sla_pool_shm_t* counter)
{
    double            r;
    ngx_uint_t        i;
    ngx_uint_t        j;
    ngx_uint_t        quantile_diff[NGX_HTTP_SLA_MAX_QUANTILES_LEN];
    const ngx_uint_t* quantile;

    /* 1. Set the initial estimate S equal to the q-th sample quantile */
    ngx_qsort(counter->quantiles_fifo, NGX_HTTP_SLA_QUANTILE_M, sizeof(ngx_uint_t), ngx_http_sla_compare_uint);

    quantile = pool->quantiles.elts;
    for (i = 0; i < pool->quantiles.nelts; i++) {
        counter->quantiles[i] = counter->quantiles_fifo[NGX_HTTP_SLA_QUANTILE_M * quantile[i] / 100];
    }

    /* 2.1. Estimate the scale r by the difference of the 75 and 25 sample quantiles */
    r = ngx_max(
        (double)0.001,
        (double)(
            counter->quantiles_fifo[NGX_HTTP_SLA_QUANTILE_M * 75 / 100] -
            counter->quantiles_fifo[NGX_HTTP_SLA_QUANTILE_M * 25 / 100]
        )
    );

    /* 2.2. Than take c */
    counter->quantiles_c = 0;
    for (i = 0; i < NGX_HTTP_SLA_QUANTILE_M; i++) {
        counter->quantiles_c += (double)1 / sqrt(i + 1);
    }

    counter->quantiles_c = r / (double)NGX_HTTP_SLA_QUANTILE_M * counter->quantiles_c;

    /* 3. Take f */
    ngx_memzero(quantile_diff, sizeof(ngx_uint_t) * NGX_HTTP_SLA_MAX_QUANTILES_LEN);

    for (i = 0; i < NGX_HTTP_SLA_QUANTILE_M; i++) {
        for (j = 0; j < pool->quantiles.nelts; j++) {
            if (abs((double)counter->quantiles_fifo[i] - counter->quantiles[j]) <= counter->quantiles_c) {
                quantile_diff[j]++;
            }
        }
    }

    for (i = 0; i < pool->quantiles.nelts; i++) {
        counter->quantiles_f[i] = (double)1 / ((double)2 * counter->quantiles_c * (double)NGX_HTTP_SLA_QUANTILE_M) * (double)ngx_max(1, quantile_diff[i]);
    }
}
示例#3
0
static u_char *
ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
    ngx_http_log_op_t *op)
{
		syslog(LOG_INFO, "[%s:%s:%d]", __FILE__, __func__, __LINE__);
    ngx_time_t      *tp;
    ngx_msec_int_t   ms;

    tp = ngx_timeofday();

    ms = (ngx_msec_int_t)
             ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
    ms = ngx_max(ms, 0);

    return ngx_sprintf(buf, "%T.%03M", ms / 1000, ms % 1000);
}
示例#4
0
static void ngx_http_sla_update_quantiles (const ngx_http_sla_pool_t* pool, ngx_http_sla_pool_shm_t* counter)
{
    double            r;
    ngx_uint_t        i;
    ngx_uint_t        j;
    ngx_uint_t        quantile_25;
    ngx_uint_t        quantile_75;
    ngx_uint_t        quantile_diff[NGX_HTTP_SLA_MAX_QUANTILES_LEN];
    ngx_uint_t        quantile_less[NGX_HTTP_SLA_MAX_QUANTILES_LEN];
    const ngx_uint_t* quantile;

    /* 1 and 2. Updating */
    ngx_memzero(quantile_diff, sizeof(ngx_uint_t) * NGX_HTTP_SLA_MAX_QUANTILES_LEN);
    ngx_memzero(quantile_less, sizeof(ngx_uint_t) * NGX_HTTP_SLA_MAX_QUANTILES_LEN);

    for (i = 0; i < NGX_HTTP_SLA_QUANTILE_M; i++) {
        for (j = 0; j < pool->quantiles.nelts; j++) {
            if ((double)counter->quantiles_fifo[i] <= counter->quantiles[j]) {
                quantile_less[j]++;
            }
            if (abs((double)counter->quantiles_fifo[i] - counter->quantiles[j]) <= counter->quantiles_c) {
                quantile_diff[j]++;
            }
        }
    }

    quantile = pool->quantiles.elts;
    for (i = 0; i < pool->quantiles.nelts; i++) {
        counter->quantiles[i]   = counter->quantiles[i] + NGX_HTTP_SLA_QUANTILE_W / counter->quantiles_f[i] * ((double)quantile[i] / (double)100 - (double)quantile_less[i] / (double)NGX_HTTP_SLA_QUANTILE_M);
        counter->quantiles_f[i] = ((double)1 - NGX_HTTP_SLA_QUANTILE_W) * counter->quantiles_f[i] + NGX_HTTP_SLA_QUANTILE_W / ((double)2 * counter->quantiles_c * (double)NGX_HTTP_SLA_QUANTILE_M) * (double)quantile_diff[i];
    }

    /* 3.1. Take r to be the difference of the current EWSA estimates for the 75 and 25 quantiles */
    for (i = 0; i < pool->quantiles.nelts; i++) {
        if (quantile[i] == 25) {
            quantile_25 = counter->quantiles[i];
        } else if (quantile[i] == 75) {
            quantile_75 = counter->quantiles[i];
            break;
        }
    }

    r = ngx_max((double)0.001, (double)(quantile_75 - quantile_25));

    /* 3.2. Take c to the next M observations */
    counter->quantiles_c = r * ngx_http_sla_quantile_cc;
}
ngx_int_t
ngx_http_statu_update_requesttime(ngx_http_request_t *r)

{
	ngx_time_t                *tp;
    ngx_msec_int_t             ms;
    
    tp = ngx_timeofday();

    ms = (ngx_msec_int_t)
         ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));

    ms = ngx_max(ms, 0);
	
/*	(void) ngx_atomic_fetch_add(ngx_stat_requesttime, ms);
*/
    return NGX_OK;
示例#6
0
static void
ngx_http_sub_init_tables(ngx_http_sub_tables_t *tables,
                         ngx_http_sub_match_t *match, ngx_uint_t n)
{
    u_char      c;
    ngx_uint_t  i, j, min, max, ch;

    min = match[0].match.len;
    max = match[0].match.len;

    for (i = 1; i < n; i++) {
        min = ngx_min(min, match[i].match.len);
        max = ngx_max(max, match[i].match.len);
    }

    tables->min_match_len = min;
    tables->max_match_len = max;

    ngx_http_sub_cmp_index = tables->min_match_len - 1;
    ngx_sort(match, n, sizeof(ngx_http_sub_match_t), ngx_http_sub_cmp_matches);

    min = ngx_min(min, 255);
    ngx_memset(tables->shift, min, 256);

    ch = 0;

    for (i = 0; i < n; i++) {

        for (j = 0; j < min; j++) {
            c = match[i].match.data[tables->min_match_len - 1 - j];
            tables->shift[c] = ngx_min(tables->shift[c], (u_char) j);
        }

        c = match[i].match.data[tables->min_match_len - 1];
        while (ch <= (ngx_uint_t) c) {
            tables->index[ch++] = (u_char) i;
        }
    }

    while (ch < 257) {
        tables->index[ch++] = (u_char) n;
    }
}
static ngx_int_t
ngx_http_req_status_log_handler(ngx_http_request_t *r)
{
    // off_t                                   bytes;
    ngx_uint_t                              i;
    // ngx_msec_t                              td;
    ngx_http_req_status_ctx_t              *r_ctx;
    ngx_http_req_status_data_t             *data;
    ngx_http_req_status_zone_node_t        *pzn;
    // ngx_http_req_status_main_conf_t        *rmcf;

    ngx_time_t                   *tp;
    ngx_msec_int_t                ms;
    r_ctx = ngx_http_get_module_ctx(r, ngx_http_req_status_module);
    if (r_ctx == NULL || r_ctx->req_zones.nelts == 0){
        return NGX_DECLINED;
    }

    // rmcf = ngx_http_get_module_main_conf(r, ngx_http_req_status_module);

    pzn = r_ctx->req_zones.elts;

    for (i = 0; i < r_ctx->req_zones.nelts; i++){
        data = &pzn[i].node->data;

        ngx_shmtx_lock(&pzn[i].zone->shpool->mutex);

        // add response time
        tp = ngx_timeofday();
        ms = (ngx_msec_int_t)
             ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
        ms = ngx_max(ms, 0);
        data->rt += ms;
        // add response time

        ngx_shmtx_unlock(&pzn[i].zone->shpool->mutex);
    }

    return NGX_DECLINED;
}
void 
ngx_tcp_lua_log_session(ngx_tcp_session_t* s)
{
    ngx_time_t         *tp;
    ngx_msec_int_t      ms;
    ngx_connection_t   *c;

    if(s->log_handler){
        s->log_handler(s);
        return;
    }

    c = s->connection;

    ngx_time_update();//tmp
    tp = ngx_timeofday();

    ms = (ngx_msec_int_t)
             ((tp->sec - s->start_sec) * 1000 + (tp->msec - s->start_msec));
    ms = ngx_max(ms, 0);

    ngx_log_error(NGX_LOG_INFO, c->log, 0, "request time %T.%03M", ms / 1000, ms % 1000);
}
示例#9
0
static void
ngx_drain_connections(ngx_cycle_t *cycle)
{
    ngx_uint_t         i, n;
    ngx_queue_t       *q;
    ngx_connection_t  *c;

    n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1);

    for (i = 0; i < n; i++) {
        if (ngx_queue_empty(&cycle->reusable_connections_queue)) {
            break;
        }

        q = ngx_queue_last(&cycle->reusable_connections_queue);
        c = ngx_queue_data(q, ngx_connection_t, queue);

        ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
                       "reusing connection");

        c->close = 1;
        c->read->handler(c->read);
    }
}
示例#10
0
static u_char *
ngx_http_log_request_time_msec(ngx_http_request_t *r, u_char *buf,
    ngx_http_log_op_t *op)
{
    ngx_time_t                *tp;
    ngx_msec_int_t             ms;
    struct timeval             tv;
    ngx_http_core_loc_conf_t  *clcf;

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
    if (clcf->request_time_cache) {
        tp = ngx_timeofday();
        ms = (ngx_msec_int_t)
                 ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
    } else {
        ngx_gettimeofday(&tv);
        ms = (tv.tv_sec - r->start_sec) * 1000
                 + (tv.tv_usec / 1000 - r->start_msec);
    }

    ms = ngx_max(ms, 0);

    return ngx_sprintf(buf, "%T", ms);
}
示例#11
0
static ngx_int_t
ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx,
                   ngx_uint_t flush)
{
    u_char                   *p, c;
    ngx_str_t                *m;
    ngx_int_t                 offset, start, next, end, len, rc;
    ngx_uint_t                shift, i, j;
    ngx_http_sub_match_t     *match;
    ngx_http_sub_tables_t    *tables;
    ngx_http_sub_loc_conf_t  *slcf;

    slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
    tables = ctx->tables;
    match = ctx->matches->elts;

    offset = ctx->offset;
    end = ctx->buf->last - ctx->pos;

    if (ctx->once) {
        /* sets start and next to end */
        offset = end + (ngx_int_t) tables->min_match_len - 1;
        goto again;
    }

    while (offset < end) {

        c = offset < 0 ? ctx->looked.data[ctx->looked.len + offset]
            : ctx->pos[offset];

        c = ngx_tolower(c);

        shift = tables->shift[c];
        if (shift > 0) {
            offset += shift;
            continue;
        }

        /* a potential match */

        start = offset - (ngx_int_t) tables->min_match_len + 1;

        i = ngx_max((ngx_uint_t) tables->index[c], ctx->index);
        j = tables->index[c + 1];

        while (i != j) {

            if (slcf->once && ctx->sub && ctx->sub[i].data) {
                goto next;
            }

            m = &match[i].match;

            rc = ngx_http_sub_match(ctx, start, m);

            if (rc == NGX_DECLINED) {
                goto next;
            }

            ctx->index = i;

            if (rc == NGX_AGAIN) {
                goto again;
            }

            ctx->offset = offset + (ngx_int_t) m->len;
            next = start + (ngx_int_t) m->len;
            end = ngx_max(next, 0);
            rc = NGX_OK;

            goto done;

next:

            i++;
        }

        offset++;
        ctx->index = 0;
    }

    if (flush) {
        for ( ;; ) {
            start = offset - (ngx_int_t) tables->min_match_len + 1;

            if (start >= end) {
                break;
            }

            for (i = 0; i < ctx->matches->nelts; i++) {
                m = &match[i].match;

                if (ngx_http_sub_match(ctx, start, m) == NGX_AGAIN) {
                    goto again;
                }
            }

            offset++;
        }
    }

again:

    ctx->offset = offset;
    start = offset - (ngx_int_t) tables->min_match_len + 1;
    next = start;
    rc = NGX_AGAIN;

done:

    /* send [ - looked.len, start ] to client */

    ctx->saved.len = ctx->looked.len + ngx_min(start, 0);
    ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->saved.len);

    ctx->copy_start = ctx->pos;
    ctx->copy_end = ctx->pos + ngx_max(start, 0);

    /* save [ next, end ] in looked */

    len = ngx_min(next, 0);
    p = ctx->looked.data;
    p = ngx_movemem(p, p + ctx->looked.len + len, - len);

    len = ngx_max(next, 0);
    p = ngx_cpymem(p, ctx->pos + len, end - len);
    ctx->looked.len = p - ctx->looked.data;

    /* update position */

    ctx->pos += end;
    ctx->offset -= end;

    return rc;
}
static ngx_int_t
ngx_http_tfs_parse_read_meta_message(ngx_http_tfs_t *t)
{
    u_char                                          *p;
    int64_t                                          curr_length;
    uint16_t                                         type;
    uint32_t                                         count;
    uint64_t                                         end_offset;
    ngx_int_t                                        i, rc;
    ngx_str_t                                        action;
    ngx_http_tfs_header_t                           *header;
    ngx_http_tfs_segment_data_t                     *first_segment, *last_segment, *segment_data;
    ngx_http_tfs_file_hole_info_t                   *file_hole_info;
    ngx_http_tfs_peer_connection_t                  *tp;
    ngx_http_tfs_ms_read_response_t                 *resp;
    ngx_http_tfs_meta_frag_meta_info_t              *fmi;

    header = (ngx_http_tfs_header_t *) t->header;
    tp = t->tfs_peer;
    type = header->type;

    switch (type) {
    case NGX_HTTP_TFS_STATUS_MESSAGE:
        ngx_str_set(&action, "read file(meta server)");
        return ngx_http_tfs_status_message(&tp->body_buffer, &action, t->log);
    }

    resp = (ngx_http_tfs_ms_read_response_t *) tp->body_buffer.pos;

    count = resp->frag_info.frag_count & ~(1 << (sizeof(uint32_t) * 8 - 1));

    t->file.cluster_id = resp->frag_info.cluster_id;

    if (t->r_ctx.action.code == NGX_HTTP_TFS_ACTION_WRITE_FILE) {
        return NGX_OK;
    }

    if (count == 0) {
        return NGX_DECLINED;
    }

    if (t->file.segment_data == NULL) {
        t->file.segment_data = ngx_pcalloc(t->pool, sizeof(ngx_http_tfs_segment_data_t) * count);
        if (t->file.segment_data == NULL) {
            return NGX_ERROR;
        }
        /* the first semgent offset is special for pread */
        t->is_first_segment = NGX_HTTP_TFS_YES;

    } else {
        /* need realloc */
        if (count > t->file.segment_count) {
            t->file.segment_data = ngx_http_tfs_prealloc(t->pool,
                          t->file.segment_data,
                          sizeof(ngx_http_tfs_segment_data_t) * t->file.segment_count,
                          sizeof(ngx_http_tfs_segment_data_t) * count);
            if (t->file.segment_data == NULL) {
                return NGX_ERROR;
            }
        }
        /* reuse */
        ngx_memzero(t->file.segment_data, sizeof(ngx_http_tfs_segment_data_t) * count);
    }

    t->file.segment_count = count;
    t->file.still_have = resp->still_have ? :t->has_split_frag;
    t->file.segment_index = 0;

    p = tp->body_buffer.pos + sizeof(ngx_http_tfs_ms_read_response_t);
    fmi = (ngx_http_tfs_meta_frag_meta_info_t *) p;

    curr_length = 0;
    for (i = 0; i < count; i++, fmi++) {
        t->file.segment_data[i].segment_info.block_id = fmi->block_id;
        t->file.segment_data[i].segment_info.file_id = fmi->file_id;
        t->file.segment_data[i].segment_info.offset = fmi->offset;
        t->file.segment_data[i].segment_info.size = fmi->size;
        t->file.segment_data[i].oper_size = fmi->size;
    }

    /* the first semgent's oper_offset and oper_size are special for pread */
    if (t->r_ctx.action.code == NGX_HTTP_TFS_ACTION_READ_FILE) {
        first_segment = &t->file.segment_data[0];
        if (t->is_first_segment) {
            /* skip file hole */
            first_segment->oper_offset = ngx_max(t->r_ctx.offset, first_segment->segment_info.offset);
            if (first_segment->segment_info.offset > 0) {
                first_segment->oper_offset %= first_segment->segment_info.offset;
            }
            first_segment->oper_size =
                first_segment->segment_info.size - first_segment->oper_offset;
            t->is_first_segment = NGX_HTTP_TFS_NO;
            if (t->r_ctx.chk_file_hole) {
                rc = ngx_array_init(&t->file_holes, t->pool, NGX_HTTP_TFS_INIT_FILE_HOLE_COUNT,
                                    sizeof(ngx_http_tfs_file_hole_info_t));
                if (rc == NGX_ERROR) {
                    return NGX_ERROR;
                }
            }
        }

        /* last segment(also special) has been readed, set its oper_size*/
        /* notice that it maybe the same as first_segment */
        if (!t->file.still_have) {
            last_segment = &t->file.segment_data[count - 1];
            end_offset = t->file.file_offset + t->file.left_length;
            if (end_offset > ((uint64_t)last_segment->segment_info.offset + last_segment->oper_offset)) {
                last_segment->oper_size =
                    ngx_min((end_offset - (last_segment->segment_info.offset + last_segment->oper_offset)),
                            last_segment->segment_info.size);

            } else { /* end_offset in file hole */
                last_segment->oper_size = 0;
            }
        }

        /* check file hole */
        if (t->r_ctx.chk_file_hole) {
            segment_data = t->file.segment_data;
            for (i = 0; i < count; i++, segment_data++) {
                /* must be file hole, add to array */
                if (t->file.file_offset < segment_data->segment_info.offset) {
                    curr_length = ngx_min(t->file.left_length,
                                          (uint64_t)(segment_data->segment_info.offset - t->file.file_offset));
                    file_hole_info = ngx_array_push(&t->file_holes);
                    if (file_hole_info == NULL) {
                        return NGX_ERROR;
                    }

                    file_hole_info->offset = t->file.file_offset;
                    file_hole_info->length = curr_length;

                    ngx_log_error(NGX_LOG_DEBUG, t->log, 0,
                                  "find file hole, offset: %uL, length: %uL",
                                  file_hole_info->offset, file_hole_info->length);

                    t->file.file_offset += curr_length;
                    t->file.left_length -= curr_length;
                    if (t->file.left_length == 0) {
                        return NGX_DECLINED;
                    }
                }
                t->file.file_offset += segment_data->oper_size;
                t->file.left_length -= segment_data->oper_size;
                if (t->file.left_length == 0) {
                    return NGX_DECLINED;
                }
            }
            return NGX_OK;
        }
    }

#if (NGX_DEBUG)
    for (i = 0; i < count; i++) {
        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, t->log, 0,
                       "segment index: %d, oper_offset: %uD, oper_size: %uD",
                       i, t->file.segment_data[i].oper_offset, t->file.segment_data[i].oper_size);
    }
#endif

    ngx_log_error(NGX_LOG_DEBUG, t->log, 0,
                  "still_have is %d, frag count is %d",
                  t->file.still_have, count);

    return NGX_OK;
}
static size_t
ngx_rtmp_log_var_context_cstring_getlen(ngx_rtmp_session_t *s,
    ngx_rtmp_log_op_t *op)
{
    return ngx_max(NGX_RTMP_MAX_NAME, NGX_RTMP_MAX_ARGS);
}
static void
ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
{
#if OPENSSL_VERSION_NUMBER >= 0x0090707fL
    const
#endif
    u_char                *p;
    int                    n;
    size_t                 len;
    time_t                 now, valid;
    ngx_str_t              response;
    X509_STORE            *store;
    STACK_OF(X509)        *chain;
    OCSP_CERTID           *id;
    OCSP_RESPONSE         *ocsp;
    OCSP_BASICRESP        *basic;
    ngx_ssl_stapling_t    *staple;
    ASN1_GENERALIZEDTIME  *thisupdate, *nextupdate;

    staple = ctx->data;
    now = ngx_time();
    ocsp = NULL;
    basic = NULL;
    id = NULL;

    if (ctx->code != 200) {
        goto error;
    }

    /* check the response */

    len = ctx->response->last - ctx->response->pos;
    p = ctx->response->pos;

    ocsp = d2i_OCSP_RESPONSE(NULL, &p, len);
    if (ocsp == NULL) {
        ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
                      "d2i_OCSP_RESPONSE() failed");
        goto error;
    }

    n = OCSP_response_status(ocsp);

    if (n != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
                      "OCSP response not successful (%d: %s)",
                      n, OCSP_response_status_str(n));
        goto error;
    }

    basic = OCSP_response_get1_basic(ocsp);
    if (basic == NULL) {
        ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
                      "OCSP_response_get1_basic() failed");
        goto error;
    }

    store = SSL_CTX_get_cert_store(staple->ssl_ctx);
    if (store == NULL) {
        ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
                      "SSL_CTX_get_cert_store() failed");
        goto error;
    }

#if OPENSSL_VERSION_NUMBER >= 0x10001000L
    SSL_CTX_get_extra_chain_certs(staple->ssl_ctx, &chain);
#else
    chain = staple->ssl_ctx->extra_certs;
#endif

    if (OCSP_basic_verify(basic, chain, store,
                          staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY)
        != 1)
    {
        ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
                      "OCSP_basic_verify() failed");
        goto error;
    }

    id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
    if (id == NULL) {
        ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
                      "OCSP_cert_to_id() failed");
        goto error;
    }

    if (OCSP_resp_find_status(basic, id, &n, NULL, NULL,
                              &thisupdate, &nextupdate)
        != 1)
    {
        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
                      "certificate status not found in the OCSP response");
        goto error;
    }

    if (n != V_OCSP_CERTSTATUS_GOOD) {
        ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
                      "certificate status \"%s\" in the OCSP response",
                      OCSP_cert_status_str(n));
        goto error;
    }

    if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) {
        ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
                      "OCSP_check_validity() failed");
        goto error;
    }

    if (nextupdate) {
        valid = ngx_ssl_stapling_time(nextupdate);
        if (valid == (time_t) NGX_ERROR) {
            ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
                          "invalid nextUpdate time in certificate status");
            goto error;
        }

    } else {
        valid = NGX_MAX_TIME_T_VALUE;
    }

    OCSP_CERTID_free(id);
    OCSP_BASICRESP_free(basic);
    OCSP_RESPONSE_free(ocsp);

    id = NULL;
    basic = NULL;
    ocsp = NULL;

    /* copy the response to memory not in ctx->pool */

    response.len = len;
    response.data = ngx_alloc(response.len, ctx->log);

    if (response.data == NULL) {
        goto error;
    }

    ngx_memcpy(response.data, ctx->response->pos, response.len);

    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
                   "ssl ocsp response, %s, %uz",
                   OCSP_cert_status_str(n), response.len);

    if (staple->staple.data) {
        ngx_free(staple->staple.data);
    }

    staple->staple = response;
    staple->valid = valid;

    /*
     * refresh before the response expires,
     * but not earlier than in 5 minutes, and at least in an hour
     */

    staple->loading = 0;
    staple->refresh = ngx_max(ngx_min(valid - 300, now + 3600), now + 300);

    ngx_ssl_ocsp_done(ctx);
    return;

error:

    staple->loading = 0;
    staple->refresh = now + 300;

    if (id) {
        OCSP_CERTID_free(id);
    }

    if (basic) {
        OCSP_BASICRESP_free(basic);
    }

    if (ocsp) {
        OCSP_RESPONSE_free(ocsp);
    }

    ngx_ssl_ocsp_done(ctx);
}
ngx_int_t
ngx_http_secure_token_url_state_machine(
	ngx_http_request_t* r,
	ngx_http_secure_token_processor_conf_t* conf,
	ngx_http_secure_token_base_ctx_t* ctx,
	u_char** cur_pos,
	u_char* buffer_end,
	ngx_http_secure_token_processor_output_t* output)
{
	ngx_int_t rc;
	u_char* new_uri_path;
	u_char ch;

	for (; (*cur_pos) < buffer_end; (*cur_pos)++)
	{
		ch = **cur_pos;

		if (ch == ctx->url_end_char || (isspace(ch) && ctx->url_end_char == 0))
		{
			// end of url
			if (conf->encrypt_uri && ctx->state == STATE_URL_PATH)
			{
				output->copy_input = 0;

				rc = ngx_http_secure_token_encrypt_uri(r, &ctx->uri_path, &output->output_buffer);
				if (rc != NGX_OK)
				{
					return NGX_ERROR;
				}
			}

			if (ctx->tokenize)
			{
				if (ctx->state == STATE_URL_QUERY)
				{
					if (ctx->last_url_char == '?' || ctx->last_url_char == '&')
					{
						output->token_index = TOKEN_PREFIX_NONE;
					}
					else
					{
						output->token_index = TOKEN_PREFIX_AMPERSAND;
					}
				}
				else
				{
					output->token_index = TOKEN_PREFIX_QUESTION;
				}
			}

			ctx->last_url_char = ch;
			ctx->state = ctx->url_end_state;
			
			return NGX_OK;
		}

		switch (ctx->state)
		{
		case STATE_URL_SCHEME:
			if (ch == scheme_delimeter[ctx->scheme_pos])
			{
				ctx->scheme_pos++;
				if (ctx->scheme_pos >= sizeof(scheme_delimeter) - 1)
				{
					ctx->state = STATE_URL_HOST;
				}
			}
			else
			{
				ctx->scheme_pos = 0;
			}
			break;

		case STATE_URL_HOST:
			if (ch != '/')
			{
				break;
			}

			ctx->state = STATE_URL_PATH;
			ctx->uri_path.len = 0;
			ctx->last_url_char = ch;

			if (conf->encrypt_uri)
			{
				// flush any buffered data before starting to process the encrypted part
				return NGX_OK;
			}
			// fallthrough

		case STATE_URL_PATH:
			ctx->last_url_char = ch;

			if (ch != '?')
			{
				if (conf->encrypt_uri)
				{
					if (ctx->uri_path.len >= ctx->uri_path_alloc_size)
					{
						ctx->uri_path_alloc_size = ngx_max(ctx->uri_path_alloc_size * 2, 1024);

						new_uri_path = ngx_pnalloc(r->pool, ctx->uri_path_alloc_size);
						if (new_uri_path == NULL)
						{
							return NGX_ERROR;
						}

						ngx_memcpy(new_uri_path, ctx->uri_path.data, ctx->uri_path.len);
						ctx->uri_path.data = new_uri_path;
					}

					ctx->uri_path.data[ctx->uri_path.len] = ch;
					ctx->uri_path.len++;

					output->copy_input = 0;
				}
				break;
			}

			ctx->state = STATE_URL_QUERY;

			if (conf->encrypt_uri)
			{
				return ngx_http_secure_token_encrypt_uri(r, &ctx->uri_path, &output->output_buffer);
			}
			break;

		case STATE_URL_QUERY:
			ctx->last_url_char = ch;
			break;
		}
	}

	return NGX_OK;
}
static u_char *
ngx_http_vhost_traffic_status_display_set_upstream_group(ngx_http_request_t *r,
        ngx_rbtree_t *rbtree, const char *fmt, u_char *buf,
        ngx_http_vhost_traffic_status_loc_conf_t *vtscf)
{
    size_t                                  len;
    u_char                                  *p, *o, *s;
    uint32_t                                hash;
    ngx_uint_t                              i, j;
    ngx_str_t                               key;
    ngx_rbtree_node_t                       *node;
    ngx_http_upstream_server_t              *us;
    ngx_http_upstream_main_conf_t           *umcf;
    ngx_http_upstream_srv_conf_t            *uscf, **uscfp;
    ngx_http_vhost_traffic_status_node_t    *vtsn;

    umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
    uscfp = umcf->upstreams.elts;

    len = 0;
    for (i = 0; i < umcf->upstreams.nelts; i++) {
        uscf = uscfp[i];
        len = ngx_max(uscf->host.len, len);
    }

    key.len = len + sizeof("@[ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]:65535") - 1;
    key.data = ngx_pnalloc(r->pool, key.len);
    if (key.data == NULL) {
        return buf;
    }

    p = key.data;

    for (i = 0; i < umcf->upstreams.nelts; i++) {

        uscf = uscfp[i];

        /* groups */
        if (uscf->servers && !uscf->port) {
            us = uscf->servers->elts;

            o = buf;

            buf = ngx_sprintf(buf, NGX_HTTP_VHOST_TRAFFIC_STATUS_JSON_FMT_ARRAY_S,
                    &uscf->host);
            s = buf;

            for (j = 0; j < uscf->servers->nelts; j++) {

                p = ngx_cpymem(p, uscf->host.data, uscf->host.len);
                *p++ = '@';
                p = ngx_cpymem(p, us[j].addrs->name.data, us[j].addrs->name.len);
                key.len = uscf->host.len + sizeof("@") - 1 + us[j].addrs->name.len;
                hash = ngx_crc32_short(key.data, key.len);
                node = ngx_http_vhost_traffic_status_node_lookup(rbtree, &key, hash);

                if (node != NULL) {
                    vtsn = (ngx_http_vhost_traffic_status_node_t *) &node->color;
                    buf = ngx_sprintf(buf, fmt,
                    &us[j].addrs->name,
                    vtsn->stat_request_counter, vtsn->stat_in_bytes, vtsn->stat_out_bytes,
                    vtsn->stat_1xx_counter, vtsn->stat_2xx_counter, vtsn->stat_3xx_counter,
                    vtsn->stat_4xx_counter, vtsn->stat_5xx_counter, vtsn->stat_upstream.rtms,
                    us[j].weight, us[j].max_fails, us[j].fail_timeout,
                    ngx_vhost_traffic_status_boolean_to_string(us[j].backup),
                    ngx_vhost_traffic_status_boolean_to_string(us[j].down));
                } else {
                    buf = ngx_sprintf(buf, fmt,
                    &us[j].addrs->name,
                    0, 0, 0,
                    0, 0, 0,
                    0, 0, (ngx_msec_t) 0,
                    us[j].weight, us[j].max_fails, us[j].fail_timeout,
                    ngx_vhost_traffic_status_boolean_to_string(us[j].backup),
                    ngx_vhost_traffic_status_boolean_to_string(us[j].down));
                }

                p = key.data;
            }

            if (s == buf) {
                buf = o;
            } else {
                buf--;
                buf = ngx_sprintf(buf, NGX_HTTP_VHOST_TRAFFIC_STATUS_JSON_FMT_ARRAY_E);
                buf = ngx_sprintf(buf, NGX_HTTP_VHOST_TRAFFIC_STATUS_JSON_FMT_NEXT);
            }
        }
    }

    /* alones */
    o = buf;

    ngx_str_set(&key, "::nogroups");

    buf = ngx_sprintf(buf, NGX_HTTP_VHOST_TRAFFIC_STATUS_JSON_FMT_ARRAY_S, &key);

    s = buf;

    buf = ngx_http_vhost_traffic_status_display_set_upstream_alone(r,
        rbtree->root, rbtree->sentinel, fmt, buf, vtscf);

    if (s == buf) {
        buf = o;
    } else {
        buf--;
        buf = ngx_sprintf(buf, NGX_HTTP_VHOST_TRAFFIC_STATUS_JSON_FMT_ARRAY_E);
        buf = ngx_sprintf(buf, NGX_HTTP_VHOST_TRAFFIC_STATUS_JSON_FMT_NEXT);
    }

    return buf;
}
示例#17
0
ngx_http_regex_t *
ngx_http_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc)
{
    u_char                     *p;
    size_t                      size;
    ngx_str_t                   name;
    ngx_uint_t                  i, n;
    ngx_http_variable_t        *v;
    ngx_http_regex_t           *re;
    ngx_http_regex_variable_t  *rv;
    ngx_http_core_main_conf_t  *cmcf;

    rc->pool = cf->pool;

    if (ngx_regex_compile(rc) != NGX_OK) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc->err);
        return NULL;
    }

    re = ngx_pcalloc(cf->pool, sizeof(ngx_http_regex_t));
    if (re == NULL) {
        return NULL;
    }

    re->regex = rc->regex;
    re->ncaptures = rc->captures;

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
    cmcf->ncaptures = ngx_max(cmcf->ncaptures, re->ncaptures);

    n = (ngx_uint_t) rc->named_captures;

    if (n == 0) {
        return re;
    }

    rv = ngx_palloc(rc->pool, n * sizeof(ngx_http_regex_variable_t));
    if (rv == NULL) {
        return NULL;
    }

    re->variables = rv;
    re->nvariables = n;
    re->name = rc->pattern;

    size = rc->name_size;
    p = rc->names;

    for (i = 0; i < n; i++) {
        rv[i].capture = 2 * ((p[0] << 8) + p[1]);

        name.data = &p[2];
        name.len = ngx_strlen(name.data);

        v = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
        if (v == NULL) {
            return NULL;
        }

        rv[i].index = ngx_http_get_variable_index(cf, &name);
        if (rv[i].index == NGX_ERROR) {
            return NULL;
        }

        v->get_handler = ngx_http_variable_not_found;

        p += size;
    }

    return re;
}
示例#18
0
static ngx_inline ngx_int_t
ngx_http_modsecurity_save_request_body(ngx_http_request_t *r)
{
    ngx_http_modsecurity_ctx_t    *ctx;
    apr_off_t                      content_length;
    ngx_buf_t                     *buf;
    ngx_http_core_srv_conf_t      *cscf;
    size_t                         size;
    ngx_http_connection_t         *hc;

    ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);

    apr_brigade_length(ctx->brigade, 0, &content_length);

    if (r->header_in->end - r->header_in->last >= content_length) {
        /* use r->header_in */

        if (ngx_buf_size(r->header_in)) {
            /* move to the end */
            ngx_memmove(r->header_in->pos + content_length,
                        r->header_in->pos,
                        ngx_buf_size(r->header_in));
        }

        if (apr_brigade_flatten(ctx->brigade,
                                (char *)r->header_in->pos,
                                (apr_size_t *)&content_length) != APR_SUCCESS) {
            return NGX_ERROR;
        }

        apr_brigade_cleanup(ctx->brigade);

        r->header_in->last += content_length;

        return NGX_OK;
    }

    if (ngx_buf_size(r->header_in)) {

        /*
         * ngx_http_set_keepalive will reuse r->header_in if
         * (r->header_in != c->buffer && r->header_in.last != r->header_in.end),
         * so we need this code block.
         * see ngx_http_set_keepalive, ngx_http_alloc_large_header_buffer
         */
        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

        size = ngx_max(cscf->large_client_header_buffers.size,
                       (size_t)content_length + ngx_buf_size(r->header_in));

        hc = r->http_connection;

#if defined(nginx_version) && nginx_version >= 1011011
        if (hc->free && size == cscf->large_client_header_buffers.size) {

            buf = hc->free->buf;
#else
        if (hc->nfree && size == cscf->large_client_header_buffers.size) {

            buf = hc->free[--hc->nfree];
#endif

            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "ModSecurity: use http free large header buffer: %p %uz",
                           buf->pos, buf->end - buf->last);

        } else if (hc->nbusy < cscf->large_client_header_buffers.num) {

            if (hc->busy == NULL) {
                hc->busy = ngx_palloc(r->connection->pool,
                                      cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
            }

            if (hc->busy == NULL) {
                return NGX_ERROR;
            } else {
                buf = ngx_create_temp_buf(r->connection->pool, size);
            }
        } else {
            /* TODO: how to deal this case ? */
            return NGX_ERROR;
        }

    } else {

        buf = ngx_create_temp_buf(r->pool, (size_t) content_length);
    }

    if (buf == NULL) {
        return NGX_ERROR;
    }

    if (apr_brigade_flatten(ctx->brigade, (char *)buf->pos,
                            (apr_size_t *)&content_length) != APR_SUCCESS) {
        return NGX_ERROR;
    }

    apr_brigade_cleanup(ctx->brigade);
    buf->last += content_length;

    ngx_memcpy(buf->last, r->header_in->pos, ngx_buf_size(r->header_in));
    buf->last += ngx_buf_size(r->header_in);

    r->header_in = buf;

    return NGX_OK;
}


static ngx_inline ngx_int_t
ngx_http_modsecurity_load_headers_out(ngx_http_request_t *r)
{

    ngx_http_modsecurity_ctx_t  *ctx;
    char                        *data;
    request_rec                 *req;
    ngx_http_variable_value_t   *vv;
    ngx_list_part_t             *part;
    ngx_table_elt_t             *h;
    ngx_uint_t                   i;
    char                        *key, *value;
    u_char                      *buf = NULL;
    size_t                       size = 0;

    ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
    req = ctx->req;

    req->status = r->headers_out.status;
    req->status_line = (char *)ngx_pstrdup0(r->pool, &r->headers_out.status_line);

    /* deep copy */
    part = &r->headers_out.headers.part;
    h = part->elts;

    for (i = 0; ; i++) {
        if (i >= part->nelts) {
            if (part->next == NULL)
                break;

            part = part->next;
            h = part->elts;
            i = 0;
        }
        size += h[i].key.len + h[i].value.len + 2;

        buf = ngx_palloc(r->pool, size);

        if (buf == NULL) {
            return NGX_ERROR;
        }

        key = (char *)buf;
        buf = ngx_cpymem(buf, h[i].key.data, h[i].key.len);
        *buf++ = '\0';

        value = (char *)buf;
        buf = ngx_cpymem(buf, h[i].value.data, h[i].value.len);
        *buf++ = '\0';

        apr_table_addn(req->headers_out, key, value);
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "ModSecurity: load headers out: \"%V: %V\"",
                       &h[i].key, &h[i].value);

    }

    for (i = 0; special_headers_out[i].name; i++) {

        vv = ngx_http_get_variable(r, &special_headers_out[i].variable_name,
                                   ngx_hash_key(special_headers_out[i].variable_name.data,
                                                special_headers_out[i].variable_name.len));

        if (vv && !vv->not_found) {

            data = ngx_palloc(r->pool, vv->len + 1);
            if (data == NULL) {
                return NGX_ERROR;
            }

            ngx_memcpy(data,vv->data, vv->len);
            data[vv->len] = '\0';

            apr_table_setn(req->headers_out, special_headers_out[i].name, data);
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "ModSecurity: load headers out: \"%s: %s\"",
                           special_headers_out[i].name, data);
        }
    }

    req->content_type = apr_table_get(ctx->req->headers_out, "Content-Type");
    req->content_encoding = apr_table_get(ctx->req->headers_out, "Content-Encoding");

    data = (char *)apr_table_get(ctx->req->headers_out, "Content-Languages");

    if(data != NULL)
    {
        ctx->req->content_languages = apr_array_make(ctx->req->pool, 1, sizeof(const char *));
        *(const char **)apr_array_push(ctx->req->content_languages) = data;
    }

    /* req->chunked = r->chunked; may be useless */
    req->clength = r->headers_out.content_length_n;
    req->mtime = apr_time_make(r->headers_out.last_modified_time, 0);

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "ModSecurity: load headers out done");

    return NGX_OK;
}
static ngx_int_t
ngx_http_reqstat_log_handler(ngx_http_request_t *r)
{
    u_char                       *p;
    ngx_int_t                    *indicator, iv;
    ngx_uint_t                    i, j, k, status, utries;
    ngx_time_t                   *tp;
    ngx_msec_int_t                ms, total_ms;
    ngx_shm_zone_t              **shm_zone, *z;
    ngx_http_reqstat_ctx_t       *ctx;
    ngx_http_reqstat_conf_t      *rcf;
    ngx_http_reqstat_store_t     *store;
    ngx_http_reqstat_rbnode_t    *fnode, **fnode_store;
    ngx_http_upstream_state_t    *state;
    ngx_http_variable_value_t    *v;

    switch (ngx_http_reqstat_check_enable(r, &rcf, &store)) {
        case NGX_ERROR:
            return NGX_ERROR;

        case NGX_DECLINED:
        case NGX_AGAIN:
            return NGX_OK;

        default:
            break;
    }

    shm_zone = rcf->monitor->elts;
    fnode_store = store->monitor_index.elts;
    for (i = 0; i < store->monitor_index.nelts; i++) {
        fnode = fnode_store[i];
        if (r->connection->requests == 1) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_CONN_TOTAL, 1);
        }

        ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_REQ_TOTAL, 1);
        ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_BYTES_IN,
                               ngx_http_request_received(r)
                                    - (store ? store->recv : 0));

        if (r->err_status) {
            status = r->err_status;

        } else if (r->headers_out.status) {
            status = r->headers_out.status;

        } else if (r->http_version == NGX_HTTP_VERSION_9) {
            status = 9;

        } else {
            status = 0;
        }

        if (status >= 200 && status < 300) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_2XX, 1);

            switch (status) {
            case 200:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_200, 1);
                break;

            case 206:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_206, 1);
                break;

            default:
                ngx_http_reqstat_count(fnode,
                                       NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1);
                break;
            }

        } else if (status >= 300 && status < 400) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_3XX, 1);

            switch (status) {
            case 302:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_302, 1);
                break;

            case 304:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_304, 1);
                break;

            default:
                ngx_http_reqstat_count(fnode,
                                       NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1);
                break;
            }

        } else if (status >= 400 && status < 500) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_4XX, 1);

            switch (status) {
            case 403:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_403, 1);
                break;

            case 404:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_404, 1);
                break;

            case 416:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_416, 1);
                break;

            case 499:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_499, 1);
                break;

            default:
                ngx_http_reqstat_count(fnode,
                                       NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1);
                break;
            }

        } else if (status >= 500 && status < 600) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_5XX, 1);

            switch (status) {
            case 500:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_500, 1);
                break;

            case 502:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_502, 1);
                break;

            case 503:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_503, 1);
                break;

            case 504:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_504, 1);
                break;

            case 508:
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_508, 1);
                break;

            default:
                ngx_http_reqstat_count(fnode,
                                       NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS, 1);
                break;
            }

        } else {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_STATUS, 1);

            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_DETAIL_STATUS,
                                   1);
        }

        /* response status of last upstream peer */

        if (r->upstream_states != NULL && r->upstream_states->nelts > 0) {
            ngx_http_upstream_state_t *state = r->upstream_states->elts;
            status = state[r->upstream_states->nelts - 1].status;

            if (status >= 400 && status < 500) {
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_4XX, 1);

            } else if (status >= 500 && status < 600) {
                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_5XX, 1);
            }
        }

        tp = ngx_timeofday();

        ms = (ngx_msec_int_t)
             ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
        ms = ngx_max(ms, 0);
        ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_RT, ms);

        if (r->upstream_states != NULL && r->upstream_states->nelts > 0) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_REQ, 1);

            j = 0;
            total_ms = 0;
            utries = 0;
            state = r->upstream_states->elts;

            for ( ;; ) {

                utries++;

#if nginx_version >= 1009002
                ms = state[j].response_time;
#else
                ms = (ngx_msec_int_t) (state[j].response_sec * 1000
                                               + state[j].response_msec);
#endif
                ms = ngx_max(ms, 0);
                total_ms += ms;

                if (++j == r->upstream_states->nelts) {
                    break;
                }

                if (state[j].peer == NULL) {
                    if (++j == r->upstream_states->nelts) {
                        break;
                    }
                }
            }

            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_RT,
                                   total_ms);
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_TRIES,
                                   utries);
        }

        z = shm_zone[i];
        ctx = z->data;

        if (ctx->user_defined) {
            indicator = ctx->user_defined->elts;
            for (j = 0; j < ctx->user_defined->nelts; j++) {
                v = ngx_http_get_indexed_variable(r, indicator[j]);
                if (v == NULL || v->not_found || !v->valid) {
                    ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
                                  "variable is uninitialized");
                    continue;
                }

                for (k = 0, p = v->data + v->len - 1; p >= v->data; p--) {
                    if (*p == '.') {
                        k = v->data + v->len - 1 - p;
                        continue;
                    }

                    if (*p < '0' || *p > '9') {
                        break;
                    }
                }

                p++;

                if (k) {
                    iv = ngx_atofp(p, v->data + v->len - p, k);

                } else {
                    iv = ngx_atoi(p, v->data + v->len - p);
                }

                if (iv == NGX_ERROR) {
                    continue;
                }

                ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_EXTRA(j), iv);
            }
        }
    }

    return NGX_OK;
}
static ngx_int_t
ngx_http_vhost_traffic_status_shm_add_upstream(ngx_http_request_t *r,
        ngx_http_vhost_traffic_status_ctx_t *ctx,
        ngx_http_core_srv_conf_t *cscf,
        ngx_http_vhost_traffic_status_loc_conf_t *vtscf)
{
    u_char                                      *p;
    size_t                                      size;
    uint32_t                                    hash;
    ngx_uint_t                                  i;
    ngx_msec_int_t                              ms;
    ngx_str_t                                   key;
    ngx_slab_pool_t                             *shpool;
    ngx_rbtree_node_t                           *node;
    ngx_http_vhost_traffic_status_node_t        *vtsn;
    ngx_http_upstream_srv_conf_t                *uscf;
    ngx_http_upstream_t                         *u;
    ngx_http_upstream_state_t                   *state;

    if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
        return NGX_OK;
    }

    u = r->upstream;

    if (u->resolved == NULL) {
        uscf = u->conf->upstream;
    } else {
        return NGX_ERROR;
    }

    state = r->upstream_states->elts;

    i = 0;
    ms = 0;
    for ( ;; ) {
        if (state[i].status) {
            ms += (ngx_msec_int_t)
                (state[i].response_sec * 1000 + state[i].response_msec);
        }
        if (++i == r->upstream_states->nelts) {
            break;
        }
    }
    ms = ngx_max(ms, 0);

    shpool = (ngx_slab_pool_t *) vtscf->shm_zone->shm.addr;

    key.len = (uscf->port ? 0 : uscf->host.len) + sizeof("@") - 1 + state[0].peer->len;
    key.data = ngx_pnalloc(r->pool, key.len);
    if (key.data == NULL) {
        return NGX_ERROR;
    }

    p = key.data;
    if (uscf->port) {
        *p++ = '@';
        p = ngx_cpymem(p, state[0].peer->data, state[0].peer->len);
    } else {
        p = ngx_cpymem(p, uscf->host.data, uscf->host.len);
        *p++ = '@';
        p = ngx_cpymem(p, state[0].peer->data, state[0].peer->len);
    }

    hash = ngx_crc32_short(key.data, key.len);

    if (vtscf->vtsn_upstream && vtscf->vtsn_hash == hash) {
        ngx_shmtx_lock(&shpool->mutex);

        ngx_vhost_traffic_status_node_set(r, vtscf->vtsn_upstream);

        vtscf->vtsn_upstream->stat_upstream.rtms = (ngx_msec_t) (vtscf->vtsn_upstream->stat_upstream.rtms + ms) / 2 +
            (vtscf->vtsn_upstream->stat_upstream.rtms + ms) % 2;

        ngx_shmtx_unlock(&shpool->mutex);
        return NGX_OK;
    }

    ngx_shmtx_lock(&shpool->mutex);

    node = ngx_http_vhost_traffic_status_node_lookup(ctx->rbtree, &key, hash);

    if (node == NULL) {
        size = offsetof(ngx_rbtree_node_t, color)
            + offsetof(ngx_http_vhost_traffic_status_node_t, data)
            + key.len;

        node = ngx_slab_alloc_locked(shpool, size);

        if (node == NULL) {
            ngx_shmtx_unlock(&shpool->mutex);
            return NGX_ERROR;
        }

        vtsn = (ngx_http_vhost_traffic_status_node_t *) &node->color;

        node->key = hash;

        vtsn->len = (u_char) key.len;
        ngx_vhost_traffic_status_node_init(r, vtsn);

        vtsn->stat_upstream.rtms = ms;
        vtsn->stat_upstream.type = uscf->port ?
            NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_UA :
            NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_UG;

        ngx_memcpy(vtsn->data, key.data, key.len);
        ngx_rbtree_insert(ctx->rbtree, node);
    } else {
        vtsn = (ngx_http_vhost_traffic_status_node_t *) &node->color;

        ngx_vhost_traffic_status_node_set(r, vtsn);

        vtsn->stat_upstream.rtms = (ngx_msec_t) (vtsn->stat_upstream.rtms + ms) / 2 +
            (vtsn->stat_upstream.rtms + ms) % 2;
    }

    vtscf->vtsn_upstream = vtsn;
    vtscf->vtsn_hash = hash;

    ngx_shmtx_unlock(&shpool->mutex);

    return NGX_OK;
}
static int
ngx_squ_file_write(squ_State *l)
{
    char                *errstr;
    size_t               size;
    u_char              *str;
    ngx_int_t            rc;
    ngx_buf_t           *b;
    ngx_file_t          *file;
    ngx_file_info_t      fi;
    ngx_squ_thread_t    *thr;
    ngx_squ_file_ctx_t  *ctx;

    thr = ngx_squ_thread(l);

    ngx_log_debug0(NGX_LOG_DEBUG_CORE, thr->log, 0, "squ file write");

    ctx = ngx_squ_file(l);

    file = &ctx->file;

    if (file->fd == NGX_INVALID_FILE) {
        errstr = "invalid fd";
        goto error;
    }

    ngx_memzero(&fi, sizeof(ngx_file_info_t));

    if (ngx_fd_info(file->fd, &fi) == NGX_FILE_ERROR) {
        ngx_log_error(NGX_LOG_ALERT, thr->log, ngx_errno,
                      ngx_fd_info_n " \"%V\" failed", &file->name);
        errstr = ngx_fd_info_n " failed";
        goto error;
    }

    size = (size_t) ngx_file_size(&fi);

    str = (u_char *) squL_checklstring(l, 2, &ctx->size);
    ctx->offset = squL_optint(l, 3, (squ_Integer) ctx->offset);

    if (ctx->offset < 0 || ctx->offset > size) {
        errstr = "invalid offset of the file";
        goto error;
    }

    b = ctx->out;

    if (b == NULL || (size_t) (b->end - b->start) < ctx->size) {
        if (b != NULL && (size_t) (b->end - b->start) > ctx->pool->max) {
            ngx_pfree(ctx->pool, b->start);
        }

        size = ngx_max(ngx_pagesize, ctx->size);

        b = ngx_create_temp_buf(ctx->pool, size);
        if (b == NULL) {
            errstr = "ngx_create_temp_buf() failed";
            goto error;
        }

        ctx->out = b;
    }

    ngx_memcpy(b->start, str, ctx->size);

    rc = ngx_squ_file_aio_write(thr, ctx);
    if (rc == NGX_AGAIN) {
        return squ_yield(l, 0);
    }

    return rc;

error:

    squ_pushboolean(l, 0);
    squ_pushstring(l, errstr);

    return 2;
}
static ngx_int_t
ngx_http_reqstat_log_handler(ngx_http_request_t *r)
{
    ngx_uint_t                    i, j, status, utries;
    ngx_time_t                   *tp;
    ngx_msec_int_t                ms, total_ms;
    ngx_http_reqstat_conf_t      *slcf;
    ngx_http_reqstat_rbnode_t    *fnode, **fnode_store;
    ngx_http_upstream_state_t    *state;
    ngx_http_reqstat_store_t     *store;

    slcf = ngx_http_get_module_loc_conf(r, ngx_http_reqstat_module);

    if (slcf->monitor == NULL) {
        return NGX_OK;
    }

    store = ngx_http_get_module_ctx(r, ngx_http_reqstat_module);

    if (store == NULL) {
        store = ngx_http_reqstat_create_store(r, slcf);
        if (store == NULL) {
            return NGX_ERROR;
        }
    } else {
        store = ngx_http_reqstat_lookup_fnode(r, slcf);
        if (store == NULL) {
            return NGX_ERROR;
        }
    }

    if (store->bypass) {
        return NGX_OK;
    }

    fnode_store = store->monitor_index.elts;
    for (i = 0; i < store->monitor_index.nelts; i++) {
        fnode = fnode_store[i];
        if (r->connection->requests == 1) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_CONN_TOTAL, 1);
        }

        ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_REQ_TOTAL, 1);
        ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_BYTES_IN,
                               r->connection->received
                                    - (store ? store->recv : 0) + store->bytes_in);
        ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_BYTES_OUT,
                               r->connection->sent
                                    - (store ? store->sent : 0));

        if (r->err_status) {
            status = r->err_status;

        } else if (r->headers_out.status) {
            status = r->headers_out.status;

        } else if (r->http_version == NGX_HTTP_VERSION_9) {
            status = 9;

        } else {
            status = 0;
        }

        if (status >= 200 && status < 300) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_2XX, 1);

        } else if (status >= 300 && status < 400) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_3XX, 1);

        } else if (status >= 400 && status < 500) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_4XX, 1);

        } else if (status >= 500 && status < 600) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_5XX, 1);

        } else {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_OTHER_STATUS, 1);
        }

        tp = ngx_timeofday();

        ms = (ngx_msec_int_t)
             ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
        ms = ngx_max(ms, 0);
        ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_RT, ms);

        if (r->upstream_states != NULL && r->upstream_states->nelts > 0) {
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_REQ, 1);

            j = 0;
            total_ms = 0;
            utries = 0;
            state = r->upstream_states->elts;

            for ( ;; ) {

                utries++;

                ms = (ngx_msec_int_t) (state[j].response_sec * 1000
                                               + state[j].response_msec);
                ms = ngx_max(ms, 0);
                total_ms += ms;

                if (++j == r->upstream_states->nelts) {
                    break;
                }

                if (state[j].peer == NULL) {
                    if (++j == r->upstream_states->nelts) {
                        break;
                    }
                }
            }

            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_RT,
                                   total_ms);
            ngx_http_reqstat_count(fnode, NGX_HTTP_REQSTAT_UPS_TRIES,
                                   utries);
        }
    }

    return NGX_OK;
}
示例#23
0
static ngx_inline ngx_int_t
ngx_http_modsecurity_save_request_body(ngx_http_request_t *r)
{
    ngx_http_modsecurity_ctx_t    *ctx;
    apr_off_t                      content_length;
    ngx_buf_t                     *buf;
    ngx_http_core_srv_conf_t      *cscf;
    size_t                         size;
    ngx_http_connection_t         *hc;

    ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);

    apr_brigade_length(ctx->brigade, 0, &content_length);

    if (r->header_in->end - r->header_in->last >= content_length) {
        /* use r->header_in */

        if (ngx_buf_size(r->header_in)) {
            /* move to the end */
            ngx_memmove(r->header_in->pos + content_length,
                        r->header_in->pos,
                        ngx_buf_size(r->header_in));
        }

        if (apr_brigade_flatten(ctx->brigade,
                                (char *)r->header_in->pos,
                                (apr_size_t *)&content_length) != APR_SUCCESS) {
            return NGX_ERROR;
        }

        apr_brigade_cleanup(ctx->brigade);

        r->header_in->last += content_length;

        return NGX_OK;
    }

    if (ngx_buf_size(r->header_in)) {

        /*
         * ngx_http_set_keepalive will reuse r->header_in if
         * (r->header_in != c->buffer && r->header_in.last != r->header_in.end),
         * so we need this code block.
         * see ngx_http_set_keepalive, ngx_http_alloc_large_header_buffer
         */
        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

        size = ngx_max(cscf->large_client_header_buffers.size,
                       (size_t)content_length + ngx_buf_size(r->header_in));

        hc = r->http_connection;

        if (hc->nfree && size == cscf->large_client_header_buffers.size) {

            buf = hc->free[--hc->nfree];

            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "ModSecurity: use http free large header buffer: %p %uz",
                           buf->pos, buf->end - buf->last);

        } else if (hc->nbusy < cscf->large_client_header_buffers.num) {

            if (hc->busy == NULL) {
                hc->busy = ngx_palloc(r->connection->pool,
                                      cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
            }

            if (hc->busy == NULL) {
                return NGX_ERROR;
            } else {
                buf = ngx_create_temp_buf(r->connection->pool, size);
            }
        } else {
            /* TODO: how to deal this case ? */
            return NGX_ERROR;
        }

    } else {

        buf = ngx_create_temp_buf(r->pool, (size_t) content_length);
    }

    if (buf == NULL) {
        return NGX_ERROR;
    }

    if (apr_brigade_flatten(ctx->brigade, (char *)buf->pos,
                            (apr_size_t *)&content_length) != APR_SUCCESS) {
        return NGX_ERROR;
    }

    apr_brigade_cleanup(ctx->brigade);
    buf->last += content_length;

    ngx_memcpy(buf->last, r->header_in->pos, ngx_buf_size(r->header_in));
    buf->last += ngx_buf_size(r->header_in);

    r->header_in = buf;

    return NGX_OK;
}
static SQInteger
ngx_squ_tcp_request_recv(HSQUIRRELVM v)
{
    char               *errstr;
    size_t              size;
    SQRESULT            rc;
    ngx_buf_t          *b;
    ngx_connection_t   *c;
    ngx_squ_thread_t   *thr;
    ngx_squ_tcp_ctx_t  *ctx;
    ngx_tcp_session_t  *s;

    thr = sq_getforeignptr(v);

    ngx_log_debug0(NGX_LOG_DEBUG_CORE, thr->log, 0, "squ tcp request recv");

    ctx = thr->module_ctx;
    s = ctx->s;
    c = s->connection;

    /* TODO: the arguments in squ stack */

    rc = sq_getinteger(v, 2, (SQInteger *) &size);

    b = s->buffer;

    if (b == NULL || (size_t) (b->end - b->start) < size) {
        if (b != NULL && (size_t) (b->end - b->start) > c->pool->max) {
            ngx_pfree(c->pool, b->start);
        }

        size = ngx_max(ngx_pagesize, size);

        b = ngx_create_temp_buf(c->pool, size);
        if (b == NULL) {
            errstr = "ngx_create_temp_buf() failed";
            goto error;
        }

        s->buffer = b;
    }

    b->last = b->pos;

    c->read->handler = ngx_squ_tcp_request_read_handler;
    c->write->handler = ngx_squ_tcp_request_dummy_handler;

    ctx->rc = 0;
    ctx->not_event = 1;

    ngx_squ_tcp_request_read_handler(c->read);

    ctx->not_event = 0;

    if (ctx->rc != NGX_AGAIN) {
        return ctx->rc;
    }

    return sq_suspendvm(v);

error:

    sq_pushbool(v, SQFalse);
#if 0
    sq_pushstring(, (SQChar *) errstr, -1);
#endif

    return 1;
}
示例#25
0
static ngx_int_t ngx_http_sla_processor (ngx_http_request_t* r)
{
    ngx_uint_t                 i;
    ngx_msec_int_t             ms;
    ngx_msec_int_t             time;
    ngx_uint_t                 status;
    ngx_str_t*                 alias;
    ngx_http_sla_pool_shm_t*   counter;
    ngx_http_sla_loc_conf_t*   config;
    ngx_http_upstream_state_t* state;

    config = ngx_http_get_module_loc_conf(r, ngx_http_sla_module);

    if (config->off != 0 || config->pool == NULL) {
        return NGX_OK;
    }

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "sla processor");

    ngx_shmtx_lock(&config->pool->shm_pool->mutex);

    if (config->pool->generation != config->pool->shm_ctx->generation) {
        ngx_shmtx_unlock(&config->pool->shm_pool->mutex);
        return NGX_OK;
    }

    /* суммарное время ответов апстримов */
    time = 0;

    if (r->upstream_states != NULL && r->upstream_states->nelts > 0) {
        state = r->upstream_states->elts;

        for (i = 0; i < r->upstream_states->nelts; i++) {
            if (state[i].peer == NULL || state[i].status < 100 || state[i].status > 599) {
                continue;
            }

            ms = (ngx_msec_int_t)(state[i].response_sec * 1000 + state[i].response_msec);
            ms = ngx_max(ms, 0);

            time += ms;

            alias = ngx_http_sla_get_alias(config->aliases, state[i].peer);
            if (alias == NULL) {
                alias = state[i].peer;
            }

            counter = ngx_http_sla_get_counter(config->pool, alias);
            if (counter == NULL) {
                ngx_shmtx_unlock(&config->pool->shm_pool->mutex);
                return NGX_ERROR;
            }

            ngx_http_sla_set_http_time(config->pool, counter, ms);
            ngx_http_sla_set_http_status(config->pool, counter, state[i].status);
        }
    }

    /* пул и счетчик по умолчанию */
    if (r->err_status) {
        status = r->err_status;
    } else if (r->headers_out.status) {
        status = r->headers_out.status;
    } else {
        status = 0;
    }

    ngx_http_sla_set_http_time(config->pool, config->pool->shm_ctx, time);
    ngx_http_sla_set_http_status(config->pool, config->pool->shm_ctx, status);

    ngx_shmtx_unlock(&config->pool->shm_pool->mutex);

    return NGX_OK;
}
示例#26
0
static ngx_int_t
ngx_stream_upstream_response_time_variable(ngx_stream_session_t *s,
    ngx_stream_variable_value_t *v, uintptr_t data)
{
    u_char                       *p;
    size_t                        len;
    ngx_uint_t                    i;
    ngx_msec_int_t                ms;
    ngx_stream_upstream_state_t  *state;

    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;

    if (s->upstream_states == NULL || s->upstream_states->nelts == 0) {
        v->not_found = 1;
        return NGX_OK;
    }

    len = s->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2);

    p = ngx_pnalloc(s->connection->pool, len);
    if (p == NULL) {
        return NGX_ERROR;
    }

    v->data = p;

    i = 0;
    state = s->upstream_states->elts;

    for ( ;; ) {

        if (data == 1) {
            if (state[i].first_byte_time == (ngx_msec_t) -1) {
                *p++ = '-';
                goto next;
            }

            ms = state[i].first_byte_time;

        } else if (data == 2 && state[i].connect_time != (ngx_msec_t) -1) {
            ms = state[i].connect_time;

        } else {
            ms = state[i].response_time;
        }

        ms = ngx_max(ms, 0);
        p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);

    next:

        if (++i == s->upstream_states->nelts) {
            break;
        }

        *p++ = ',';
        *p++ = ' ';
    }

    v->len = p - v->data;

    return NGX_OK;
}