Mercurial > hg > nginx-vendor-current
comparison src/http/ngx_http_log_handler.c @ 28:7ca9bdc82b3f NGINX_0_1_14
nginx 0.1.14
*) Feature: the autoconfiguration directives:
--http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH, and
--http-fastcgi-temp-path=PATH
*) Change: the directory name for the temporary files with the client
request body is specified by directive client_body_temp_path, by
default it is <prefix>/client_body_temp.
*) Feature: the ngx_http_fastcgi_module and the directives:
fastcgi_pass, fastcgi_root, fastcgi_index, fastcgi_params,
fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout,
fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers,
fastcgi_busy_buffers_size, fastcgi_temp_path,
fastcgi_max_temp_file_size, fastcgi_temp_file_write_size,
fastcgi_next_upstream, and fastcgi_x_powered_by.
*) Bugfix: the "[alert] zero size buf" error; bug appeared in 0.1.3.
*) Change: the URI must be specified after the host name in the
proxy_pass directive.
*) Change: the %3F symbol in the URI was considered as the argument
string start.
*) Feature: the unix domain sockets support in the
ngx_http_proxy_module.
*) Feature: the ssl_engine and ssl_ciphers directives.
Thanks to Sergey Skvortsov for SSL-accelerator.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 18 Jan 2005 00:00:00 +0300 |
parents | 45fe5b98a9de |
children | aab2ea7c0458 |
comparison
equal
deleted
inserted
replaced
27:66901c2556fd | 28:7ca9bdc82b3f |
---|---|
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 #include <nginx.h> | 10 #include <nginx.h> |
11 | 11 |
12 | 12 |
13 static u_char *ngx_http_log_addr(ngx_http_request_t *r, u_char *buf, | 13 static u_char *ngx_http_log_addr(ngx_http_request_t *r, u_char *buf, |
14 uintptr_t data); | 14 ngx_http_log_op_t *op); |
15 static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, | 15 static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, |
16 uintptr_t data); | 16 ngx_http_log_op_t *op); |
17 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, | 17 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, |
18 uintptr_t data); | 18 ngx_http_log_op_t *op); |
19 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, | 19 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, |
20 uintptr_t data); | 20 ngx_http_log_op_t *op); |
21 static u_char *ngx_http_log_msec(ngx_http_request_t *r, u_char *buf, | 21 static u_char *ngx_http_log_msec(ngx_http_request_t *r, u_char *buf, |
22 uintptr_t data); | 22 ngx_http_log_op_t *op); |
23 static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf, | |
24 ngx_http_log_op_t *op); | |
25 static u_char *ngx_http_log_length(ngx_http_request_t *r, u_char *buf, | |
26 ngx_http_log_op_t *op); | |
27 static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf, | |
28 ngx_http_log_op_t *op); | |
29 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, | |
30 ngx_http_log_op_t *op); | |
31 | |
32 static size_t ngx_http_log_request_getlen(ngx_http_request_t *r, | |
33 uintptr_t data); | |
23 static u_char *ngx_http_log_request(ngx_http_request_t *r, u_char *buf, | 34 static u_char *ngx_http_log_request(ngx_http_request_t *r, u_char *buf, |
24 uintptr_t data); | 35 ngx_http_log_op_t *op); |
25 static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf, | 36 |
26 uintptr_t data); | 37 static ngx_int_t ngx_http_log_header_in_compile(ngx_http_log_op_t *op, |
27 static u_char *ngx_http_log_length(ngx_http_request_t *r, u_char *buf, | 38 ngx_str_t *value); |
28 uintptr_t data); | 39 static size_t ngx_http_log_header_in_getlen(ngx_http_request_t *r, |
29 static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf, | 40 uintptr_t data); |
30 uintptr_t data); | |
31 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, | |
32 uintptr_t data); | |
33 static u_char *ngx_http_log_header_in(ngx_http_request_t *r, u_char *buf, | 41 static u_char *ngx_http_log_header_in(ngx_http_request_t *r, u_char *buf, |
34 uintptr_t data); | 42 ngx_http_log_op_t *op); |
43 static size_t ngx_http_log_unknown_header_in_getlen(ngx_http_request_t *r, | |
44 uintptr_t data); | |
45 static u_char *ngx_http_log_unknown_header_in(ngx_http_request_t *r, | |
46 u_char *buf, | |
47 ngx_http_log_op_t *op); | |
48 | |
49 static ngx_int_t ngx_http_log_header_out_compile(ngx_http_log_op_t *op, | |
50 ngx_str_t *value); | |
51 static size_t ngx_http_log_header_out_getlen(ngx_http_request_t *r, | |
52 uintptr_t data); | |
53 static u_char *ngx_http_log_header_out(ngx_http_request_t *r, u_char *buf, | |
54 ngx_http_log_op_t *op); | |
55 static size_t ngx_http_log_unknown_header_out_getlen(ngx_http_request_t *r, | |
56 uintptr_t data); | |
57 static u_char *ngx_http_log_unknown_header_out(ngx_http_request_t *r, | |
58 u_char *buf, | |
59 ngx_http_log_op_t *op); | |
60 | |
35 static u_char *ngx_http_log_connection_header_out(ngx_http_request_t *r, | 61 static u_char *ngx_http_log_connection_header_out(ngx_http_request_t *r, |
36 u_char *buf, uintptr_t data); | 62 u_char *buf, |
63 ngx_http_log_op_t *op); | |
37 static u_char *ngx_http_log_transfer_encoding_header_out(ngx_http_request_t *r, | 64 static u_char *ngx_http_log_transfer_encoding_header_out(ngx_http_request_t *r, |
38 u_char *buf, | 65 u_char *buf, |
39 uintptr_t data); | 66 ngx_http_log_op_t *op); |
40 static u_char *ngx_http_log_unknown_header_in(ngx_http_request_t *r, | 67 |
41 u_char *buf, uintptr_t data); | 68 static ngx_table_elt_t *ngx_http_log_unknown_header(ngx_list_t *headers, |
42 static u_char *ngx_http_log_header_out(ngx_http_request_t *r, u_char *buf, | 69 ngx_str_t *value); |
43 uintptr_t data); | 70 |
44 static u_char *ngx_http_log_unknown_header_out(ngx_http_request_t *r, u_char *buf, | 71 static ngx_int_t ngx_http_log_set_formats(ngx_conf_t *cf); |
45 uintptr_t data); | |
46 | |
47 static ngx_int_t ngx_http_log_pre_conf(ngx_conf_t *cf); | |
48 static void *ngx_http_log_create_main_conf(ngx_conf_t *cf); | 72 static void *ngx_http_log_create_main_conf(ngx_conf_t *cf); |
49 static void *ngx_http_log_create_loc_conf(ngx_conf_t *cf); | 73 static void *ngx_http_log_create_loc_conf(ngx_conf_t *cf); |
50 static char *ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, | 74 static char *ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, |
51 void *child); | 75 void *child); |
52 static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, | 76 static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, |
76 ngx_null_command | 100 ngx_null_command |
77 }; | 101 }; |
78 | 102 |
79 | 103 |
80 ngx_http_module_t ngx_http_log_module_ctx = { | 104 ngx_http_module_t ngx_http_log_module_ctx = { |
81 ngx_http_log_pre_conf, /* pre conf */ | 105 ngx_http_log_set_formats, /* pre conf */ |
82 | 106 |
83 ngx_http_log_create_main_conf, /* create main configuration */ | 107 ngx_http_log_create_main_conf, /* create main configuration */ |
84 NULL, /* init main configuration */ | 108 NULL, /* init main configuration */ |
85 | 109 |
86 NULL, /* create server configuration */ | 110 NULL, /* create server configuration */ |
108 ngx_string("%addr - - [%time] \"%request\" %status %apache_length " | 132 ngx_string("%addr - - [%time] \"%request\" %status %apache_length " |
109 "\"%{Referer}i\" \"%{User-Agent}i\""); | 133 "\"%{Referer}i\" \"%{User-Agent}i\""); |
110 | 134 |
111 | 135 |
112 ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { | 136 ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { |
113 { ngx_string("addr"), INET_ADDRSTRLEN - 1, ngx_http_log_addr }, | 137 { ngx_string("addr"), INET_ADDRSTRLEN - 1, NULL, NULL, ngx_http_log_addr }, |
114 { ngx_string("conn"), NGX_INT32_LEN, ngx_http_log_connection }, | 138 { ngx_string("conn"), NGX_INT32_LEN, NULL, NULL, ngx_http_log_connection }, |
115 { ngx_string("pipe"), 1, ngx_http_log_pipe }, | 139 { ngx_string("pipe"), 1, NULL, NULL, ngx_http_log_pipe }, |
116 { ngx_string("time"), sizeof("28/Sep/1970:12:00:00") - 1, | 140 { ngx_string("time"), sizeof("28/Sep/1970:12:00:00") - 1, |
117 ngx_http_log_time }, | 141 NULL, NULL, ngx_http_log_time }, |
118 { ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec }, | 142 { ngx_string("msec"), NGX_TIME_T_LEN + 4, NULL, NULL, ngx_http_log_msec }, |
119 { ngx_string("request"), 0, ngx_http_log_request }, | 143 { ngx_string("status"), 3, NULL, NULL, ngx_http_log_status }, |
120 { ngx_string("status"), 3, ngx_http_log_status }, | 144 { ngx_string("length"), NGX_OFF_T_LEN, NULL, NULL, ngx_http_log_length }, |
121 { ngx_string("length"), NGX_OFF_T_LEN, ngx_http_log_length }, | 145 { ngx_string("apache_length"), NGX_OFF_T_LEN, |
122 { ngx_string("apache_length"), NGX_OFF_T_LEN, ngx_http_log_apache_length }, | 146 NULL, NULL, ngx_http_log_apache_length }, |
123 { ngx_string("request_length"), NGX_SIZE_T_LEN, | 147 { ngx_string("request_length"), NGX_SIZE_T_LEN, |
124 ngx_http_log_request_length }, | 148 NULL, NULL, ngx_http_log_request_length }, |
125 { ngx_string("i"), NGX_HTTP_LOG_ARG, ngx_http_log_header_in }, | 149 |
126 { ngx_string("o"), NGX_HTTP_LOG_ARG, ngx_http_log_header_out }, | 150 { ngx_string("request"), 0, NULL, |
127 { ngx_null_string, 0, NULL } | 151 ngx_http_log_request_getlen, |
152 ngx_http_log_request }, | |
153 | |
154 { ngx_string("i"), 0, ngx_http_log_header_in_compile, | |
155 ngx_http_log_header_in_getlen, | |
156 ngx_http_log_header_in }, | |
157 | |
158 { ngx_string("o"), 0, ngx_http_log_header_out_compile, | |
159 ngx_http_log_header_out_getlen, | |
160 ngx_http_log_header_out }, | |
161 | |
162 { ngx_null_string, 0, NULL, NULL, NULL } | |
128 }; | 163 }; |
129 | 164 |
130 | 165 |
131 ngx_int_t ngx_http_log_handler(ngx_http_request_t *r) | 166 ngx_int_t ngx_http_log_handler(ngx_http_request_t *r) |
132 { | 167 { |
133 ngx_uint_t i, l; | 168 ngx_uint_t i, l; |
134 uintptr_t data; | |
135 u_char *line, *p; | 169 u_char *line, *p; |
136 size_t len; | 170 size_t len; |
137 ngx_http_log_t *log; | 171 ngx_http_log_t *log; |
138 ngx_http_log_op_t *op; | 172 ngx_http_log_op_t *op; |
139 ngx_http_log_loc_conf_t *lcf; | 173 ngx_http_log_loc_conf_t *lcf; |
155 | 189 |
156 len = 0; | 190 len = 0; |
157 op = log[l].ops->elts; | 191 op = log[l].ops->elts; |
158 for (i = 0; i < log[l].ops->nelts; i++) { | 192 for (i = 0; i < log[l].ops->nelts; i++) { |
159 if (op[i].len == 0) { | 193 if (op[i].len == 0) { |
160 len += (size_t) op[i].op(r, NULL, op[i].data); | 194 len += op[i].getlen(r, op[i].data); |
161 | 195 |
162 } else { | 196 } else { |
163 len += op[i].len; | 197 len += op[i].len; |
164 } | 198 } |
165 } | 199 } |
175 } | 209 } |
176 | 210 |
177 p = line; | 211 p = line; |
178 | 212 |
179 for (i = 0; i < log[l].ops->nelts; i++) { | 213 for (i = 0; i < log[l].ops->nelts; i++) { |
180 if (op[i].op == NGX_HTTP_LOG_COPY_SHORT) { | 214 p = op[i].run(r, p, &op[i]); |
181 len = op[i].len; | |
182 data = op[i].data; | |
183 while (len--) { | |
184 *p++ = (char) (data & 0xff); | |
185 data >>= 8; | |
186 } | |
187 | |
188 } else if (op[i].op == NGX_HTTP_LOG_COPY_LONG) { | |
189 p = ngx_cpymem(p, (void *) op[i].data, op[i].len); | |
190 | |
191 } else { | |
192 p = op[i].op(r, p, op[i].data); | |
193 } | |
194 } | 215 } |
195 | 216 |
196 #if (NGX_WIN32) | 217 #if (NGX_WIN32) |
197 *p++ = CR; *p++ = LF; | 218 *p++ = CR; *p++ = LF; |
198 WriteFile(log[l].file->fd, line, p - line, &written, NULL); | 219 WriteFile(log[l].file->fd, line, p - line, &written, NULL); |
204 | 225 |
205 return NGX_OK; | 226 return NGX_OK; |
206 } | 227 } |
207 | 228 |
208 | 229 |
230 static u_char *ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, | |
231 ngx_http_log_op_t *op) | |
232 { | |
233 size_t len; | |
234 uintptr_t data; | |
235 | |
236 len = op->len; | |
237 data = op->data; | |
238 | |
239 while (len--) { | |
240 *buf++ = (u_char) (data & 0xff); | |
241 data >>= 8; | |
242 } | |
243 | |
244 return buf; | |
245 } | |
246 | |
247 | |
248 static u_char *ngx_http_log_copy_long(ngx_http_request_t *r, u_char *buf, | |
249 ngx_http_log_op_t *op) | |
250 { | |
251 return ngx_cpymem(buf, (u_char *) op->data, op->len); | |
252 } | |
253 | |
254 | |
209 static u_char *ngx_http_log_addr(ngx_http_request_t *r, u_char *buf, | 255 static u_char *ngx_http_log_addr(ngx_http_request_t *r, u_char *buf, |
210 uintptr_t data) | 256 ngx_http_log_op_t *op) |
211 { | 257 { |
212 return ngx_cpymem(buf, r->connection->addr_text.data, | 258 return ngx_cpymem(buf, r->connection->addr_text.data, |
213 r->connection->addr_text.len); | 259 r->connection->addr_text.len); |
214 } | 260 } |
215 | 261 |
216 | 262 |
217 static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, | 263 static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, |
218 uintptr_t data) | 264 ngx_http_log_op_t *op) |
219 { | 265 { |
220 return ngx_sprintf(buf, "%ui", r->connection->number); | 266 return ngx_sprintf(buf, "%ui", r->connection->number); |
221 } | 267 } |
222 | 268 |
223 | 269 |
224 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, | 270 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, |
225 uintptr_t data) | 271 ngx_http_log_op_t *op) |
226 { | 272 { |
227 if (r->pipeline) { | 273 if (r->pipeline) { |
228 *buf = 'p'; | 274 *buf = 'p'; |
229 } else { | 275 } else { |
230 *buf = '.'; | 276 *buf = '.'; |
233 return buf + 1; | 279 return buf + 1; |
234 } | 280 } |
235 | 281 |
236 | 282 |
237 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, | 283 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, |
238 uintptr_t data) | 284 ngx_http_log_op_t *op) |
239 { | 285 { |
240 return ngx_cpymem(buf, ngx_cached_http_log_time.data, | 286 return ngx_cpymem(buf, ngx_cached_http_log_time.data, |
241 ngx_cached_http_log_time.len); | 287 ngx_cached_http_log_time.len); |
242 } | 288 } |
243 | 289 |
244 | 290 |
245 static u_char *ngx_http_log_msec(ngx_http_request_t *r, u_char *buf, | 291 static u_char *ngx_http_log_msec(ngx_http_request_t *r, u_char *buf, |
246 uintptr_t data) | 292 ngx_http_log_op_t *op) |
247 { | 293 { |
248 struct timeval tv; | 294 struct timeval tv; |
249 | 295 |
250 ngx_gettimeofday(&tv); | 296 ngx_gettimeofday(&tv); |
251 | 297 |
252 return ngx_sprintf(buf, "%l.%03l", tv.tv_sec, tv.tv_usec / 1000); | 298 return ngx_sprintf(buf, "%l.%03l", tv.tv_sec, tv.tv_usec / 1000); |
253 } | 299 } |
254 | 300 |
255 | 301 |
302 static size_t ngx_http_log_request_getlen(ngx_http_request_t *r, | |
303 uintptr_t data) | |
304 { | |
305 return r->request_line.len; | |
306 } | |
307 | |
308 | |
256 static u_char *ngx_http_log_request(ngx_http_request_t *r, u_char *buf, | 309 static u_char *ngx_http_log_request(ngx_http_request_t *r, u_char *buf, |
257 uintptr_t data) | 310 ngx_http_log_op_t *op) |
258 { | 311 { |
259 if (buf == NULL) { | |
260 /* find the request line length */ | |
261 return (u_char *) r->request_line.len; | |
262 } | |
263 | |
264 return ngx_cpymem(buf, r->request_line.data, r->request_line.len); | 312 return ngx_cpymem(buf, r->request_line.data, r->request_line.len); |
265 } | 313 } |
266 | 314 |
267 | 315 |
268 static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf, | 316 static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf, |
269 uintptr_t data) | 317 ngx_http_log_op_t *op) |
270 { | 318 { |
271 return ngx_sprintf(buf, "%ui", | 319 return ngx_sprintf(buf, "%ui", |
272 r->err_status ? r->err_status : r->headers_out.status); | 320 r->err_status ? r->err_status : r->headers_out.status); |
273 } | 321 } |
274 | 322 |
275 | 323 |
276 static u_char *ngx_http_log_length(ngx_http_request_t *r, u_char *buf, | 324 static u_char *ngx_http_log_length(ngx_http_request_t *r, u_char *buf, |
277 uintptr_t data) | 325 ngx_http_log_op_t *op) |
278 { | 326 { |
279 return ngx_sprintf(buf, "%O", r->connection->sent); | 327 return ngx_sprintf(buf, "%O", r->connection->sent); |
280 } | 328 } |
281 | 329 |
282 | 330 |
283 static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf, | 331 static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf, |
284 uintptr_t data) | 332 ngx_http_log_op_t *op) |
285 { | 333 { |
286 return ngx_sprintf(buf, "%O", r->connection->sent - r->header_size); | 334 return ngx_sprintf(buf, "%O", r->connection->sent - r->header_size); |
287 } | 335 } |
288 | 336 |
289 | 337 |
290 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, | 338 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, |
291 uintptr_t data) | 339 ngx_http_log_op_t *op) |
292 { | 340 { |
293 return ngx_sprintf(buf, "%z", r->request_length); | 341 return ngx_sprintf(buf, "%z", r->request_length); |
294 } | 342 } |
295 | 343 |
296 | 344 |
345 static ngx_int_t ngx_http_log_header_in_compile(ngx_http_log_op_t *op, | |
346 ngx_str_t *value) | |
347 { | |
348 ngx_uint_t i; | |
349 | |
350 op->len = 0; | |
351 | |
352 for (i = 0; ngx_http_headers_in[i].name.len != 0; i++) { | |
353 | |
354 if (ngx_http_headers_in[i].name.len != value->len) { | |
355 continue; | |
356 } | |
357 | |
358 if (ngx_strncasecmp(ngx_http_headers_in[i].name.data, value->data, | |
359 value->len) == 0) | |
360 { | |
361 op->getlen = ngx_http_log_header_in_getlen; | |
362 op->run = ngx_http_log_header_in; | |
363 op->data = ngx_http_headers_in[i].offset; | |
364 | |
365 return NGX_OK; | |
366 } | |
367 } | |
368 | |
369 op->getlen = ngx_http_log_unknown_header_in_getlen; | |
370 op->run = ngx_http_log_unknown_header_in; | |
371 op->data = (uintptr_t) value; | |
372 | |
373 return NGX_OK; | |
374 } | |
375 | |
376 | |
377 static size_t ngx_http_log_header_in_getlen(ngx_http_request_t *r, | |
378 uintptr_t data) | |
379 { | |
380 ngx_table_elt_t *h; | |
381 | |
382 h = *(ngx_table_elt_t **) ((char *) &r->headers_in + data); | |
383 | |
384 if (h) { | |
385 return h->value.len; | |
386 } | |
387 | |
388 return 1; | |
389 } | |
390 | |
391 | |
297 static u_char *ngx_http_log_header_in(ngx_http_request_t *r, u_char *buf, | 392 static u_char *ngx_http_log_header_in(ngx_http_request_t *r, u_char *buf, |
298 uintptr_t data) | 393 ngx_http_log_op_t *op) |
299 { | 394 { |
300 ngx_uint_t i; | 395 ngx_table_elt_t *h; |
301 ngx_str_t *s; | 396 |
302 ngx_table_elt_t *h; | 397 h = *(ngx_table_elt_t **) ((char *) &r->headers_in + op->data); |
303 ngx_http_log_op_t *op; | 398 |
304 | 399 if (h) { |
305 if (r) { | 400 return ngx_cpymem(buf, h->value.data, h->value.len); |
306 h = *(ngx_table_elt_t **) ((char *) &r->headers_in + data); | 401 } |
307 | 402 |
308 if (h == NULL) { | 403 *buf = '-'; |
309 | 404 |
310 /* no header */ | 405 return buf + 1; |
311 | 406 } |
312 if (buf) { | 407 |
313 *buf = '-'; | 408 |
314 } | 409 static size_t ngx_http_log_unknown_header_in_getlen(ngx_http_request_t *r, |
410 uintptr_t data) | |
411 { | |
412 ngx_table_elt_t *h; | |
413 | |
414 h = ngx_http_log_unknown_header(&r->headers_in.headers, (ngx_str_t *) data); | |
415 | |
416 if (h) { | |
417 return h->value.len; | |
418 } | |
419 | |
420 return 1; | |
421 } | |
422 | |
423 | |
424 static u_char *ngx_http_log_unknown_header_in(ngx_http_request_t *r, | |
425 u_char *buf, | |
426 ngx_http_log_op_t *op) | |
427 { | |
428 ngx_table_elt_t *h; | |
429 | |
430 h = ngx_http_log_unknown_header(&r->headers_in.headers, | |
431 (ngx_str_t *) op->data); | |
432 | |
433 if (h) { | |
434 return ngx_cpymem(buf, h->value.data, h->value.len); | |
435 } | |
436 | |
437 *buf = '-'; | |
438 | |
439 return buf + 1; | |
440 } | |
441 | |
442 | |
443 static ngx_int_t ngx_http_log_header_out_compile(ngx_http_log_op_t *op, | |
444 ngx_str_t *value) | |
445 { | |
446 ngx_uint_t i; | |
447 | |
448 op->len = 0; | |
449 | |
450 for (i = 0; ngx_http_headers_out[i].name.len != 0; i++) { | |
451 | |
452 if (ngx_http_headers_out[i].name.len != value->len) { | |
453 continue; | |
454 } | |
455 | |
456 if (ngx_strncasecmp(ngx_http_headers_out[i].name.data, value->data, | |
457 value->len) == 0) | |
458 { | |
459 op->getlen = ngx_http_log_header_out_getlen; | |
460 op->run = ngx_http_log_header_out; | |
461 op->data = ngx_http_headers_out[i].offset; | |
462 | |
463 return NGX_OK; | |
464 } | |
465 } | |
466 | |
467 if (value->len == sizeof("Connection") - 1 | |
468 && ngx_strncasecmp(value->data, "Connection", value->len) == 0) | |
469 { | |
470 op->len = sizeof("keep-alive") - 1; | |
471 op->getlen = NULL; | |
472 op->run = ngx_http_log_connection_header_out; | |
473 op->data = 0; | |
474 return NGX_OK; | |
475 } | |
476 | |
477 if (value->len == sizeof("Transfer-Encoding") - 1 | |
478 && ngx_strncasecmp(value->data, "Transfer-Encoding", value->len) == 0) | |
479 { | |
480 op->len = sizeof("chunked") - 1; | |
481 op->getlen = NULL; | |
482 op->run = ngx_http_log_transfer_encoding_header_out; | |
483 op->data = 0; | |
484 return NGX_OK; | |
485 } | |
486 | |
487 op->getlen = ngx_http_log_unknown_header_out_getlen; | |
488 op->run = ngx_http_log_unknown_header_out; | |
489 op->data = (uintptr_t) value; | |
490 | |
491 return NGX_OK; | |
492 } | |
493 | |
494 | |
495 static size_t ngx_http_log_header_out_getlen(ngx_http_request_t *r, | |
496 uintptr_t data) | |
497 { | |
498 ngx_table_elt_t *h; | |
499 | |
500 h = *(ngx_table_elt_t **) ((char *) &r->headers_out + data); | |
501 | |
502 if (h) { | |
503 return h->value.len; | |
504 } | |
505 | |
506 /* | |
507 * No header pointer was found. | |
508 * However, some headers: "Date", "Server", "Content-Length", | |
509 * and "Last-Modified" have a special handling in the header filter | |
510 * but we do not set up their pointers in the filter because | |
511 * they are too seldom needed to be logged. | |
512 */ | |
513 | |
514 if (data == offsetof(ngx_http_headers_out_t, date)) { | |
515 return ngx_cached_http_time.len; | |
516 } | |
517 | |
518 if (data == offsetof(ngx_http_headers_out_t, server)) { | |
519 return (sizeof(NGINX_VER) - 1); | |
520 } | |
521 | |
522 if (data == offsetof(ngx_http_headers_out_t, content_length)) { | |
523 if (r->headers_out.content_length_n == -1) { | |
524 return 1; | |
525 } | |
526 | |
527 return NGX_OFF_T_LEN; | |
528 } | |
529 | |
530 if (data == offsetof(ngx_http_headers_out_t, last_modified)) { | |
531 if (r->headers_out.last_modified_time == -1) { | |
532 return 1; | |
533 } | |
534 | |
535 return sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; | |
536 } | |
537 | |
538 return 1; | |
539 } | |
540 | |
541 | |
542 static u_char *ngx_http_log_header_out(ngx_http_request_t *r, u_char *buf, | |
543 ngx_http_log_op_t *op) | |
544 { | |
545 ngx_table_elt_t *h; | |
546 | |
547 h = *(ngx_table_elt_t **) ((char *) &r->headers_out + op->data); | |
548 | |
549 if (h) { | |
550 return ngx_cpymem(buf, h->value.data, h->value.len); | |
551 } | |
552 | |
553 /* | |
554 * No header pointer was found. | |
555 * However, some headers: "Date", "Server", "Content-Length", | |
556 * and "Last-Modified" have a special handling in the header filter | |
557 * but we do not set up their pointers in the filter because | |
558 * they are too seldom needed to be logged. | |
559 */ | |
560 | |
561 if (op->data == offsetof(ngx_http_headers_out_t, date)) { | |
562 return ngx_cpymem(buf, ngx_cached_http_time.data, | |
563 ngx_cached_http_time.len); | |
564 } | |
565 | |
566 if (op->data == offsetof(ngx_http_headers_out_t, server)) { | |
567 return ngx_cpymem(buf, NGINX_VER, sizeof(NGINX_VER) - 1); | |
568 } | |
569 | |
570 if (op->data == offsetof(ngx_http_headers_out_t, content_length)) { | |
571 if (r->headers_out.content_length_n == -1) { | |
572 *buf = '-'; | |
315 | 573 |
316 return buf + 1; | 574 return buf + 1; |
317 } | 575 } |
318 | 576 |
319 if (buf == NULL) { | 577 return ngx_sprintf(buf, "%O", r->headers_out.content_length_n); |
320 /* find the header length */ | 578 } |
321 return (u_char *) h->value.len; | 579 |
322 } | 580 if (op->data == offsetof(ngx_http_headers_out_t, last_modified)) { |
323 | 581 if (r->headers_out.last_modified_time == -1) { |
582 *buf = '-'; | |
583 | |
584 return buf + 1; | |
585 } | |
586 | |
587 return ngx_http_time(buf, r->headers_out.last_modified_time); | |
588 } | |
589 | |
590 *buf = '-'; | |
591 | |
592 return buf + 1; | |
593 } | |
594 | |
595 | |
596 static size_t ngx_http_log_unknown_header_out_getlen(ngx_http_request_t *r, | |
597 uintptr_t data) | |
598 { | |
599 ngx_table_elt_t *h; | |
600 | |
601 h = ngx_http_log_unknown_header(&r->headers_out.headers, | |
602 (ngx_str_t *) data); | |
603 | |
604 if (h) { | |
605 return h->value.len; | |
606 } | |
607 | |
608 return 1; | |
609 } | |
610 | |
611 | |
612 static u_char *ngx_http_log_unknown_header_out(ngx_http_request_t *r, | |
613 u_char *buf, | |
614 ngx_http_log_op_t *op) | |
615 { | |
616 ngx_table_elt_t *h; | |
617 | |
618 h = ngx_http_log_unknown_header(&r->headers_out.headers, | |
619 (ngx_str_t *) op->data); | |
620 | |
621 if (h) { | |
324 return ngx_cpymem(buf, h->value.data, h->value.len); | 622 return ngx_cpymem(buf, h->value.data, h->value.len); |
325 } | 623 } |
326 | 624 |
327 /* find an offset while a format string compilation */ | 625 *buf = '-'; |
328 | 626 |
329 op = (ngx_http_log_op_t *) buf; | 627 return buf + 1; |
330 s = (ngx_str_t *) data; | 628 } |
331 | 629 |
332 op->len = 0; | 630 |
333 | 631 static ngx_table_elt_t *ngx_http_log_unknown_header(ngx_list_t *headers, |
334 for (i = 0; ngx_http_headers_in[i].name.len != 0; i++) { | 632 ngx_str_t *value) |
335 if (ngx_http_headers_in[i].name.len != s->len) { | |
336 continue; | |
337 } | |
338 | |
339 if (ngx_strncasecmp(ngx_http_headers_in[i].name.data, s->data, s->len) | |
340 == 0) | |
341 { | |
342 op->op = ngx_http_log_header_in; | |
343 op->data = ngx_http_headers_in[i].offset; | |
344 return NULL; | |
345 } | |
346 } | |
347 | |
348 op->op = ngx_http_log_unknown_header_in; | |
349 op->data = (uintptr_t) s; | |
350 | |
351 return NULL; | |
352 } | |
353 | |
354 | |
355 static u_char *ngx_http_log_unknown_header_in(ngx_http_request_t *r, | |
356 u_char *buf, uintptr_t data) | |
357 { | 633 { |
358 ngx_uint_t i; | 634 ngx_uint_t i; |
359 ngx_str_t *s; | |
360 ngx_list_part_t *part; | 635 ngx_list_part_t *part; |
361 ngx_table_elt_t *h; | 636 ngx_table_elt_t *h; |
362 | 637 |
363 s = (ngx_str_t *) data; | 638 part = &headers->part; |
364 | |
365 part = &r->headers_in.headers.part; | |
366 h = part->elts; | 639 h = part->elts; |
367 | 640 |
368 for (i = 0; /* void */; i++) { | 641 for (i = 0; /* void */; i++) { |
369 | 642 |
370 if (i >= part->nelts) { | 643 if (i >= part->nelts) { |
375 part = part->next; | 648 part = part->next; |
376 h = part->elts; | 649 h = part->elts; |
377 i = 0; | 650 i = 0; |
378 } | 651 } |
379 | 652 |
380 if (h[i].key.len != s->len) { | 653 if (h[i].key.len != value->len) { |
381 continue; | 654 continue; |
382 } | 655 } |
383 | 656 |
384 if (ngx_strncasecmp(h[i].key.data, s->data, s->len) == 0) { | 657 if (ngx_strncasecmp(h[i].key.data, value->data, value->len) == 0) { |
385 if (buf == NULL) { | 658 return &h[i]; |
386 /* find the header length */ | 659 } |
387 return (u_char *) h[i].value.len; | 660 } |
388 } | |
389 | |
390 return ngx_cpymem(buf, h[i].value.data, h[i].value.len); | |
391 } | |
392 } | |
393 | |
394 /* no header */ | |
395 | |
396 if (buf) { | |
397 *buf = '-'; | |
398 } | |
399 | |
400 return buf + 1; | |
401 } | |
402 | |
403 | |
404 static u_char *ngx_http_log_header_out(ngx_http_request_t *r, u_char *buf, | |
405 uintptr_t data) | |
406 { | |
407 ngx_uint_t i; | |
408 ngx_str_t *s; | |
409 ngx_table_elt_t *h; | |
410 ngx_http_log_op_t *op; | |
411 | |
412 if (r) { | |
413 | |
414 /* run-time execution */ | |
415 | |
416 if (r->http_version < NGX_HTTP_VERSION_10) { | |
417 if (buf) { | |
418 *buf = '-'; | |
419 } | |
420 | |
421 return buf + 1; | |
422 } | |
423 | |
424 h = *(ngx_table_elt_t **) ((char *) &r->headers_out + data); | |
425 | |
426 if (h == NULL) { | |
427 | |
428 /* | |
429 * No header pointer was found. | |
430 * However, some headers: "Date", "Server", "Content-Length", | |
431 * and "Last-Modified" have a special handling in the header filter | |
432 * but we do not set up their pointers in the filter because | |
433 * they are too seldom needed to be logged. | |
434 */ | |
435 | |
436 if (data == offsetof(ngx_http_headers_out_t, date)) { | |
437 if (buf == NULL) { | |
438 return (u_char *) ngx_cached_http_time.len; | |
439 } | |
440 return ngx_cpymem(buf, ngx_cached_http_time.data, | |
441 ngx_cached_http_time.len); | |
442 } | |
443 | |
444 if (data == offsetof(ngx_http_headers_out_t, server)) { | |
445 if (buf == NULL) { | |
446 return (u_char *) (sizeof(NGINX_VER) - 1); | |
447 } | |
448 return ngx_cpymem(buf, NGINX_VER, sizeof(NGINX_VER) - 1); | |
449 } | |
450 | |
451 if (data == offsetof(ngx_http_headers_out_t, content_length)) { | |
452 if (r->headers_out.content_length_n == -1) { | |
453 if (buf) { | |
454 *buf = '-'; | |
455 } | |
456 return buf + 1; | |
457 } | |
458 | |
459 if (buf == NULL) { | |
460 return (u_char *) NGX_OFF_T_LEN; | |
461 } | |
462 return ngx_sprintf(buf, "%O", r->headers_out.content_length_n); | |
463 } | |
464 | |
465 if (data == offsetof(ngx_http_headers_out_t, last_modified)) { | |
466 if (r->headers_out.last_modified_time == -1) { | |
467 if (buf) { | |
468 *buf = '-'; | |
469 } | |
470 return buf + 1; | |
471 } | |
472 | |
473 if (buf == NULL) { | |
474 return (u_char *) | |
475 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; | |
476 } | |
477 return ngx_http_time(buf, r->headers_out.last_modified_time); | |
478 } | |
479 | |
480 if (buf) { | |
481 *buf = '-'; | |
482 } | |
483 | |
484 return buf + 1; | |
485 } | |
486 | |
487 if (buf == NULL) { | |
488 /* find the header length */ | |
489 return (u_char *) h->value.len; | |
490 } | |
491 | |
492 return ngx_cpymem(buf, h->value.data, h->value.len); | |
493 } | |
494 | |
495 /* find an offset while a format string compilation */ | |
496 | |
497 op = (ngx_http_log_op_t *) buf; | |
498 s = (ngx_str_t *) data; | |
499 | |
500 op->len = 0; | |
501 | |
502 for (i = 0; ngx_http_headers_out[i].name.len != 0; i++) { | |
503 if (ngx_http_headers_out[i].name.len != s->len) { | |
504 continue; | |
505 } | |
506 | |
507 if (ngx_strncasecmp(ngx_http_headers_out[i].name.data, s->data, s->len) | |
508 == 0) | |
509 { | |
510 op->op = ngx_http_log_header_out; | |
511 op->data = ngx_http_headers_out[i].offset; | |
512 return NULL; | |
513 } | |
514 } | |
515 | |
516 if (s->len == sizeof("Connection") - 1 | |
517 && ngx_strncasecmp(s->data, "Connection", s->len) == 0) | |
518 { | |
519 op->op = ngx_http_log_connection_header_out; | |
520 op->data = (uintptr_t) NULL; | |
521 return NULL; | |
522 } | |
523 | |
524 if (s->len == sizeof("Transfer-Encoding") - 1 | |
525 && ngx_strncasecmp(s->data, "Transfer-Encoding", s->len) == 0) { | |
526 op->op = ngx_http_log_transfer_encoding_header_out; | |
527 op->data = (uintptr_t) NULL; | |
528 return NULL; | |
529 } | |
530 | |
531 op->op = ngx_http_log_unknown_header_out; | |
532 op->data = (uintptr_t) s; | |
533 | 661 |
534 return NULL; | 662 return NULL; |
535 } | 663 } |
536 | 664 |
537 | 665 |
538 static u_char *ngx_http_log_connection_header_out(ngx_http_request_t *r, | 666 static u_char *ngx_http_log_connection_header_out(ngx_http_request_t *r, |
539 u_char *buf, uintptr_t data) | 667 u_char *buf, |
540 { | 668 ngx_http_log_op_t *op) |
541 if (buf == NULL) { | 669 { |
542 return (u_char *) ((r->keepalive) ? sizeof("keep-alive") - 1: | |
543 sizeof("close") - 1); | |
544 } | |
545 | |
546 if (r->keepalive) { | 670 if (r->keepalive) { |
547 return ngx_cpymem(buf, "keep-alive", sizeof("keep-alive") - 1); | 671 return ngx_cpymem(buf, "keep-alive", sizeof("keep-alive") - 1); |
548 | 672 |
549 } else { | 673 } else { |
550 return ngx_cpymem(buf, "close", sizeof("close") - 1); | 674 return ngx_cpymem(buf, "close", sizeof("close") - 1); |
552 } | 676 } |
553 | 677 |
554 | 678 |
555 static u_char *ngx_http_log_transfer_encoding_header_out(ngx_http_request_t *r, | 679 static u_char *ngx_http_log_transfer_encoding_header_out(ngx_http_request_t *r, |
556 u_char *buf, | 680 u_char *buf, |
557 uintptr_t data) | 681 ngx_http_log_op_t *op) |
558 { | 682 { |
559 if (buf == NULL) { | |
560 return (u_char *) ((r->chunked) ? sizeof("chunked") - 1 : 1); | |
561 } | |
562 | |
563 if (r->chunked) { | 683 if (r->chunked) { |
564 return ngx_cpymem(buf, "chunked", sizeof("chunked") - 1); | 684 return ngx_cpymem(buf, "chunked", sizeof("chunked") - 1); |
565 } | 685 } |
566 | 686 |
567 *buf = '-'; | 687 *buf = '-'; |
568 | 688 |
569 return buf + 1; | 689 return buf + 1; |
570 } | 690 } |
571 | 691 |
572 | 692 |
573 static u_char *ngx_http_log_unknown_header_out(ngx_http_request_t *r, | 693 static ngx_int_t ngx_http_log_set_formats(ngx_conf_t *cf) |
574 u_char *buf, | |
575 uintptr_t data) | |
576 { | |
577 ngx_uint_t i; | |
578 ngx_str_t *s; | |
579 ngx_list_part_t *part; | |
580 ngx_table_elt_t *h; | |
581 | |
582 s = (ngx_str_t *) data; | |
583 | |
584 part = &r->headers_out.headers.part; | |
585 h = part->elts; | |
586 | |
587 for (i = 0; /* void */; i++) { | |
588 | |
589 if (i >= part->nelts) { | |
590 if (part->next == NULL) { | |
591 break; | |
592 } | |
593 | |
594 part = part->next; | |
595 h = part->elts; | |
596 i = 0; | |
597 } | |
598 | |
599 if (h[i].key.len != s->len) { | |
600 continue; | |
601 } | |
602 | |
603 if (ngx_strncasecmp(h[i].key.data, s->data, s->len) == 0) { | |
604 if (buf == NULL) { | |
605 /* find the header length */ | |
606 return (u_char *) h[i].value.len; | |
607 } | |
608 | |
609 return ngx_cpymem(buf, h[i].value.data, h[i].value.len); | |
610 } | |
611 } | |
612 | |
613 /* no header */ | |
614 | |
615 if (buf) { | |
616 *buf = '-'; | |
617 } | |
618 | |
619 return buf + 1; | |
620 } | |
621 | |
622 | |
623 static ngx_int_t ngx_http_log_pre_conf(ngx_conf_t *cf) | |
624 { | 694 { |
625 ngx_http_log_op_name_t *op; | 695 ngx_http_log_op_name_t *op; |
626 | 696 |
627 for (op = ngx_http_log_fmt_ops; op->name.len; op++) { /* void */ } | 697 for (op = ngx_http_log_fmt_ops; op->name.len; op++) { /* void */ } |
628 op->op = NULL; | 698 op->run = NULL; |
629 | 699 |
630 return NGX_OK; | 700 return NGX_OK; |
631 } | 701 } |
632 | 702 |
633 | 703 |
887 if (fname_len == 0) { | 957 if (fname_len == 0) { |
888 invalid = 1; | 958 invalid = 1; |
889 break; | 959 break; |
890 } | 960 } |
891 | 961 |
892 for (name = ngx_http_log_fmt_ops; name->op; name++) { | 962 for (name = ngx_http_log_fmt_ops; name->run; name++) { |
893 if (name->name.len == 0) { | 963 if (name->name.len == 0) { |
894 name = (ngx_http_log_op_name_t *) name->op; | 964 name = (ngx_http_log_op_name_t *) name->run; |
895 } | 965 } |
896 | 966 |
897 if (name->name.len == fname_len | 967 if (name->name.len == fname_len |
898 && ngx_strncmp(name->name.data, fname, fname_len) == 0) | 968 && ngx_strncmp(name->name.data, fname, fname_len) == 0) |
899 { | 969 { |
900 if (name->len != NGX_HTTP_LOG_ARG) { | 970 if (name->compile == NULL) { |
901 if (arg.len) { | 971 if (arg.len) { |
902 fname[fname_len] = '\0'; | 972 fname[fname_len] = '\0'; |
903 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 973 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
904 "\"%s\" must not have argument", | 974 "\"%s\" must not have argument", |
905 data); | 975 data); |
906 return NGX_CONF_ERROR; | 976 return NGX_CONF_ERROR; |
907 } | 977 } |
908 | 978 |
909 op->len = name->len; | 979 op->len = name->len; |
910 op->op = name->op; | 980 op->getlen = name->getlen; |
981 op->run = name->run; | |
911 op->data = 0; | 982 op->data = 0; |
912 | 983 |
913 break; | 984 break; |
914 } | 985 } |
915 | 986 |
924 if (!(a = ngx_palloc(cf->pool, sizeof(ngx_str_t)))) { | 995 if (!(a = ngx_palloc(cf->pool, sizeof(ngx_str_t)))) { |
925 return NGX_CONF_ERROR; | 996 return NGX_CONF_ERROR; |
926 } | 997 } |
927 | 998 |
928 *a = arg; | 999 *a = arg; |
929 name->op(NULL, (u_char *) op, (uintptr_t) a); | 1000 if (name->compile(op, a) == NGX_ERROR) { |
1001 return NGX_CONF_ERROR; | |
1002 } | |
930 | 1003 |
931 break; | 1004 break; |
932 } | 1005 } |
933 } | 1006 } |
934 | 1007 |
947 len = &value[s].data[i] - data; | 1020 len = &value[s].data[i] - data; |
948 | 1021 |
949 if (len) { | 1022 if (len) { |
950 | 1023 |
951 op->len = len; | 1024 op->len = len; |
1025 op->getlen = NULL; | |
952 | 1026 |
953 if (len <= sizeof(uintptr_t)) { | 1027 if (len <= sizeof(uintptr_t)) { |
954 op->op = NGX_HTTP_LOG_COPY_SHORT; | 1028 op->run = ngx_http_log_copy_short; |
955 op->data = 0; | 1029 op->data = 0; |
956 | 1030 |
957 while (len--) { | 1031 while (len--) { |
958 op->data <<= 8; | 1032 op->data <<= 8; |
959 op->data |= data[len]; | 1033 op->data |= data[len]; |
960 } | 1034 } |
961 | 1035 |
962 } else { | 1036 } else { |
963 op->op = NGX_HTTP_LOG_COPY_LONG; | 1037 op->run = ngx_http_log_copy_long; |
964 | 1038 |
965 if (!(p = ngx_palloc(cf->pool, len))) { | 1039 if (!(p = ngx_palloc(cf->pool, len))) { |
966 return NGX_CONF_ERROR; | 1040 return NGX_CONF_ERROR; |
967 } | 1041 } |
968 | 1042 |