annotate src/stream/ngx_stream_script.h @ 6874:7cc2d3a96ea3

Fixed trailer construction with limit on FreeBSD and macOS. The ngx_chain_coalesce_file() function may produce more bytes to send then requested in the limit passed, as it aligns the last file position to send to memory page boundary. As a result, (limit - send) may become negative. This resulted in big positive number when converted to size_t while calling ngx_output_chain_to_iovec(). Another part of the problem is in ngx_chain_coalesce_file(): it changes cl to the next chain link even if the current buffer is only partially sent due to limit. Therefore, if a file buffer was not expected to be fully sent due to limit, and was followed by a memory buffer, nginx called sendfile() with a part of the file buffer, and the memory buffer in trailer. If there were enough room in the socket buffer, this resulted in a part of the file buffer being skipped, and corresponding part of the memory buffer sent instead. The bug was introduced in 8e903522c17a (1.7.8). Configurations affected are ones using limits, that is, limit_rate and/or sendfile_max_chunk, and memory buffers after file ones (may happen when using subrequests or with proxying with disk buffering). Fix is to explicitly check if (send < limit) before constructing trailer with ngx_output_chain_to_iovec(). Additionally, ngx_chain_coalesce_file() was modified to preserve unfinished file buffers in cl.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 20 Jan 2017 21:12:48 +0300
parents 0125b151c9a5
children b82162b8496a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6607
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
2 /*
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
4 * Copyright (C) Nginx, Inc.
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
5 */
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
6
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
7
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
8 #ifndef _NGX_STREAM_SCRIPT_H_INCLUDED_
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
9 #define _NGX_STREAM_SCRIPT_H_INCLUDED_
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
10
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
11
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
12 #include <ngx_config.h>
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
13 #include <ngx_core.h>
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
14 #include <ngx_stream.h>
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
15
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
16
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
17 typedef struct {
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
18 u_char *ip;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
19 u_char *pos;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
20 ngx_stream_variable_value_t *sp;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
21
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
22 ngx_str_t buf;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
23 ngx_str_t line;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
24
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
25 unsigned flushed:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
26 unsigned skip:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
27
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
28 ngx_stream_session_t *session;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
29 } ngx_stream_script_engine_t;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
30
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
31
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
32 typedef struct {
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
33 ngx_conf_t *cf;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
34 ngx_str_t *source;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
35
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
36 ngx_array_t **flushes;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
37 ngx_array_t **lengths;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
38 ngx_array_t **values;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
39
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
40 ngx_uint_t variables;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
41 ngx_uint_t ncaptures;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
42 ngx_uint_t size;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
43
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
44 void *main;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
45
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
46 unsigned complete_lengths:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
47 unsigned complete_values:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
48 unsigned zero:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
49 unsigned conf_prefix:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
50 unsigned root_prefix:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
51 } ngx_stream_script_compile_t;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
52
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
53
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
54 typedef struct {
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
55 ngx_str_t value;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
56 ngx_uint_t *flushes;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
57 void *lengths;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
58 void *values;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
59 } ngx_stream_complex_value_t;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
60
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
61
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
62 typedef struct {
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
63 ngx_conf_t *cf;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
64 ngx_str_t *value;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
65 ngx_stream_complex_value_t *complex_value;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
66
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
67 unsigned zero:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
68 unsigned conf_prefix:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
69 unsigned root_prefix:1;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
70 } ngx_stream_compile_complex_value_t;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
71
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
72
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
73 typedef void (*ngx_stream_script_code_pt) (ngx_stream_script_engine_t *e);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
74 typedef size_t (*ngx_stream_script_len_code_pt) (ngx_stream_script_engine_t *e);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
75
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
76
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
77 typedef struct {
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
78 ngx_stream_script_code_pt code;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
79 uintptr_t len;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
80 } ngx_stream_script_copy_code_t;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
81
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
82
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
83 typedef struct {
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
84 ngx_stream_script_code_pt code;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
85 uintptr_t index;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
86 } ngx_stream_script_var_code_t;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
87
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
88
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
89 typedef struct {
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
90 ngx_stream_script_code_pt code;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
91 uintptr_t n;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
92 } ngx_stream_script_copy_capture_code_t;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
93
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
94
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
95 typedef struct {
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
96 ngx_stream_script_code_pt code;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
97 uintptr_t conf_prefix;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
98 } ngx_stream_script_full_name_code_t;
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
99
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
100
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
101 void ngx_stream_script_flush_complex_value(ngx_stream_session_t *s,
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
102 ngx_stream_complex_value_t *val);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
103 ngx_int_t ngx_stream_complex_value(ngx_stream_session_t *s,
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
104 ngx_stream_complex_value_t *val, ngx_str_t *value);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
105 ngx_int_t ngx_stream_compile_complex_value(
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
106 ngx_stream_compile_complex_value_t *ccv);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
107 char *ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
108 void *conf);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
109
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
110
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
111 ngx_uint_t ngx_stream_script_variables_count(ngx_str_t *value);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
112 ngx_int_t ngx_stream_script_compile(ngx_stream_script_compile_t *sc);
6678
0125b151c9a5 Stream: log module.
Vladimir Homutov <vl@nginx.com>
parents: 6607
diff changeset
113 u_char *ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value,
0125b151c9a5 Stream: log module.
Vladimir Homutov <vl@nginx.com>
parents: 6607
diff changeset
114 void *code_lengths, size_t reserved, void *code_values);
0125b151c9a5 Stream: log module.
Vladimir Homutov <vl@nginx.com>
parents: 6607
diff changeset
115 void ngx_stream_script_flush_no_cacheable_variables(ngx_stream_session_t *s,
0125b151c9a5 Stream: log module.
Vladimir Homutov <vl@nginx.com>
parents: 6607
diff changeset
116 ngx_array_t *indices);
6607
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
117
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
118 void *ngx_stream_script_add_code(ngx_array_t *codes, size_t size, void *code);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
119
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
120 size_t ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
121 void ngx_stream_script_copy_code(ngx_stream_script_engine_t *e);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
122 size_t ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
123 void ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
124 size_t ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
125 void ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e);
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
126
c70b7f4537e1 Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
127 #endif /* _NGX_STREAM_SCRIPT_H_INCLUDED_ */