aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemontest_post.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemontest_post.c')
-rw-r--r--src/daemon/daemontest_post.c538
1 files changed, 220 insertions, 318 deletions
diff --git a/src/daemon/daemontest_post.c b/src/daemon/daemontest_post.c
index 2c020563..61850a24 100644
--- a/src/daemon/daemontest_post.c
+++ b/src/daemon/daemontest_post.c
@@ -41,246 +41,187 @@
41 41
42static int oneone; 42static int oneone;
43 43
44struct CBC { 44struct CBC
45 char * buf; 45{
46 char *buf;
46 size_t pos; 47 size_t pos;
47 size_t size; 48 size_t size;
48}; 49};
49 50
50static size_t copyBuffer(void * ptr, 51static size_t
51 size_t size, 52copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
52 size_t nmemb, 53{
53 void * ctx) { 54 struct CBC *cbc = ctx;
54 struct CBC * cbc = ctx;
55 55
56 if (cbc->pos + size * nmemb > cbc->size) 56 if (cbc->pos + size * nmemb > cbc->size)
57 return 0; /* overflow */ 57 return 0; /* overflow */
58 memcpy(&cbc->buf[cbc->pos], 58 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
59 ptr,
60 size * nmemb);
61 cbc->pos += size * nmemb; 59 cbc->pos += size * nmemb;
62 return size * nmemb; 60 return size * nmemb;
63} 61}
64 62
65static int ahc_echo(void * cls, 63static int
66 struct MHD_Connection * connection, 64ahc_echo (void *cls,
67 const char * url, 65 struct MHD_Connection *connection,
68 const char * method, 66 const char *url,
69 const char * version, 67 const char *method,
70 const char * upload_data, 68 const char *version,
71 unsigned int * upload_data_size) { 69 const char *upload_data, unsigned int *upload_data_size)
72 struct MHD_Response * response; 70{
71 struct MHD_Response *response;
73 int ret; 72 int ret;
74 const char * r1; 73 const char *r1;
75 const char * r2; 74 const char *r2;
76 75
77 if (0 != strcmp("POST", method)) { 76 if (0 != strcmp ("POST", method))
78 printf("METHOD: %s\n", method); 77 {
79 return MHD_NO; /* unexpected method */ 78 printf ("METHOD: %s\n", method);
80 } 79 return MHD_NO; /* unexpected method */
81 r1 = MHD_lookup_connection_value(connection, 80 }
82 MHD_POSTDATA_KIND, 81 r1 = MHD_lookup_connection_value (connection, MHD_POSTDATA_KIND, "name");
83 "name"); 82 r2 = MHD_lookup_connection_value (connection, MHD_POSTDATA_KIND, "project");
84 r2 = MHD_lookup_connection_value(connection, 83 if ((r1 != NULL) &&
85 MHD_POSTDATA_KIND, 84 (r2 != NULL) &&
86 "project"); 85 (0 == strcmp ("daniel", r1)) && (0 == strcmp ("curl", r2)))
87 if ( (r1 != NULL) && 86 {
88 (r2 != NULL) && 87 response = MHD_create_response_from_data (strlen (url),
89 (0 == strcmp("daniel", 88 (void *) url,
90 r1)) && 89 MHD_NO, MHD_YES);
91 (0 == strcmp("curl", 90 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
92 r2)) ) { 91 MHD_destroy_response (response);
93 response = MHD_create_response_from_data(strlen(url), 92 return MHD_YES; /* done */
94 (void*) url, 93 }
95 MHD_NO,
96 MHD_YES);
97 ret = MHD_queue_response(connection,
98 MHD_HTTP_OK,
99 response);
100 MHD_destroy_response(response);
101 return MHD_YES; /* done */
102 }
103 return MHD_YES; 94 return MHD_YES;
104} 95}
105 96
106 97
107static int testInternalPost() { 98static int
108 struct MHD_Daemon * d; 99testInternalPost ()
109 CURL * c; 100{
101 struct MHD_Daemon *d;
102 CURL *c;
110 char buf[2048]; 103 char buf[2048];
111 struct CBC cbc; 104 struct CBC cbc;
112 105
113 cbc.buf = buf; 106 cbc.buf = buf;
114 cbc.size = 2048; 107 cbc.size = 2048;
115 cbc.pos = 0; 108 cbc.pos = 0;
116 d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, 109 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
117 1080, 110 1080, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
118 NULL,
119 NULL,
120 &ahc_echo,
121 NULL,
122 MHD_OPTION_END);
123 if (d == NULL) 111 if (d == NULL)
124 return 1; 112 return 1;
125 c = curl_easy_init(); 113 c = curl_easy_init ();
126 curl_easy_setopt(c, 114 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world");
127 CURLOPT_URL, 115 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
128 "http://localhost:1080/hello_world"); 116 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
129 curl_easy_setopt(c, 117 curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
130 CURLOPT_WRITEFUNCTION, 118 curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
131 &copyBuffer); 119 curl_easy_setopt (c, CURLOPT_POST, 1L);
132 curl_easy_setopt(c, 120 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
133 CURLOPT_WRITEDATA, 121 curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L);
134 &cbc);
135 curl_easy_setopt(c,
136 CURLOPT_POSTFIELDS,
137 POST_DATA);
138 curl_easy_setopt(c,
139 CURLOPT_POSTFIELDSIZE,
140 strlen(POST_DATA));
141 curl_easy_setopt(c,
142 CURLOPT_POST,
143 1L);
144 curl_easy_setopt(c,
145 CURLOPT_FAILONERROR,
146 1);
147 curl_easy_setopt(c,
148 CURLOPT_TIMEOUT,
149 2L);
150 if (oneone) 122 if (oneone)
151 curl_easy_setopt(c, 123 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
152 CURLOPT_HTTP_VERSION,
153 CURL_HTTP_VERSION_1_1);
154 else 124 else
155 curl_easy_setopt(c, 125 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
156 CURLOPT_HTTP_VERSION, 126 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L);
157 CURL_HTTP_VERSION_1_0);
158 curl_easy_setopt(c,
159 CURLOPT_CONNECTTIMEOUT,
160 2L);
161 // NOTE: use of CONNECTTIMEOUT without also 127 // NOTE: use of CONNECTTIMEOUT without also
162 // setting NOSIGNAL results in really weird 128 // setting NOSIGNAL results in really weird
163 // crashes on my system! 129 // crashes on my system!
164 curl_easy_setopt(c, 130 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
165 CURLOPT_NOSIGNAL, 131 if (CURLE_OK != curl_easy_perform (c))
166 1); 132 {
167 if (CURLE_OK != curl_easy_perform(c)) { 133 curl_easy_cleanup (c);
168 curl_easy_cleanup(c); 134 MHD_stop_daemon (d);
169 MHD_stop_daemon(d); 135 return 2;
170 return 2; 136 }
171 } 137 curl_easy_cleanup (c);
172 curl_easy_cleanup(c); 138 if (cbc.pos != strlen ("/hello_world"))
173 if (cbc.pos != strlen("/hello_world")) { 139 {
174 MHD_stop_daemon(d); 140 MHD_stop_daemon (d);
175 return 4; 141 return 4;
176 } 142 }
177 143
178 if (0 != strncmp("/hello_world", 144 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
179 cbc.buf, 145 {
180 strlen("/hello_world"))) { 146 MHD_stop_daemon (d);
181 MHD_stop_daemon(d); 147 return 8;
182 return 8; 148 }
183 } 149 MHD_stop_daemon (d);
184 MHD_stop_daemon(d);
185 150
186 return 0; 151 return 0;
187} 152}
188 153
189static int testMultithreadedPost() { 154static int
190 struct MHD_Daemon * d; 155testMultithreadedPost ()
191 CURL * c; 156{
157 struct MHD_Daemon *d;
158 CURL *c;
192 char buf[2048]; 159 char buf[2048];
193 struct CBC cbc; 160 struct CBC cbc;
194 161
195 cbc.buf = buf; 162 cbc.buf = buf;
196 cbc.size = 2048; 163 cbc.size = 2048;
197 cbc.pos = 0; 164 cbc.pos = 0;
198 d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION |MHD_USE_DEBUG, 165 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
199 1081, 166 1081, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
200 NULL,
201 NULL,
202 &ahc_echo,
203 NULL,
204 MHD_OPTION_END);
205 if (d == NULL) 167 if (d == NULL)
206 return 16; 168 return 16;
207 c = curl_easy_init(); 169 c = curl_easy_init ();
208 curl_easy_setopt(c, 170 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
209 CURLOPT_URL, 171 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
210 "http://localhost:1081/hello_world"); 172 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
211 curl_easy_setopt(c, 173 curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
212 CURLOPT_WRITEFUNCTION, 174 curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
213 &copyBuffer); 175 curl_easy_setopt (c, CURLOPT_POST, 1L);
214 curl_easy_setopt(c, 176 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
215 CURLOPT_WRITEDATA, 177 curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L);
216 &cbc);
217 curl_easy_setopt(c,
218 CURLOPT_POSTFIELDS,
219 POST_DATA);
220 curl_easy_setopt(c,
221 CURLOPT_POSTFIELDSIZE,
222 strlen(POST_DATA));
223 curl_easy_setopt(c,
224 CURLOPT_POST,
225 1L);
226 curl_easy_setopt(c,
227 CURLOPT_FAILONERROR,
228 1);
229 curl_easy_setopt(c,
230 CURLOPT_TIMEOUT,
231 2L);
232 if (oneone) 178 if (oneone)
233 curl_easy_setopt(c, 179 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
234 CURLOPT_HTTP_VERSION,
235 CURL_HTTP_VERSION_1_1);
236 else 180 else
237 curl_easy_setopt(c, 181 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
238 CURLOPT_HTTP_VERSION, 182 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L);
239 CURL_HTTP_VERSION_1_0);
240 curl_easy_setopt(c,
241 CURLOPT_CONNECTTIMEOUT,
242 2L);
243 // NOTE: use of CONNECTTIMEOUT without also 183 // NOTE: use of CONNECTTIMEOUT without also
244 // setting NOSIGNAL results in really weird 184 // setting NOSIGNAL results in really weird
245 // crashes on my system! 185 // crashes on my system!
246 curl_easy_setopt(c, 186 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
247 CURLOPT_NOSIGNAL, 187 if (CURLE_OK != curl_easy_perform (c))
248 1); 188 {
249 if (CURLE_OK != curl_easy_perform(c)) { 189 curl_easy_cleanup (c);
250 curl_easy_cleanup(c); 190 MHD_stop_daemon (d);
251 MHD_stop_daemon(d); 191 return 32;
252 return 32; 192 }
253 } 193 curl_easy_cleanup (c);
254 curl_easy_cleanup(c); 194 if (cbc.pos != strlen ("/hello_world"))
255 if (cbc.pos != strlen("/hello_world")) { 195 {
256 MHD_stop_daemon(d); 196 MHD_stop_daemon (d);
257 return 64; 197 return 64;
258 } 198 }
259 if (0 != strncmp("/hello_world", 199 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
260 cbc.buf, 200 {
261 strlen("/hello_world"))) { 201 MHD_stop_daemon (d);
262 MHD_stop_daemon(d); 202 return 128;
263 return 128; 203 }
264 } 204 MHD_stop_daemon (d);
265 MHD_stop_daemon(d);
266 205
267 return 0; 206 return 0;
268} 207}
269 208
270 209
271static int testExternalPost() { 210static int
272 struct MHD_Daemon * d; 211testExternalPost ()
273 CURL * c; 212{
213 struct MHD_Daemon *d;
214 CURL *c;
274 char buf[2048]; 215 char buf[2048];
275 struct CBC cbc; 216 struct CBC cbc;
276 CURLM * multi; 217 CURLM *multi;
277 CURLMcode mret; 218 CURLMcode mret;
278 fd_set rs; 219 fd_set rs;
279 fd_set ws; 220 fd_set ws;
280 fd_set es; 221 fd_set es;
281 int max; 222 int max;
282 int running; 223 int running;
283 struct CURLMsg * msg; 224 struct CURLMsg *msg;
284 time_t start; 225 time_t start;
285 struct timeval tv; 226 struct timeval tv;
286 227
@@ -288,163 +229,124 @@ static int testExternalPost() {
288 cbc.buf = buf; 229 cbc.buf = buf;
289 cbc.size = 2048; 230 cbc.size = 2048;
290 cbc.pos = 0; 231 cbc.pos = 0;
291 d = MHD_start_daemon(MHD_USE_DEBUG, 232 d = MHD_start_daemon (MHD_USE_DEBUG,
292 1082, 233 1082, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
293 NULL,
294 NULL,
295 &ahc_echo,
296 NULL,
297 MHD_OPTION_END);
298 if (d == NULL) 234 if (d == NULL)
299 return 256; 235 return 256;
300 c = curl_easy_init(); 236 c = curl_easy_init ();
301 curl_easy_setopt(c, 237 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world");
302 CURLOPT_URL, 238 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
303 "http://localhost:1082/hello_world"); 239 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
304 curl_easy_setopt(c, 240 curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
305 CURLOPT_WRITEFUNCTION, 241 curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
306 &copyBuffer); 242 curl_easy_setopt (c, CURLOPT_POST, 1L);
307 curl_easy_setopt(c, 243 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
308 CURLOPT_WRITEDATA, 244 curl_easy_setopt (c, CURLOPT_TIMEOUT, 5L);
309 &cbc);
310 curl_easy_setopt(c,
311 CURLOPT_POSTFIELDS,
312 POST_DATA);
313 curl_easy_setopt(c,
314 CURLOPT_POSTFIELDSIZE,
315 strlen(POST_DATA));
316 curl_easy_setopt(c,
317 CURLOPT_POST,
318 1L);
319 curl_easy_setopt(c,
320 CURLOPT_FAILONERROR,
321 1);
322 curl_easy_setopt(c,
323 CURLOPT_TIMEOUT,
324 5L);
325 if (oneone) 245 if (oneone)
326 curl_easy_setopt(c, 246 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
327 CURLOPT_HTTP_VERSION,
328 CURL_HTTP_VERSION_1_1);
329 else 247 else
330 curl_easy_setopt(c, 248 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
331 CURLOPT_HTTP_VERSION, 249 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
332 CURL_HTTP_VERSION_1_0);
333 curl_easy_setopt(c,
334 CURLOPT_CONNECTTIMEOUT,
335 5L);
336 // NOTE: use of CONNECTTIMEOUT without also 250 // NOTE: use of CONNECTTIMEOUT without also
337 // setting NOSIGNAL results in really weird 251 // setting NOSIGNAL results in really weird
338 // crashes on my system! 252 // crashes on my system!
339 curl_easy_setopt(c, 253 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
340 CURLOPT_NOSIGNAL,
341 1);
342 254
343 255
344 multi = curl_multi_init(); 256 multi = curl_multi_init ();
345 if (multi == NULL) { 257 if (multi == NULL)
346 curl_easy_cleanup(c); 258 {
347 MHD_stop_daemon(d); 259 curl_easy_cleanup (c);
348 return 512; 260 MHD_stop_daemon (d);
349 } 261 return 512;
350 mret = curl_multi_add_handle(multi, c); 262 }
351 if (mret != CURLM_OK) { 263 mret = curl_multi_add_handle (multi, c);
352 curl_multi_cleanup(multi); 264 if (mret != CURLM_OK)
353 curl_easy_cleanup(c); 265 {
354 MHD_stop_daemon(d); 266 curl_multi_cleanup (multi);
355 return 1024; 267 curl_easy_cleanup (c);
356 } 268 MHD_stop_daemon (d);
357 start = time(NULL); 269 return 1024;
358 while ( (time(NULL) - start < 5) && 270 }
359 (multi != NULL) ) { 271 start = time (NULL);
360 max = 0; 272 while ((time (NULL) - start < 5) && (multi != NULL))
361 FD_ZERO(&rs); 273 {
362 FD_ZERO(&ws); 274 max = 0;
363 FD_ZERO(&es); 275 FD_ZERO (&rs);
364 curl_multi_perform(multi, &running); 276 FD_ZERO (&ws);
365 mret = curl_multi_fdset(multi, 277 FD_ZERO (&es);
366 &rs, 278 curl_multi_perform (multi, &running);
367 &ws, 279 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
368 &es, 280 if (mret != CURLM_OK)
369 &max); 281 {
370 if (mret != CURLM_OK) { 282 curl_multi_remove_handle (multi, c);
371 curl_multi_remove_handle(multi, c); 283 curl_multi_cleanup (multi);
372 curl_multi_cleanup(multi); 284 curl_easy_cleanup (c);
373 curl_easy_cleanup(c); 285 MHD_stop_daemon (d);
374 MHD_stop_daemon(d); 286 return 2048;
375 return 2048; 287 }
288 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
289 {
290 curl_multi_remove_handle (multi, c);
291 curl_multi_cleanup (multi);
292 curl_easy_cleanup (c);
293 MHD_stop_daemon (d);
294 return 4096;
295 }
296 tv.tv_sec = 0;
297 tv.tv_usec = 1000;
298 select (max + 1, &rs, &ws, &es, &tv);
299 curl_multi_perform (multi, &running);
300 if (running == 0)
301 {
302 msg = curl_multi_info_read (multi, &running);
303 if (msg == NULL)
304 break;
305 if (msg->msg == CURLMSG_DONE)
306 {
307 if (msg->data.result != CURLE_OK)
308 printf ("%s failed at %s:%d: `%s'\n",
309 "curl_multi_perform",
310 __FILE__,
311 __LINE__, curl_easy_strerror (msg->data.result));
312 curl_multi_remove_handle (multi, c);
313 curl_multi_cleanup (multi);
314 curl_easy_cleanup (c);
315 c = NULL;
316 multi = NULL;
317 }
318 }
319 MHD_run (d);
376 } 320 }
377 if (MHD_YES != MHD_get_fdset(d, 321 if (multi != NULL)
378 &rs, 322 {
379 &ws, 323 curl_multi_remove_handle (multi, c);
380 &es, 324 curl_easy_cleanup (c);
381 &max)) { 325 curl_multi_cleanup (multi);
382 curl_multi_remove_handle(multi, c);
383 curl_multi_cleanup(multi);
384 curl_easy_cleanup(c);
385 MHD_stop_daemon(d);
386 return 4096;
387 } 326 }
388 tv.tv_sec = 0; 327 MHD_stop_daemon (d);
389 tv.tv_usec = 1000; 328 if (cbc.pos != strlen ("/hello_world"))
390 select(max + 1,
391 &rs,
392 &ws,
393 &es,
394 &tv);
395 curl_multi_perform(multi, &running);
396 if (running == 0) {
397 msg = curl_multi_info_read(multi,
398 &running);
399 if (msg == NULL)
400 break;
401 if (msg->msg == CURLMSG_DONE) {
402 if (msg->data.result != CURLE_OK)
403 printf("%s failed at %s:%d: `%s'\n",
404 "curl_multi_perform",
405 __FILE__,
406 __LINE__,
407 curl_easy_strerror(msg->data.result));
408 curl_multi_remove_handle(multi, c);
409 curl_multi_cleanup(multi);
410 curl_easy_cleanup(c);
411 c = NULL;
412 multi = NULL;
413 }
414 }
415 MHD_run(d);
416 }
417 if (multi != NULL) {
418 curl_multi_remove_handle(multi, c);
419 curl_easy_cleanup(c);
420 curl_multi_cleanup(multi);
421 }
422 MHD_stop_daemon(d);
423 if (cbc.pos != strlen("/hello_world"))
424 return 8192; 329 return 8192;
425 if (0 != strncmp("/hello_world", 330 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
426 cbc.buf,
427 strlen("/hello_world")))
428 return 16384; 331 return 16384;
429 return 0; 332 return 0;
430} 333}
431 334
432 335
433 336
434int main(int argc, 337int
435 char * const * argv) { 338main (int argc, char *const *argv)
339{
436 unsigned int errorCount = 0; 340 unsigned int errorCount = 0;
437 341
438 oneone = NULL != strstr(argv[0], "11"); 342 oneone = NULL != strstr (argv[0], "11");
439 if (0 != curl_global_init(CURL_GLOBAL_WIN32)) 343 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
440 return 2; 344 return 2;
441 errorCount += testInternalPost(); 345 errorCount += testInternalPost ();
442 errorCount += testMultithreadedPost(); 346 errorCount += testMultithreadedPost ();
443 errorCount += testExternalPost(); 347 errorCount += testExternalPost ();
444 if (errorCount != 0) 348 if (errorCount != 0)
445 fprintf(stderr, 349 fprintf (stderr, "Error (code: %u)\n", errorCount);
446 "Error (code: %u)\n", 350 curl_global_cleanup ();
447 errorCount); 351 return errorCount != 0; /* 0 == pass */
448 curl_global_cleanup();
449 return errorCount != 0; /* 0 == pass */
450} 352}