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); }
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; }
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; }
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; }
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; }
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]); } }