Fossil SCM
Set a default timeout on CGI requests of 300 seconds.
Commit
859d6b16949351dc81b5c1066e3e6f29290ef2ffcc94e37335b4ec6a1d2e07bc
Parent
6ada7e37686eb3c…
1 file changed
+35
-7
+35
-7
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -1947,10 +1947,13 @@ | ||
| 1947 | 1947 | ** |
| 1948 | 1948 | ** debug: FILE Causing debugging information to be written |
| 1949 | 1949 | ** into FILE. |
| 1950 | 1950 | ** |
| 1951 | 1951 | ** errorlog: FILE Warnings, errors, and panics written to FILE. |
| 1952 | +** | |
| 1953 | +** timeout: SECONDS Do not run for longer than SECONDS. The default | |
| 1954 | +** timeout is 300 seconds. | |
| 1952 | 1955 | ** |
| 1953 | 1956 | ** extroot: DIR Directory that is the root of the sub-CGI tree |
| 1954 | 1957 | ** on the /ext page. |
| 1955 | 1958 | ** |
| 1956 | 1959 | ** redirect: REPO URL Extract the "name" query parameter and search |
| @@ -1981,10 +1984,11 @@ | ||
| 1981 | 1984 | g.httpOut = stdout; |
| 1982 | 1985 | g.httpIn = stdin; |
| 1983 | 1986 | fossil_binary_mode(g.httpOut); |
| 1984 | 1987 | fossil_binary_mode(g.httpIn); |
| 1985 | 1988 | g.cgiOutput = 1; |
| 1989 | + fossil_set_timeout(300); | |
| 1986 | 1990 | blob_read_from_file(&config, zFile, ExtFILE); |
| 1987 | 1991 | while( blob_line(&config, &line) ){ |
| 1988 | 1992 | if( !blob_token(&line, &key) ) continue; |
| 1989 | 1993 | if( blob_buffer(&key)[0]=='#' ) continue; |
| 1990 | 1994 | if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ |
| @@ -2105,10 +2109,19 @@ | ||
| 2105 | 2109 | ** Enables the /ext webpage to use sub-cgi rooted at DIRECTORY |
| 2106 | 2110 | */ |
| 2107 | 2111 | g.zExtRoot = mprintf("%s", blob_str(&value)); |
| 2108 | 2112 | blob_reset(&value); |
| 2109 | 2113 | continue; |
| 2114 | + } | |
| 2115 | + if( blob_eq(&key, "timeout:") && blob_token(&line, &value) ){ | |
| 2116 | + /* timeout: SECONDS | |
| 2117 | + ** | |
| 2118 | + ** Set an alarm() that kills the process after SECONDS. The | |
| 2119 | + ** default value is 300 seconds. | |
| 2120 | + */ | |
| 2121 | + fossil_set_timeout(atoi(blob_str(&value))); | |
| 2122 | + continue; | |
| 2110 | 2123 | } |
| 2111 | 2124 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 2112 | 2125 | /* HOME: VALUE |
| 2113 | 2126 | ** |
| 2114 | 2127 | ** Set CGI parameter "HOME" to VALUE. This is legacy. Use |
| @@ -2453,15 +2466,31 @@ | ||
| 2453 | 2466 | } |
| 2454 | 2467 | #endif |
| 2455 | 2468 | #endif |
| 2456 | 2469 | |
| 2457 | 2470 | /* |
| 2458 | -** Send a time-out reply | |
| 2471 | +** Respond to a SIGALRM by writing a message to the error log (if there | |
| 2472 | +** is one) and exiting. | |
| 2459 | 2473 | */ |
| 2460 | -void sigalrm_handler(int x){ | |
| 2474 | +static void sigalrm_handler(int x){ | |
| 2461 | 2475 | fossil_panic("TIMEOUT"); |
| 2462 | 2476 | } |
| 2477 | + | |
| 2478 | +/* | |
| 2479 | +** Arrange to timeout using SIGALRM after N seconds. Or if N==0, cancel | |
| 2480 | +** any pending timeout. | |
| 2481 | +** | |
| 2482 | +** Bugs: | |
| 2483 | +** (1) This only works on unix systems. | |
| 2484 | +** (2) Any call to sleep() or sqlite3_sleep() will cancel the alarm. | |
| 2485 | +*/ | |
| 2486 | +void fossil_set_timeout(int N){ | |
| 2487 | +#ifndef _WIN32 | |
| 2488 | + signal(SIGALRM, sigalrm_handler); | |
| 2489 | + alarm(N); | |
| 2490 | +#endif | |
| 2491 | +} | |
| 2463 | 2492 | |
| 2464 | 2493 | /* |
| 2465 | 2494 | ** COMMAND: server* |
| 2466 | 2495 | ** COMMAND: ui |
| 2467 | 2496 | ** |
| @@ -2539,11 +2568,11 @@ | ||
| 2539 | 2568 | int isUiCmd; /* True if command is "ui", not "server' */ |
| 2540 | 2569 | const char *zNotFound; /* The --notfound option or NULL */ |
| 2541 | 2570 | int flags = 0; /* Server flags */ |
| 2542 | 2571 | #if !defined(_WIN32) |
| 2543 | 2572 | int noJail; /* Do not enter the chroot jail */ |
| 2544 | - const char *zMaxLatency; /* Maximum runtime of any single HTTP request */ | |
| 2573 | + const char *zTimeout = "300"; /* Max runtime of any single HTTP request */ | |
| 2545 | 2574 | #endif |
| 2546 | 2575 | int allowRepoList; /* List repositories on URL "/" */ |
| 2547 | 2576 | const char *zAltBase; /* Argument to the --baseurl option */ |
| 2548 | 2577 | const char *zFileGlob; /* Static content must match this */ |
| 2549 | 2578 | char *zIpAddr = 0; /* Bind to this IP address */ |
| @@ -2571,11 +2600,11 @@ | ||
| 2571 | 2600 | zFileGlob = find_option("files",0,1); |
| 2572 | 2601 | } |
| 2573 | 2602 | skin_override(); |
| 2574 | 2603 | #if !defined(_WIN32) |
| 2575 | 2604 | noJail = find_option("nojail",0,0)!=0; |
| 2576 | - zMaxLatency = find_option("max-latency",0,1); | |
| 2605 | + zTimeout = find_option("max-latency",0,1); | |
| 2577 | 2606 | #endif |
| 2578 | 2607 | g.useLocalauth = find_option("localauth", 0, 0)!=0; |
| 2579 | 2608 | Th_InitTraceLog(); |
| 2580 | 2609 | zPort = find_option("port", "P", 1); |
| 2581 | 2610 | isUiCmd = g.argv[1][0]=='u'; |
| @@ -2689,13 +2718,12 @@ | ||
| 2689 | 2718 | ** |
| 2690 | 2719 | ** So, when control reaches this point, we are running as a |
| 2691 | 2720 | ** child process, the HTTP or SCGI request is pending on file |
| 2692 | 2721 | ** descriptor 0 and the reply should be written to file descriptor 1. |
| 2693 | 2722 | */ |
| 2694 | - if( zMaxLatency ){ | |
| 2695 | - signal(SIGALRM, sigalrm_handler); | |
| 2696 | - alarm(atoi(zMaxLatency)); | |
| 2723 | + if( zTimeout ){ | |
| 2724 | + fossil_set_timeout(atoi(zTimeout)); | |
| 2697 | 2725 | } |
| 2698 | 2726 | g.httpIn = stdin; |
| 2699 | 2727 | g.httpOut = stdout; |
| 2700 | 2728 | |
| 2701 | 2729 | #if !defined(_WIN32) |
| 2702 | 2730 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1947,10 +1947,13 @@ | |
| 1947 | ** |
| 1948 | ** debug: FILE Causing debugging information to be written |
| 1949 | ** into FILE. |
| 1950 | ** |
| 1951 | ** errorlog: FILE Warnings, errors, and panics written to FILE. |
| 1952 | ** |
| 1953 | ** extroot: DIR Directory that is the root of the sub-CGI tree |
| 1954 | ** on the /ext page. |
| 1955 | ** |
| 1956 | ** redirect: REPO URL Extract the "name" query parameter and search |
| @@ -1981,10 +1984,11 @@ | |
| 1981 | g.httpOut = stdout; |
| 1982 | g.httpIn = stdin; |
| 1983 | fossil_binary_mode(g.httpOut); |
| 1984 | fossil_binary_mode(g.httpIn); |
| 1985 | g.cgiOutput = 1; |
| 1986 | blob_read_from_file(&config, zFile, ExtFILE); |
| 1987 | while( blob_line(&config, &line) ){ |
| 1988 | if( !blob_token(&line, &key) ) continue; |
| 1989 | if( blob_buffer(&key)[0]=='#' ) continue; |
| 1990 | if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ |
| @@ -2105,10 +2109,19 @@ | |
| 2105 | ** Enables the /ext webpage to use sub-cgi rooted at DIRECTORY |
| 2106 | */ |
| 2107 | g.zExtRoot = mprintf("%s", blob_str(&value)); |
| 2108 | blob_reset(&value); |
| 2109 | continue; |
| 2110 | } |
| 2111 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 2112 | /* HOME: VALUE |
| 2113 | ** |
| 2114 | ** Set CGI parameter "HOME" to VALUE. This is legacy. Use |
| @@ -2453,15 +2466,31 @@ | |
| 2453 | } |
| 2454 | #endif |
| 2455 | #endif |
| 2456 | |
| 2457 | /* |
| 2458 | ** Send a time-out reply |
| 2459 | */ |
| 2460 | void sigalrm_handler(int x){ |
| 2461 | fossil_panic("TIMEOUT"); |
| 2462 | } |
| 2463 | |
| 2464 | /* |
| 2465 | ** COMMAND: server* |
| 2466 | ** COMMAND: ui |
| 2467 | ** |
| @@ -2539,11 +2568,11 @@ | |
| 2539 | int isUiCmd; /* True if command is "ui", not "server' */ |
| 2540 | const char *zNotFound; /* The --notfound option or NULL */ |
| 2541 | int flags = 0; /* Server flags */ |
| 2542 | #if !defined(_WIN32) |
| 2543 | int noJail; /* Do not enter the chroot jail */ |
| 2544 | const char *zMaxLatency; /* Maximum runtime of any single HTTP request */ |
| 2545 | #endif |
| 2546 | int allowRepoList; /* List repositories on URL "/" */ |
| 2547 | const char *zAltBase; /* Argument to the --baseurl option */ |
| 2548 | const char *zFileGlob; /* Static content must match this */ |
| 2549 | char *zIpAddr = 0; /* Bind to this IP address */ |
| @@ -2571,11 +2600,11 @@ | |
| 2571 | zFileGlob = find_option("files",0,1); |
| 2572 | } |
| 2573 | skin_override(); |
| 2574 | #if !defined(_WIN32) |
| 2575 | noJail = find_option("nojail",0,0)!=0; |
| 2576 | zMaxLatency = find_option("max-latency",0,1); |
| 2577 | #endif |
| 2578 | g.useLocalauth = find_option("localauth", 0, 0)!=0; |
| 2579 | Th_InitTraceLog(); |
| 2580 | zPort = find_option("port", "P", 1); |
| 2581 | isUiCmd = g.argv[1][0]=='u'; |
| @@ -2689,13 +2718,12 @@ | |
| 2689 | ** |
| 2690 | ** So, when control reaches this point, we are running as a |
| 2691 | ** child process, the HTTP or SCGI request is pending on file |
| 2692 | ** descriptor 0 and the reply should be written to file descriptor 1. |
| 2693 | */ |
| 2694 | if( zMaxLatency ){ |
| 2695 | signal(SIGALRM, sigalrm_handler); |
| 2696 | alarm(atoi(zMaxLatency)); |
| 2697 | } |
| 2698 | g.httpIn = stdin; |
| 2699 | g.httpOut = stdout; |
| 2700 | |
| 2701 | #if !defined(_WIN32) |
| 2702 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1947,10 +1947,13 @@ | |
| 1947 | ** |
| 1948 | ** debug: FILE Causing debugging information to be written |
| 1949 | ** into FILE. |
| 1950 | ** |
| 1951 | ** errorlog: FILE Warnings, errors, and panics written to FILE. |
| 1952 | ** |
| 1953 | ** timeout: SECONDS Do not run for longer than SECONDS. The default |
| 1954 | ** timeout is 300 seconds. |
| 1955 | ** |
| 1956 | ** extroot: DIR Directory that is the root of the sub-CGI tree |
| 1957 | ** on the /ext page. |
| 1958 | ** |
| 1959 | ** redirect: REPO URL Extract the "name" query parameter and search |
| @@ -1981,10 +1984,11 @@ | |
| 1984 | g.httpOut = stdout; |
| 1985 | g.httpIn = stdin; |
| 1986 | fossil_binary_mode(g.httpOut); |
| 1987 | fossil_binary_mode(g.httpIn); |
| 1988 | g.cgiOutput = 1; |
| 1989 | fossil_set_timeout(300); |
| 1990 | blob_read_from_file(&config, zFile, ExtFILE); |
| 1991 | while( blob_line(&config, &line) ){ |
| 1992 | if( !blob_token(&line, &key) ) continue; |
| 1993 | if( blob_buffer(&key)[0]=='#' ) continue; |
| 1994 | if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){ |
| @@ -2105,10 +2109,19 @@ | |
| 2109 | ** Enables the /ext webpage to use sub-cgi rooted at DIRECTORY |
| 2110 | */ |
| 2111 | g.zExtRoot = mprintf("%s", blob_str(&value)); |
| 2112 | blob_reset(&value); |
| 2113 | continue; |
| 2114 | } |
| 2115 | if( blob_eq(&key, "timeout:") && blob_token(&line, &value) ){ |
| 2116 | /* timeout: SECONDS |
| 2117 | ** |
| 2118 | ** Set an alarm() that kills the process after SECONDS. The |
| 2119 | ** default value is 300 seconds. |
| 2120 | */ |
| 2121 | fossil_set_timeout(atoi(blob_str(&value))); |
| 2122 | continue; |
| 2123 | } |
| 2124 | if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){ |
| 2125 | /* HOME: VALUE |
| 2126 | ** |
| 2127 | ** Set CGI parameter "HOME" to VALUE. This is legacy. Use |
| @@ -2453,15 +2466,31 @@ | |
| 2466 | } |
| 2467 | #endif |
| 2468 | #endif |
| 2469 | |
| 2470 | /* |
| 2471 | ** Respond to a SIGALRM by writing a message to the error log (if there |
| 2472 | ** is one) and exiting. |
| 2473 | */ |
| 2474 | static void sigalrm_handler(int x){ |
| 2475 | fossil_panic("TIMEOUT"); |
| 2476 | } |
| 2477 | |
| 2478 | /* |
| 2479 | ** Arrange to timeout using SIGALRM after N seconds. Or if N==0, cancel |
| 2480 | ** any pending timeout. |
| 2481 | ** |
| 2482 | ** Bugs: |
| 2483 | ** (1) This only works on unix systems. |
| 2484 | ** (2) Any call to sleep() or sqlite3_sleep() will cancel the alarm. |
| 2485 | */ |
| 2486 | void fossil_set_timeout(int N){ |
| 2487 | #ifndef _WIN32 |
| 2488 | signal(SIGALRM, sigalrm_handler); |
| 2489 | alarm(N); |
| 2490 | #endif |
| 2491 | } |
| 2492 | |
| 2493 | /* |
| 2494 | ** COMMAND: server* |
| 2495 | ** COMMAND: ui |
| 2496 | ** |
| @@ -2539,11 +2568,11 @@ | |
| 2568 | int isUiCmd; /* True if command is "ui", not "server' */ |
| 2569 | const char *zNotFound; /* The --notfound option or NULL */ |
| 2570 | int flags = 0; /* Server flags */ |
| 2571 | #if !defined(_WIN32) |
| 2572 | int noJail; /* Do not enter the chroot jail */ |
| 2573 | const char *zTimeout = "300"; /* Max runtime of any single HTTP request */ |
| 2574 | #endif |
| 2575 | int allowRepoList; /* List repositories on URL "/" */ |
| 2576 | const char *zAltBase; /* Argument to the --baseurl option */ |
| 2577 | const char *zFileGlob; /* Static content must match this */ |
| 2578 | char *zIpAddr = 0; /* Bind to this IP address */ |
| @@ -2571,11 +2600,11 @@ | |
| 2600 | zFileGlob = find_option("files",0,1); |
| 2601 | } |
| 2602 | skin_override(); |
| 2603 | #if !defined(_WIN32) |
| 2604 | noJail = find_option("nojail",0,0)!=0; |
| 2605 | zTimeout = find_option("max-latency",0,1); |
| 2606 | #endif |
| 2607 | g.useLocalauth = find_option("localauth", 0, 0)!=0; |
| 2608 | Th_InitTraceLog(); |
| 2609 | zPort = find_option("port", "P", 1); |
| 2610 | isUiCmd = g.argv[1][0]=='u'; |
| @@ -2689,13 +2718,12 @@ | |
| 2718 | ** |
| 2719 | ** So, when control reaches this point, we are running as a |
| 2720 | ** child process, the HTTP or SCGI request is pending on file |
| 2721 | ** descriptor 0 and the reply should be written to file descriptor 1. |
| 2722 | */ |
| 2723 | if( zTimeout ){ |
| 2724 | fossil_set_timeout(atoi(zTimeout)); |
| 2725 | } |
| 2726 | g.httpIn = stdin; |
| 2727 | g.httpOut = stdout; |
| 2728 | |
| 2729 | #if !defined(_WIN32) |
| 2730 |