Fossil SCM

Modifications to the "fossil ui" idle timeout feature: (0) Make the Javascript work with IE (lacking the `fetch()' function) (1) Ensure the Javascript keep-alive polling interval is lower than the idle timeout (2) Add the short form `-t' as an alias for the `--idle-timeout' command-line option, since it is now always required to enable legacy behavior.

florian 2020-04-10 14:01 idle-time-suggestions
Commit fae4ae058d92d47b6c9cd3be63854b4a6c06729b96caf4c5e53a1c7468c521c4
3 files changed +40 -35 +15 +6 -7
+40 -35
--- src/main.c
+++ src/main.c
@@ -203,10 +203,13 @@
203203
int *aCommitFile; /* Array of files to be committed */
204204
int markPrivate; /* All new artifacts are private if true */
205205
char *ckinLockFail; /* Check-in lock failure received from server */
206206
int clockSkewSeen; /* True if clocks on client and server out of sync */
207207
int wikiFlags; /* Wiki conversion flags applied to %W */
208
+ int iHTTPdIdleTimeout; /* Auto-shutdown the HTTP server after an idle timeout
209
+ ** of N seconds without HTTP requests; disabled if set
210
+ ** to 0 (default). */
208211
char isHTTP; /* True if server/CGI modes, else assume CLI. */
209212
char javascriptHyperlink; /* If true, set href= using script, not HTML */
210213
Blob httpHeader; /* Complete text of the HTTP request header */
211214
UrlData url; /* Information about current URL */
212215
const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -2371,11 +2374,11 @@
23712374
** --files GLOB comma-separate glob patterns for static file to serve
23722375
** --host NAME specify hostname of the server
23732376
** --https signal a request coming in via https
23742377
** --in FILE Take input from FILE instead of standard input
23752378
** --ipaddr ADDR Assume the request comes from the given IP address
2376
-** --keep-alive Include "keepalive.js" in HTML pages
2379
+** --keep-alive N Add "keep alive" script in HTML to poll every N seconds
23772380
** --localauth enable automatic login for local connections
23782381
** --nocompress do not compress HTTP replies
23792382
** --nodelay omit backoffice processing if it would delay process exit
23802383
** --nojail drop root privilege but do not enter the chroot jail
23812384
** --nossl signal that no SSL connections are available
@@ -2392,10 +2395,11 @@
23922395
*/
23932396
void cmd_http(void){
23942397
const char *zIpAddr = 0;
23952398
const char *zNotFound;
23962399
const char *zHost;
2400
+ const char *zKeepAliveTimeout;
23972401
const char *zAltBase;
23982402
const char *zFileGlob;
23992403
const char *zInFile;
24002404
const char *zOutFile;
24012405
int useSCGI;
@@ -2451,11 +2455,13 @@
24512455
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
24522456
cgi_replace_parameter("HTTPS","on");
24532457
}
24542458
zHost = find_option("host", 0, 1);
24552459
if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
2456
- if( find_option("keep-alive",0,0) ) style_load_js("keepalive.js");
2460
+ zKeepAliveTimeout = find_option("keep-alive", 0, 1);
2461
+ if( zKeepAliveTimeout )
2462
+ g.iHTTPdIdleTimeout = atoi(zKeepAliveTimeout);
24572463
24582464
#if defined(_WIN32) && USE_SEE
24592465
zPidKey = find_option("usepidkey", 0, 1);
24602466
if( zPidKey ){
24612467
DWORD processId = 0;
@@ -2632,36 +2638,36 @@
26322638
** --localauth option is present and the "localauth" setting is off and the
26332639
** connection is from localhost. The "ui" command also enables --repolist
26342640
** by default.
26352641
**
26362642
** Options:
2637
-** --baseurl URL Use URL as the base (useful for reverse proxies)
2638
-** --create Create a new REPOSITORY if it does not already exist
2639
-** --extroot DIR Document root for the /ext extension mechanism
2640
-** --files GLOBLIST Comma-separated list of glob patterns for static files
2641
-** --idle-timeout N Exit if no HTTP requests are received for N seconds.
2642
-** "0" means never. 0 is default for the "server"
2643
-** command and "60" is the default for the "ui" command.
2644
-** --localauth enable automatic login for requests from localhost
2645
-** --localhost listen on 127.0.0.1 only (always true for "ui")
2646
-** --https Indicates that the input is coming through a reverse
2647
-** proxy that has already translated HTTPS into HTTP.
2648
-** --max-latency N Do not let any single HTTP request run for more than N
2649
-** seconds (only works on unix)
2650
-** --nocompress Do not compress HTTP replies
2651
-** --nojail Drop root privileges but do not enter the chroot jail
2652
-** --nossl signal that no SSL connections are available (Always
2653
-** set by default for the "ui" command)
2654
-** --notfound URL Redirect
2655
-** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
2656
-** -P|--port TCPPORT listen to request on port TCPPORT
2657
-** --th-trace trace TH1 execution (for debugging purposes)
2658
-** --repolist If REPOSITORY is dir, URL "/" lists repos.
2659
-** --scgi Accept SCGI rather than HTTP
2660
-** --skin LABEL Use override skin LABEL
2661
-** --usepidkey Use saved encryption key from parent process. This is
2662
-** only necessary when using SEE on Windows.
2643
+** --baseurl URL Use URL as the base (useful for reverse proxies)
2644
+** --create Create a new REPOSITORY if it does not already exist
2645
+** --extroot DIR Document root for the /ext extension mechanism
2646
+** --files GLOBLIST Comma-separated list of glob patterns for static files
2647
+** -t|--idle-timeout N Exit if no HTTP requests are received for N seconds.
2648
+** "0" means never. "0" is the default for the "server"
2649
+** command and "60" is the default for the "ui" command.
2650
+** --localauth enable automatic login for requests from localhost
2651
+** --localhost listen on 127.0.0.1 only (always true for "ui")
2652
+** --https Indicates that the input is coming through a reverse
2653
+** proxy that has already translated HTTPS into HTTP.
2654
+** --max-latency N Do not let any single HTTP request run for more than N
2655
+** seconds (only works on unix)
2656
+** --nocompress Do not compress HTTP replies
2657
+** --nojail Drop root privileges but do not enter the chroot jail
2658
+** --nossl signal that no SSL connections are available (Always
2659
+** set by default for the "ui" command)
2660
+** --notfound URL Redirect
2661
+** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
2662
+** -P|--port TCPPORT listen to request on port TCPPORT
2663
+** --th-trace trace TH1 execution (for debugging purposes)
2664
+** --repolist If REPOSITORY is dir, URL "/" lists repos.
2665
+** --scgi Accept SCGI rather than HTTP
2666
+** --skin LABEL Use override skin LABEL
2667
+** --usepidkey Use saved encryption key from parent process. This is
2668
+** only necessary when using SEE on Windows.
26632669
**
26642670
** See also: cgi, http, winsrv
26652671
*/
26662672
void cmd_webserver(void){
26672673
int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2679,11 +2685,10 @@
26792685
const char *zAltBase; /* Argument to the --baseurl option */
26802686
const char *zFileGlob; /* Static content must match this */
26812687
char *zIpAddr = 0; /* Bind to this IP address */
26822688
int fCreate = 0; /* The --create flag */
26832689
const char *zIdleTimeout; /* Value of the --idle-timeout flag */
2684
- int iIdle = 0; /* Idle timeout value */
26852690
const char *zInitPage = 0; /* Start on this page. --page option */
26862691
#if defined(_WIN32) && USE_SEE
26872692
const char *zPidKey;
26882693
#endif
26892694
@@ -2713,15 +2718,15 @@
27132718
Th_InitTraceLog();
27142719
zPort = find_option("port", "P", 1);
27152720
isUiCmd = g.argv[1][0]=='u';
27162721
if( isUiCmd ){
27172722
zInitPage = find_option("page", 0, 1);
2718
- iIdle = 60;
2723
+ g.iHTTPdIdleTimeout = 60;
27192724
}
2720
- zIdleTimeout = find_option("idle-timeout",0,1);
2725
+ zIdleTimeout = find_option("idle-timeout", "t", 1);
27212726
if( zIdleTimeout ){
2722
- iIdle = atoi(zIdleTimeout);
2727
+ g.iHTTPdIdleTimeout = atoi(zIdleTimeout);
27232728
}
27242729
27252730
zNotFound = find_option("notfound", 0, 1);
27262731
allowRepoList = find_option("repolist",0,0)!=0;
27272732
if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
@@ -2817,11 +2822,11 @@
28172822
}
28182823
}
28192824
if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
28202825
if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
28212826
db_close(1);
2822
- if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, iIdle, flags) ){
2827
+ if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
28232828
fossil_fatal("unable to listen on TCP socket %d", iPort);
28242829
}
28252830
/* For the parent process, the cgi_http_server() command above never
28262831
** returns (except in the case of an error). Instead, for each incoming
28272832
** client connection, a child process is created, file descriptors 0
@@ -2857,11 +2862,11 @@
28572862
if( flags & HTTP_SERVER_SCGI ){
28582863
cgi_handle_scgi_request();
28592864
}else{
28602865
cgi_handle_http_request(0);
28612866
}
2862
- if( iIdle>0 ) style_load_js("keepalive.js");
2867
+
28632868
process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
28642869
if( g.fAnyTrace ){
28652870
fprintf(stderr, "/***** Webpage finished in subprocess %d *****/\n",
28662871
getpid());
28672872
}
@@ -2886,11 +2891,11 @@
28862891
if( allowRepoList ){
28872892
flags |= HTTP_SERVER_REPOLIST;
28882893
}
28892894
if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
28902895
win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
2891
- zAltBase, zNotFound, zFileGlob, zIpAddr, iIdle, flags);
2896
+ zAltBase, zNotFound, zFileGlob, zIpAddr, flags);
28922897
}
28932898
#endif
28942899
}
28952900
28962901
/*
28972902
--- src/main.c
+++ src/main.c
@@ -203,10 +203,13 @@
203 int *aCommitFile; /* Array of files to be committed */
204 int markPrivate; /* All new artifacts are private if true */
205 char *ckinLockFail; /* Check-in lock failure received from server */
206 int clockSkewSeen; /* True if clocks on client and server out of sync */
207 int wikiFlags; /* Wiki conversion flags applied to %W */
 
 
 
208 char isHTTP; /* True if server/CGI modes, else assume CLI. */
209 char javascriptHyperlink; /* If true, set href= using script, not HTML */
210 Blob httpHeader; /* Complete text of the HTTP request header */
211 UrlData url; /* Information about current URL */
212 const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -2371,11 +2374,11 @@
2371 ** --files GLOB comma-separate glob patterns for static file to serve
2372 ** --host NAME specify hostname of the server
2373 ** --https signal a request coming in via https
2374 ** --in FILE Take input from FILE instead of standard input
2375 ** --ipaddr ADDR Assume the request comes from the given IP address
2376 ** --keep-alive Include "keepalive.js" in HTML pages
2377 ** --localauth enable automatic login for local connections
2378 ** --nocompress do not compress HTTP replies
2379 ** --nodelay omit backoffice processing if it would delay process exit
2380 ** --nojail drop root privilege but do not enter the chroot jail
2381 ** --nossl signal that no SSL connections are available
@@ -2392,10 +2395,11 @@
2392 */
2393 void cmd_http(void){
2394 const char *zIpAddr = 0;
2395 const char *zNotFound;
2396 const char *zHost;
 
2397 const char *zAltBase;
2398 const char *zFileGlob;
2399 const char *zInFile;
2400 const char *zOutFile;
2401 int useSCGI;
@@ -2451,11 +2455,13 @@
2451 zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
2452 cgi_replace_parameter("HTTPS","on");
2453 }
2454 zHost = find_option("host", 0, 1);
2455 if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
2456 if( find_option("keep-alive",0,0) ) style_load_js("keepalive.js");
 
 
2457
2458 #if defined(_WIN32) && USE_SEE
2459 zPidKey = find_option("usepidkey", 0, 1);
2460 if( zPidKey ){
2461 DWORD processId = 0;
@@ -2632,36 +2638,36 @@
2632 ** --localauth option is present and the "localauth" setting is off and the
2633 ** connection is from localhost. The "ui" command also enables --repolist
2634 ** by default.
2635 **
2636 ** Options:
2637 ** --baseurl URL Use URL as the base (useful for reverse proxies)
2638 ** --create Create a new REPOSITORY if it does not already exist
2639 ** --extroot DIR Document root for the /ext extension mechanism
2640 ** --files GLOBLIST Comma-separated list of glob patterns for static files
2641 ** --idle-timeout N Exit if no HTTP requests are received for N seconds.
2642 ** "0" means never. 0 is default for the "server"
2643 ** command and "60" is the default for the "ui" command.
2644 ** --localauth enable automatic login for requests from localhost
2645 ** --localhost listen on 127.0.0.1 only (always true for "ui")
2646 ** --https Indicates that the input is coming through a reverse
2647 ** proxy that has already translated HTTPS into HTTP.
2648 ** --max-latency N Do not let any single HTTP request run for more than N
2649 ** seconds (only works on unix)
2650 ** --nocompress Do not compress HTTP replies
2651 ** --nojail Drop root privileges but do not enter the chroot jail
2652 ** --nossl signal that no SSL connections are available (Always
2653 ** set by default for the "ui" command)
2654 ** --notfound URL Redirect
2655 ** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
2656 ** -P|--port TCPPORT listen to request on port TCPPORT
2657 ** --th-trace trace TH1 execution (for debugging purposes)
2658 ** --repolist If REPOSITORY is dir, URL "/" lists repos.
2659 ** --scgi Accept SCGI rather than HTTP
2660 ** --skin LABEL Use override skin LABEL
2661 ** --usepidkey Use saved encryption key from parent process. This is
2662 ** only necessary when using SEE on Windows.
2663 **
2664 ** See also: cgi, http, winsrv
2665 */
2666 void cmd_webserver(void){
2667 int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2679,11 +2685,10 @@
2679 const char *zAltBase; /* Argument to the --baseurl option */
2680 const char *zFileGlob; /* Static content must match this */
2681 char *zIpAddr = 0; /* Bind to this IP address */
2682 int fCreate = 0; /* The --create flag */
2683 const char *zIdleTimeout; /* Value of the --idle-timeout flag */
2684 int iIdle = 0; /* Idle timeout value */
2685 const char *zInitPage = 0; /* Start on this page. --page option */
2686 #if defined(_WIN32) && USE_SEE
2687 const char *zPidKey;
2688 #endif
2689
@@ -2713,15 +2718,15 @@
2713 Th_InitTraceLog();
2714 zPort = find_option("port", "P", 1);
2715 isUiCmd = g.argv[1][0]=='u';
2716 if( isUiCmd ){
2717 zInitPage = find_option("page", 0, 1);
2718 iIdle = 60;
2719 }
2720 zIdleTimeout = find_option("idle-timeout",0,1);
2721 if( zIdleTimeout ){
2722 iIdle = atoi(zIdleTimeout);
2723 }
2724
2725 zNotFound = find_option("notfound", 0, 1);
2726 allowRepoList = find_option("repolist",0,0)!=0;
2727 if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
@@ -2817,11 +2822,11 @@
2817 }
2818 }
2819 if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
2820 if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
2821 db_close(1);
2822 if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, iIdle, flags) ){
2823 fossil_fatal("unable to listen on TCP socket %d", iPort);
2824 }
2825 /* For the parent process, the cgi_http_server() command above never
2826 ** returns (except in the case of an error). Instead, for each incoming
2827 ** client connection, a child process is created, file descriptors 0
@@ -2857,11 +2862,11 @@
2857 if( flags & HTTP_SERVER_SCGI ){
2858 cgi_handle_scgi_request();
2859 }else{
2860 cgi_handle_http_request(0);
2861 }
2862 if( iIdle>0 ) style_load_js("keepalive.js");
2863 process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
2864 if( g.fAnyTrace ){
2865 fprintf(stderr, "/***** Webpage finished in subprocess %d *****/\n",
2866 getpid());
2867 }
@@ -2886,11 +2891,11 @@
2886 if( allowRepoList ){
2887 flags |= HTTP_SERVER_REPOLIST;
2888 }
2889 if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
2890 win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
2891 zAltBase, zNotFound, zFileGlob, zIpAddr, iIdle, flags);
2892 }
2893 #endif
2894 }
2895
2896 /*
2897
--- src/main.c
+++ src/main.c
@@ -203,10 +203,13 @@
203 int *aCommitFile; /* Array of files to be committed */
204 int markPrivate; /* All new artifacts are private if true */
205 char *ckinLockFail; /* Check-in lock failure received from server */
206 int clockSkewSeen; /* True if clocks on client and server out of sync */
207 int wikiFlags; /* Wiki conversion flags applied to %W */
208 int iHTTPdIdleTimeout; /* Auto-shutdown the HTTP server after an idle timeout
209 ** of N seconds without HTTP requests; disabled if set
210 ** to 0 (default). */
211 char isHTTP; /* True if server/CGI modes, else assume CLI. */
212 char javascriptHyperlink; /* If true, set href= using script, not HTML */
213 Blob httpHeader; /* Complete text of the HTTP request header */
214 UrlData url; /* Information about current URL */
215 const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -2371,11 +2374,11 @@
2374 ** --files GLOB comma-separate glob patterns for static file to serve
2375 ** --host NAME specify hostname of the server
2376 ** --https signal a request coming in via https
2377 ** --in FILE Take input from FILE instead of standard input
2378 ** --ipaddr ADDR Assume the request comes from the given IP address
2379 ** --keep-alive N Add "keep alive" script in HTML to poll every N seconds
2380 ** --localauth enable automatic login for local connections
2381 ** --nocompress do not compress HTTP replies
2382 ** --nodelay omit backoffice processing if it would delay process exit
2383 ** --nojail drop root privilege but do not enter the chroot jail
2384 ** --nossl signal that no SSL connections are available
@@ -2392,10 +2395,11 @@
2395 */
2396 void cmd_http(void){
2397 const char *zIpAddr = 0;
2398 const char *zNotFound;
2399 const char *zHost;
2400 const char *zKeepAliveTimeout;
2401 const char *zAltBase;
2402 const char *zFileGlob;
2403 const char *zInFile;
2404 const char *zOutFile;
2405 int useSCGI;
@@ -2451,11 +2455,13 @@
2455 zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
2456 cgi_replace_parameter("HTTPS","on");
2457 }
2458 zHost = find_option("host", 0, 1);
2459 if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
2460 zKeepAliveTimeout = find_option("keep-alive", 0, 1);
2461 if( zKeepAliveTimeout )
2462 g.iHTTPdIdleTimeout = atoi(zKeepAliveTimeout);
2463
2464 #if defined(_WIN32) && USE_SEE
2465 zPidKey = find_option("usepidkey", 0, 1);
2466 if( zPidKey ){
2467 DWORD processId = 0;
@@ -2632,36 +2638,36 @@
2638 ** --localauth option is present and the "localauth" setting is off and the
2639 ** connection is from localhost. The "ui" command also enables --repolist
2640 ** by default.
2641 **
2642 ** Options:
2643 ** --baseurl URL Use URL as the base (useful for reverse proxies)
2644 ** --create Create a new REPOSITORY if it does not already exist
2645 ** --extroot DIR Document root for the /ext extension mechanism
2646 ** --files GLOBLIST Comma-separated list of glob patterns for static files
2647 ** -t|--idle-timeout N Exit if no HTTP requests are received for N seconds.
2648 ** "0" means never. "0" is the default for the "server"
2649 ** command and "60" is the default for the "ui" command.
2650 ** --localauth enable automatic login for requests from localhost
2651 ** --localhost listen on 127.0.0.1 only (always true for "ui")
2652 ** --https Indicates that the input is coming through a reverse
2653 ** proxy that has already translated HTTPS into HTTP.
2654 ** --max-latency N Do not let any single HTTP request run for more than N
2655 ** seconds (only works on unix)
2656 ** --nocompress Do not compress HTTP replies
2657 ** --nojail Drop root privileges but do not enter the chroot jail
2658 ** --nossl signal that no SSL connections are available (Always
2659 ** set by default for the "ui" command)
2660 ** --notfound URL Redirect
2661 ** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci"
2662 ** -P|--port TCPPORT listen to request on port TCPPORT
2663 ** --th-trace trace TH1 execution (for debugging purposes)
2664 ** --repolist If REPOSITORY is dir, URL "/" lists repos.
2665 ** --scgi Accept SCGI rather than HTTP
2666 ** --skin LABEL Use override skin LABEL
2667 ** --usepidkey Use saved encryption key from parent process. This is
2668 ** only necessary when using SEE on Windows.
2669 **
2670 ** See also: cgi, http, winsrv
2671 */
2672 void cmd_webserver(void){
2673 int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2679,11 +2685,10 @@
2685 const char *zAltBase; /* Argument to the --baseurl option */
2686 const char *zFileGlob; /* Static content must match this */
2687 char *zIpAddr = 0; /* Bind to this IP address */
2688 int fCreate = 0; /* The --create flag */
2689 const char *zIdleTimeout; /* Value of the --idle-timeout flag */
 
2690 const char *zInitPage = 0; /* Start on this page. --page option */
2691 #if defined(_WIN32) && USE_SEE
2692 const char *zPidKey;
2693 #endif
2694
@@ -2713,15 +2718,15 @@
2718 Th_InitTraceLog();
2719 zPort = find_option("port", "P", 1);
2720 isUiCmd = g.argv[1][0]=='u';
2721 if( isUiCmd ){
2722 zInitPage = find_option("page", 0, 1);
2723 g.iHTTPdIdleTimeout = 60;
2724 }
2725 zIdleTimeout = find_option("idle-timeout", "t", 1);
2726 if( zIdleTimeout ){
2727 g.iHTTPdIdleTimeout = atoi(zIdleTimeout);
2728 }
2729
2730 zNotFound = find_option("notfound", 0, 1);
2731 allowRepoList = find_option("repolist",0,0)!=0;
2732 if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
@@ -2817,11 +2822,11 @@
2822 }
2823 }
2824 if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY;
2825 if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT;
2826 db_close(1);
2827 if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
2828 fossil_fatal("unable to listen on TCP socket %d", iPort);
2829 }
2830 /* For the parent process, the cgi_http_server() command above never
2831 ** returns (except in the case of an error). Instead, for each incoming
2832 ** client connection, a child process is created, file descriptors 0
@@ -2857,11 +2862,11 @@
2862 if( flags & HTTP_SERVER_SCGI ){
2863 cgi_handle_scgi_request();
2864 }else{
2865 cgi_handle_http_request(0);
2866 }
2867
2868 process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
2869 if( g.fAnyTrace ){
2870 fprintf(stderr, "/***** Webpage finished in subprocess %d *****/\n",
2871 getpid());
2872 }
@@ -2886,11 +2891,11 @@
2891 if( allowRepoList ){
2892 flags |= HTTP_SERVER_REPOLIST;
2893 }
2894 if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
2895 win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
2896 zAltBase, zNotFound, zFileGlob, zIpAddr, flags);
2897 }
2898 #endif
2899 }
2900
2901 /*
2902
+15
--- src/style.c
+++ src/style.c
@@ -769,10 +769,25 @@
769769
if( blob_size(&blobOnLoad)>0 ){
770770
@ window.onload = function(){
771771
cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad));
772772
cgi_append_content("\n}\n", -1);
773773
}
774
+ if( g.iHTTPdIdleTimeout>0 ){
775
+ /* This javascript runs on web-pages that need to periodically send
776
+ ** a keep-alive HTTP request back to the server. This is typically
777
+ ** used with the "fossil ui" command with a --idle-timeout set. The
778
+ ** HTTP server will stop if it does not receive a new HTTP request
779
+ ** within some time interval (60 seconds). This script keeps sending
780
+ ** new HTTP requests every 20 seconds or so to keep the server running
781
+ ** while the page is still viewable.
782
+ */
783
+ /* TODO: move to separate function, or to built-in file enhanced to handle
784
+ ** the g.iHTTPdIdleTimeout variable? */
785
+ @ setInterval(function(){
786
+ @ var xhr=new XMLHttpRequest();xhr.open('GET','/noop',true);xhr.send();
787
+ @ },%d((g.iHTTPdIdleTimeout-1)*1000+100));
788
+ }
774789
@ </script>
775790
}
776791
777792
/*
778793
** Extra JS to run after all content is loaded.
779794
--- src/style.c
+++ src/style.c
@@ -769,10 +769,25 @@
769 if( blob_size(&blobOnLoad)>0 ){
770 @ window.onload = function(){
771 cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad));
772 cgi_append_content("\n}\n", -1);
773 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774 @ </script>
775 }
776
777 /*
778 ** Extra JS to run after all content is loaded.
779
--- src/style.c
+++ src/style.c
@@ -769,10 +769,25 @@
769 if( blob_size(&blobOnLoad)>0 ){
770 @ window.onload = function(){
771 cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad));
772 cgi_append_content("\n}\n", -1);
773 }
774 if( g.iHTTPdIdleTimeout>0 ){
775 /* This javascript runs on web-pages that need to periodically send
776 ** a keep-alive HTTP request back to the server. This is typically
777 ** used with the "fossil ui" command with a --idle-timeout set. The
778 ** HTTP server will stop if it does not receive a new HTTP request
779 ** within some time interval (60 seconds). This script keeps sending
780 ** new HTTP requests every 20 seconds or so to keep the server running
781 ** while the page is still viewable.
782 */
783 /* TODO: move to separate function, or to built-in file enhanced to handle
784 ** the g.iHTTPdIdleTimeout variable? */
785 @ setInterval(function(){
786 @ var xhr=new XMLHttpRequest();xhr.open('GET','/noop',true);xhr.send();
787 @ },%d((g.iHTTPdIdleTimeout-1)*1000+100));
788 }
789 @ </script>
790 }
791
792 /*
793 ** Extra JS to run after all content is loaded.
794
+6 -7
--- src/winhttp.c
+++ src/winhttp.c
@@ -522,11 +522,10 @@
522522
const char *zStopper, /* Stop server when this file exists (Or NULL) */
523523
const char *zBaseUrl, /* The --baseurl option, or NULL */
524524
const char *zNotFound, /* The --notfound option, or NULL */
525525
const char *zFileGlob, /* The --fileglob option, or NULL */
526526
const char *zIpAddr, /* Bind to this IP address, if not NULL */
527
- int iIdleTimeout, /* Idle timeout in seconds. 0 means none */
528527
int flags /* One or more HTTP_SERVER_ flags */
529528
){
530529
HANDLE hStoppedEvent;
531530
WSADATA wd;
532531
DualSocket ds;
@@ -558,12 +557,12 @@
558557
blob_appendf(&options, " --localauth");
559558
}
560559
if( g.thTrace ){
561560
blob_appendf(&options, " --th-trace");
562561
}
563
- if( iIdleTimeout>0 ){
564
- blob_appendf(&options, " --keep-alive");
562
+ if( g.iHTTPdIdleTimeout>0 ){
563
+ blob_appendf(&options, " --keep-alive %d", g.iHTTPdIdleTimeout);
565564
}
566565
if( flags & HTTP_SERVER_REPOLIST ){
567566
blob_appendf(&options, " --repolist");
568567
}
569568
zSkin = skin_in_use();
@@ -640,11 +639,11 @@
640639
_beginthread(win32_server_stopper, 0, (void*)pServer);
641640
}
642641
/* Set the service status to running and pass the listener socket to the
643642
** service handling procedures. */
644643
win32_http_service_running(&ds);
645
- if( iIdleTimeout>0 ) stopTime = time(0) + iIdleTimeout;
644
+ if( g.iHTTPdIdleTimeout>0 ) stopTime = time(0) + g.iHTTPdIdleTimeout;
646645
for(;;){
647646
DualSocket client;
648647
DualAddr client_addr;
649648
HttpRequest *pRequest;
650649
int wsaError;
@@ -672,11 +671,11 @@
672671
pRequest->id = ++idCnt;
673672
pRequest->s = client.s4;
674673
memcpy(&pRequest->addr, &client_addr.a4, sizeof(client_addr.a4));
675674
pRequest->flags = flags;
676675
pRequest->zOptions = blob_str(&options);
677
- if( iIdleTimeout>0 ) stopTime = time(0) + iIdleTimeout;
676
+ if( g.iHTTPdIdleTimeout>0 ) stopTime = time(0) + g.iHTTPdIdleTimeout;
678677
if( flags & HTTP_SERVER_SCGI ){
679678
_beginthread(win32_scgi_request, 0, (void*)pRequest);
680679
}else{
681680
_beginthread(win32_http_request, 0, (void*)pRequest);
682681
}
@@ -686,18 +685,18 @@
686685
pRequest->id = ++idCnt;
687686
pRequest->s = client.s6;
688687
memcpy(&pRequest->addr, &client_addr.a6, sizeof(client_addr.a6));
689688
pRequest->flags = flags;
690689
pRequest->zOptions = blob_str(&options);
691
- if( iIdleTimeout>0 ) stopTime = time(0) + iIdleTimeout;
690
+ if( g.iHTTPdIdleTimeout>0 ) stopTime = time(0) + g.iHTTPdIdleTimeout;
692691
if( flags & HTTP_SERVER_SCGI ){
693692
_beginthread(win32_scgi_request, 0, (void*)pRequest);
694693
}else{
695694
_beginthread(win32_http_request, 0, (void*)pRequest);
696695
}
697696
}
698
- if( iIdleTimeout>0 && stopTime<time(0) ) break;
697
+ if( g.iHTTPdIdleTimeout>0 && stopTime<time(0) ) break;
699698
}
700699
DualSocket_close(&ds);
701700
WSACleanup();
702701
SetEvent(hStoppedEvent);
703702
CloseHandle(hStoppedEvent);
704703
--- src/winhttp.c
+++ src/winhttp.c
@@ -522,11 +522,10 @@
522 const char *zStopper, /* Stop server when this file exists (Or NULL) */
523 const char *zBaseUrl, /* The --baseurl option, or NULL */
524 const char *zNotFound, /* The --notfound option, or NULL */
525 const char *zFileGlob, /* The --fileglob option, or NULL */
526 const char *zIpAddr, /* Bind to this IP address, if not NULL */
527 int iIdleTimeout, /* Idle timeout in seconds. 0 means none */
528 int flags /* One or more HTTP_SERVER_ flags */
529 ){
530 HANDLE hStoppedEvent;
531 WSADATA wd;
532 DualSocket ds;
@@ -558,12 +557,12 @@
558 blob_appendf(&options, " --localauth");
559 }
560 if( g.thTrace ){
561 blob_appendf(&options, " --th-trace");
562 }
563 if( iIdleTimeout>0 ){
564 blob_appendf(&options, " --keep-alive");
565 }
566 if( flags & HTTP_SERVER_REPOLIST ){
567 blob_appendf(&options, " --repolist");
568 }
569 zSkin = skin_in_use();
@@ -640,11 +639,11 @@
640 _beginthread(win32_server_stopper, 0, (void*)pServer);
641 }
642 /* Set the service status to running and pass the listener socket to the
643 ** service handling procedures. */
644 win32_http_service_running(&ds);
645 if( iIdleTimeout>0 ) stopTime = time(0) + iIdleTimeout;
646 for(;;){
647 DualSocket client;
648 DualAddr client_addr;
649 HttpRequest *pRequest;
650 int wsaError;
@@ -672,11 +671,11 @@
672 pRequest->id = ++idCnt;
673 pRequest->s = client.s4;
674 memcpy(&pRequest->addr, &client_addr.a4, sizeof(client_addr.a4));
675 pRequest->flags = flags;
676 pRequest->zOptions = blob_str(&options);
677 if( iIdleTimeout>0 ) stopTime = time(0) + iIdleTimeout;
678 if( flags & HTTP_SERVER_SCGI ){
679 _beginthread(win32_scgi_request, 0, (void*)pRequest);
680 }else{
681 _beginthread(win32_http_request, 0, (void*)pRequest);
682 }
@@ -686,18 +685,18 @@
686 pRequest->id = ++idCnt;
687 pRequest->s = client.s6;
688 memcpy(&pRequest->addr, &client_addr.a6, sizeof(client_addr.a6));
689 pRequest->flags = flags;
690 pRequest->zOptions = blob_str(&options);
691 if( iIdleTimeout>0 ) stopTime = time(0) + iIdleTimeout;
692 if( flags & HTTP_SERVER_SCGI ){
693 _beginthread(win32_scgi_request, 0, (void*)pRequest);
694 }else{
695 _beginthread(win32_http_request, 0, (void*)pRequest);
696 }
697 }
698 if( iIdleTimeout>0 && stopTime<time(0) ) break;
699 }
700 DualSocket_close(&ds);
701 WSACleanup();
702 SetEvent(hStoppedEvent);
703 CloseHandle(hStoppedEvent);
704
--- src/winhttp.c
+++ src/winhttp.c
@@ -522,11 +522,10 @@
522 const char *zStopper, /* Stop server when this file exists (Or NULL) */
523 const char *zBaseUrl, /* The --baseurl option, or NULL */
524 const char *zNotFound, /* The --notfound option, or NULL */
525 const char *zFileGlob, /* The --fileglob option, or NULL */
526 const char *zIpAddr, /* Bind to this IP address, if not NULL */
 
527 int flags /* One or more HTTP_SERVER_ flags */
528 ){
529 HANDLE hStoppedEvent;
530 WSADATA wd;
531 DualSocket ds;
@@ -558,12 +557,12 @@
557 blob_appendf(&options, " --localauth");
558 }
559 if( g.thTrace ){
560 blob_appendf(&options, " --th-trace");
561 }
562 if( g.iHTTPdIdleTimeout>0 ){
563 blob_appendf(&options, " --keep-alive %d", g.iHTTPdIdleTimeout);
564 }
565 if( flags & HTTP_SERVER_REPOLIST ){
566 blob_appendf(&options, " --repolist");
567 }
568 zSkin = skin_in_use();
@@ -640,11 +639,11 @@
639 _beginthread(win32_server_stopper, 0, (void*)pServer);
640 }
641 /* Set the service status to running and pass the listener socket to the
642 ** service handling procedures. */
643 win32_http_service_running(&ds);
644 if( g.iHTTPdIdleTimeout>0 ) stopTime = time(0) + g.iHTTPdIdleTimeout;
645 for(;;){
646 DualSocket client;
647 DualAddr client_addr;
648 HttpRequest *pRequest;
649 int wsaError;
@@ -672,11 +671,11 @@
671 pRequest->id = ++idCnt;
672 pRequest->s = client.s4;
673 memcpy(&pRequest->addr, &client_addr.a4, sizeof(client_addr.a4));
674 pRequest->flags = flags;
675 pRequest->zOptions = blob_str(&options);
676 if( g.iHTTPdIdleTimeout>0 ) stopTime = time(0) + g.iHTTPdIdleTimeout;
677 if( flags & HTTP_SERVER_SCGI ){
678 _beginthread(win32_scgi_request, 0, (void*)pRequest);
679 }else{
680 _beginthread(win32_http_request, 0, (void*)pRequest);
681 }
@@ -686,18 +685,18 @@
685 pRequest->id = ++idCnt;
686 pRequest->s = client.s6;
687 memcpy(&pRequest->addr, &client_addr.a6, sizeof(client_addr.a6));
688 pRequest->flags = flags;
689 pRequest->zOptions = blob_str(&options);
690 if( g.iHTTPdIdleTimeout>0 ) stopTime = time(0) + g.iHTTPdIdleTimeout;
691 if( flags & HTTP_SERVER_SCGI ){
692 _beginthread(win32_scgi_request, 0, (void*)pRequest);
693 }else{
694 _beginthread(win32_http_request, 0, (void*)pRequest);
695 }
696 }
697 if( g.iHTTPdIdleTimeout>0 && stopTime<time(0) ) break;
698 }
699 DualSocket_close(&ds);
700 WSACleanup();
701 SetEvent(hStoppedEvent);
702 CloseHandle(hStoppedEvent);
703

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button