aboutsummaryrefslogtreecommitdiff
path: root/src/http/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/modules')
-rw-r--r--src/http/modules/ngx_http_auth_basic_module.c56
-rw-r--r--src/http/modules/ngx_http_proxy_module.c10
-rw-r--r--src/http/modules/ngx_http_userid_filter_module.c214
3 files changed, 165 insertions, 115 deletions
diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c
index 98c47bd64..06d0df54e 100644
--- a/src/http/modules/ngx_http_auth_basic_module.c
+++ b/src/http/modules/ngx_http_auth_basic_module.c
@@ -90,8 +90,9 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
off_t offset;
ssize_t n;
ngx_fd_t fd;
- ngx_str_t auth, encoded, pwd;
- ngx_uint_t i, login, len, left, passwd;
+ ngx_int_t rc;
+ ngx_str_t pwd;
+ ngx_uint_t i, login, left, passwd;
ngx_file_t file;
ngx_http_auth_basic_ctx_t *ctx;
ngx_http_auth_basic_loc_conf_t *alcf;
@@ -115,57 +116,16 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
&alcf->realm);
}
- if (r->headers_in.authorization == NULL) {
- return ngx_http_auth_basic_set_realm(r, &alcf->realm);
- }
-
- encoded = r->headers_in.authorization->value;
+ rc = ngx_http_auth_basic_user(r);
- if (encoded.len < sizeof("Basic ") - 1
- || ngx_strncasecmp(encoded.data, "Basic ", sizeof("Basic ") - 1) != 0)
- {
+ if (rc == NGX_DECLINED) {
return ngx_http_auth_basic_set_realm(r, &alcf->realm);
}
- encoded.len -= sizeof("Basic ") - 1;
- encoded.data += sizeof("Basic ") - 1;
-
- while (encoded.len && encoded.data[0] == ' ') {
- encoded.len--;
- encoded.data++;
- }
-
- if (encoded.len == 0) {
- return ngx_http_auth_basic_set_realm(r, &alcf->realm);
- }
-
- auth.len = ngx_base64_decoded_length(encoded.len);
- auth.data = ngx_palloc(r->pool, auth.len + 1);
- if (auth.data == NULL) {
+ if (rc == NGX_ERROR) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
- return ngx_http_auth_basic_set_realm(r, &alcf->realm);
- }
-
- auth.data[auth.len] = '\0';
-
- for (len = 0; len < auth.len; len++) {
- if (auth.data[len] == ':') {
- break;
- }
- }
-
- if (len == auth.len) {
- return ngx_http_auth_basic_set_realm(r, &alcf->realm);
- }
-
- r->headers_in.user.len = len;
- r->headers_in.user.data = auth.data;
- r->headers_in.passwd.len = auth.len - len - 1;
- r->headers_in.passwd.data = &auth.data[len + 1];
-
fd = ngx_open_file(alcf->user_file.data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
if (fd == NGX_INVALID_FILE) {
@@ -208,12 +168,12 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
break;
}
- if (buf[i] != auth.data[login]) {
+ if (buf[i] != r->headers_in.user.data[login]) {
state = sw_skip;
break;
}
- if (login == len) {
+ if (login == r->headers_in.user.len) {
state = sw_passwd;
passwd = i + 1;
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 8288df1c4..e8b9c4ee9 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -424,10 +424,10 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
escape = 0;
- loc_len = r->valid_location ? u->conf->location->len : 1;
+ loc_len = r->valid_location ? u->conf->location->len - 1 : 0;
if (plcf->upstream.pass_unparsed_uri && r->valid_unparsed_uri) {
- len += r->unparsed_uri.len - 1;
+ len += r->unparsed_uri.len;
} else {
if (r->quoted_uri) {
@@ -508,11 +508,11 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
r->method_name.len + 1);
}
- b->last = ngx_cpymem(b->last, u->conf->uri.data, u->conf->uri.len);
+ b->last = ngx_cpymem(b->last, u->conf->uri.data, u->conf->uri.len - 1);
if (plcf->upstream.pass_unparsed_uri && r->valid_unparsed_uri) {
- b->last = ngx_cpymem(b->last, r->unparsed_uri.data + 1,
- r->unparsed_uri.len - 1);
+ b->last = ngx_cpymem(b->last, r->unparsed_uri.data,
+ r->unparsed_uri.len);
} else {
if (escape) {
ngx_escape_uri(b->last, r->uri.data + loc_len,
diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c
index af60d80b3..5ee9712f8 100644
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -26,18 +26,22 @@ typedef struct {
ngx_str_t name;
ngx_str_t domain;
ngx_str_t path;
- time_t expires;
ngx_str_t p3p;
+
+ time_t expires;
+
+ u_char mark;
} ngx_http_userid_conf_t;
typedef struct {
uint32_t uid_got[4];
uint32_t uid_set[4];
+ ngx_str_t cookie;
} ngx_http_userid_ctx_t;
-static ngx_int_t ngx_http_userid_get_uid(ngx_http_request_t *r,
+static void ngx_http_userid_get_uid(ngx_http_request_t *r,
ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf);
static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r,
ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf);
@@ -61,6 +65,9 @@ static char *ngx_http_userid_path(ngx_conf_t *cf, void *post, void *data);
static char *ngx_http_userid_expires(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_userid_p3p(ngx_conf_t *cf, void *post, void *data);
+static char *ngx_http_userid_mark(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+
static uint32_t sequencer_v1 = 1;
@@ -84,7 +91,6 @@ static ngx_conf_enum_t ngx_http_userid_state[] = {
static ngx_conf_post_handler_pt ngx_http_userid_domain_p =
ngx_http_userid_domain;
-
static ngx_conf_post_handler_pt ngx_http_userid_path_p = ngx_http_userid_path;
static ngx_conf_post_handler_pt ngx_http_userid_p3p_p = ngx_http_userid_p3p;
@@ -99,28 +105,28 @@ static ngx_command_t ngx_http_userid_commands[] = {
ngx_http_userid_state },
{ ngx_string("userid_service"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_userid_conf_t, service),
NULL },
{ ngx_string("userid_name"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_userid_conf_t, name),
NULL },
{ ngx_string("userid_domain"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_userid_conf_t, domain),
&ngx_http_userid_domain_p },
{ ngx_string("userid_path"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_userid_conf_t, path),
@@ -140,6 +146,13 @@ static ngx_command_t ngx_http_userid_commands[] = {
offsetof(ngx_http_userid_conf_t, p3p),
&ngx_http_userid_p3p_p },
+ { ngx_string("userid_mark"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_userid_mark,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
ngx_null_command
};
@@ -205,15 +218,24 @@ ngx_http_userid_filter(ngx_http_request_t *r)
ngx_http_set_ctx(r, ctx, ngx_http_userid_filter_module);
+ ngx_http_userid_get_uid(r, ctx, conf);
- rc = ngx_http_userid_get_uid(r, ctx, conf);
-
- if (rc != NGX_OK) {
- return rc;
+ if (conf->enable == NGX_HTTP_USERID_LOG) {
+ return ngx_http_next_header_filter(r);
}
- if (conf->enable == NGX_HTTP_USERID_LOG || ctx->uid_got[3] != 0) {
- return ngx_http_next_header_filter(r);
+ if (ctx->uid_got[3] != 0) {
+ if (conf->mark == '\0') {
+ return ngx_http_next_header_filter(r);
+
+ } else {
+ if (ctx->cookie.len > 23
+ && ctx->cookie.data[22] == conf->mark
+ && ctx->cookie.data[23] == '=')
+ {
+ return ngx_http_next_header_filter(r);
+ }
+ }
}
rc = ngx_http_userid_set_uid(r, ctx, conf);
@@ -226,7 +248,7 @@ ngx_http_userid_filter(ngx_http_request_t *r)
}
-static ngx_int_t
+static void
ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
ngx_http_userid_conf_t *conf)
{
@@ -235,23 +257,29 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
ngx_table_elt_t **cookies;
n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &conf->name,
- &src);
+ &ctx->cookie);
if (n == NGX_DECLINED) {
- return NGX_OK;
+ return;
}
- if (src.len < 22) {
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "uid cookie: \"%V\"", &ctx->cookie);
+
+ if (ctx->cookie.len < 22) {
cookies = r->headers_in.cookies.elts;
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"client sent too short userid cookie \"%V\"",
&cookies[n]->value);
- return NGX_OK;
+ return;
}
+ src = ctx->cookie;
+
/*
- * we have to limit encoded string to 22 characters
- * because there are already the millions cookies with a garbage
- * instead of the correct base64 trail "=="
+ * we have to limit the encoded string to 22 characters because
+ * 1) cookie may be marked by "userid_mark",
+ * 2) and there are already the millions cookies with a garbage
+ * instead of the correct base64 trail "=="
*/
src.len = 22;
@@ -263,15 +291,13 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"client sent invalid userid cookie \"%V\"",
&cookies[n]->value);
- return NGX_OK;
+ return;
}
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"uid: %08XD%08XD%08XD%08XD",
ctx->uid_got[0], ctx->uid_got[1],
ctx->uid_got[2], ctx->uid_got[3]);
-
- return NGX_OK;
}
@@ -286,47 +312,58 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
ngx_str_t src, dst;
ngx_table_elt_t *set_cookie, *p3p;
- /* TODO: mutex for sequencers */
+ /*
+ * TODO: in the threaded mode the sequencers should be in TLS and their
+ * ranges should be divided between threads
+ */
- if (conf->enable == NGX_HTTP_USERID_V1) {
- if (conf->service == NGX_CONF_UNSET) {
- ctx->uid_set[0] = 0;
- } else {
- ctx->uid_set[0] = htonl(conf->service);
- }
+ if (ctx->uid_got[3] == 0) {
- ctx->uid_set[1] = ngx_time();
- ctx->uid_set[2] = ngx_pid;
- ctx->uid_set[3] = sequencer_v1;
- sequencer_v1 += 0x100;
+ if (conf->enable == NGX_HTTP_USERID_V1) {
+ if (conf->service == NGX_CONF_UNSET) {
+ ctx->uid_set[0] = 0;
+ } else {
+ ctx->uid_set[0] = conf->service;
+ }
+ ctx->uid_set[1] = ngx_time();
+ ctx->uid_set[2] = ngx_pid;
+ ctx->uid_set[3] = sequencer_v1;
+ sequencer_v1 += 0x100;
- } else {
- if (conf->service == NGX_CONF_UNSET) {
- if (r->in_addr == 0) {
- slen = sizeof(struct sockaddr_in);
- if (getsockname(r->connection->fd,
- (struct sockaddr *) &sin, &slen) == -1)
- {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log,
- ngx_socket_errno, "getsockname() failed");
+ } else {
+ if (conf->service == NGX_CONF_UNSET) {
+ if (r->in_addr == 0) {
+ slen = sizeof(struct sockaddr_in);
+ if (getsockname(r->connection->fd,
+ (struct sockaddr *) &sin, &slen) == -1)
+ {
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log,
+ ngx_socket_errno, "getsockname() failed");
+ }
+
+ r->in_addr = sin.sin_addr.s_addr;
}
- r->in_addr = sin.sin_addr.s_addr;
- }
+ ctx->uid_set[0] = htonl(r->in_addr);
- ctx->uid_set[0] = htonl(r->in_addr);
+ } else {
+ ctx->uid_set[0] = htonl(conf->service);
+ }
- } else {
- ctx->uid_set[0] = htonl(conf->service);
+ ctx->uid_set[1] = htonl(ngx_time());
+ ctx->uid_set[2] = htonl(ngx_pid);
+ ctx->uid_set[3] = htonl(sequencer_v2);
+ sequencer_v2 += 0x100;
+ if (sequencer_v2 < 0x03030302) {
+ sequencer_v2 = 0x03030302;
+ }
}
- ctx->uid_set[1] = htonl(ngx_time());
- ctx->uid_set[2] = htonl(ngx_pid);
- ctx->uid_set[3] = htonl(sequencer_v2);
- sequencer_v2 += 0x100;
- if (sequencer_v2 < 0x03030302) {
- sequencer_v2 = 0x03030302;
- }
+ } else {
+ ctx->uid_set[0] = ctx->uid_got[0];
+ ctx->uid_set[1] = ctx->uid_got[1];
+ ctx->uid_set[2] = ctx->uid_got[2];
+ ctx->uid_set[3] = ctx->uid_got[3];
}
len = conf->name.len + 1 + ngx_base64_encoded_length(16) + conf->path.len;
@@ -347,13 +384,24 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
p = ngx_cpymem(cookie, conf->name.data, conf->name.len);
*p++ = '=';
- src.len = 16;
- src.data = (u_char *) ctx->uid_set;
- dst.data = p;
+ if (ctx->uid_got[3] == 0) {
+ src.len = 16;
+ src.data = (u_char *) ctx->uid_set;
+ dst.data = p;
- ngx_encode_base64(&dst, &src);
+ ngx_encode_base64(&dst, &src);
- p += dst.len;
+ p += dst.len;
+
+ if (conf->mark) {
+ *(p - 2) = conf->mark;
+ }
+
+ } else {
+ p = ngx_cpymem(p, ctx->cookie.data, 22);
+ *p++ = conf->mark;
+ *p++ = '=';
+ }
if (conf->expires == NGX_HTTP_USERID_MAX_EXPIRES) {
p = ngx_cpymem(p, expires, sizeof(expires) - 1);
@@ -545,6 +593,7 @@ ngx_http_userid_create_conf(ngx_conf_t *cf)
conf->enable = NGX_CONF_UNSET_UINT;
conf->service = NGX_CONF_UNSET;
conf->expires = NGX_CONF_UNSET;
+ conf->mark = (u_char) '\xFF';
return conf;
}
@@ -567,6 +616,14 @@ ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->service, prev->service, NGX_CONF_UNSET);
ngx_conf_merge_sec_value(conf->expires, prev->expires, 0);
+ if (conf->mark == (u_char) '\xFF') {
+ if (prev->mark == (u_char) '\xFF') {
+ conf->mark = '\0';
+ } else {
+ conf->mark = prev->mark;
+ }
+ }
+
return NGX_CONF_OK;
}
@@ -627,7 +684,7 @@ ngx_http_userid_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_userid_conf_t *ucf = conf;
- ngx_str_t *value;
+ ngx_str_t *value;
if (ucf->expires != NGX_CONF_UNSET) {
return "is duplicate";
@@ -670,3 +727,36 @@ ngx_http_userid_p3p(ngx_conf_t *cf, void *post, void *data)
return NGX_CONF_OK;
}
+
+
+static char *
+ngx_http_userid_mark(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_userid_conf_t *ucf = conf;
+
+ ngx_str_t *value;
+
+ if (ucf->mark != (u_char) '\xFF') {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+ ucf->mark = '\0';
+ return NGX_CONF_OK;
+ }
+
+ if (value[1].len != 1
+ || !((value[1].data[0] >= '0' && value[1].data[0] <= '9')
+ || (value[1].data[0] >= 'A' && value[1].data[0] <= 'Z')
+ || (value[1].data[0] >= 'a' && value[1].data[0] <= 'z')
+ || value[1].data[0] == '='))
+ {
+ return "value must be \"off\" or a single letter, digit or \"=\"";
+ }
+
+ ucf->mark = value[1].data[0];
+
+ return NGX_CONF_OK;
+}