[mod_evhost] partial matching patterns (fixes #1194)

"%%" "%_" "%x" "%{x.y}" where x and y are *single digit* 0 - 9
and y is the 1-indexed position of a single char to add, similar to
http://httpd.apache.org/docs/2.4/mod/mod_vhost_alias.html
(but not supporting the entire Apache mod_vhost_alias syntax)

The lighttpd syntax for adding a single char at a give position requires
that the "%{x.y}" syntax, including the curly braces, which is different
from the Apache mod_vhost_alias syntax.

x-ref:
  "Partial matching in mod_evhost patterns"
  https://redmine.lighttpd.net/issues/1194
This commit is contained in:
Glenn Strauss 2016-10-20 13:50:39 -04:00
parent 9f93454d56
commit a3bba43b30
1 changed files with 44 additions and 5 deletions

View File

@ -73,21 +73,41 @@ FREE_FUNC(mod_evhost_free) {
return HANDLER_GO_ON;
}
static void mod_evhost_parse_pattern(plugin_config *s) {
static int mod_evhost_parse_pattern(plugin_config *s) {
char *ptr = s->path_pieces_raw->ptr,*pos;
s->path_pieces = NULL;
for(pos=ptr;*ptr;ptr++) {
if(*ptr == '%') {
size_t len;
s->path_pieces = realloc(s->path_pieces,(s->len+2) * sizeof(*s->path_pieces));
s->path_pieces[s->len] = buffer_init();
s->path_pieces[s->len+1] = buffer_init();
buffer_copy_string_len(s->path_pieces[s->len],pos,ptr-pos);
pos = ptr + 2;
/* "%%" "%_" "%x" "%{x.y}" where x and y are *single digit* 0 - 9 */
if (ptr[1] == '%' || ptr[1] == '_' || light_isdigit(ptr[1])) {
len = 2;
} else if (ptr[1] == '{') {
if (!light_isdigit(ptr[2])) return -1;
if (ptr[3] == '.') {
if (!light_isdigit(ptr[4])) return -1;
if (ptr[5] != '}') return -1;
len = 6;
} else if (ptr[3] == '}') {
len = 4;
} else {
return -1;
}
} else {
return -1;
}
buffer_copy_string_len(s->path_pieces[s->len+1],ptr++,2);
buffer_copy_string_len(s->path_pieces[s->len],pos,ptr-pos);
pos = ptr + len;
buffer_copy_string_len(s->path_pieces[s->len+1],ptr,len);
ptr += len - 1; /*(ptr++ in for() loop)*/
s->len += 2;
}
@ -101,6 +121,8 @@ static void mod_evhost_parse_pattern(plugin_config *s) {
s->len += 1;
}
return 0;
}
SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
@ -150,7 +172,10 @@ SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
}
if (!buffer_string_is_empty(s->path_pieces_raw)) {
mod_evhost_parse_pattern(s);
if (0 != mod_evhost_parse_pattern(s)) {
log_error_write(srv, __FILE__, __LINE__, "sb", "invalid evhost.path-pattern:");
return HANDLER_ERROR;
}
}
}
@ -301,6 +326,20 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
/* strip the port out of the authority-part of the URI scheme */
buffer_append_string_len(p->tmp_buf, con->uri.authority->ptr, colon - con->uri.authority->ptr); /* adds fqdn */
}
} else if (ptr[1] == '{' ) {
char s[3] = "% ";
s[1] = ptr[2]; /*(assumes single digit before '.', and, optionally, '.' and single digit after '.')*/
if (NULL != (ds = (data_string *)array_get_element(parsed_host, s))) {
if (ptr[3] != '.' || ptr[4] == '0') {
buffer_append_string_buffer(p->tmp_buf, ds->value);
} else {
if ((size_t)(ptr[4]-'0') <= buffer_string_length(ds->value)) {
buffer_append_string_len(p->tmp_buf, ds->value->ptr+(ptr[4]-'0')-1, 1);
}
}
} else {
/* unhandled %-sequence */
}
} else if (NULL != (ds = (data_string *)array_get_element(parsed_host,p->conf.path_pieces[i]->ptr))) {
buffer_append_string_buffer(p->tmp_buf,ds->value);
} else {