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