comparison src/http/modules/ngx_http_log_module.c @ 260:0effe91f6083 NGINX_0_5_0

nginx 0.5.0 *) Change: the parameters in the "%name" form in the "log_format" directive are not supported anymore. *) Change: the "proxy_upstream_max_fails", "proxy_upstream_fail_timeout", "fastcgi_upstream_max_fails", "fastcgi_upstream_fail_timeout", "memcached_upstream_max_fails", and "memcached_upstream_fail_timeout" directives are not supported anymore. *) Feature: the "server" directive in the "upstream" context supports the "max_fails", "fail_timeout", and "down" parameters. *) Feature: the "ip_hash" directive inside the "upstream" block. *) Feature: the WAIT status in the "Auth-Status" header line of the IMAP/POP3 proxy authentication server response. *) Bugfix: nginx could not be built on 64-bit platforms; bug appeared in 0.4.14.
author Igor Sysoev <http://sysoev.ru>
date Mon, 04 Dec 2006 00:00:00 +0300
parents fa32d59d9a15
children 251bcd11a5b8
comparison
equal deleted inserted replaced
259:c68f18041059 260:0effe91f6083
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