Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2004-08-27 19:40:59 +0400
committerIgor Sysoev <igor@sysoev.ru>2004-08-27 19:40:59 +0400
commit967fd637e08b6df4f635014fb572296372c89254 (patch)
tree4f9dfe10ea18abb68a6f0aaf774f5f5e7c54cc3b
parent6d7332d02a043a92f2baf9bbe29949f3760a502c (diff)
nginx-0.0.10-2004-08-27-19:40:59 import
-rw-r--r--auto/modules5
-rw-r--r--auto/options2
-rw-r--r--auto/sources4
-rw-r--r--src/core/nginx.c59
-rw-r--r--src/core/ngx_conf_file.h1
-rw-r--r--src/core/ngx_output_chain.c4
-rw-r--r--src/core/ngx_string.c95
-rw-r--r--src/core/ngx_string.h3
-rw-r--r--src/http/modules/ngx_http_access_handler.c2
-rw-r--r--src/http/modules/ngx_http_userid_handler.c421
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_upstream.c2
-rw-r--r--src/http/ngx_http.c5
-rw-r--r--src/http/ngx_http_core_module.h1
-rw-r--r--src/http/ngx_http_request.c49
-rw-r--r--src/http/ngx_http_request.h2
15 files changed, 616 insertions, 39 deletions
diff --git a/auto/modules b/auto/modules
index ce6096791..a645070a1 100644
--- a/auto/modules
+++ b/auto/modules
@@ -87,6 +87,11 @@ if [ $HTTP_ACCESS = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_ACCESS_SRCS"
fi
+if [ $HTTP_USERID = YES ]; then
+ HTTP_MODULES="$HTTP_MODULES $HTTP_USERID_MODULE"
+ HTTP_SRCS="$HTTP_SRCS $HTTP_USERID_SRCS"
+fi
+
if [ $HTTP_STATUS = YES ]; then
have=NGX_HTTP_STATUS . auto/have
HTTP_MODULES="$HTTP_MODULES $HTTP_STATUS_MODULE"
diff --git a/auto/options b/auto/options
index 5aea141d6..f7c19904c 100644
--- a/auto/options
+++ b/auto/options
@@ -34,6 +34,7 @@ HTTP_GZIP=YES
HTTP_SSL=NO
HTTP_SSI=YES
HTTP_ACCESS=YES
+HTTP_USERID=YES
HTTP_STATUS=YES
HTTP_REWRITE=YES
HTTP_PROXY=YES
@@ -92,6 +93,7 @@ do
--without-http_gzip_module) HTTP_GZIP=NO ;;
--without-http_ssi_module) HTTP_SSI=NO ;;
--without-http_access_module) HTTP_ACCESS=NO ;;
+ --without-http_userid_module) HTTP_USERID=NO ;;
--without-http_status_module) HTTP_STATUS=NO ;;
--without-http_rewrite_module) HTTP_REWRITE=NO ;;
--without-http_proxy_module) HTTP_PROXY=NO ;;
diff --git a/auto/sources b/auto/sources
index 6b66e51b1..0f278c76d 100644
--- a/auto/sources
+++ b/auto/sources
@@ -261,6 +261,10 @@ HTTP_ACCESS_MODULE=ngx_http_access_module
HTTP_ACCESS_SRCS=src/http/modules/ngx_http_access_handler.c
+HTTP_USERID_MODULE=ngx_http_userid_module
+HTTP_USERID_SRCS=src/http/modules/ngx_http_userid_handler.c
+
+
HTTP_STATUS_MODULE=ngx_http_status_module
HTTP_STATUS_SRCS=src/http/modules/ngx_http_status_handler.c
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 6d6103c0e..17071c1c5 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -140,6 +140,65 @@ int main(int argc, char *const *argv)
return 1;
}
+{
+ ngx_str_t d, s;
+
+ s.data = "12";
+ s.len = sizeof("12") - 1;
+
+ if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed");
+ } else {
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data);
+ }
+
+ s.data = "123";
+ s.len = sizeof("123") - 1;
+
+ if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed");
+ } else {
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data);
+ }
+
+ s.data = "1234";
+ s.len = sizeof("1234") - 1;
+
+ if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed");
+ } else {
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data);
+ }
+
+ s.data = "12345";
+ s.len = sizeof("12345") - 1;
+
+ if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed");
+ } else {
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data);
+ }
+
+ s.data = "123456";
+ s.len = sizeof("123456") - 1;
+
+ if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed");
+ } else {
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data);
+ }
+
+ s.data = "12345678901234567890";
+ s.len = sizeof("12345678901234567890") - 1;
+
+ if (ngx_encode_base64(init_cycle.pool, &s, &d) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ERR, log, 0, "ngx_encode_base64() failed");
+ } else {
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "BASE64: %d:\"%s\"", d.len, d.data);
+ }
+
+}
+
if (ngx_add_inherited_sockets(&init_cycle) == NGX_ERROR) {
return 1;
}
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index c09ee552b..7286dbf41 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -276,7 +276,6 @@ char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index db4321bc0..f177076de 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -275,6 +275,10 @@ ngx_int_t ngx_chain_writer(void *data, ngx_chain_t *in)
for (/* void */; in; in = in->next) {
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
+ "WRITER buf: %d", ngx_buf_size(in->buf));
+
ngx_alloc_link_and_set_buf(cl, in->buf, ctx->pool, NGX_ERROR);
*ctx->last = cl;
ctx->last = &cl->next;
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index f14040f3f..7231651c0 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -126,7 +126,7 @@ void ngx_md5_text(u_char *text, u_char *md5)
ngx_int_t ngx_encode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst)
{
u_char *d, *s;
- ngx_uint_t i;
+ size_t len;
static u_char basis64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -136,24 +136,28 @@ ngx_int_t ngx_encode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst)
dst->data = d;
s = src->data;
+ len = src->len;
- for (i = 0; i < src->len - 2; i += 3) {
- *d++ = basis64[(s[i] >> 2) & 0x3f];
- *d++ = basis64[((s[i] & 3) << 4) | (s[i + 1] >> 4)];
- *d++ = basis64[((s[i + 1] & 0x0f) << 2) | (s[i + 2] >> 6)];
- *d++ = basis64[s[i + 2] & 0x3f];
+ while (len > 2) {
+ *d++ = basis64[(s[0] >> 2) & 0x3f];
+ *d++ = basis64[((s[0] & 3) << 4) | (s[1] >> 4)];
+ *d++ = basis64[((s[1] & 0x0f) << 2) | (s[2] >> 6)];
+ *d++ = basis64[s[2] & 0x3f];
+
+ s += 3;
+ len -= 3;
}
- if (i < src->len) {
- *d++ = basis64[(s[i] >> 2) & 0x3f];
+ if (len) {
+ *d++ = basis64[(s[0] >> 2) & 0x3f];
- if (i == src->len - 1) {
- *d++ = basis64[(s[i] & 3) << 4];
+ if (len == 1) {
+ *d++ = basis64[(s[0] & 3) << 4];
*d++ = '=';
} else {
- *d++ = basis64[((s[i] & 3) << 4) | (s[i + 1] >> 4)];
- *d++ = basis64[(s[i + 1] & 0x0f) << 2];
+ *d++ = basis64[((s[0] & 3) << 4) | (s[1] >> 4)];
+ *d++ = basis64[(s[1] & 0x0f) << 2];
}
*d++ = '=';
@@ -168,34 +172,69 @@ ngx_int_t ngx_encode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst)
ngx_int_t ngx_decode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst)
{
- u_char *d, *s, c;
+ size_t len;
+ u_char *d, *s;
+ static u_char basis64[] =
+ { 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
+ 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 77,
+ 77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,
+
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 };
+
+ for (len = 0; len < src->len; len++) {
+ if (src->data[len] == '=') {
+ break;
+ }
+
+ if (basis64[src->data[len]] == 77) {
+ return NGX_ERROR;
+ }
+ }
+
+ if (len % 4 == 1) {
+ return NGX_ERROR;
+ }
- if (!(d = ngx_palloc(pool, ((src->len + 3) / 4) * 3))) {
+ if (!(d = ngx_palloc(pool, ((len + 3) / 4) * 3 + 1))) {
return NGX_ABORT;
}
dst->data = d;
- s = src->data;
-
- if (*s == '+') {
- c = 62;
- } else if (*s == '/') {
- c = 63;
+ s = src->data;
- } else if (*s >= '0' && *s <= '9') {
- c = *s - '0' + 52;
+ while (len > 3) {
+ *d++ = basis64[s[0]] << 2 | basis64[s[1]] >> 4;
+ *d++ = basis64[s[1]] << 4 | basis64[s[2]] >> 2;
+ *d++ = basis64[s[2]] << 6 | basis64[s[3]];
- } else if (*s >= 'A' && *s <= 'Z') {
- c = *s - 'A';
+ s += 4;
+ len -= 4;
+ }
- } else if (*s >= 'a' && *s <= 'z') {
- c = *s - 'a' + 26;
+ if (len > 1) {
+ *d++ = basis64[s[0]] << 2 | basis64[s[1]] >> 4;
+ }
- } else {
- return NGX_ERROR;
+ if (len > 2) {
+ *d++ = basis64[s[1]] << 4 | basis64[s[2]] >> 2;
}
+ dst->len = d - dst->data;
+ *d++ = '\0';
+
return NGX_OK;
}
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index d087e3e96..8a0212685 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -71,6 +71,9 @@ ngx_int_t ngx_hextoi(u_char *line, size_t n);
void ngx_md5_text(u_char *text, u_char *md5);
+ngx_int_t ngx_encode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst);
+ngx_int_t ngx_decode_base64(ngx_pool_t *pool, ngx_str_t *src, ngx_str_t *dst);
+
#define ngx_qsort qsort
diff --git a/src/http/modules/ngx_http_access_handler.c b/src/http/modules/ngx_http_access_handler.c
index 6dd572931..086f2fc0e 100644
--- a/src/http/modules/ngx_http_access_handler.c
+++ b/src/http/modules/ngx_http_access_handler.c
@@ -68,7 +68,7 @@ ngx_module_t ngx_http_access_module = {
ngx_http_access_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
ngx_http_access_init, /* init module */
- NULL /* init child */
+ NULL /* init process */
};
diff --git a/src/http/modules/ngx_http_userid_handler.c b/src/http/modules/ngx_http_userid_handler.c
new file mode 100644
index 000000000..f4bbb522b
--- /dev/null
+++ b/src/http/modules/ngx_http_userid_handler.c
@@ -0,0 +1,421 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+#define NGX_HTTP_USERID_OFF 0x0002
+#define NGX_HTTP_USERID_ON 0x0004
+#define NGX_HTTP_USERID_LOGONLY 0x0008
+#define NGX_HTTP_USERID_TIME 0x0010
+
+
+typedef struct {
+ ngx_flag_t enable;
+
+ ngx_int_t version;
+ ngx_int_t service;
+
+ ngx_str_t name;
+ ngx_str_t domain;
+ ngx_str_t path;
+ time_t expires;
+
+ ngx_int_t p3p;
+ ngx_str_t p3p_string;
+} ngx_http_userid_conf_t;
+
+
+typedef struct {
+ uint32_t uid_got[4];
+ uint32_t uid_set[4];
+ struct timeval tv;
+} ngx_http_userid_ctx_t;
+
+
+static ngx_int_t ngx_http_userid_get_uid(ngx_http_request_t *r,
+ ngx_http_userid_ctx_t *ctx,
+ ngx_http_userid_conf_t *conf);
+
+static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf,
+ uintptr_t data);
+static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf,
+ uintptr_t data);
+static u_char *ngx_http_userid_log_uid_time(ngx_http_request_t *r, u_char *buf,
+ uintptr_t data);
+
+static ngx_int_t ngx_http_userid_pre_conf(ngx_conf_t *cf);
+static void *ngx_http_userid_create_conf(ngx_conf_t *cf);
+static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent,
+ void *child);
+static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle);
+
+
+static ngx_conf_enum_t ngx_http_userid_mask[] = {
+ { ngx_string("off"), NGX_HTTP_USERID_OFF },
+ { ngx_string("on"), NGX_HTTP_USERID_ON },
+ { ngx_string("logonly"), NGX_HTTP_USERID_LOGONLY },
+ { ngx_string("time"), NGX_HTTP_USERID_TIME },
+ { ngx_null_string, 0 }
+};
+
+
+static ngx_command_t ngx_http_userid_commands[] = {
+
+ { ngx_string("userid"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY,
+ ngx_conf_set_bitmask_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_userid_conf_t, enable),
+ ngx_http_userid_mask},
+
+ { ngx_string("userid_service"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ 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_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_conf_set_str_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_userid_conf_t, domain),
+ NULL},
+
+ { ngx_string("userid_path"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_str_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_userid_conf_t, path),
+ NULL},
+
+ { ngx_string("userid_expires"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_sec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_userid_conf_t, expires),
+ NULL},
+
+ ngx_null_command
+};
+
+
+ngx_http_module_t ngx_http_userid_module_ctx = {
+ ngx_http_userid_pre_conf, /* pre conf */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL, /* merge server configuration */
+
+ ngx_http_userid_create_conf, /* create location configration */
+ ngx_http_userid_merge_conf /* merge location configration */
+};
+
+
+ngx_module_t ngx_http_userid_module = {
+ NGX_MODULE,
+ &ngx_http_userid_module_ctx, /* module context */
+ ngx_http_userid_commands, /* module directives */
+ NGX_HTTP_MODULE, /* module type */
+ ngx_http_userid_init, /* init module */
+ NULL /* init process */
+};
+
+
+static ngx_http_log_op_name_t ngx_http_userid_log_fmt_ops[] = {
+ { ngx_string("uid_got"), 0, ngx_http_userid_log_uid_got },
+ { ngx_string("uid_set"), 0, ngx_http_userid_log_uid_set },
+ { ngx_string("uid_time"), TIME_T_LEN + 4, ngx_http_userid_log_uid_time },
+ { ngx_null_string, 0, NULL }
+};
+
+
+static ngx_int_t ngx_http_userid_handler(ngx_http_request_t *r)
+{
+ ngx_int_t rc;
+ struct timeval tv;
+ ngx_http_userid_ctx_t *ctx;
+ ngx_http_userid_conf_t *conf;
+
+ conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_module);
+
+ if (conf->enable & NGX_HTTP_USERID_OFF) {
+ return NGX_OK;
+ }
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module);
+
+ if (ctx) {
+ return NGX_OK;
+ }
+
+ ngx_http_create_ctx(r, ctx, ngx_http_userid_module,
+ sizeof(ngx_http_userid_ctx_t),
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
+
+ if (conf->enable & (NGX_HTTP_USERID_ON|NGX_HTTP_USERID_LOGONLY)) {
+ rc = ngx_http_userid_get_uid(r, ctx, conf);
+
+ if (rc != NGX_OK) {
+ return rc;
+ }
+ }
+
+ if (conf->enable & NGX_HTTP_USERID_TIME) {
+ ngx_gettimeofday(&ctx->tv);
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t ngx_http_userid_get_uid(ngx_http_request_t *r,
+ ngx_http_userid_ctx_t *ctx,
+ ngx_http_userid_conf_t *conf)
+{
+ u_char *start, *last, *end;
+ uint32_t *uid;
+ ngx_int_t rc;
+ ngx_uint_t *cookies, i;
+ ngx_str_t src, dst;
+ ngx_table_elt_t *headers;
+
+ headers = r->headers_in.headers.elts;
+ cookies = r->headers_in.cookies.elts;
+
+ for (i = 0; i < r->headers_in.cookies.nelts; i++) {
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "cookie: %d:\"%s\"",
+ cookies[i],
+ headers[cookies[i]].value.data);
+
+ end = headers[cookies[i]].value.data + headers[cookies[i]].value.len;
+
+ for (start = headers[cookies[i]].value.data; start < end; /* void */) {
+
+ if (conf->name.len >= headers[cookies[i]].value.len
+ || ngx_strncmp(start, conf->name.data, conf->name.len) != 0)
+ {
+ start += conf->name.len;
+ while (start < end && *start++ != ';') { /* void */ }
+
+ for (/* void */; start < end && *start == ' '; start++) { /**/ }
+
+ continue;
+ }
+
+ for (start += conf->name.len; start < end && *start == ' '; start++)
+ {
+ /* void */
+ }
+
+ if (*start != '=') {
+ break;
+ }
+
+ for (start++; start < end && *start == ' '; start++) { /* void */ }
+
+ for (last = start; last < end && *last != ';'; last++) { /**/ }
+
+ if (last - start < 22) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "client sent too short userid cookie \"%s\"",
+ headers[cookies[i]].value.data);
+ break;
+ }
+
+ /*
+ * 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 "=="
+ */
+
+ src.len = 22;
+ src.data = start;
+
+ rc = ngx_decode_base64(r->pool, &src, &dst);
+
+ if (rc == NGX_ABORT) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if (rc == NGX_ERROR) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "client sent invalid userid cookie \"%s\"",
+ headers[cookies[i]].value.data);
+ break;
+ }
+
+ uid = (uint32_t *) dst.data;
+ ctx->uid_got[0] = uid[0];
+ ctx->uid_got[1] = uid[1];
+ ctx->uid_got[2] = uid[2];
+ ctx->uid_got[3] = uid[3];
+
+ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "uid: %08X%08X%08X%08X",
+ uid[0], uid[1], uid[2], uid[3]);
+
+ return NGX_OK;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
+static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf,
+ uintptr_t data)
+{
+ ngx_http_userid_ctx_t *ctx;
+ ngx_http_userid_conf_t *conf;
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module);
+
+ if (ctx == NULL || ctx->uid_got[3] == 0) {
+ if (buf == NULL) {
+ return (u_char *) 1;
+ }
+
+ *buf = '-';
+ return buf + 1;
+ }
+
+ conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_module);
+
+ if (buf == NULL) {
+ return (u_char *) (conf->name.len + 1 + 32);
+ }
+
+ buf = ngx_cpymem(buf, conf->name.data, conf->name.len);
+
+ *buf++ = '=';
+
+ return buf + ngx_snprintf((char *) buf, 33, "%08X%08X%08X%08X",
+ ctx->uid_got[0], ctx->uid_got[1],
+ ctx->uid_got[2], ctx->uid_got[3]);
+}
+
+
+static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf,
+ uintptr_t data)
+{
+ if (buf == NULL) {
+ return (u_char *) 1;
+ }
+
+ *buf = '-';
+
+ return buf + 1;
+}
+
+
+static u_char *ngx_http_userid_log_uid_time(ngx_http_request_t *r, u_char *buf,
+ uintptr_t data)
+{
+ ngx_http_userid_ctx_t *ctx;
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module);
+
+ if (ctx == NULL || ctx->tv.tv_sec == 0) {
+ *buf = '-';
+ return buf + 1;
+ }
+
+ return buf + ngx_snprintf((char *) buf, TIME_T_LEN + 5,
+ "%ld.%03ld",
+ ctx->tv.tv_sec, ctx->tv.tv_usec / 1000);
+}
+
+
+static ngx_int_t ngx_http_userid_pre_conf(ngx_conf_t *cf)
+{
+ ngx_http_log_op_name_t *op;
+
+ for (op = ngx_http_userid_log_fmt_ops; op->name.len; op++) { /* void */ }
+ op->op = NULL;
+
+ op = ngx_http_log_fmt_ops;
+
+ for (op = ngx_http_log_fmt_ops; op->op; op++) {
+ if (op->name.len == 0) {
+ op = (ngx_http_log_op_name_t *) op->op;
+ }
+ }
+
+ op->op = (ngx_http_log_op_pt) ngx_http_userid_log_fmt_ops;
+
+ return NGX_OK;
+}
+
+
+static void *ngx_http_userid_create_conf(ngx_conf_t *cf)
+{
+ ngx_http_userid_conf_t *conf;
+
+ if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_userid_conf_t)))) {
+ return NGX_CONF_ERROR;
+ }
+
+ /* set by ngx_pcalloc():
+
+ conf->enable = 0;
+
+ conf->name.len = 0;
+ conf->name.date = NULL;
+ conf->domain.len = 0;
+ conf->domain.date = NULL;
+ conf->path.len = 0;
+ conf->path.date = NULL;
+
+ */
+
+
+ return conf;
+}
+
+
+static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent,
+ void *child)
+{
+ ngx_http_userid_conf_t *prev = parent;
+ ngx_http_userid_conf_t *conf = child;
+
+ ngx_conf_merge_bitmask_value(conf->enable, prev->enable,
+ (NGX_CONF_BITMASK_SET
+ |NGX_HTTP_USERID_OFF));
+
+ ngx_conf_merge_str_value(conf->name, prev->name, "uid");
+ ngx_conf_merge_str_value(conf->domain, prev->domain, ".");
+ ngx_conf_merge_str_value(conf->path, prev->path, "/");
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle)
+{
+ ngx_http_handler_pt *h;
+ ngx_http_core_main_conf_t *cmcf;
+
+ cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
+
+ h = ngx_push_array(&cmcf->phases[NGX_HTTP_MISC_PHASE].handlers);
+ if (h == NULL) {
+ return NGX_ERROR;
+ }
+
+ *h = ngx_http_userid_handler;
+
+ return NGX_OK;
+}
diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c
index 3599f0abd..80759aebf 100644
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -627,6 +627,8 @@ static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p)
output->allocated = 1;
r->request_body->buf->pos = r->request_body->buf->start;
+ r->request_body->buf->last = r->request_body->buf->start;
+ r->request_body->buf->tag = (ngx_buf_tag_t) &ngx_http_proxy_module;
}
p->request_sent = 0;
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 492ba6f8a..b8b246196 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -257,6 +257,11 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
*h = ngx_http_find_location_config;
+ ngx_init_array(cmcf->phases[NGX_HTTP_MISC_PHASE].handlers,
+ cf->cycle->pool, 10, sizeof(ngx_http_handler_pt),
+ NGX_CONF_ERROR);
+ cmcf->phases[NGX_HTTP_MISC_PHASE].type = NGX_DECLINED;
+
ngx_init_array(cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers,
cf->cycle->pool, 10, sizeof(ngx_http_handler_pt),
NGX_CONF_ERROR);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 6c0e7a1b0..75bb6b3af 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -23,6 +23,7 @@ typedef enum {
NGX_HTTP_FIND_CONFIG_PHASE,
+ NGX_HTTP_MISC_PHASE,
NGX_HTTP_ACCESS_PHASE,
NGX_HTTP_CONTENT_PHASE,
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 95e6d5f2b..b05ea92ce 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -617,12 +617,28 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
return;
}
- /* r->headers_in.headers.elts = NULL; */
/* r->headers_in.headers.nelts = 0; */
r->headers_in.headers.size = sizeof(ngx_table_elt_t);
r->headers_in.headers.nalloc = 20;
r->headers_in.headers.pool = r->pool;
+
+ /* init the r->headers_in.cookies array */
+
+ r->headers_in.cookies.elts = ngx_pcalloc(r->pool,
+ 5 * sizeof(ngx_uint_t));
+ if (r->headers_in.cookies.elts == NULL) {
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ /* r->headers_in.cookies.nelts = 0; */
+ r->headers_in.cookies.size = sizeof(ngx_uint_t);
+ r->headers_in.cookies.nalloc = 5;
+ r->headers_in.cookies.pool = r->pool;
+
+
ctx = c->log->data;
ctx->action = "reading client request headers";
ctx->url = r->unparsed_uri.data;
@@ -715,6 +731,7 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
{
ssize_t n;
ngx_int_t rc, i, offset;
+ ngx_uint_t *cookie;
ngx_table_elt_t *h;
ngx_connection_t *c;
ngx_http_request_t *r;
@@ -783,17 +800,31 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
h->value.data[h->value.len] = '\0';
}
- for (i = 0; ngx_http_headers_in[i].name.len != 0; i++) {
- if (ngx_http_headers_in[i].name.len != h->key.len) {
- continue;
+ if (h->key.len == sizeof("Cookie") - 1
+ && ngx_strcasecmp(h->key.data, "Cookie") == 0)
+ {
+ if (!(cookie = ngx_push_array(&r->headers_in.cookies))) {
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_http_close_connection(c);
+ return;
}
- if (ngx_strcasecmp(ngx_http_headers_in[i].name.data,
- h->key.data) == 0)
- {
- *((ngx_table_elt_t **) ((char *) &r->headers_in
+ *cookie = r->headers_in.headers.nelts - 1;
+
+ } else {
+
+ for (i = 0; ngx_http_headers_in[i].name.len != 0; i++) {
+ if (ngx_http_headers_in[i].name.len != h->key.len) {
+ continue;
+ }
+
+ if (ngx_strcasecmp(ngx_http_headers_in[i].name.data,
+ h->key.data) == 0)
+ {
+ *((ngx_table_elt_t **) ((char *) &r->headers_in
+ ngx_http_headers_in[i].offset)) = h;
- break;
+ break;
+ }
}
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index d987c515a..470dcc16d 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -138,6 +138,8 @@ typedef struct {
ngx_table_elt_t *x_forwarded_for;
#endif
+ ngx_array_t cookies;
+
size_t host_name_len;
ssize_t content_length_n;
size_t connection_type;