| | @@ -33,11 +33,11 @@ |
| 33 | 33 | struct HttpRequest { |
| 34 | 34 | int id; /* ID counter */ |
| 35 | 35 | SOCKET s; /* Socket on which to receive data */ |
| 36 | 36 | SOCKADDR_IN addr; /* Address from which data is coming */ |
| 37 | 37 | int flags; /* Flags passed to win32_http_server() */ |
| 38 | | - const char *zOptions; /* --notfound and/or --localauth options */ |
| 38 | + const char *zOptions; /* --baseurl, --notfound and/or --localauth options */ |
| 39 | 39 | }; |
| 40 | 40 | |
| 41 | 41 | /* |
| 42 | 42 | ** Prefix for a temporary file. |
| 43 | 43 | */ |
| | @@ -236,10 +236,11 @@ |
| 236 | 236 | */ |
| 237 | 237 | void win32_http_server( |
| 238 | 238 | int mnPort, int mxPort, /* Range of allowed TCP port numbers */ |
| 239 | 239 | const char *zBrowser, /* Command to launch browser. (Or NULL) */ |
| 240 | 240 | const char *zStopper, /* Stop server when this file is exists (Or NULL) */ |
| 241 | + const char *zBaseUrl, /* The --baseurl option, or NULL */ |
| 241 | 242 | const char *zNotFound, /* The --notfound option, or NULL */ |
| 242 | 243 | const char *zFileGlob, /* The --fileglob option, or NULL */ |
| 243 | 244 | const char *zIpAddr, /* Bind to this IP address, if not NULL */ |
| 244 | 245 | int flags /* One or more HTTP_SERVER_ flags */ |
| 245 | 246 | ){ |
| | @@ -251,10 +252,13 @@ |
| 251 | 252 | Blob options; |
| 252 | 253 | wchar_t zTmpPath[MAX_PATH]; |
| 253 | 254 | |
| 254 | 255 | if( zStopper ) file_delete(zStopper); |
| 255 | 256 | blob_zero(&options); |
| 257 | + if( zBaseUrl ){ |
| 258 | + blob_appendf(&options, " --baseurl %s", zBaseUrl); |
| 259 | + } |
| 256 | 260 | if( zNotFound ){ |
| 257 | 261 | blob_appendf(&options, " --notfound %s", zNotFound); |
| 258 | 262 | } |
| 259 | 263 | if( zFileGlob ){ |
| 260 | 264 | blob_appendf(&options, " --files-urlenc %T", zFileGlob); |
| | @@ -365,10 +369,11 @@ |
| 365 | 369 | ** function and to the service control handler function. |
| 366 | 370 | */ |
| 367 | 371 | typedef struct HttpService HttpService; |
| 368 | 372 | struct HttpService { |
| 369 | 373 | int port; /* Port on which the http server should run */ |
| 374 | + const char *zBaseUrl; /* The --baseurl option, or NULL */ |
| 370 | 375 | const char *zNotFound; /* The --notfound option, or NULL */ |
| 371 | 376 | const char *zFileGlob; /* The --files option, or NULL */ |
| 372 | 377 | int flags; /* One or more HTTP_SERVER_ flags */ |
| 373 | 378 | int isRunningAsService; /* Are we running as a service ? */ |
| 374 | 379 | const wchar_t *zServiceName;/* Name of the service */ |
| | @@ -376,11 +381,11 @@ |
| 376 | 381 | }; |
| 377 | 382 | |
| 378 | 383 | /* |
| 379 | 384 | ** Variables used for running as windows service. |
| 380 | 385 | */ |
| 381 | | -static HttpService hsData = {8080, NULL, NULL, 0, 0, NULL, INVALID_SOCKET}; |
| 386 | +static HttpService hsData = {8080, NULL, NULL, NULL, 0, 0, NULL, INVALID_SOCKET}; |
| 382 | 387 | static SERVICE_STATUS ssStatus; |
| 383 | 388 | static SERVICE_STATUS_HANDLE sshStatusHandle; |
| 384 | 389 | |
| 385 | 390 | /* |
| 386 | 391 | ** Get message string of the last system error. Return a pointer to the |
| | @@ -517,12 +522,12 @@ |
| 517 | 522 | ssStatus.dwServiceSpecificExitCode = 0; |
| 518 | 523 | win32_report_service_status(SERVICE_START_PENDING, NO_ERROR, 3000); |
| 519 | 524 | |
| 520 | 525 | /* Execute the http server */ |
| 521 | 526 | win32_http_server(hsData.port, hsData.port, |
| 522 | | - NULL, NULL, hsData.zNotFound, hsData.zFileGlob, 0, |
| 523 | | - hsData.flags); |
| 527 | + NULL, NULL, hsData.zBaseUrl, hsData.zNotFound, |
| 528 | + hsData.zFileGlob, 0, hsData.flags); |
| 524 | 529 | |
| 525 | 530 | /* Service has stopped now. */ |
| 526 | 531 | win32_report_service_status(SERVICE_STOPPED, NO_ERROR, 0); |
| 527 | 532 | return; |
| 528 | 533 | } |
| | @@ -545,10 +550,11 @@ |
| 545 | 550 | ** integer value. When running as service, this routine does not return until |
| 546 | 551 | ** the service is stopped. In this case, the return value is zero. |
| 547 | 552 | */ |
| 548 | 553 | int win32_http_service( |
| 549 | 554 | int nPort, /* TCP port number */ |
| 555 | + const char *zBaseUrl, /* The --baseurl option, or NULL */ |
| 550 | 556 | const char *zNotFound, /* The --notfound option, or NULL */ |
| 551 | 557 | const char *zFileGlob, /* The --files option, or NULL */ |
| 552 | 558 | int flags /* One or more HTTP_SERVER_ flags */ |
| 553 | 559 | ){ |
| 554 | 560 | /* Define the service table. */ |
| | @@ -555,10 +561,11 @@ |
| 555 | 561 | SERVICE_TABLE_ENTRYW ServiceTable[] = |
| 556 | 562 | {{L"", (LPSERVICE_MAIN_FUNCTIONW)win32_http_service_main}, {NULL, NULL}}; |
| 557 | 563 | |
| 558 | 564 | /* Initialize the HttpService structure. */ |
| 559 | 565 | hsData.port = nPort; |
| 566 | + hsData.zBaseUrl = zBaseUrl; |
| 560 | 567 | hsData.zNotFound = zNotFound; |
| 561 | 568 | hsData.zFileGlob = zFileGlob; |
| 562 | 569 | hsData.flags = flags; |
| 563 | 570 | |
| 564 | 571 | /* Try to start the control dispatcher thread for the service. */ |
| | @@ -572,11 +579,11 @@ |
| 572 | 579 | return 0; |
| 573 | 580 | } |
| 574 | 581 | |
| 575 | 582 | /* dupe ifdef needed for mkindex |
| 576 | 583 | ** COMMAND: winsrv* |
| 577 | | -** |
| 584 | +** |
| 578 | 585 | ** Usage: %fossil winsrv METHOD ?SERVICE-NAME? ?OPTIONS? |
| 579 | 586 | ** |
| 580 | 587 | ** Where METHOD is one of: create delete show start stop. |
| 581 | 588 | ** |
| 582 | 589 | ** The winsrv command manages Fossil as a Windows service. This allows |
| | @@ -617,10 +624,14 @@ |
| 617 | 624 | ** Password for the user account. |
| 618 | 625 | ** |
| 619 | 626 | ** The following options are more or less the same as for the "server" |
| 620 | 627 | ** command and influence the behaviour of the http server: |
| 621 | 628 | ** |
| 629 | +** --baseurl URL |
| 630 | +** |
| 631 | +** Use URL as the base (useful for reverse proxies) |
| 632 | +** |
| 622 | 633 | ** -P|--port TCPPORT |
| 623 | 634 | ** |
| 624 | 635 | ** Specifies the TCP port (default port is 8080) on which the |
| 625 | 636 | ** server should listen. |
| 626 | 637 | ** |
| | @@ -699,10 +710,11 @@ |
| 699 | 710 | SC_HANDLE hScm; |
| 700 | 711 | SC_HANDLE hSvc; |
| 701 | 712 | SERVICE_DESCRIPTIONW |
| 702 | 713 | svcDescr = {L"Fossil - Distributed Software Configuration Management"}; |
| 703 | 714 | DWORD dwStartType = SERVICE_DEMAND_START; |
| 715 | + const char *zAltBase = find_option("baseurl", 0, 1); |
| 704 | 716 | const char *zDisplay = find_option("display", "D", 1); |
| 705 | 717 | const char *zStart = find_option("start", "S", 1); |
| 706 | 718 | const char *zUsername = find_option("username", "U", 1); |
| 707 | 719 | const char *zPassword = find_option("password", "W", 1); |
| 708 | 720 | const char *zPort = find_option("port", "P", 1); |
| | @@ -754,10 +766,11 @@ |
| 754 | 766 | } |
| 755 | 767 | db_close(0); |
| 756 | 768 | /* Build the fully-qualified path to the service binary file. */ |
| 757 | 769 | blob_zero(&binPath); |
| 758 | 770 | blob_appendf(&binPath, "\"%s\" server", g.nameOfExe); |
| 771 | + if( zAltBase ) blob_appendf(&binPath, " --baseurl %s", zAltBase); |
| 759 | 772 | if( zPort ) blob_appendf(&binPath, " --port %s", zPort); |
| 760 | 773 | if( useSCGI ) blob_appendf(&binPath, " --scgi"); |
| 761 | 774 | if( allowRepoList ) blob_appendf(&binPath, " --repolist"); |
| 762 | 775 | if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound); |
| 763 | 776 | if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob); |
| 764 | 777 | |