len = tf->name.len;
}
- reserve = len - r->uri.len;
-
/* 16 bytes are preallocation */
- reserve = reserve < 16 ? 16 : reserve + 16;
-
- reserve += alias;
+ reserve = ngx_abs((ssize_t) (len - r->uri.len)) + alias + 16;
if (reserve > allocated) {
ngx_int_t rc;
ngx_http_core_loc_conf_t *pclcf;
#if (NGX_PCRE)
- ngx_int_t n;
+ ngx_int_t n, len;
ngx_uint_t noregex;
ngx_http_core_loc_conf_t *clcf, **clcfp;
if (noregex == 0 && pclcf->regex_locations) {
+ len = 0;
+
for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"test location: ~ \"%V\"", &(*clcfp)->name);
- n = ngx_regex_exec((*clcfp)->regex, &r->uri, NULL, 0);
+ if ((*clcfp)->captures && r->captures == NULL) {
+
+ len = (NGX_HTTP_MAX_CAPTURES + 1) * 3 * sizeof(int);
+
+ r->captures = ngx_palloc(r->pool, len);
+ if (r->captures == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len);
if (n == NGX_REGEX_NO_MATCHED) {
continue;
r->loc_conf = (*clcfp)->loc_conf;
+ r->ncaptures = len;
+ r->captures_data = r->uri.data;
+
/* look up nested locations */
rc = ngx_http_core_find_location(r);
exten = ngx_pnalloc(r->pool, r->exten.len);
if (exten == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
hash = ngx_hash_strlow(exten, r->exten.data, r->exten.len);
return NULL;
}
- if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0)== NGX_ERROR)
- {
+ if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0) != NGX_OK) {
return NULL;
}
*root_length = path->len - reserved;
last = path->data + *root_length;
+
+ if (alias) {
+ *last = '\0';
+ return last;
+ }
}
last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
{
socklen_t len;
ngx_connection_t *c;
- struct sockaddr_in sin;
-
- /* AF_INET only */
+ u_char sa[NGX_SOCKADDRLEN];
c = r->connection;
- if (r->in_addr == 0) {
- len = sizeof(struct sockaddr_in);
- if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) {
+ if (c->local_sockaddr == NULL) {
+
+ len = NGX_SOCKADDRLEN;
+
+ if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) {
ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
return NGX_ERROR;
}
- r->in_addr = sin.sin_addr.s_addr;
+ c->local_sockaddr = ngx_palloc(r->connection->pool, len);
+ if (c->local_sockaddr == NULL) {
+ return NGX_ERROR;
+ }
- } else {
- sin.sin_family = c->sockaddr->sa_family;
- sin.sin_addr.s_addr = r->in_addr;
+ c->local_socklen = len;
+ ngx_memcpy(c->local_sockaddr, &sa, len);
}
if (s == NULL) {
return NGX_OK;
}
- s->len = ngx_sock_ntop((struct sockaddr *) &sin, s->data,
- NGX_INET_ADDRSTRLEN);
+ s->len = ngx_sock_ntop(c->local_sockaddr, s->data, s->len, 0);
return NGX_OK;
}
if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
sizeof(ngx_table_elt_t))
- == NGX_ERROR)
+ != NGX_OK)
{
return NGX_ERROR;
}
c->data = sr;
}
- sr->in_addr = r->in_addr;
- sr->port = r->port;
- sr->port_text = r->port_text;
-
sr->variables = r->variables;
sr->log_handler = r->log_handler;
}
clcf->name = *regex;
+ clcf->captures = (ngx_regex_capture_count(clcf->regex) > 0);
return NGX_OK;
if (ngx_strcmp(value[0].data, "include") == 0) {
file = value[1];
- if (ngx_conf_full_name(cf->cycle, &file, 1) == NGX_ERROR){
+ if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
return NGX_CONF_ERROR;
}
* conf->client_large_buffers.num = 0;
*/
- if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t))
- == NGX_ERROR)
+ if (ngx_array_init(&cscf->listen, cf->temp_pool, 4,
+ sizeof(ngx_http_listen_t))
+ != NGX_OK)
{
return NGX_CONF_ERROR;
}
if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
sizeof(ngx_http_server_name_t))
- == NGX_ERROR)
+ != NGX_OK)
{
return NGX_CONF_ERROR;
}
ngx_http_core_srv_conf_t *conf = child;
ngx_http_listen_t *ls;
+ struct sockaddr_in *sin;
ngx_http_server_name_t *sn;
/* TODO: it does not merge, it inits only */
ngx_memzero(ls, sizeof(ngx_http_listen_t));
- ls->addr = INADDR_ANY;
+ sin = (struct sockaddr_in *) &ls->sockaddr;
+
+ sin->sin_family = AF_INET;
#if (NGX_WIN32)
- ls->port = 80;
+ sin->sin_port = htons(80);
#else
- /* STUB: getuid() should be cached */
- ls->port = (getuid() == 0) ? 80 : 8000;
+ sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
#endif
- ls->family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_ANY;
+
+ ls->socklen = sizeof(struct sockaddr_in);
ls->conf.backlog = NGX_LISTEN_BACKLOG;
ls->conf.rcvbuf = -1;
ls->conf.sndbuf = -1;
+ ls->conf.wildcard = 1;
+
+ (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
+ NGX_SOCKADDR_STRLEN, 1);
}
if (conf->server_name.data == NULL) {
#if (NGX_PCRE)
sn->regex = NULL;
+ sn->captures = 0;
#endif
sn->core_srv_conf = conf;
sn->name.len = conf->server_name.len;
conf->root.len = sizeof("html") - 1;
conf->root.data = (u_char *) "html";
- if (ngx_conf_full_name(cf->cycle, &conf->root, 0) == NGX_ERROR) {
+ if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
}
-/* AF_INET only */
-
static char *
ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_memzero(ls, sizeof(ngx_http_listen_t));
- ls->family = u.family;
- ls->addr = u.addr.in_addr;
- ls->port = u.port;
+ ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen);
+
+ ls->socklen = u.socklen;
ls->file_name = cf->conf_file->file.name.data;
ls->line = cf->conf_file->line;
ls->conf.backlog = NGX_LISTEN_BACKLOG;
ls->conf.rcvbuf = -1;
ls->conf.sndbuf = -1;
+ ls->conf.wildcard = u.wildcard;
- n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, NGX_INET_ADDRSTRLEN);
- ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port);
+ (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
+ NGX_SOCKADDR_STRLEN, 1);
if (cf->args->nelts == 2) {
return NGX_CONF_OK;
#if (NGX_PCRE)
sn->regex = NULL;
+ sn->captures = 0;
#endif
sn->core_srv_conf = cscf;
sn->name = value[i];
return NGX_CONF_ERROR;
}
+ sn->captures = (ngx_regex_capture_count(sn->regex) > 0);
sn->name = value[i];
}
#else
return NGX_CONF_ERROR;
}
-#if (NGX_PCRE)
-
- if (lcf->regex && alias) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"alias\" directive may not be used "
- "inside location given by regular expression");
-
- return NGX_CONF_ERROR;
- }
-
-#endif
-
value = cf->args->elts;
if (ngx_strstr(value[1].data, "$document_root")
}
if (lcf->root.data[0] != '$') {
- if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) == NGX_ERROR) {
+ if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
n = ngx_http_script_variables_count(&lcf->root);
- if (n == 0) {
- return NGX_CONF_OK;
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+ if (n) {
+ sc.cf = cf;
+ sc.source = &lcf->root;
+ sc.lengths = &lcf->root_lengths;
+ sc.values = &lcf->root_values;
+ sc.variables = n;
+ sc.complete_lengths = 1;
+ sc.complete_values = 1;
+
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
}
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+#if (NGX_PCRE)
- sc.cf = cf;
- sc.source = &lcf->root;
- sc.lengths = &lcf->root_lengths;
- sc.values = &lcf->root_values;
- sc.variables = n;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
+ if (alias && lcf->regex
+ && (ngx_regex_capture_count(lcf->regex) <= 0 || sc.ncaptures == 0))
+ {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "the \"alias\" directive must use captures "
+ "inside location given by regular expression");
- if (ngx_http_script_compile(&sc) != NGX_OK) {
return NGX_CONF_ERROR;
}
+#endif
+
return NGX_CONF_OK;
}