static ngx_int_t
ngx_http_data_dome_auth_handler(ngx_http_request_t *r)
{
    ngx_buf_t                       *b;
    ngx_int_t                        rc;
    ngx_str_t                        val;
    ngx_str_t                        x_datadome_response;
    ngx_uint_t                       i;
    ngx_chain_t                      out;
    ngx_list_part_t                 *part;
    ngx_table_elt_t                 *header;
    ngx_table_elt_t                 *location;
    ngx_http_data_dome_auth_ctx_t   *ctx;
    ngx_http_data_dome_auth_conf_t  *acf;

    // you can dissable this module in location or if level
    acf = ngx_http_get_module_loc_conf(r, ngx_http_data_dome_auth_module);

    if (acf->uri_lengths == NULL) {
  return NGX_DECLINED;
    }

    if (r->internal && acf->pass_internal_redirect) {
  return NGX_DECLINED;
    }

    // but module use main request context to keep the status
    // to prevent duplicated query to API server
    ctx = ngx_http_get_module_ctx(r->main, ngx_http_data_dome_auth_module);

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->main->connection->log, 0,
		   "Data Dome auth request handler, ctx: %p", ctx);

    if (ctx != NULL) {
    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->main->connection->log, 0,
		   "Data Dome auth request handler ctx: declined %d, processing: %d, done: %d",
		    ctx->declined, ctx->processing, ctx->done);

	if (ctx->declined) {
	    return NGX_DECLINED;
	}

	if (ctx->processing) {
	    return NGX_OK;
	}

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

    if (ngx_http_data_dome_auth_set_variables(r, acf, ctx) != NGX_OK) {
        return NGX_ERROR;
    }

	if (acf->learning) {
	    return NGX_OK;
	}

    if (ctx->subrequest_rc < NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    x_datadome_response.len = 0;

    part = &ctx->subrequest->headers_out.headers.part;
    header = part->elts;

    for (i = 0; /* void */ ; i++) {

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }

            part = part->next;
            header = part->elts;
            i = 0;
        }

        if (header[i].hash == 0) {
            continue;
        }

        if (header[i].key.len != sizeof("X-DataDomeResponse") - 1) {
            continue;
        }

        if (ngx_strncmp(header[i].key.data, "X-DataDomeResponse", header[i].key.len) != 0) {
            continue;
        }

        x_datadome_response = header[i].value;

        break;
    }

    if (x_datadome_response.len == 0) {
	    ngx_log_error(NGX_LOG_ERR, r->main->connection->log, 0, "API server response hasn't got X-DataDomeResponse");
	    return NGX_DECLINED;
    }

    if ((ngx_uint_t)ngx_atoi(x_datadome_response.data, x_datadome_response.len) != ctx->subrequest->headers_out.status) {
	    ngx_log_error(NGX_LOG_ERR, r->main->connection->log, 0, "API server response's X-DataDomeResponse (%V) != status (%d)",
	        &x_datadome_response, ctx->subrequest->headers_out.status);
	    return NGX_DECLINED;
    }

	if (ngx_http_data_dome_auth_execute_x_datadome_headers(r->main->pool, "X-DataDome-headers",
	                                                       &ctx->subrequest->headers_out.headers,
	                                                       &r->main->headers_out.headers) == NGX_ERROR) {
	    return NGX_ERROR;
	}

	if (ngx_http_data_dome_auth_execute_x_datadome_headers(r->main->pool, "X-DataDome-request-headers",
	                                                       &ctx->subrequest->headers_out.headers,
	                                                       &r->main->headers_in.headers) == NGX_ERROR) {
	    return NGX_ERROR;
	}

	switch (ctx->subrequest->headers_out.status) {
	case NGX_HTTP_MOVED_PERMANENTLY:
	case NGX_HTTP_MOVED_TEMPORARILY:
	case NGX_HTTP_UNAUTHORIZED:
	case NGX_HTTP_FORBIDDEN:

        part = &ctx->subrequest->headers_out.headers.part;
        header = part->elts;

        for (i = 0; /* void */ ; i++) {

            if (i >= part->nelts) {
                if (part->next == NULL) {
                  break;
                }

                part = part->next;
                header = part->elts;
                i = 0;
            }

            if (header[i].hash == 0) {
                continue;
            }

            if (header[i].key.len != sizeof("Location") - 1) {
                continue;
            }

            if (ngx_strncmp(header[i].key.data, "Location", header[i].key.len) != 0) {
                continue;
            }

            location = ngx_list_push(&r->main->headers_out.headers);
            if (location == NULL) {
              return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            location->hash = 1;
            location->key = header[i].key;
            location->lowcase_key = header[i].lowcase_key;
            location->value = header[i].value;

            break;
        }

	    // nginx reset upstream buffer length, so, use body lenght from header ;)
	    val.len = ctx->subrequest->headers_out.content_length_n;
	    val.data = ctx->subrequest->upstream->buffer.pos;

	    // if response hasn't Content-Length and body the length was -1, fix it
	    if (ctx->subrequest->headers_out.content_length_n < 0) {
	      val.len = 0;
	    }

	    if (val.len == 0) {
    	    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
	    		   "Data Dome auth send response without body: s: %d",
		    	   ctx->subrequest->headers_out.status);
            return ctx->subrequest->headers_out.status;
	    }

	    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
			   "Data Dome auth send response: s: %d, c: %V, b: %V",
			   ctx->subrequest->headers_out.status, &ctx->subrequest->headers_out.content_type, &val);

        r->headers_out.status = ctx->subrequest->headers_out.status;

        r->headers_out.content_length_n = val.len;

        if (ctx->subrequest->headers_out.content_type.len) {
            r->headers_out.content_type_len = ctx->subrequest->headers_out.content_type.len;
            r->headers_out.content_type = ctx->subrequest->headers_out.content_type;
        } else {
            if (ngx_http_set_content_type(r) != NGX_OK) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }
        }

        if (r->method == NGX_HTTP_HEAD || val.len == 0) {
            rc = ngx_http_send_header(r);
            if (rc != NGX_OK) {
                return rc;
            }

            return NGX_DONE;
        }

        b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
        if (b == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
        b->pos = val.data;
        b->last = val.data + val.len;
        b->memory = val.len ? 1 : 0;
        b->last_buf = (r == r->main) ? 1 : 0;
        b->last_in_chain = 1;

        out.buf = b;
        out.next = NULL;

        rc = ngx_http_send_header(r);

        if (rc == NGX_ERROR || rc > NGX_OK) {
            return rc;
        }

        if (r->header_only) {
            ngx_http_finalize_request(r, NGX_DONE);
            return NGX_DONE;
        }

        rc = ngx_http_output_filter(r, &out);
	    if (rc != NGX_OK) {
	      return rc;
	    }

        ngx_http_finalize_request(r, NGX_DONE);
	    return NGX_DONE;

	case NGX_HTTP_OK:

	    return NGX_OK;

	default:

	    ngx_log_error(NGX_LOG_ERR, r->main->connection->log, 0,
			  "Data Dome auth request unexpected status: %d, pass", ctx->subrequest->headers_out.status);

	    return NGX_OK;
	}
    }

    ctx = ngx_pcalloc(r->main->pool, sizeof(ngx_http_data_dome_auth_ctx_t));
    if (ctx == NULL) {
	return NGX_ERROR;
    }

    if (ngx_http_script_run(r, &ctx->uri, acf->uri_lengths->elts, 0, acf->uri_values->elts)
        == NULL)
    {
        return NGX_ERROR;
    }

    if (ngx_strncmp(ctx->uri.data, "off", ctx->uri.len) == 0) {
	    return NGX_DECLINED;
    }

    ngx_http_set_ctx(r->main, ctx, ngx_http_data_dome_auth_module);

#if (NGX_PCRE)

    if (acf->uri_regex_exclusion) {
        if (ngx_regex_exec(acf->uri_regex_exclusion, &r->main->uri, NULL, 0) != NGX_REGEX_NO_MATCHED) {

            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->main->connection->log, 0,
                  "Data Dome auth URI regex exclusion: \"%V\" match with URI: %V",
                   &acf->uri_regex_exclusion_raw, &r->main->uri);

            ctx->declined = 1;
            return NGX_DECLINED;
        }
    }

    if (acf->uri_regex) {

	if (ngx_regex_exec(acf->uri_regex, &r->main->uri, NULL, 0) != NGX_REGEX_NO_MATCHED) {

	    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->main->connection->log, 0,
			  "Data Dome auth URI regex: \"%V\" match with URI: %V",
			   &acf->uri_regex_raw, &r->main->uri);

	    goto validate;
	}

	ctx->declined = 1;
	return NGX_DECLINED;
    }

 validate:

#endif

    ctx->processing = 1;

    // keep original read and write event handler because read client body may override it
    ctx->read_event_handler = r->main->read_event_handler;
    ctx->write_event_handler = r->main->write_event_handler;

    return ngx_http_data_dome_subrequest(r);
}
예제 #2
0
ngx_int_t
ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
{
    ngx_int_t         n;
    ngx_uint_t        i;
    ngx_regex_elt_t  *re;

    re = a->elts;

    for (i = 0; i < a->nelts; i++) {

        n = ngx_regex_exec(re[i].regex, s, NULL, 0);

        if (n == NGX_REGEX_NO_MATCHED) {
            continue;
        }

        if (n < 0) {
            ngx_log_error(NGX_LOG_ALERT, log, 0,
                          ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"",
                          n, s, re[i].name);
            return NGX_ERROR;
        }

        /* match */

        return NGX_OK;
    }

    return NGX_DECLINED;
}
static ngx_int_t
ngx_http_data_dome_auth_is_uri_regex_matched(ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data)
{
    ngx_http_data_dome_auth_conf_t  *acf;

    acf = ngx_http_get_module_loc_conf(r, ngx_http_data_dome_auth_module);

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

    if (acf->uri_regex_exclusion) {
        if (ngx_regex_exec(acf->uri_regex_exclusion, &r->main->uri, NULL, 0) != NGX_REGEX_NO_MATCHED) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->main->connection->log, 0,
                           "Data Dome auth is uri regex exclusion matched; r->main->uri: %V, acf->uri_regex_exclusion: %V",
                           &r->main->uri, &acf->uri_regex_exclusion_raw);
            v->len = sizeof("0") - 1;
            v->data = (u_char *) "0";
            return NGX_OK;
        }
    }

    if (acf->uri_regex) {
        if (ngx_regex_exec(acf->uri_regex, &r->main->uri, NULL, 0) == NGX_REGEX_NO_MATCHED) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->main->connection->log, 0,
                           "Data Dome auth is uri regex matched var: uri isn't matched; r->main->uri: %V, acf->uri_regex: %V",
                           &r->main->uri, &acf->uri_regex_raw);
            v->len = sizeof("0") - 1;
            v->data = (u_char *) "0";
            return NGX_OK;
        } else {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->main->connection->log, 0,
                           "Data Dome auth is uri regex matched var: uri is matched; r->main->uri: %V, acf->uri_regex: %V",
                           &r->main->uri, &acf->uri_regex_raw);
            v->len = sizeof("1") - 1;
            v->data = (u_char *) "1";
            return NGX_OK;
        }
    }

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->main->connection->log, 0,
                   "Data Dome auth uri regex uri isn't set");
    v->len = sizeof("1") - 1;
    v->data = (u_char *) "1";
    return NGX_OK;
}
ngx_http_push_stream_requested_channel_t *
ngx_http_push_stream_parse_channels_ids_from_path(ngx_http_request_t *r, ngx_pool_t *pool) {
    ngx_http_push_stream_main_conf_t               *mcf = ngx_http_get_module_main_conf(r, ngx_http_push_stream_module);
    ngx_http_push_stream_loc_conf_t                *cf = ngx_http_get_module_loc_conf(r, ngx_http_push_stream_module);
    ngx_http_variable_value_t                      *vv_channels_path = ngx_http_get_indexed_variable(r, cf->index_channels_path);
    ngx_http_push_stream_requested_channel_t       *channels_ids, *cur;
    ngx_str_t                                       aux;
    int                                             captures[15];
    ngx_int_t                                       n;

    if (vv_channels_path == NULL || vv_channels_path->not_found || vv_channels_path->len == 0) {
        return NULL;
    }

    if ((channels_ids = ngx_pcalloc(pool, sizeof(ngx_http_push_stream_requested_channel_t))) == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: unable to allocate memory for channels_ids queue");
        return NULL;
    }

    ngx_queue_init(&channels_ids->queue);

    // doing the parser of given channel path
    aux.data = vv_channels_path->data;
    do {
        aux.len = vv_channels_path->len - (aux.data - vv_channels_path->data);
        if ((n = ngx_regex_exec(mcf->backtrack_parser_regex, &aux, captures, 15)) >= 0) {
            if ((cur = ngx_pcalloc(pool, sizeof(ngx_http_push_stream_requested_channel_t))) == NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: unable to allocate memory for channel_id item");
                return NULL;
            }

            if ((cur->id = ngx_http_push_stream_create_str(pool, captures[0])) == NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: unable to allocate memory for channel_id string");
                return NULL;
            }
            ngx_memcpy(cur->id->data, aux.data, captures[0]);
            cur->backtrack_messages = 0;
            if (captures[7] > captures[6]) {
                cur->backtrack_messages = ngx_atoi(aux.data + captures[6], captures[7] - captures[6]);
            }

            ngx_queue_insert_tail(&channels_ids->queue, &cur->queue);

            aux.data = aux.data + captures[1];
        }
    } while ((n != NGX_REGEX_NO_MATCHED) && (aux.data < (vv_channels_path->data + vv_channels_path->len)));

    return channels_ids;
}
예제 #5
0
ngx_int_t
ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s)
{//用已经编译的regex 跟e->line,也就是s去匹配,看看是否匹配成功。如果匹配成功,整理存放在r->variables里面、
    ngx_int_t                   rc, index;
    ngx_uint_t                  i, n, len;
    ngx_http_variable_value_t  *vv;
    ngx_http_core_main_conf_t  *cmcf;
    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
    if (re->ncaptures) {//根据ncaptures大小,申请内存用于存放正则匹配的结果。
        len = cmcf->ncaptures;
        if (r->captures == NULL) {
            r->captures = ngx_palloc(r->pool, len * sizeof(int));
            if (r->captures == NULL) {
                return NGX_ERROR;
            }
        }
    } else {
        len = 0;
    }
	//进行正则匹配,结果存放在captures里面,2个槽位为单位,[beg,end], [beg,end]
    rc = ngx_regex_exec(re->regex, s, r->captures, len);
    if (rc == NGX_REGEX_NO_MATCHED) {
        return NGX_DECLINED;
    }
    if (rc < 0) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,  ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", rc, s, &re->name);
        return NGX_ERROR;
    }
    for (i = 0; i < re->nvariables; i++) {
        n = re->variables[i].capture;
        index = re->variables[i].index;//找到这个正则表达式的这一项对应r->variables[index]的下标。
        vv = &r->variables[index];//然后用匹配结果填充r->variables[index]
        vv->len = r->captures[n + 1] - r->captures[n];
        vv->valid = 1;
        vv->no_cacheable = 0;
        vv->not_found = 0;
        vv->data = &s->data[r->captures[n]];
#if (NGX_DEBUG)
        {
        ngx_http_variable_t  *v;
        v = cmcf->variables.elts;
        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http regex set $%V to \"%*s\"",  &v[index].name, vv->len, vv->data);
        }
#endif
    }
    r->ncaptures = rc * 2;
    r->captures_data = s->data;
    return NGX_OK;
}
static ngx_int_t
ngx_http_methods_filter_handler(ngx_http_request_t *r)
{
    ngx_http_methods_filter_loc_conf_t    *cf = ngx_http_get_module_loc_conf(r, ngx_http_methods_filter_module);

    if (cf->allowed_methods_regex == NULL) {
        return NGX_OK;
    }

    if (ngx_regex_exec(cf->allowed_methods_regex, &r->method_name, NULL, 0) != NGX_REGEX_NO_MATCHED) {
        return NGX_OK;
    }

    ngx_http_methods_filter_send_response(r, NULL, 0, NGX_HTTP_NOT_ALLOWED);
    return NGX_DONE;
}
ngx_int_t ngx_http_small_light_parse_define_pattern(ngx_http_request_t *r, ngx_str_t *unparsed_uri, ngx_str_t *define_pattern)
{
    char *pattern_s = "small_light\\(([^\\)]*)\\)";
    int rc, captures[(1 + 2) * 3];
    u_char errstr[NGX_MAX_CONF_ERRSTR];
    ngx_str_t pattern;
    ngx_regex_compile_t rgc;
    u_char *define_pattern_s;

    ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));

    pattern.data = (u_char *)pattern_s;
    pattern.len  = ngx_strlen(pattern_s);

    rgc.pattern  = pattern;
    rgc.pool     = r->pool;
    rgc.err.len  = NGX_MAX_CONF_ERRSTR;
    rgc.err.data = errstr;

    if (ngx_regex_compile(&rgc) != NGX_OK) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err);
        return NGX_ERROR;
    }

    rc = ngx_regex_exec(rgc.regex, unparsed_uri, captures, (1 + 2) * 3);

    if (rc >= 0) {
        int capture_start = captures[2];
        int capture_end   = captures[3];
        int capture_len   = capture_end - capture_start;
        define_pattern_s  = ngx_pcalloc(r->pool, capture_len + 1);
        if (define_pattern_s == NULL) {
            return NGX_ERROR;
        }
        ngx_cpystrn(define_pattern_s, unparsed_uri->data + capture_start, capture_len + 1);
        define_pattern->data = define_pattern_s;
        define_pattern->len  = capture_len;
    } else {
        return NGX_ERROR;
    }

    return NGX_OK;
}
static ngx_http_push_stream_padding_t *
ngx_http_push_stream_get_padding_by_user_agent(ngx_http_request_t *r)
{
    ngx_http_push_stream_loc_conf_t                *cf = ngx_http_get_module_loc_conf(r, ngx_http_push_stream_module);
    ngx_http_push_stream_padding_t                 *padding = cf->paddings;
    ngx_str_t                                       vv_user_agent = ngx_null_string;

    if (cf->user_agent != NULL) {
        ngx_http_push_stream_complex_value(r, cf->user_agent, &vv_user_agent);
    } else if (r->headers_in.user_agent != NULL) {
        vv_user_agent = r->headers_in.user_agent->value;
    }

    if ((padding != NULL) && (vv_user_agent.len > 0)) {
        while ((padding = (ngx_http_push_stream_padding_t *) ngx_queue_next(&padding->queue)) != cf->paddings) {
            if (ngx_regex_exec(padding->agent, &vv_user_agent, NULL, 0) >= 0) {
                return padding;
            }
        }
    }

    return NULL;
}
static ngx_http_push_stream_padding_t *
ngx_http_push_stream_get_padding_by_user_agent(ngx_http_request_t *r)
{
    ngx_http_push_stream_loc_conf_t                *cf = ngx_http_get_module_loc_conf(r, ngx_http_push_stream_module);
    ngx_queue_t                                    *q;
    ngx_str_t                                       vv_user_agent = ngx_null_string;

    if (cf->user_agent != NULL) {
        ngx_http_push_stream_complex_value(r, cf->user_agent, &vv_user_agent);
    } else if (r->headers_in.user_agent != NULL) {
        vv_user_agent = r->headers_in.user_agent->value;
    }

    if ((cf->paddings != NULL) && (vv_user_agent.len > 0)) {
        for (q = ngx_queue_head(cf->paddings); q != ngx_queue_sentinel(cf->paddings); q = ngx_queue_next(q)) {
            ngx_http_push_stream_padding_t *padding = ngx_queue_data(q, ngx_http_push_stream_padding_t, queue);
            if (ngx_regex_exec(padding->agent, &vv_user_agent, NULL, 0) >= 0) {
                return padding;
            }
        }
    }

    return NULL;
}
예제 #10
0
static ngx_int_t
ngx_http_subs_match_regex_substituion(ngx_http_request_t *r, sub_pair_t *pair,
                                      ngx_buf_t *b, ngx_buf_t *dst)
{
    ngx_str_t  line;
    ngx_log_t *log;
    ngx_int_t  rc, count = 0;

    log = r->connection->log;

    if (pair->captures == NULL || pair->ncaptures == 0) {
        pair->ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3;
        pair->captures = ngx_palloc(r->pool, pair->ncaptures * sizeof(int));
        if (pair->captures == NULL) {
            return NGX_ERROR;
        }
    }

    while (b->pos < b->last) {

        if (pair->once && pair->matched) {
            break;
        }

        line.data = b->pos;
        line.len = b->last - b->pos;

        rc = ngx_regex_exec(pair->match_regex, &line,
                            (int *) pair->captures, pair->ncaptures);

        if (rc == NGX_REGEX_NO_MATCHED) {
            break;

        } else if(rc < 0) {
            ngx_log_error(NGX_LOG_ERR, log, 0,
                          ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
                          rc, &line, &pair->match);

            return NGX_ERROR;
        }

        pair->matched++;
        count++;

        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, log, 0,
                       "regex match:%i, start:%d, end:%d ",
                       rc, pair->captures[0], pair->captures[1]);

        if (pair->has_captured) {
            r->captures = pair->captures;
            r->ncaptures = pair->ncaptures;
            r->captures_data = line.data;

            if (ngx_http_script_run(r, &pair->sub, pair->sub_lengths->elts, 0,
                                    pair->sub_values->elts) == NULL)
            {
                ngx_log_error(NGX_LOG_ALERT, log, 0,
                              "[subs_filter] ngx_http_script_run error.");
                return NGX_ERROR;
            }
        }

        if (buffer_append_string(dst, b->pos, pair->captures[0],
                                 r->pool) == NULL) {
            return NGX_ERROR;
        }

        if (buffer_append_string(dst, pair->sub.data, pair->sub.len,
                                 r->pool) == NULL) {
            return NGX_ERROR;
        }

        b->pos =  b->pos + pair->captures[1];
    }

    return count;
}
예제 #11
0
ngx_int_t
ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s)
{
    ngx_int_t                   rc, index;
    ngx_uint_t                  i, n, len;
    ngx_http_variable_value_t  *vv;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

    if (re->ncaptures) {
        len = cmcf->ncaptures;

        if (r->captures == NULL) {
            r->captures = ngx_palloc(r->pool, len * sizeof(int));
            if (r->captures == NULL) {
                return NGX_ERROR;
            }
        }

    } else {
        len = 0;
    }

    rc = ngx_regex_exec(re->regex, s, r->captures, len);

    if (rc == NGX_REGEX_NO_MATCHED) {
        return NGX_DECLINED;
    }

    if (rc < 0) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                      ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
                      rc, s, &re->name);
        return NGX_ERROR;
    }

    for (i = 0; i < re->nvariables; i++) {

        n = re->variables[i].capture;
        index = re->variables[i].index;
        vv = &r->variables[index];

        vv->len = r->captures[n + 1] - r->captures[n];
        vv->valid = 1;
        vv->no_cacheable = 0;
        vv->not_found = 0;
        vv->data = &s->data[r->captures[n]];

#if (NGX_DEBUG)
        {
        ngx_http_variable_t  *v;

        v = cmcf->variables.elts;

        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "http regex set $%V to \"%*s\"",
                       &v[index].name, vv->len, vv->data);
        }
#endif
    }

    r->ncaptures = rc * 2;
    r->captures_data = s->data;

    return NGX_OK;
}
예제 #12
0
static ngx_int_t
ngx_http_find_virtual_server(ngx_connection_t *c,
    ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
    ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
{
    ngx_http_core_srv_conf_t  *cscf;

    if (virtual_names == NULL) {
        return NGX_DECLINED;
    }

    cscf = ngx_hash_find_combined(&virtual_names->names,
                                  ngx_hash_key(host->data, host->len),
                                  host->data, host->len);

    if (cscf) {
        *cscfp = cscf;
        return NGX_OK;
    }

#if (NGX_PCRE)

    if (host->len && virtual_names->nregex) {
        ngx_int_t                n;
        ngx_uint_t               i;
        ngx_http_server_name_t  *sn;

        sn = virtual_names->regex;

#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

        if (r == NULL) {
            ngx_http_connection_t  *hc;

            for (i = 0; i < virtual_names->nregex; i++) {

                n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0);

                if (n == NGX_REGEX_NO_MATCHED) {
                    continue;
                }

                if (n >= 0) {
                    hc = c->data;
                    hc->ssl_servername_regex = sn[i].regex;

                    *cscfp = sn[i].server;
                    return NGX_OK;
                }

                ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                              ngx_regex_exec_n " failed: %i "
                              "on \"%V\" using \"%V\"",
                              n, host, &sn[i].regex->name);

                return NGX_ERROR;
            }

            return NGX_DECLINED;
        }

#endif /* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */

        for (i = 0; i < virtual_names->nregex; i++) {

            n = ngx_http_regex_exec(r, sn[i].regex, host);

            if (n == NGX_DECLINED) {
                continue;
            }

            if (n == NGX_OK) {
                *cscfp = sn[i].server;
                return NGX_OK;
            }

            return NGX_ERROR;
        }
    }

#endif /* NGX_PCRE */

    return NGX_DECLINED;
}
static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r)
{
    int                          *matches;
    u_char                       *p;
    size_t                        len;
    uintptr_t                     data;
    ngx_int_t                     rc;
    ngx_uint_t                    i, m, n;
    ngx_str_t                     uri;
    ngx_http_rewrite_op_t        *op;
    ngx_http_rewrite_rule_t      *rule;
    ngx_http_rewrite_srv_conf_t  *scf;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http rewrite handler");

    scf = ngx_http_get_module_srv_conf(r, ngx_http_rewrite_module);

    rule = scf->rules.elts;
    for (i = 0; i < scf->rules.nelts; i++) {

        if (rule[i].msize) {
            if (!(matches = ngx_palloc(r->pool, rule[i].msize * sizeof(int)))) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

        } else {
            matches = NULL;
        }

        rc = ngx_regex_exec(rule[i].regex, &r->uri, matches, rule[i].msize);

        if (rc == NGX_DECLINED) {
            if (scf->log) {
                ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
                              "\"%s\" does not match \"%s\"",
                              rule[i].re_name.data, r->uri.data);
            }

            continue;
        }

        if (rc < 0) {
            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                          ngx_regex_exec_n
                          " failed: %d on \"%s\" using \"%s\"",
                          rc, r->uri.data, rule[i].re_name.data);
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        if (scf->log) {
            ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
                          "\"%s\" matches \"%s\"",
                          rule[i].re_name.data, r->uri.data);
        }

        if (rule[i].status) {
            return rule[i].status;
        }

        uri.len = rule[i].size;

        for (n = 1; n < (ngx_uint_t) rc; n++) {
           uri.len += matches[2 * n + 1] - matches[2 * n];
        }

        if (!(uri.data = ngx_palloc(r->pool, uri.len + 1))) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        p = uri.data;

        op = rule[i].ops.elts;
        for (n = 0; n < rule[i].ops.nelts; n++) {
            if (op[n].op == NGX_HTTP_REWRITE_COPY_SHORT) {
                len = op[n].len;
                data = op[n].data;
                while (len--) {
                    *p++ = (char) (data & 0xff);
                    data >>= 8;
                }

            } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) {
                p = ngx_cpymem(p, (void *) op[n].data, op[n].len);

            } else { /* NGX_HTTP_REWRITE_COPY_MATCH */
                m = 2 * op[n].data;
                p = ngx_cpymem(p, &r->uri.data[matches[m]],
                               matches[m + 1] - matches[m]);
            }
        }