Mercurial > hg > nginx
comparison src/http/modules/ngx_http_log_module.c @ 880:3b763d36e055
axe old % log format
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 27 Nov 2006 14:46:15 +0000 |
parents | 63a820b0bc6c |
children | be52cfdb3e31 |
comparison
equal
deleted
inserted
replaced
879:804514cb0758 | 880:3b763d36e055 |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 #include <nginx.h> | 10 #include <nginx.h> |
11 | 11 |
12 | |
13 typedef struct ngx_http_log_op_s ngx_http_log_op_t; | |
14 | |
15 typedef u_char *(*ngx_http_log_op_run_pt) (ngx_http_request_t *r, u_char *buf, | |
16 ngx_http_log_op_t *op); | |
17 | |
18 typedef size_t (*ngx_http_log_op_getlen_pt) (ngx_http_request_t *r, | |
19 uintptr_t data); | |
20 | |
21 | |
22 struct ngx_http_log_op_s { | |
23 size_t len; | |
24 ngx_http_log_op_getlen_pt getlen; | |
25 ngx_http_log_op_run_pt run; | |
26 uintptr_t data; | |
27 }; | |
12 | 28 |
13 | 29 |
14 typedef struct { | 30 typedef struct { |
15 ngx_str_t name; | 31 ngx_str_t name; |
16 ngx_array_t *ops; /* array of ngx_http_log_op_t */ | 32 ngx_array_t *ops; /* array of ngx_http_log_op_t */ |
41 size_t len; | 57 size_t len; |
42 ngx_http_log_op_run_pt run; | 58 ngx_http_log_op_run_pt run; |
43 } ngx_http_log_var_t; | 59 } ngx_http_log_var_t; |
44 | 60 |
45 | 61 |
46 static u_char *ngx_http_log_addr(ngx_http_request_t *r, u_char *buf, | |
47 ngx_http_log_op_t *op); | |
48 static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, | 62 static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, |
49 ngx_http_log_op_t *op); | 63 ngx_http_log_op_t *op); |
50 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, | 64 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, |
51 ngx_http_log_op_t *op); | 65 ngx_http_log_op_t *op); |
52 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, | 66 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, |
62 static u_char *ngx_http_log_body_bytes_sent(ngx_http_request_t *r, | 76 static u_char *ngx_http_log_body_bytes_sent(ngx_http_request_t *r, |
63 u_char *buf, ngx_http_log_op_t *op); | 77 u_char *buf, ngx_http_log_op_t *op); |
64 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, | 78 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, |
65 ngx_http_log_op_t *op); | 79 ngx_http_log_op_t *op); |
66 | 80 |
67 static size_t ngx_http_log_request_getlen(ngx_http_request_t *r, | |
68 uintptr_t data); | |
69 static u_char *ngx_http_log_request(ngx_http_request_t *r, u_char *buf, | |
70 ngx_http_log_op_t *op); | |
71 | |
72 static ngx_int_t ngx_http_log_header_in_compile(ngx_conf_t *cf, | |
73 ngx_http_log_op_t *op, ngx_str_t *value); | |
74 static size_t ngx_http_log_header_in_getlen(ngx_http_request_t *r, | |
75 uintptr_t data); | |
76 static u_char *ngx_http_log_header_in(ngx_http_request_t *r, u_char *buf, | |
77 ngx_http_log_op_t *op); | |
78 static size_t ngx_http_log_unknown_header_in_getlen(ngx_http_request_t *r, | |
79 uintptr_t data); | |
80 static u_char *ngx_http_log_unknown_header_in(ngx_http_request_t *r, | |
81 u_char *buf, ngx_http_log_op_t *op); | |
82 | |
83 static ngx_int_t ngx_http_log_header_out_compile(ngx_conf_t *cf, | |
84 ngx_http_log_op_t *op, ngx_str_t *value); | |
85 static size_t ngx_http_log_header_out_getlen(ngx_http_request_t *r, | |
86 uintptr_t data); | |
87 static u_char *ngx_http_log_header_out(ngx_http_request_t *r, u_char *buf, | |
88 ngx_http_log_op_t *op); | |
89 static size_t ngx_http_log_unknown_header_out_getlen(ngx_http_request_t *r, | |
90 uintptr_t data); | |
91 static u_char *ngx_http_log_unknown_header_out(ngx_http_request_t *r, | |
92 u_char *buf, ngx_http_log_op_t *op); | |
93 | |
94 static u_char *ngx_http_log_connection_header_out(ngx_http_request_t *r, | |
95 u_char *buf, ngx_http_log_op_t *op); | |
96 static u_char *ngx_http_log_transfer_encoding_header_out(ngx_http_request_t *r, | |
97 u_char *buf, ngx_http_log_op_t *op); | |
98 | |
99 static ngx_table_elt_t *ngx_http_log_unknown_header(ngx_list_t *headers, | |
100 ngx_str_t *value); | |
101 | |
102 static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, | 81 static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, |
103 ngx_http_log_op_t *op, ngx_str_t *value); | 82 ngx_http_log_op_t *op, ngx_str_t *value); |
104 static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r, | 83 static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r, |
105 uintptr_t data); | 84 uintptr_t data); |
106 static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, | 85 static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, |
107 ngx_http_log_op_t *op); | 86 ngx_http_log_op_t *op); |
108 | 87 |
109 | 88 |
110 static ngx_int_t ngx_http_log_set_formats(ngx_conf_t *cf); | |
111 static void *ngx_http_log_create_main_conf(ngx_conf_t *cf); | 89 static void *ngx_http_log_create_main_conf(ngx_conf_t *cf); |
112 static void *ngx_http_log_create_loc_conf(ngx_conf_t *cf); | 90 static void *ngx_http_log_create_loc_conf(ngx_conf_t *cf); |
113 static char *ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, | 91 static char *ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, |
114 void *child); | 92 void *child); |
115 static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, | 93 static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, |
141 ngx_null_command | 119 ngx_null_command |
142 }; | 120 }; |
143 | 121 |
144 | 122 |
145 static ngx_http_module_t ngx_http_log_module_ctx = { | 123 static ngx_http_module_t ngx_http_log_module_ctx = { |
146 ngx_http_log_set_formats, /* preconfiguration */ | 124 NULL, /* preconfiguration */ |
147 ngx_http_log_init, /* postconfiguration */ | 125 ngx_http_log_init, /* postconfiguration */ |
148 | 126 |
149 ngx_http_log_create_main_conf, /* create main configuration */ | 127 ngx_http_log_create_main_conf, /* create main configuration */ |
150 NULL, /* init main configuration */ | 128 NULL, /* init main configuration */ |
151 | 129 |
200 | 178 |
201 { ngx_null_string, 0, NULL } | 179 { ngx_null_string, 0, NULL } |
202 }; | 180 }; |
203 | 181 |
204 | 182 |
205 ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { | |
206 { ngx_string("addr"), INET_ADDRSTRLEN - 1, NULL, NULL, ngx_http_log_addr }, | |
207 { ngx_string("conn"), NGX_ATOMIC_T_LEN, NULL, NULL, | |
208 ngx_http_log_connection }, | |
209 { ngx_string("pipe"), 1, NULL, NULL, ngx_http_log_pipe }, | |
210 { ngx_string("time"), sizeof("28/Sep/1970:12:00:00 +0600") - 1, | |
211 NULL, NULL, ngx_http_log_time }, | |
212 { ngx_string("msec"), NGX_TIME_T_LEN + 4, NULL, NULL, ngx_http_log_msec }, | |
213 { ngx_string("request_time"), NGX_TIME_T_LEN, NULL, NULL, | |
214 ngx_http_log_request_time }, | |
215 { ngx_string("status"), 3, NULL, NULL, ngx_http_log_status }, | |
216 { ngx_string("length"), NGX_OFF_T_LEN, | |
217 NULL, NULL, ngx_http_log_bytes_sent }, | |
218 { ngx_string("apache_length"), NGX_OFF_T_LEN, | |
219 NULL, NULL, ngx_http_log_body_bytes_sent }, | |
220 { ngx_string("request_length"), NGX_SIZE_T_LEN, | |
221 NULL, NULL, ngx_http_log_request_length }, | |
222 | |
223 { ngx_string("request"), 0, NULL, | |
224 ngx_http_log_request_getlen, | |
225 ngx_http_log_request }, | |
226 | |
227 { ngx_string("i"), 0, ngx_http_log_header_in_compile, NULL, | |
228 ngx_http_log_header_in }, | |
229 { ngx_string("o"), 0, ngx_http_log_header_out_compile, NULL, | |
230 ngx_http_log_header_out }, | |
231 { ngx_string("v"), 0, ngx_http_log_variable_compile, NULL, | |
232 ngx_http_log_variable }, | |
233 | |
234 { ngx_null_string, 0, NULL, NULL, NULL } | |
235 }; | |
236 | |
237 | |
238 ngx_int_t | 183 ngx_int_t |
239 ngx_http_log_handler(ngx_http_request_t *r) | 184 ngx_http_log_handler(ngx_http_request_t *r) |
240 { | 185 { |
241 ngx_uint_t i, l; | 186 ngx_uint_t i, l; |
242 u_char *line, *p; | 187 u_char *line, *p; |
365 return ngx_cpymem(buf, (u_char *) op->data, op->len); | 310 return ngx_cpymem(buf, (u_char *) op->data, op->len); |
366 } | 311 } |
367 | 312 |
368 | 313 |
369 static u_char * | 314 static u_char * |
370 ngx_http_log_addr(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) | |
371 { | |
372 return ngx_cpymem(buf, r->connection->addr_text.data, | |
373 r->connection->addr_text.len); | |
374 } | |
375 | |
376 | |
377 static u_char * | |
378 ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, | 315 ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, |
379 ngx_http_log_op_t *op) | 316 ngx_http_log_op_t *op) |
380 { | 317 { |
381 return ngx_sprintf(buf, "%ui", r->connection->number); | 318 return ngx_sprintf(buf, "%ui", r->connection->number); |
382 } | 319 } |
424 | 361 |
425 return ngx_sprintf(buf, "%T", elapsed); | 362 return ngx_sprintf(buf, "%T", elapsed); |
426 } | 363 } |
427 | 364 |
428 | 365 |
429 static size_t | |
430 ngx_http_log_request_getlen(ngx_http_request_t *r, uintptr_t data) | |
431 { | |
432 return r->request_line.len; | |
433 } | |
434 | |
435 | |
436 static u_char * | |
437 ngx_http_log_request(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) | |
438 { | |
439 return ngx_cpymem(buf, r->request_line.data, r->request_line.len); | |
440 } | |
441 | |
442 | |
443 static u_char * | 366 static u_char * |
444 ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) | 367 ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) |
445 { | 368 { |
446 return ngx_sprintf(buf, "%ui", | 369 return ngx_sprintf(buf, "%ui", |
447 r->err_status ? r->err_status : r->headers_out.status); | 370 r->err_status ? r->err_status : r->headers_out.status); |
477 static u_char * | 400 static u_char * |
478 ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, | 401 ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, |
479 ngx_http_log_op_t *op) | 402 ngx_http_log_op_t *op) |
480 { | 403 { |
481 return ngx_sprintf(buf, "%O", r->request_length); | 404 return ngx_sprintf(buf, "%O", r->request_length); |
482 } | |
483 | |
484 | |
485 static ngx_int_t | |
486 ngx_http_log_header_in_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, | |
487 ngx_str_t *value) | |
488 { | |
489 ngx_uint_t i; | |
490 | |
491 op->len = 0; | |
492 | |
493 for (i = 0; ngx_http_headers_in[i].name.len != 0; i++) { | |
494 | |
495 if (ngx_http_headers_in[i].name.len != value->len) { | |
496 continue; | |
497 } | |
498 | |
499 /* STUB: "Cookie" speacial handling */ | |
500 if (ngx_http_headers_in[i].offset == 0) { | |
501 continue; | |
502 } | |
503 | |
504 if (ngx_strncasecmp(ngx_http_headers_in[i].name.data, value->data, | |
505 value->len) == 0) | |
506 { | |
507 op->getlen = ngx_http_log_header_in_getlen; | |
508 op->run = ngx_http_log_header_in; | |
509 op->data = ngx_http_headers_in[i].offset; | |
510 | |
511 return NGX_OK; | |
512 } | |
513 } | |
514 | |
515 op->getlen = ngx_http_log_unknown_header_in_getlen; | |
516 op->run = ngx_http_log_unknown_header_in; | |
517 op->data = (uintptr_t) value; | |
518 | |
519 return NGX_OK; | |
520 } | |
521 | |
522 | |
523 static size_t | |
524 ngx_http_log_header_in_getlen(ngx_http_request_t *r, uintptr_t data) | |
525 { | |
526 ngx_table_elt_t *h; | |
527 | |
528 h = *(ngx_table_elt_t **) ((char *) &r->headers_in + data); | |
529 | |
530 if (h) { | |
531 return h->value.len; | |
532 } | |
533 | |
534 return 1; | |
535 } | |
536 | |
537 | |
538 static u_char * | |
539 ngx_http_log_header_in(ngx_http_request_t *r, u_char *buf, | |
540 ngx_http_log_op_t *op) | |
541 { | |
542 ngx_table_elt_t *h; | |
543 | |
544 h = *(ngx_table_elt_t **) ((char *) &r->headers_in + op->data); | |
545 | |
546 if (h) { | |
547 return ngx_cpymem(buf, h->value.data, h->value.len); | |
548 } | |
549 | |
550 *buf = '-'; | |
551 | |
552 return buf + 1; | |
553 } | |
554 | |
555 | |
556 static size_t | |
557 ngx_http_log_unknown_header_in_getlen(ngx_http_request_t *r, uintptr_t data) | |
558 { | |
559 ngx_table_elt_t *h; | |
560 | |
561 h = ngx_http_log_unknown_header(&r->headers_in.headers, (ngx_str_t *) data); | |
562 | |
563 if (h) { | |
564 return h->value.len; | |
565 } | |
566 | |
567 return 1; | |
568 } | |
569 | |
570 | |
571 static u_char * | |
572 ngx_http_log_unknown_header_in(ngx_http_request_t *r, u_char *buf, | |
573 ngx_http_log_op_t *op) | |
574 { | |
575 ngx_table_elt_t *h; | |
576 | |
577 h = ngx_http_log_unknown_header(&r->headers_in.headers, | |
578 (ngx_str_t *) op->data); | |
579 | |
580 if (h) { | |
581 return ngx_cpymem(buf, h->value.data, h->value.len); | |
582 } | |
583 | |
584 *buf = '-'; | |
585 | |
586 return buf + 1; | |
587 } | |
588 | |
589 | |
590 static ngx_int_t | |
591 ngx_http_log_header_out_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, | |
592 ngx_str_t *value) | |
593 { | |
594 ngx_uint_t i; | |
595 | |
596 op->len = 0; | |
597 | |
598 for (i = 0; ngx_http_headers_out[i].name.len != 0; i++) { | |
599 | |
600 if (ngx_http_headers_out[i].name.len != value->len) { | |
601 continue; | |
602 } | |
603 | |
604 if (ngx_strncasecmp(ngx_http_headers_out[i].name.data, value->data, | |
605 value->len) == 0) | |
606 { | |
607 op->getlen = ngx_http_log_header_out_getlen; | |
608 op->run = ngx_http_log_header_out; | |
609 op->data = ngx_http_headers_out[i].offset; | |
610 | |
611 return NGX_OK; | |
612 } | |
613 } | |
614 | |
615 if (value->len == sizeof("Connection") - 1 | |
616 && ngx_strncasecmp(value->data, "Connection", value->len) == 0) | |
617 { | |
618 op->len = sizeof("keep-alive") - 1; | |
619 op->getlen = NULL; | |
620 op->run = ngx_http_log_connection_header_out; | |
621 op->data = 0; | |
622 return NGX_OK; | |
623 } | |
624 | |
625 if (value->len == sizeof("Transfer-Encoding") - 1 | |
626 && ngx_strncasecmp(value->data, "Transfer-Encoding", value->len) == 0) | |
627 { | |
628 op->len = sizeof("chunked") - 1; | |
629 op->getlen = NULL; | |
630 op->run = ngx_http_log_transfer_encoding_header_out; | |
631 op->data = 0; | |
632 return NGX_OK; | |
633 } | |
634 | |
635 op->getlen = ngx_http_log_unknown_header_out_getlen; | |
636 op->run = ngx_http_log_unknown_header_out; | |
637 op->data = (uintptr_t) value; | |
638 | |
639 return NGX_OK; | |
640 } | |
641 | |
642 | |
643 static size_t | |
644 ngx_http_log_header_out_getlen(ngx_http_request_t *r, uintptr_t data) | |
645 { | |
646 ngx_table_elt_t *h; | |
647 | |
648 h = *(ngx_table_elt_t **) ((char *) &r->headers_out + data); | |
649 | |
650 if (h) { | |
651 return h->value.len; | |
652 } | |
653 | |
654 /* | |
655 * No header pointer was found. | |
656 * However, some headers: "Date", "Server", "Content-Length", | |
657 * and "Last-Modified" have a special handling in the header filter, | |
658 * but we do not set up their pointers in the filter, | |
659 * because they are too seldom needed to be logged. | |
660 */ | |
661 | |
662 if (data == offsetof(ngx_http_headers_out_t, date)) { | |
663 return ngx_cached_http_time.len; | |
664 } | |
665 | |
666 if (data == offsetof(ngx_http_headers_out_t, server)) { | |
667 return (sizeof(NGINX_VER) - 1); | |
668 } | |
669 | |
670 if (data == offsetof(ngx_http_headers_out_t, content_length)) { | |
671 if (r->headers_out.content_length_n == -1) { | |
672 return 1; | |
673 } | |
674 | |
675 return NGX_OFF_T_LEN; | |
676 } | |
677 | |
678 if (data == offsetof(ngx_http_headers_out_t, last_modified)) { | |
679 if (r->headers_out.last_modified_time == -1) { | |
680 return 1; | |
681 } | |
682 | |
683 return sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; | |
684 } | |
685 | |
686 return 1; | |
687 } | |
688 | |
689 | |
690 static u_char * | |
691 ngx_http_log_header_out(ngx_http_request_t *r, u_char *buf, | |
692 ngx_http_log_op_t *op) | |
693 { | |
694 ngx_table_elt_t *h; | |
695 | |
696 h = *(ngx_table_elt_t **) ((char *) &r->headers_out + op->data); | |
697 | |
698 if (h) { | |
699 return ngx_cpymem(buf, h->value.data, h->value.len); | |
700 } | |
701 | |
702 /* | |
703 * No header pointer was found. | |
704 * However, some headers: "Date", "Server", "Content-Length", | |
705 * and "Last-Modified" have a special handling in the header filter, | |
706 * but we do not set up their pointers in the filter, | |
707 * because they are too seldom needed to be logged. | |
708 */ | |
709 | |
710 if (op->data == offsetof(ngx_http_headers_out_t, date)) { | |
711 return ngx_cpymem(buf, ngx_cached_http_time.data, | |
712 ngx_cached_http_time.len); | |
713 } | |
714 | |
715 if (op->data == offsetof(ngx_http_headers_out_t, server)) { | |
716 return ngx_cpymem(buf, NGINX_VER, sizeof(NGINX_VER) - 1); | |
717 } | |
718 | |
719 if (op->data == offsetof(ngx_http_headers_out_t, content_length)) { | |
720 if (r->headers_out.content_length_n == -1) { | |
721 *buf = '-'; | |
722 | |
723 return buf + 1; | |
724 } | |
725 | |
726 return ngx_sprintf(buf, "%O", r->headers_out.content_length_n); | |
727 } | |
728 | |
729 if (op->data == offsetof(ngx_http_headers_out_t, last_modified)) { | |
730 if (r->headers_out.last_modified_time == -1) { | |
731 *buf = '-'; | |
732 | |
733 return buf + 1; | |
734 } | |
735 | |
736 return ngx_http_time(buf, r->headers_out.last_modified_time); | |
737 } | |
738 | |
739 *buf = '-'; | |
740 | |
741 return buf + 1; | |
742 } | |
743 | |
744 | |
745 static size_t | |
746 ngx_http_log_unknown_header_out_getlen(ngx_http_request_t *r, uintptr_t data) | |
747 { | |
748 ngx_table_elt_t *h; | |
749 | |
750 h = ngx_http_log_unknown_header(&r->headers_out.headers, | |
751 (ngx_str_t *) data); | |
752 | |
753 if (h) { | |
754 return h->value.len; | |
755 } | |
756 | |
757 return 1; | |
758 } | |
759 | |
760 | |
761 static u_char * | |
762 ngx_http_log_unknown_header_out(ngx_http_request_t *r, u_char *buf, | |
763 ngx_http_log_op_t *op) | |
764 { | |
765 ngx_table_elt_t *h; | |
766 | |
767 h = ngx_http_log_unknown_header(&r->headers_out.headers, | |
768 (ngx_str_t *) op->data); | |
769 | |
770 if (h) { | |
771 return ngx_cpymem(buf, h->value.data, h->value.len); | |
772 } | |
773 | |
774 *buf = '-'; | |
775 | |
776 return buf + 1; | |
777 } | |
778 | |
779 | |
780 static ngx_table_elt_t * | |
781 ngx_http_log_unknown_header(ngx_list_t *headers, ngx_str_t *value) | |
782 { | |
783 ngx_uint_t i; | |
784 ngx_list_part_t *part; | |
785 ngx_table_elt_t *h; | |
786 | |
787 part = &headers->part; | |
788 h = part->elts; | |
789 | |
790 for (i = 0; /* void */; i++) { | |
791 | |
792 if (i >= part->nelts) { | |
793 if (part->next == NULL) { | |
794 break; | |
795 } | |
796 | |
797 part = part->next; | |
798 h = part->elts; | |
799 i = 0; | |
800 } | |
801 | |
802 if (h[i].key.len != value->len) { | |
803 continue; | |
804 } | |
805 | |
806 if (ngx_strncasecmp(h[i].key.data, value->data, value->len) == 0) { | |
807 return &h[i]; | |
808 } | |
809 } | |
810 | |
811 return NULL; | |
812 } | |
813 | |
814 | |
815 static u_char * | |
816 ngx_http_log_connection_header_out(ngx_http_request_t *r, u_char *buf, | |
817 ngx_http_log_op_t *op) | |
818 { | |
819 if (r->keepalive) { | |
820 return ngx_cpymem(buf, "keep-alive", sizeof("keep-alive") - 1); | |
821 | |
822 } else { | |
823 return ngx_cpymem(buf, "close", sizeof("close") - 1); | |
824 } | |
825 } | |
826 | |
827 | |
828 static u_char * | |
829 ngx_http_log_transfer_encoding_header_out(ngx_http_request_t *r, u_char *buf, | |
830 ngx_http_log_op_t *op) | |
831 { | |
832 if (r->chunked) { | |
833 return ngx_cpymem(buf, "chunked", sizeof("chunked") - 1); | |
834 } | |
835 | |
836 *buf = '-'; | |
837 | |
838 return buf + 1; | |
839 } | 405 } |
840 | 406 |
841 | 407 |
842 static ngx_int_t | 408 static ngx_int_t |
843 ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, | 409 ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, |
885 *buf = '-'; | 451 *buf = '-'; |
886 return buf + 1; | 452 return buf + 1; |
887 } | 453 } |
888 | 454 |
889 return ngx_cpymem(buf, value->data, value->len); | 455 return ngx_cpymem(buf, value->data, value->len); |
890 } | |
891 | |
892 | |
893 static ngx_int_t | |
894 ngx_http_log_set_formats(ngx_conf_t *cf) | |
895 { | |
896 ngx_http_log_op_name_t *op; | |
897 | |
898 for (op = ngx_http_log_fmt_ops; op->name.len; op++) { /* void */ } | |
899 op->run = NULL; | |
900 | |
901 return NGX_OK; | |
902 } | 456 } |
903 | 457 |
904 | 458 |
905 static void * | 459 static void * |
906 ngx_http_log_create_main_conf(ngx_conf_t *cf) | 460 ngx_http_log_create_main_conf(ngx_conf_t *cf) |
1150 | 704 |
1151 static char * | 705 static char * |
1152 ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *ops, | 706 ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *ops, |
1153 ngx_array_t *args, ngx_uint_t s) | 707 ngx_array_t *args, ngx_uint_t s) |
1154 { | 708 { |
1155 u_char *data, *p, *fname, *arg_data, ch; | 709 u_char *data, *p, ch; |
1156 size_t i, len, fname_len, arg_len; | 710 size_t i, len; |
1157 ngx_str_t *value, var, *a; | 711 ngx_str_t *value, var; |
1158 ngx_uint_t bracket; | 712 ngx_uint_t bracket; |
1159 ngx_http_log_op_t *op; | 713 ngx_http_log_op_t *op; |
1160 ngx_http_log_var_t *v; | 714 ngx_http_log_var_t *v; |
1161 ngx_http_log_op_name_t *name; | |
1162 static ngx_uint_t warn; | |
1163 | 715 |
1164 value = args->elts; | 716 value = args->elts; |
1165 arg_data = NULL; | |
1166 | 717 |
1167 for ( /* void */ ; s < args->nelts; s++) { | 718 for ( /* void */ ; s < args->nelts; s++) { |
719 | |
720 for (i = 0; i < value[s].len; i++) { | |
721 if (value[s].data[i] != '%') { | |
722 continue; | |
723 } | |
724 | |
725 ch = value[s].data[i + 1]; | |
726 | |
727 if ((ch >= 'A' && ch <= 'Z') | |
728 || (ch >= 'a' && ch <= 'z') | |
729 || ch == '{') | |
730 { | |
731 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
732 "the parameters in the \"%%name\" form are not supported, " | |
733 "use the \"$variable\" instead"); | |
734 | |
735 return NGX_CONF_ERROR; | |
736 } | |
737 } | |
1168 | 738 |
1169 i = 0; | 739 i = 0; |
1170 | 740 |
1171 while (i < value[s].len) { | 741 while (i < value[s].len) { |
1172 | 742 |
1175 return NGX_CONF_ERROR; | 745 return NGX_CONF_ERROR; |
1176 } | 746 } |
1177 | 747 |
1178 data = &value[s].data[i]; | 748 data = &value[s].data[i]; |
1179 | 749 |
1180 if (value[s].data[i] == '%') { | 750 if (value[s].data[i] == '$') { |
1181 i++; | |
1182 | |
1183 if (i == value[s].len) { | |
1184 goto invalid; | |
1185 } | |
1186 | |
1187 if (value[s].data[i] == '{') { | |
1188 i++; | |
1189 | |
1190 arg_data = &value[s].data[i]; | |
1191 | |
1192 while (i < value[s].len && value[s].data[i] != '}') { | |
1193 i++; | |
1194 } | |
1195 | |
1196 arg_len = &value[s].data[i] - arg_data; | |
1197 | |
1198 if (i == value[s].len || arg_len == 0) { | |
1199 goto invalid; | |
1200 } | |
1201 | |
1202 i++; | |
1203 | |
1204 } else { | |
1205 arg_len = 0; | |
1206 } | |
1207 | |
1208 if (warn == 0) { | |
1209 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | |
1210 "the parameters in the \"%%name\" form are deprecated, " | |
1211 "use the \"$variable\" instead"); | |
1212 warn = 1; | |
1213 } | |
1214 | |
1215 fname = &value[s].data[i]; | |
1216 | |
1217 while (i < value[s].len | |
1218 && ((value[s].data[i] >= 'a' && value[s].data[i] <= 'z') | |
1219 || value[s].data[i] == '_')) | |
1220 { | |
1221 i++; | |
1222 } | |
1223 | |
1224 fname_len = &value[s].data[i] - fname; | |
1225 | |
1226 if (fname_len == 0) { | |
1227 goto invalid; | |
1228 } | |
1229 | |
1230 for (name = ngx_http_log_fmt_ops; name->run; name++) { | |
1231 if (name->name.len == 0) { | |
1232 name = (ngx_http_log_op_name_t *) name->run; | |
1233 } | |
1234 | |
1235 if (name->name.len == fname_len | |
1236 && ngx_strncmp(name->name.data, fname, fname_len) == 0) | |
1237 { | |
1238 if (name->compile == NULL) { | |
1239 if (arg_len) { | |
1240 fname[fname_len] = '\0'; | |
1241 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1242 "\"%s\" must not have argument", | |
1243 data); | |
1244 return NGX_CONF_ERROR; | |
1245 } | |
1246 | |
1247 op->len = name->len; | |
1248 op->getlen = name->getlen; | |
1249 op->run = name->run; | |
1250 op->data = 0; | |
1251 | |
1252 break; | |
1253 } | |
1254 | |
1255 if (arg_len == 0) { | |
1256 fname[fname_len] = '\0'; | |
1257 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1258 "\"%s\" requires argument", | |
1259 data); | |
1260 return NGX_CONF_ERROR; | |
1261 } | |
1262 | |
1263 a = ngx_palloc(cf->pool, sizeof(ngx_str_t)); | |
1264 if (a == NULL) { | |
1265 return NGX_CONF_ERROR; | |
1266 } | |
1267 | |
1268 a->len = arg_len; | |
1269 a->data = arg_data; | |
1270 | |
1271 if (name->compile(cf, op, a) == NGX_ERROR) { | |
1272 return NGX_CONF_ERROR; | |
1273 } | |
1274 | |
1275 break; | |
1276 } | |
1277 } | |
1278 | |
1279 if (name->name.len == 0) { | |
1280 goto invalid; | |
1281 } | |
1282 | |
1283 continue; | |
1284 | |
1285 } else if (value[s].data[i] == '$') { | |
1286 | 751 |
1287 if (++i == value[s].len) { | 752 if (++i == value[s].len) { |
1288 goto invalid; | 753 goto invalid; |
1289 } | 754 } |
1290 | 755 |
1362 continue; | 827 continue; |
1363 } | 828 } |
1364 | 829 |
1365 i++; | 830 i++; |
1366 | 831 |
1367 while (i < value[s].len | 832 while (i < value[s].len && value[s].data[i] != '$') { |
1368 && value[s].data[i] != '$' | |
1369 && value[s].data[i] != '%') | |
1370 { | |
1371 i++; | 833 i++; |
1372 } | 834 } |
1373 | 835 |
1374 len = &value[s].data[i] - data; | 836 len = &value[s].data[i] - data; |
1375 | 837 |