comparison src/http/modules/ngx_http_userid_handler.c @ 408:d6e2b445c1b8

nginx-0.0.10-2004-08-27-19:40:59 import
author Igor Sysoev <igor@sysoev.ru>
date Fri, 27 Aug 2004 15:40:59 +0000
parents
children
comparison
equal deleted inserted replaced
407:35fe251cd231 408:d6e2b445c1b8
1
2 #include <ngx_config.h>
3 #include <ngx_core.h>
4 #include <ngx_http.h>
5
6
7 #define NGX_HTTP_USERID_OFF 0x0002
8 #define NGX_HTTP_USERID_ON 0x0004
9 #define NGX_HTTP_USERID_LOGONLY 0x0008
10 #define NGX_HTTP_USERID_TIME 0x0010
11
12
13 typedef struct {
14 ngx_flag_t enable;
15
16 ngx_int_t version;
17 ngx_int_t service;
18
19 ngx_str_t name;
20 ngx_str_t domain;
21 ngx_str_t path;
22 time_t expires;
23
24 ngx_int_t p3p;
25 ngx_str_t p3p_string;
26 } ngx_http_userid_conf_t;
27
28
29 typedef struct {
30 uint32_t uid_got[4];
31 uint32_t uid_set[4];
32 struct timeval tv;
33 } ngx_http_userid_ctx_t;
34
35
36 static ngx_int_t ngx_http_userid_get_uid(ngx_http_request_t *r,
37 ngx_http_userid_ctx_t *ctx,
38 ngx_http_userid_conf_t *conf);
39
40 static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf,
41 uintptr_t data);
42 static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf,
43 uintptr_t data);
44 static u_char *ngx_http_userid_log_uid_time(ngx_http_request_t *r, u_char *buf,
45 uintptr_t data);
46
47 static ngx_int_t ngx_http_userid_pre_conf(ngx_conf_t *cf);
48 static void *ngx_http_userid_create_conf(ngx_conf_t *cf);
49 static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent,
50 void *child);
51 static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle);
52
53
54 static ngx_conf_enum_t ngx_http_userid_mask[] = {
55 { ngx_string("off"), NGX_HTTP_USERID_OFF },
56 { ngx_string("on"), NGX_HTTP_USERID_ON },
57 { ngx_string("logonly"), NGX_HTTP_USERID_LOGONLY },
58 { ngx_string("time"), NGX_HTTP_USERID_TIME },
59 { ngx_null_string, 0 }
60 };
61
62
63 static ngx_command_t ngx_http_userid_commands[] = {
64
65 { ngx_string("userid"),
66 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY,
67 ngx_conf_set_bitmask_slot,
68 NGX_HTTP_LOC_CONF_OFFSET,
69 offsetof(ngx_http_userid_conf_t, enable),
70 ngx_http_userid_mask},
71
72 { ngx_string("userid_service"),
73 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
74 ngx_conf_set_num_slot,
75 NGX_HTTP_LOC_CONF_OFFSET,
76 offsetof(ngx_http_userid_conf_t, service),
77 NULL},
78
79 { ngx_string("userid_name"),
80 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
81 ngx_conf_set_str_slot,
82 NGX_HTTP_LOC_CONF_OFFSET,
83 offsetof(ngx_http_userid_conf_t, name),
84 NULL},
85
86 { ngx_string("userid_domain"),
87 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
88 ngx_conf_set_str_slot,
89 NGX_HTTP_LOC_CONF_OFFSET,
90 offsetof(ngx_http_userid_conf_t, domain),
91 NULL},
92
93 { ngx_string("userid_path"),
94 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
95 ngx_conf_set_str_slot,
96 NGX_HTTP_LOC_CONF_OFFSET,
97 offsetof(ngx_http_userid_conf_t, path),
98 NULL},
99
100 { ngx_string("userid_expires"),
101 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
102 ngx_conf_set_sec_slot,
103 NGX_HTTP_LOC_CONF_OFFSET,
104 offsetof(ngx_http_userid_conf_t, expires),
105 NULL},
106
107 ngx_null_command
108 };
109
110
111 ngx_http_module_t ngx_http_userid_module_ctx = {
112 ngx_http_userid_pre_conf, /* pre conf */
113
114 NULL, /* create main configuration */
115 NULL, /* init main configuration */
116
117 NULL, /* create server configuration */
118 NULL, /* merge server configuration */
119
120 ngx_http_userid_create_conf, /* create location configration */
121 ngx_http_userid_merge_conf /* merge location configration */
122 };
123
124
125 ngx_module_t ngx_http_userid_module = {
126 NGX_MODULE,
127 &ngx_http_userid_module_ctx, /* module context */
128 ngx_http_userid_commands, /* module directives */
129 NGX_HTTP_MODULE, /* module type */
130 ngx_http_userid_init, /* init module */
131 NULL /* init process */
132 };
133
134
135 static ngx_http_log_op_name_t ngx_http_userid_log_fmt_ops[] = {
136 { ngx_string("uid_got"), 0, ngx_http_userid_log_uid_got },
137 { ngx_string("uid_set"), 0, ngx_http_userid_log_uid_set },
138 { ngx_string("uid_time"), TIME_T_LEN + 4, ngx_http_userid_log_uid_time },
139 { ngx_null_string, 0, NULL }
140 };
141
142
143 static ngx_int_t ngx_http_userid_handler(ngx_http_request_t *r)
144 {
145 ngx_int_t rc;
146 struct timeval tv;
147 ngx_http_userid_ctx_t *ctx;
148 ngx_http_userid_conf_t *conf;
149
150 conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_module);
151
152 if (conf->enable & NGX_HTTP_USERID_OFF) {
153 return NGX_OK;
154 }
155
156 ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module);
157
158 if (ctx) {
159 return NGX_OK;
160 }
161
162 ngx_http_create_ctx(r, ctx, ngx_http_userid_module,
163 sizeof(ngx_http_userid_ctx_t),
164 NGX_HTTP_INTERNAL_SERVER_ERROR);
165
166 if (conf->enable & (NGX_HTTP_USERID_ON|NGX_HTTP_USERID_LOGONLY)) {
167 rc = ngx_http_userid_get_uid(r, ctx, conf);
168
169 if (rc != NGX_OK) {
170 return rc;
171 }
172 }
173
174 if (conf->enable & NGX_HTTP_USERID_TIME) {
175 ngx_gettimeofday(&ctx->tv);
176 }
177
178 return NGX_OK;
179 }
180
181
182 static ngx_int_t ngx_http_userid_get_uid(ngx_http_request_t *r,
183 ngx_http_userid_ctx_t *ctx,
184 ngx_http_userid_conf_t *conf)
185 {
186 u_char *start, *last, *end;
187 uint32_t *uid;
188 ngx_int_t rc;
189 ngx_uint_t *cookies, i;
190 ngx_str_t src, dst;
191 ngx_table_elt_t *headers;
192
193 headers = r->headers_in.headers.elts;
194 cookies = r->headers_in.cookies.elts;
195
196 for (i = 0; i < r->headers_in.cookies.nelts; i++) {
197 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
198 "cookie: %d:\"%s\"",
199 cookies[i],
200 headers[cookies[i]].value.data);
201
202 end = headers[cookies[i]].value.data + headers[cookies[i]].value.len;
203
204 for (start = headers[cookies[i]].value.data; start < end; /* void */) {
205
206 if (conf->name.len >= headers[cookies[i]].value.len
207 || ngx_strncmp(start, conf->name.data, conf->name.len) != 0)
208 {
209 start += conf->name.len;
210 while (start < end && *start++ != ';') { /* void */ }
211
212 for (/* void */; start < end && *start == ' '; start++) { /**/ }
213
214 continue;
215 }
216
217 for (start += conf->name.len; start < end && *start == ' '; start++)
218 {
219 /* void */
220 }
221
222 if (*start != '=') {
223 break;
224 }
225
226 for (start++; start < end && *start == ' '; start++) { /* void */ }
227
228 for (last = start; last < end && *last != ';'; last++) { /**/ }
229
230 if (last - start < 22) {
231 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
232 "client sent too short userid cookie \"%s\"",
233 headers[cookies[i]].value.data);
234 break;
235 }
236
237 /*
238 * we have to limit encoded string to 22 characters
239 * because there are already the millions cookies with a garbage
240 * instead of the correct base64 trail "=="
241 */
242
243 src.len = 22;
244 src.data = start;
245
246 rc = ngx_decode_base64(r->pool, &src, &dst);
247
248 if (rc == NGX_ABORT) {
249 return NGX_HTTP_INTERNAL_SERVER_ERROR;
250 }
251
252 if (rc == NGX_ERROR) {
253 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
254 "client sent invalid userid cookie \"%s\"",
255 headers[cookies[i]].value.data);
256 break;
257 }
258
259 uid = (uint32_t *) dst.data;
260 ctx->uid_got[0] = uid[0];
261 ctx->uid_got[1] = uid[1];
262 ctx->uid_got[2] = uid[2];
263 ctx->uid_got[3] = uid[3];
264
265 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
266 "uid: %08X%08X%08X%08X",
267 uid[0], uid[1], uid[2], uid[3]);
268
269 return NGX_OK;
270 }
271 }
272
273 return NGX_OK;
274 }
275
276
277 static u_char *ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf,
278 uintptr_t data)
279 {
280 ngx_http_userid_ctx_t *ctx;
281 ngx_http_userid_conf_t *conf;
282
283 ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module);
284
285 if (ctx == NULL || ctx->uid_got[3] == 0) {
286 if (buf == NULL) {
287 return (u_char *) 1;
288 }
289
290 *buf = '-';
291 return buf + 1;
292 }
293
294 conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_module);
295
296 if (buf == NULL) {
297 return (u_char *) (conf->name.len + 1 + 32);
298 }
299
300 buf = ngx_cpymem(buf, conf->name.data, conf->name.len);
301
302 *buf++ = '=';
303
304 return buf + ngx_snprintf((char *) buf, 33, "%08X%08X%08X%08X",
305 ctx->uid_got[0], ctx->uid_got[1],
306 ctx->uid_got[2], ctx->uid_got[3]);
307 }
308
309
310 static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf,
311 uintptr_t data)
312 {
313 if (buf == NULL) {
314 return (u_char *) 1;
315 }
316
317 *buf = '-';
318
319 return buf + 1;
320 }
321
322
323 static u_char *ngx_http_userid_log_uid_time(ngx_http_request_t *r, u_char *buf,
324 uintptr_t data)
325 {
326 ngx_http_userid_ctx_t *ctx;
327
328 ctx = ngx_http_get_module_ctx(r, ngx_http_userid_module);
329
330 if (ctx == NULL || ctx->tv.tv_sec == 0) {
331 *buf = '-';
332 return buf + 1;
333 }
334
335 return buf + ngx_snprintf((char *) buf, TIME_T_LEN + 5,
336 "%ld.%03ld",
337 ctx->tv.tv_sec, ctx->tv.tv_usec / 1000);
338 }
339
340
341 static ngx_int_t ngx_http_userid_pre_conf(ngx_conf_t *cf)
342 {
343 ngx_http_log_op_name_t *op;
344
345 for (op = ngx_http_userid_log_fmt_ops; op->name.len; op++) { /* void */ }
346 op->op = NULL;
347
348 op = ngx_http_log_fmt_ops;
349
350 for (op = ngx_http_log_fmt_ops; op->op; op++) {
351 if (op->name.len == 0) {
352 op = (ngx_http_log_op_name_t *) op->op;
353 }
354 }
355
356 op->op = (ngx_http_log_op_pt) ngx_http_userid_log_fmt_ops;
357
358 return NGX_OK;
359 }
360
361
362 static void *ngx_http_userid_create_conf(ngx_conf_t *cf)
363 {
364 ngx_http_userid_conf_t *conf;
365
366 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_userid_conf_t)))) {
367 return NGX_CONF_ERROR;
368 }
369
370 /* set by ngx_pcalloc():
371
372 conf->enable = 0;
373
374 conf->name.len = 0;
375 conf->name.date = NULL;
376 conf->domain.len = 0;
377 conf->domain.date = NULL;
378 conf->path.len = 0;
379 conf->path.date = NULL;
380
381 */
382
383
384 return conf;
385 }
386
387
388 static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent,
389 void *child)
390 {
391 ngx_http_userid_conf_t *prev = parent;
392 ngx_http_userid_conf_t *conf = child;
393
394 ngx_conf_merge_bitmask_value(conf->enable, prev->enable,
395 (NGX_CONF_BITMASK_SET
396 |NGX_HTTP_USERID_OFF));
397
398 ngx_conf_merge_str_value(conf->name, prev->name, "uid");
399 ngx_conf_merge_str_value(conf->domain, prev->domain, ".");
400 ngx_conf_merge_str_value(conf->path, prev->path, "/");
401
402 return NGX_CONF_OK;
403 }
404
405
406 static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle)
407 {
408 ngx_http_handler_pt *h;
409 ngx_http_core_main_conf_t *cmcf;
410
411 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
412
413 h = ngx_push_array(&cmcf->phases[NGX_HTTP_MISC_PHASE].handlers);
414 if (h == NULL) {
415 return NGX_ERROR;
416 }
417
418 *h = ngx_http_userid_handler;
419
420 return NGX_OK;
421 }