Mercurial > hg > nginx-quic
annotate src/os/win32/ngx_process.c @ 5992:174512857ccf
Cache: do not inherit last_modified and etag from stale response.
When replacing a stale cache entry, its last_modified and etag could be
inherited from the old entry if the response code is not 200 or 206. Moreover,
etag could be inherited with any response code if it's missing in the new
response. As a result, the cache entry is left with invalid last_modified or
etag which could lead to broken revalidation.
For example, when a file is deleted from backend, its last_modified is copied to
the new 404 cache entry and is used later for revalidation. Once the old file
appears again with its original timestamp, revalidation succeeds and the cached
404 response is sent to client instead of the file.
The problem appeared with etags in 44b9ab7752e3 (1.7.3) and affected
last_modified in 1573fc7875fa (1.7.9).
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 02 Mar 2015 19:47:13 +0300 |
parents | e00b71ece8b3 |
children | 2b7dacb381ed |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
280
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
280
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
4412 | 4 * Copyright (C) Nginx, Inc. |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
280
diff
changeset
|
5 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
280
diff
changeset
|
6 |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
11 |
2725 | 12 int ngx_argc; |
13 char **ngx_argv; | |
14 char **ngx_os_argv; | |
15 | |
16 ngx_int_t ngx_last_process; | |
17 ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; | |
452 | 18 |
19 | |
2725 | 20 ngx_pid_t |
21 ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn) | |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
22 { |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
23 u_long rc, n, code; |
2725 | 24 ngx_int_t s; |
25 ngx_pid_t pid; | |
26 ngx_exec_ctx_t ctx; | |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
27 HANDLE events[2]; |
2725 | 28 char file[MAX_PATH + 1]; |
29 | |
30 if (respawn >= 0) { | |
31 s = respawn; | |
32 | |
33 } else { | |
34 for (s = 0; s < ngx_last_process; s++) { | |
35 if (ngx_processes[s].handle == NULL) { | |
36 break; | |
37 } | |
38 } | |
39 | |
40 if (s == NGX_MAX_PROCESSES) { | |
41 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
42 "no more than %d processes can be spawned", | |
43 NGX_MAX_PROCESSES); | |
44 return NGX_INVALID_PID; | |
45 } | |
46 } | |
47 | |
48 n = GetModuleFileName(NULL, file, MAX_PATH); | |
49 | |
50 if (n == 0) { | |
51 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
52 "GetModuleFileName() failed"); | |
53 return NGX_INVALID_PID; | |
54 } | |
55 | |
56 file[n] = '\0'; | |
57 | |
58 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
59 "GetModuleFileName: \"%s\"", file); | |
60 | |
61 ctx.path = file; | |
62 ctx.name = name; | |
2745
1983932b8075
pass command lines options to workers
Igor Sysoev <igor@sysoev.ru>
parents:
2737
diff
changeset
|
63 ctx.args = GetCommandLine(); |
2725 | 64 ctx.argv = NULL; |
65 ctx.envp = NULL; | |
66 | |
67 pid = ngx_execute(cycle, &ctx); | |
68 | |
69 if (pid == NGX_INVALID_PID) { | |
70 return pid; | |
71 } | |
72 | |
73 ngx_memzero(&ngx_processes[s], sizeof(ngx_process_t)); | |
74 | |
75 ngx_processes[s].handle = ctx.child; | |
76 ngx_processes[s].pid = pid; | |
77 ngx_processes[s].name = name; | |
78 | |
79 ngx_sprintf(ngx_processes[s].term_event, "ngx_%s_term_%ul%Z", name, pid); | |
80 ngx_sprintf(ngx_processes[s].quit_event, "ngx_%s_quit_%ul%Z", name, pid); | |
81 ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%ul%Z", | |
82 name, pid); | |
83 | |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
84 events[0] = ngx_master_process_event; |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
85 events[1] = ctx.child; |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
86 |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
87 rc = WaitForMultipleObjects(2, events, 0, 5000); |
2725 | 88 |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
89 ngx_time_update(); |
2725 | 90 |
91 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
92 "WaitForMultipleObjects: %ul", rc); |
2725 | 93 |
94 switch (rc) { | |
95 | |
96 case WAIT_OBJECT_0: | |
97 | |
98 ngx_processes[s].term = OpenEvent(EVENT_MODIFY_STATE, 0, | |
99 (char *) ngx_processes[s].term_event); | |
100 if (ngx_processes[s].term == NULL) { | |
101 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
102 "OpenEvent(\"%s\") failed", | |
103 ngx_processes[s].term_event); | |
104 goto failed; | |
105 } | |
106 | |
107 ngx_processes[s].quit = OpenEvent(EVENT_MODIFY_STATE, 0, | |
108 (char *) ngx_processes[s].quit_event); | |
109 if (ngx_processes[s].quit == NULL) { | |
110 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
111 "OpenEvent(\"%s\") failed", | |
112 ngx_processes[s].quit_event); | |
113 goto failed; | |
114 } | |
115 | |
116 ngx_processes[s].reopen = OpenEvent(EVENT_MODIFY_STATE, 0, | |
117 (char *) ngx_processes[s].reopen_event); | |
118 if (ngx_processes[s].reopen == NULL) { | |
119 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
120 "OpenEvent(\"%s\") failed", | |
121 ngx_processes[s].reopen_event); | |
122 goto failed; | |
123 } | |
124 | |
125 if (ResetEvent(ngx_master_process_event) == 0) { | |
126 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
127 "ResetEvent(\"%s\") failed", | |
128 ngx_master_process_event_name); | |
129 goto failed; | |
130 } | |
131 | |
132 break; | |
2737
d52cf82d0d77
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
133 |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
134 case WAIT_OBJECT_0 + 1: |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
135 if (GetExitCodeProcess(ctx.child, &code) == 0) { |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
136 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
137 "GetExitCodeProcess(%P) failed", pid); |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
138 } |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
139 |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
140 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
141 "%s process %P exited with code %Xul", |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
142 name, pid, code); |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
143 |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
144 goto failed; |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
145 |
2725 | 146 case WAIT_TIMEOUT: |
147 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
148 "the event \"%s\" was not signaled for 5s", | |
149 ngx_master_process_event_name); | |
150 goto failed; | |
151 | |
152 case WAIT_FAILED: | |
153 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
154 "WaitForSingleObject(\"%s\") failed", | |
155 ngx_master_process_event_name); | |
156 | |
157 goto failed; | |
158 } | |
159 | |
160 if (respawn >= 0) { | |
161 return pid; | |
162 } | |
163 | |
164 switch (respawn) { | |
165 | |
166 case NGX_PROCESS_RESPAWN: | |
3016
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2909
diff
changeset
|
167 ngx_processes[s].just_spawn = 0; |
2725 | 168 break; |
169 | |
170 case NGX_PROCESS_JUST_RESPAWN: | |
3016
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2909
diff
changeset
|
171 ngx_processes[s].just_spawn = 1; |
2725 | 172 break; |
173 } | |
174 | |
175 if (s == ngx_last_process) { | |
176 ngx_last_process++; | |
177 } | |
178 | |
179 return pid; | |
180 | |
181 failed: | |
182 | |
183 if (ngx_processes[s].reopen) { | |
184 ngx_close_handle(ngx_processes[s].reopen); | |
185 } | |
186 | |
187 if (ngx_processes[s].quit) { | |
188 ngx_close_handle(ngx_processes[s].quit); | |
189 } | |
190 | |
191 if (ngx_processes[s].term) { | |
192 ngx_close_handle(ngx_processes[s].term); | |
193 } | |
194 | |
195 TerminateProcess(ngx_processes[s].handle, 2); | |
196 | |
197 if (ngx_processes[s].handle) { | |
198 ngx_close_handle(ngx_processes[s].handle); | |
4757
e00b71ece8b3
Win32: fixed cpu hog after process startup failure.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
199 ngx_processes[s].handle = NULL; |
2725 | 200 } |
201 | |
202 return NGX_INVALID_PID; | |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
203 } |
2725 | 204 |
205 | |
206 ngx_pid_t | |
207 ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx) | |
208 { | |
209 STARTUPINFO si; | |
210 PROCESS_INFORMATION pi; | |
211 | |
212 ngx_memzero(&si, sizeof(STARTUPINFO)); | |
213 si.cb = sizeof(STARTUPINFO); | |
214 | |
215 ngx_memzero(&pi, sizeof(PROCESS_INFORMATION)); | |
216 | |
2745
1983932b8075
pass command lines options to workers
Igor Sysoev <igor@sysoev.ru>
parents:
2737
diff
changeset
|
217 if (CreateProcess(ctx->path, ctx->args, |
2725 | 218 NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &si, &pi) |
219 == 0) | |
220 { | |
221 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno, | |
222 "CreateProcess(\"%s\") failed", ngx_argv[0]); | |
223 | |
224 return 0; | |
225 } | |
226 | |
227 ctx->child = pi.hProcess; | |
228 | |
229 if (CloseHandle(pi.hThread) == 0) { | |
230 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
231 "CloseHandle(pi.hThread) failed"); | |
232 } | |
233 | |
234 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, | |
235 "start %s process %P", ctx->name, pi.dwProcessId); | |
236 | |
237 return pi.dwProcessId; | |
238 } |