Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add the --unix-socket option to the "fossil server" command. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
7fc2902126d43f87f897a46d12209f5b |
| User & Date: | drh 2024-08-05 20:23:40.923 |
Context
|
2024-08-06
| ||
| 20:39 | Enhancements to unix-domain socket support for "fossil server": (1) Change the command-line option to "--socket-name FILENAME" for creating the unix socket. (It was formerly --unix-socket.) (2) Add new command-line options "--socket-mode MODE" and "--socket-owner USER" or "... USER:GROUP" to set permissions and ownership on the new socket. (3) Attempt to unlink the socket from the filesystem upon exit. ... (check-in: effdadadd0 user: drh tags: trunk) | |
| 15:00 | Change --unix-socket to --socket-name. Add --socket-mode and --socket-owner. Mostly working, accept that --socket-owner seemingly has no effect, even though the fchown() return 0. There is currently a debugging printf() in that line of code. This is an experimental check-in. ... (check-in: 9f71e5cc02 user: drh tags: unix-sockets) | |
|
2024-08-05
| ||
| 20:23 | Add the --unix-socket option to the "fossil server" command. ... (check-in: 7fc2902126 user: drh tags: trunk) | |
| 15:10 | Replace the JavaScript-based side-by-side diff view with a CSS Grid, as discussed in [forum:93398561d3986c41|forum post 93398561d3986c41]. ... (check-in: 71e9ca7869 user: stephan tags: trunk) | |
Changes
Changes to src/cgi.c.
| ︙ | ︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | # if !defined(_WIN32_WINNT) # define _WIN32_WINNT 0x0501 # endif # include <winsock2.h> # include <ws2tcpip.h> #else # include <sys/socket.h> # include <netinet/in.h> # include <arpa/inet.h> # include <sys/times.h> # include <sys/time.h> # include <sys/wait.h> # include <sys/select.h> #endif #ifdef __EMX__ typedef int socklen_t; #endif #include <time.h> #include <stdio.h> #include <stdlib.h> | > > | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | # if !defined(_WIN32_WINNT) # define _WIN32_WINNT 0x0501 # endif # include <winsock2.h> # include <ws2tcpip.h> #else # include <sys/socket.h> # include <sys/un.h> # include <netinet/in.h> # include <arpa/inet.h> # include <sys/times.h> # include <sys/time.h> # include <sys/wait.h> # include <sys/select.h> # include <errno.h> #endif #ifdef __EMX__ typedef int socklen_t; #endif #include <time.h> #include <stdio.h> #include <stdlib.h> |
| ︙ | ︙ | |||
2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 | */ #define HTTP_SERVER_LOCALHOST 0x0001 /* Bind to 127.0.0.1 only */ #define HTTP_SERVER_SCGI 0x0002 /* SCGI instead of HTTP */ #define HTTP_SERVER_HAD_REPOSITORY 0x0004 /* Was the repository open? */ #define HTTP_SERVER_HAD_CHECKOUT 0x0008 /* Was a checkout open? */ #define HTTP_SERVER_REPOLIST 0x0010 /* Allow repo listing */ #define HTTP_SERVER_NOFORK 0x0020 /* Do not call fork() */ #endif /* INTERFACE */ /* ** Maximum number of child processes that we can have running ** at one time. Set this to 0 for "no limit". */ | > | 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 | */ #define HTTP_SERVER_LOCALHOST 0x0001 /* Bind to 127.0.0.1 only */ #define HTTP_SERVER_SCGI 0x0002 /* SCGI instead of HTTP */ #define HTTP_SERVER_HAD_REPOSITORY 0x0004 /* Was the repository open? */ #define HTTP_SERVER_HAD_CHECKOUT 0x0008 /* Was a checkout open? */ #define HTTP_SERVER_REPOLIST 0x0010 /* Allow repo listing */ #define HTTP_SERVER_NOFORK 0x0020 /* Do not call fork() */ #define HTTP_SERVER_UNIXDOMAINSOCK 0x0040 /* Use a unix-domain socket */ #endif /* INTERFACE */ /* ** Maximum number of child processes that we can have running ** at one time. Set this to 0 for "no limit". */ |
| ︙ | ︙ | |||
2513 2514 2515 2516 2517 2518 2519 2520 | int nRequest = 0; /* Number of requests handled so far */ fd_set readfds; /* Set of file descriptors for select() */ socklen_t lenaddr; /* Length of the inaddr structure */ int child; /* PID of the child process */ int nchildren = 0; /* Number of child processes */ struct timeval delay; /* How long to wait inside select() */ struct sockaddr_in inaddr; /* The socket address */ int opt = 1; /* setsockopt flag */ | > > | > > > > > > > > > > > > > | | | | | | | | | | | | | | > | > > > | > > > > | > > > > > | | | > | | 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 |
int nRequest = 0; /* Number of requests handled so far */
fd_set readfds; /* Set of file descriptors for select() */
socklen_t lenaddr; /* Length of the inaddr structure */
int child; /* PID of the child process */
int nchildren = 0; /* Number of child processes */
struct timeval delay; /* How long to wait inside select() */
struct sockaddr_in inaddr; /* The socket address */
struct sockaddr_un uxaddr; /* The address for unix-domain sockets */
int opt = 1; /* setsockopt flag */
int rc; /* Result code from system calls */
int iPort = mnPort; /* Port to try to use */
while( iPort<=mxPort ){
if( flags & HTTP_SERVER_UNIXDOMAINSOCK ){
memset(&uxaddr, 0, sizeof(uxaddr));
if( strlen(zIpAddr)>sizeof(uxaddr.sun_path) ){
fossil_fatal("name of unix-domain socket too big: %s\n"
"max size: %d\n", zIpAddr, (int)sizeof(uxaddr.sun_path));
}
if( unlink(zIpAddr)==-1 && errno!=ENOENT ){
fossil_fatal("Cannot remove existing file at %s\n", zIpAddr);
}
uxaddr.sun_family = AF_UNIX;
strncpy(uxaddr.sun_path, zIpAddr, sizeof(uxaddr.sun_path)-1);
listener = socket(AF_UNIX, SOCK_STREAM, 0);
}else{
memset(&inaddr, 0, sizeof(inaddr));
inaddr.sin_family = AF_INET;
if( zIpAddr ){
inaddr.sin_addr.s_addr = inet_addr(zIpAddr);
if( inaddr.sin_addr.s_addr == INADDR_NONE ){
fossil_fatal("not a valid IP address: %s", zIpAddr);
}
}else if( flags & HTTP_SERVER_LOCALHOST ){
inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}else{
inaddr.sin_addr.s_addr = htonl(INADDR_ANY);
}
inaddr.sin_port = htons(iPort);
listener = socket(AF_INET, SOCK_STREAM, 0);
}
if( listener<0 ){
iPort++;
continue;
}
/* if we can't terminate nicely, at least allow the socket to be reused */
setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
if( flags & HTTP_SERVER_UNIXDOMAINSOCK ){
rc = bind(listener, (struct sockaddr*)&uxaddr, sizeof(uxaddr));
}else{
rc = bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr));
}
if( rc<0 ){
close(listener);
iPort++;
continue;
}
break;
}
if( iPort>mxPort ){
if( flags & HTTP_SERVER_UNIXDOMAINSOCK ){
fossil_fatal("unable to listen on unix-domain socket %s", zIpAddr);
}else if( mnPort==mxPort ){
fossil_fatal("unable to open listening socket on port %d", mnPort);
}else{
fossil_fatal("unable to open listening socket on any"
" port in the range %d..%d", mnPort, mxPort);
}
}
if( iPort>mxPort ) return 1;
listen(listener,10);
if( flags & HTTP_SERVER_UNIXDOMAINSOCK ){
fossil_print("Listening for %s requests on unix-domain socket %s\n",
(flags & HTTP_SERVER_SCGI)!=0 ? "SCGI" :
g.httpUseSSL?"TLS-encrypted HTTPS":"HTTP", zIpAddr);
}else{
fossil_print("Listening for %s requests on TCP port %d\n",
(flags & HTTP_SERVER_SCGI)!=0 ? "SCGI" :
g.httpUseSSL?"TLS-encrypted HTTPS":"HTTP", iPort);
}
fflush(stdout);
if( zBrowser && (flags & HTTP_SERVER_UNIXDOMAINSOCK)==0 ){
assert( strstr(zBrowser,"%d")!=0 );
zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
#if defined(__CYGWIN__)
/* On Cygwin, we can do better than "echo" */
if( fossil_strncmp(zBrowser, "echo ", 5)==0 ){
wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 |
** --pkey FILE Read the private key used for TLS from FILE
** -P|--port [IP:]PORT Listen on the given IP (optional) and port
** --repolist If REPOSITORY is dir, URL "/" lists repos
** --scgi Accept SCGI rather than HTTP
** --skin LABEL Use override skin LABEL, or the site's default skin if
** LABEL is an empty string.
** --th-trace Trace TH1 execution (for debugging purposes)
** --usepidkey Use saved encryption key from parent process. This is
** only necessary when using SEE on Windows or Linux.
**
** See also: [[cgi]], [[http]], [[winsrv]]
*/
void cmd_webserver(void){
int iPort, mxPort; /* Range of TCP ports allowed */
| > > | 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 |
** --pkey FILE Read the private key used for TLS from FILE
** -P|--port [IP:]PORT Listen on the given IP (optional) and port
** --repolist If REPOSITORY is dir, URL "/" lists repos
** --scgi Accept SCGI rather than HTTP
** --skin LABEL Use override skin LABEL, or the site's default skin if
** LABEL is an empty string.
** --th-trace Trace TH1 execution (for debugging purposes)
** --unix-socket NAME Listen on unix-domain socket NAME rather than on a
** TCP/IP port.
** --usepidkey Use saved encryption key from parent process. This is
** only necessary when using SEE on Windows or Linux.
**
** See also: [[cgi]], [[http]], [[winsrv]]
*/
void cmd_webserver(void){
int iPort, mxPort; /* Range of TCP ports allowed */
|
| ︙ | ︙ | |||
3205 3206 3207 3208 3209 3210 3211 | const char *zChRoot; /* Use for chroot instead of repository path */ int noJail; /* Do not enter the chroot jail */ const char *zTimeout = 0; /* Max runtime of any single HTTP request */ #endif int allowRepoList; /* List repositories on URL "/" */ const char *zAltBase; /* Argument to the --baseurl option */ const char *zFileGlob; /* Static content must match this */ | | | 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 | const char *zChRoot; /* Use for chroot instead of repository path */ int noJail; /* Do not enter the chroot jail */ const char *zTimeout = 0; /* Max runtime of any single HTTP request */ #endif int allowRepoList; /* List repositories on URL "/" */ const char *zAltBase; /* Argument to the --baseurl option */ const char *zFileGlob; /* Static content must match this */ char *zIpAddr = 0; /* Bind to this IP address or UN socket */ int fCreate = 0; /* The --create flag */ int fNoBrowser = 0; /* Do not auto-launch web-browser */ const char *zInitPage = 0; /* Start on this page. --page option */ int findServerArg = 2; /* argv index for find_server_repository() */ char *zRemote = 0; /* Remote host on which to run "fossil ui" */ const char *zJsMode; /* The --jsmode parameter */ const char *zFossilCmd =0; /* Name of "fossil" binary on remote system */ |
| ︙ | ︙ | |||
3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 |
}
g.zCkoutAlias = find_option("ckout-alias",0,1);
g.zMainMenuFile = find_option("mainmenu",0,1);
if( g.zMainMenuFile!=0 && file_size(g.zMainMenuFile,ExtFILE)<0 ){
fossil_fatal("Cannot read --mainmenu file %s", g.zMainMenuFile);
}
if( find_option("acme",0,0)!=0 ) g.fAllowACME = 1;
/* Undocumented option: --debug-nofork
**
** This sets the HTTP_SERVER_NOFORK flag, which causes only the
** very first incoming TCP/IP connection to be processed. Used for
** debugging, since debugging across a fork() can be tricky
*/
| > > > > > > > > > > > > > | 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 |
}
g.zCkoutAlias = find_option("ckout-alias",0,1);
g.zMainMenuFile = find_option("mainmenu",0,1);
if( g.zMainMenuFile!=0 && file_size(g.zMainMenuFile,ExtFILE)<0 ){
fossil_fatal("Cannot read --mainmenu file %s", g.zMainMenuFile);
}
if( find_option("acme",0,0)!=0 ) g.fAllowACME = 1;
zIpAddr = (char*)find_option("unix-socket",0,1);
if( zIpAddr ){
#if defined(_WIN32)
fossil_fatal("unix sockets are not supported on Windows");
#endif
if( zPort ){
fossil_fatal("cannot specify a port number for a unix socket");
}
if( isUiCmd && !fNoBrowser ){
fossil_fatal("cannot start a web-browser on a unix socket");
}
flags |= HTTP_SERVER_UNIXDOMAINSOCK;
}
/* Undocumented option: --debug-nofork
**
** This sets the HTTP_SERVER_NOFORK flag, which causes only the
** very first incoming TCP/IP connection to be processed. Used for
** debugging, since debugging across a fork() can be tricky
*/
|
| ︙ | ︙ |