Fossil SCM
[https://www.fossil-scm.org/forum/forumpost/89dba2d978|Plan Z]
Commit
8264fd75bc13923fdd5cbf590bc3e97d52a4698ad0a41fa125a5ad9f00b50aa3
Parent
80cd49f063188f9…
2 files changed
+2
-10
+18
-135
+2
-10
| --- src/doc.c | ||
| +++ src/doc.c | ||
| @@ -513,15 +513,13 @@ | ||
| 513 | 513 | ** Transfer content to the output. During the transfer, when text of |
| 514 | 514 | ** the following form is seen: |
| 515 | 515 | ** |
| 516 | 516 | ** href="$ROOT/ |
| 517 | 517 | ** action="$ROOT/ |
| 518 | -** nonce="$NONCE" | |
| 519 | 518 | ** |
| 520 | -** Convert $ROOT to the root URI of the repository and $NONCE to the | |
| 521 | -** CSP nonce returned by style_nonce(). Allow ' in place of " | |
| 522 | -** and any case for href or action or nonce. | |
| 519 | +** Convert $ROOT to the root URI of the repository. | |
| 520 | +** Allow ' in place of " | |
| 523 | 521 | */ |
| 524 | 522 | void convert_href_and_output(Blob *pIn){ |
| 525 | 523 | int i, base; |
| 526 | 524 | int n = blob_size(pIn); |
| 527 | 525 | char *z = blob_buffer(pIn); |
| @@ -534,16 +532,10 @@ | ||
| 534 | 532 | && (fossil_strnicmp(&z[i-7]," href=", 6)==0 || |
| 535 | 533 | fossil_strnicmp(&z[i-9]," action=", 8)==0) |
| 536 | 534 | ){ |
| 537 | 535 | blob_appendf(cgi_output_blob(), "%R"); |
| 538 | 536 | base = i+5; |
| 539 | - } else if( strncmp(&z[i],"$NONCE", 6)==0 | |
| 540 | - && (fossil_strnicmp(&z[i-8]," nonce=", 6)==0) | |
| 541 | - && z[i+6]==z[i-1] | |
| 542 | - ) { | |
| 543 | - blob_append(cgi_output_blob(), style_nonce(), -1); | |
| 544 | - base = i+6; | |
| 545 | 537 | } |
| 546 | 538 | } |
| 547 | 539 | } |
| 548 | 540 | blob_append(cgi_output_blob(), &z[base], i-base); |
| 549 | 541 | } |
| 550 | 542 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -513,15 +513,13 @@ | |
| 513 | ** Transfer content to the output. During the transfer, when text of |
| 514 | ** the following form is seen: |
| 515 | ** |
| 516 | ** href="$ROOT/ |
| 517 | ** action="$ROOT/ |
| 518 | ** nonce="$NONCE" |
| 519 | ** |
| 520 | ** Convert $ROOT to the root URI of the repository and $NONCE to the |
| 521 | ** CSP nonce returned by style_nonce(). Allow ' in place of " |
| 522 | ** and any case for href or action or nonce. |
| 523 | */ |
| 524 | void convert_href_and_output(Blob *pIn){ |
| 525 | int i, base; |
| 526 | int n = blob_size(pIn); |
| 527 | char *z = blob_buffer(pIn); |
| @@ -534,16 +532,10 @@ | |
| 534 | && (fossil_strnicmp(&z[i-7]," href=", 6)==0 || |
| 535 | fossil_strnicmp(&z[i-9]," action=", 8)==0) |
| 536 | ){ |
| 537 | blob_appendf(cgi_output_blob(), "%R"); |
| 538 | base = i+5; |
| 539 | } else if( strncmp(&z[i],"$NONCE", 6)==0 |
| 540 | && (fossil_strnicmp(&z[i-8]," nonce=", 6)==0) |
| 541 | && z[i+6]==z[i-1] |
| 542 | ) { |
| 543 | blob_append(cgi_output_blob(), style_nonce(), -1); |
| 544 | base = i+6; |
| 545 | } |
| 546 | } |
| 547 | } |
| 548 | blob_append(cgi_output_blob(), &z[base], i-base); |
| 549 | } |
| 550 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -513,15 +513,13 @@ | |
| 513 | ** Transfer content to the output. During the transfer, when text of |
| 514 | ** the following form is seen: |
| 515 | ** |
| 516 | ** href="$ROOT/ |
| 517 | ** action="$ROOT/ |
| 518 | ** |
| 519 | ** Convert $ROOT to the root URI of the repository. |
| 520 | ** Allow ' in place of " |
| 521 | */ |
| 522 | void convert_href_and_output(Blob *pIn){ |
| 523 | int i, base; |
| 524 | int n = blob_size(pIn); |
| 525 | char *z = blob_buffer(pIn); |
| @@ -534,16 +532,10 @@ | |
| 532 | && (fossil_strnicmp(&z[i-7]," href=", 6)==0 || |
| 533 | fossil_strnicmp(&z[i-9]," action=", 8)==0) |
| 534 | ){ |
| 535 | blob_appendf(cgi_output_blob(), "%R"); |
| 536 | base = i+5; |
| 537 | } |
| 538 | } |
| 539 | } |
| 540 | blob_append(cgi_output_blob(), &z[base], i-base); |
| 541 | } |
| 542 |
+18
-135
| --- www/server/index.html | ||
| +++ www/server/index.html | ||
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | <div class='fossil-doc' data-title="How To Configure A Fossil Server"> |
| 2 | 2 | |
| 3 | -<style type="text/css" nonce="$NONCE"> | |
| 3 | +<style type="text/css"> | |
| 4 | 4 | p { |
| 5 | 5 | margin-left: 4em; |
| 6 | 6 | margin-right: 3em; |
| 7 | 7 | } |
| 8 | 8 | |
| @@ -64,14 +64,14 @@ | ||
| 64 | 64 | <h2 id="methods">Methods</h2> |
| 65 | 65 | |
| 66 | 66 | <p>There are basically four ways to set up a Fossil server:</p> |
| 67 | 67 | |
| 68 | 68 | <ol> |
| 69 | + <li><a id="cgi" href="any/cgi.md">CGI</a> | |
| 69 | 70 | <li><a id="standalone" href="any/none.md">Stand-alone HTTP server</a> |
| 70 | 71 | <li>Socket listener |
| 71 | 72 | <li><a id="scgi" href="any/scgi.md">SCGI</a> |
| 72 | - <li><a id="cgi" href="any/cgi.md">CGI</a> | |
| 73 | 73 | </ol> |
| 74 | 74 | |
| 75 | 75 | <p>All of these methods can serve either a single repository or a |
| 76 | 76 | directory containing repositories named "<tt>*.fossil</tt>".</p> |
| 77 | 77 | |
| @@ -80,10 +80,25 @@ | ||
| 80 | 80 | the same time. These methods use clean, well-defined, standard |
| 81 | 81 | interfaces (CGI, SCGI, and HTTP) which allow you to easily migrate from |
| 82 | 82 | one method to another to accommodate changes in hosting providers or |
| 83 | 83 | administrator preferences.</p> |
| 84 | 84 | |
| 85 | +<h3>CGI</h3> | |
| 86 | + | |
| 87 | +<p>Most ordinary web servers can <a href="any/cgi.md">run Fossil as a | |
| 88 | +CGI script</a>. This method is known to work with Apache, <a | |
| 89 | +href="windows/cgi.md">IIS</a>, <tt>lighttpd</tt>, and <a | |
| 90 | +href="any/althttpd.md"><tt>althttpd</tt></a>. The Fossil server | |
| 91 | +administrator places a <a href="/help?cmd=cgi">short CGI script</a> in | |
| 92 | +the web server's document hierarchy, and when a client requests the | |
| 93 | +appropriate URL, that script runs Fossil to generate the response.</p> | |
| 94 | + | |
| 95 | +<p>CGI is a good choice for merging Fossil into an existing web site, | |
| 96 | +particularly on hosts that have CGI set up for you already and won't let | |
| 97 | +you modify the web server configuration further. The Fossil <a | |
| 98 | +href="../selfhost.wiki">self-hosting repositories</a> are implemented | |
| 99 | +with CGI underneath <tt>althttpd</tt>.</p> | |
| 85 | 100 | |
| 86 | 101 | <h3>Stand-alone HTTP Server</h3> |
| 87 | 102 | |
| 88 | 103 | <p>This is the <a href="any/none.md">easiest method</a>. |
| 89 | 104 | A stand-alone server uses the <a |
| @@ -91,11 +106,10 @@ | ||
| 91 | 106 | process that listens for incoming HTTP requests on a socket and then |
| 92 | 107 | dispatches a copy of itself to deal with each incoming request. You can |
| 93 | 108 | expose Fossil directly to the clients in this way or you can interpose a |
| 94 | 109 | <a href="https://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a> |
| 95 | 110 | layer between the clients and Fossil.</p> |
| 96 | - | |
| 97 | 111 | |
| 98 | 112 | <h3>Socket Listener</h3> |
| 99 | 113 | |
| 100 | 114 | <p>Only slightly more complicated is the socket listener method. |
| 101 | 115 | Instead of letting Fossil run in the background continuously to handle |
| @@ -108,11 +122,10 @@ | ||
| 108 | 122 | href="any/xinetd.md"><tt>xinetd</tt></a>, <a id="stunnel" |
| 109 | 123 | href="any/stunnel.md"><tt>stunnel</tt></a>, <a |
| 110 | 124 | href="macos/service.md"><tt>launchd</tt></a>, and <a |
| 111 | 125 | href="debian/service.md"><tt>systemd</tt></a>.</p> |
| 112 | 126 | |
| 113 | - | |
| 114 | 127 | <h3>SCGI</h3> |
| 115 | 128 | |
| 116 | 129 | <p>The Fossil standalone server can also run <a href="any/scgi.md">in |
| 117 | 130 | SCGI mode</a> — <a href="/help/server"><tt>fossil server --scgi</tt></a> |
| 118 | 131 | — instead of <a href="any/none.md">HTTP mode</a>, which allows it to |
| @@ -123,51 +136,22 @@ | ||
| 123 | 136 | up because you also have to set up an SCGI-to-HTTP proxy for it. It is |
| 124 | 137 | worth taking on this difficulty only when you need to integrate Fossil |
| 125 | 138 | into an existing web site already being served by an SCGI-capable web |
| 126 | 139 | server.</p> |
| 127 | 140 | |
| 128 | - | |
| 129 | -<h3>CGI</h3> | |
| 130 | - | |
| 131 | -<p>Most ordinary web servers can <a href="any/cgi.md">run Fossil as a | |
| 132 | -CGI script</a>. This method is known to work with Apache, <a | |
| 133 | -href="windows/cgi.md">IIS</a>, <tt>lighttpd</tt>, and <a | |
| 134 | -href="any/althttpd.md"><tt>althttpd</tt></a>. The Fossil server | |
| 135 | -administrator places a <a href="/help?cmd=cgi">short CGI script</a> in | |
| 136 | -the web server's document hierarchy, and when a client requests the | |
| 137 | -appropriate URL, that script runs Fossil to generate the response.</p> | |
| 138 | - | |
| 139 | -<p>Back when CGI was first created, this method was quite simple, but | |
| 140 | -because of all of the security barriers put up around CGI in most web | |
| 141 | -servers, it can actually be one of the most complicated methods to set | |
| 142 | -up, feature-for-feature. Reverse proxying (both HTTP and SCGI) is the | |
| 143 | -only more complicated method for serving Fossil, but you do get a lot of | |
| 144 | -additional power when doing that.</p> | |
| 145 | - | |
| 146 | -<p>CGI is a good choice for merging Fossil into an existing web site, | |
| 147 | -particularly on hosts that have CGI set up for you already and won't let | |
| 148 | -you modify the web server configuration further. The Fossil <a | |
| 149 | -href="../selfhost.wiki">self-hosting repositories</a> are implemented | |
| 150 | -with CGI underneath <tt>althttpd</tt>.</p> | |
| 151 | - | |
| 152 | - | |
| 153 | - | |
| 154 | 141 | <h2 id="matrix">Setup Tutorials</h2> |
| 155 | 142 | |
| 156 | 143 | <p>We've broken the configuration for each method out into a series of |
| 157 | 144 | sub-articles. Some of these are generic, while others depend on |
| 158 | 145 | particular operating systems or front-end software:</p> |
| 159 | 146 | |
| 160 | 147 | <div id="tutpick" class="show"></div> |
| 161 | 148 | |
| 162 | -<!-- Define alternative to JS tutorial picker below. When updating this | |
| 163 | - table, update "matrix" in the JS code below to match! --> | |
| 164 | -<noscript id="tutmatrix"> | |
| 165 | 149 | <table style="margin-left: 6em;"> |
| 166 | 150 | <tr> |
| 167 | 151 | <th class="host">⇩ OS / Method ⇨</th> |
| 168 | - <th class="fep">none</th> | |
| 152 | + <th class="fep">direct</th> | |
| 169 | 153 | <th class="fep">inetd</th> |
| 170 | 154 | <th class="fep">stunnel</th> |
| 171 | 155 | <th class="fep">CGI</th> |
| 172 | 156 | <th class="fep">SCGI</th> |
| 173 | 157 | <th class="fep">althttpd</th> |
| @@ -250,106 +234,5 @@ | ||
| 250 | 234 | <li><a id="about" href="../aboutcgi.wiki" >How CGI Works In Fossil</a> |
| 251 | 235 | <li><a id="sync" href="../sync.wiki" >The Fossil Sync Protocol</a> |
| 252 | 236 | </ul> |
| 253 | 237 | |
| 254 | 238 | </div> |
| 255 | - | |
| 256 | -<script type="text/javascript" nonce="$NONCE"> | |
| 257 | - (function() { | |
| 258 | - // Define data structure analog to <table> above. Matrix elements | |
| 259 | - // can have one of these constant values or a string for a one-off | |
| 260 | - // custom value. Values outside the <table> above go at the end of | |
| 261 | - // the rows we define here. | |
| 262 | - const YES = 1; // host-specific doc provided | |
| 263 | - const IFA = 2; // inherit doc from "any" | |
| 264 | - const NO = 3; // method invalid or undocumented for this host OS | |
| 265 | - const methods = [ | |
| 266 | - "none", "inetd", "stunnel", "CGI", "SCGI", "althttpd", "proxy", "service" | |
| 267 | - ]; | |
| 268 | - const matrix = { | |
| 269 | - "any OS": [ YES, YES, YES, YES, YES, YES, NO, NO ], | |
| 270 | - "Debian or Ubuntu": [ IFA, IFA, IFA, IFA, IFA, IFA, "nginx", YES ], | |
| 271 | - "macOS": [ IFA, NO, IFA, IFA, IFA, IFA, NO, YES ], | |
| 272 | - "Windows": [ YES, NO, YES, YES, NO, NO, "IIS", NO ], | |
| 273 | - } | |
| 274 | - const osNames = Object.keys(matrix).sort((e) => { | |
| 275 | - return e.toLowerCase() | |
| 276 | - }).map((longName, i) => { | |
| 277 | - var shortName = longName.toLowerCase().split(' ')[0]; | |
| 278 | - return [ longName, shortName ]; | |
| 279 | - }); | |
| 280 | - const osNameMap = Object.fromEntries(osNames); | |
| 281 | - //console.log("OS name map: " + JSON.stringify(osNameMap)); | |
| 282 | - | |
| 283 | - // Build initial tutorial chooser HTML, and insert it into doc where | |
| 284 | - // the static HTML <table> matrix normally goes. | |
| 285 | - var html = '<p><b>I want to run Fossil on</b> <select id="os">'; | |
| 286 | - for (var os of osNames) { | |
| 287 | - const longName = os[0]; | |
| 288 | - const shortName = os[1]; | |
| 289 | - html += '<option name="' + shortName + '">' + longName + '</option>'; | |
| 290 | - } | |
| 291 | - html += '</select> <b>underneath</b> <select id="fep"></select>' | |
| 292 | - html += '<a id="all">SHOW ALL</a></p>'; | |
| 293 | - const picker = document.querySelector('div#tutpick'); | |
| 294 | - picker.innerHTML = html; | |
| 295 | - | |
| 296 | - // Slide noscript <table> in place of JS tutorial chooser on | |
| 297 | - // "SHOW ALL" click. | |
| 298 | - document.querySelector('a#all').addEventListener('click', () => { | |
| 299 | - picker.classList.remove('show'); | |
| 300 | - picker.innerHTML = document.querySelector('#tutmatrix').innerHTML; | |
| 301 | - setTimeout(() => { | |
| 302 | - // Let doc update to set new height, so transition happens. | |
| 303 | - picker.classList.add('show'); | |
| 304 | - }, 10); | |
| 305 | - }); | |
| 306 | - | |
| 307 | - // Attach event handlers to drop-downs. Have to wait until the page | |
| 308 | - // loads, else we'll get null back from querySelector(('select#foo')). | |
| 309 | - window.addEventListener('load', () => { | |
| 310 | - // Set up the FEP choice drop-down on initial page load and | |
| 311 | - // update it when the OS choice drop-down changes. | |
| 312 | - const osSel = document.querySelector('select#os'); | |
| 313 | - const fepSel = document.querySelector('select#fep'); | |
| 314 | - function osClickHandler() { | |
| 315 | - var osLong = osSel.value; | |
| 316 | - var osShort = osNameMap[osLong]; | |
| 317 | - | |
| 318 | - var html = '<option>---</option>'; | |
| 319 | - matrix[osLong].forEach((choice, i) => { | |
| 320 | - var mu; | |
| 321 | - if (typeof(choice) === 'string') { | |
| 322 | - mu = choice; | |
| 323 | - choice = YES; | |
| 324 | - } | |
| 325 | - else { | |
| 326 | - mu = methods[i]; | |
| 327 | - } | |
| 328 | - const ml = mu.toLowerCase(); | |
| 329 | - | |
| 330 | - if (choice != NO) { | |
| 331 | - if (choice == YES) { | |
| 332 | - html += '<option value="' + osShort + '/' + ml + '.md">'; | |
| 333 | - } | |
| 334 | - else if (choice == IFA) { | |
| 335 | - html += '<option value="any/' + ml + '.md">'; | |
| 336 | - } | |
| 337 | - html += mu + '</option>'; | |
| 338 | - } | |
| 339 | - }); | |
| 340 | - | |
| 341 | - fepSel.innerHTML = html; | |
| 342 | - } | |
| 343 | - osSel.addEventListener('change', osClickHandler); | |
| 344 | - osClickHandler(); // load fepSel initial content | |
| 345 | - | |
| 346 | - // Go to selected document when user changes FEP drop-down | |
| 347 | - fepSel.addEventListener('change', () => { | |
| 348 | - var doc = fepSel.value; | |
| 349 | - if (doc) location.href = doc; | |
| 350 | - // else it's the --- entry, either because we just reloaded the | |
| 351 | - // <option> set or because the user re-selected it. | |
| 352 | - }); | |
| 353 | - }); | |
| 354 | - })(); | |
| 355 | -</script> | |
| 356 | 239 |
| --- www/server/index.html | |
| +++ www/server/index.html | |
| @@ -1,8 +1,8 @@ | |
| 1 | <div class='fossil-doc' data-title="How To Configure A Fossil Server"> |
| 2 | |
| 3 | <style type="text/css" nonce="$NONCE"> |
| 4 | p { |
| 5 | margin-left: 4em; |
| 6 | margin-right: 3em; |
| 7 | } |
| 8 | |
| @@ -64,14 +64,14 @@ | |
| 64 | <h2 id="methods">Methods</h2> |
| 65 | |
| 66 | <p>There are basically four ways to set up a Fossil server:</p> |
| 67 | |
| 68 | <ol> |
| 69 | <li><a id="standalone" href="any/none.md">Stand-alone HTTP server</a> |
| 70 | <li>Socket listener |
| 71 | <li><a id="scgi" href="any/scgi.md">SCGI</a> |
| 72 | <li><a id="cgi" href="any/cgi.md">CGI</a> |
| 73 | </ol> |
| 74 | |
| 75 | <p>All of these methods can serve either a single repository or a |
| 76 | directory containing repositories named "<tt>*.fossil</tt>".</p> |
| 77 | |
| @@ -80,10 +80,25 @@ | |
| 80 | the same time. These methods use clean, well-defined, standard |
| 81 | interfaces (CGI, SCGI, and HTTP) which allow you to easily migrate from |
| 82 | one method to another to accommodate changes in hosting providers or |
| 83 | administrator preferences.</p> |
| 84 | |
| 85 | |
| 86 | <h3>Stand-alone HTTP Server</h3> |
| 87 | |
| 88 | <p>This is the <a href="any/none.md">easiest method</a>. |
| 89 | A stand-alone server uses the <a |
| @@ -91,11 +106,10 @@ | |
| 91 | process that listens for incoming HTTP requests on a socket and then |
| 92 | dispatches a copy of itself to deal with each incoming request. You can |
| 93 | expose Fossil directly to the clients in this way or you can interpose a |
| 94 | <a href="https://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a> |
| 95 | layer between the clients and Fossil.</p> |
| 96 | |
| 97 | |
| 98 | <h3>Socket Listener</h3> |
| 99 | |
| 100 | <p>Only slightly more complicated is the socket listener method. |
| 101 | Instead of letting Fossil run in the background continuously to handle |
| @@ -108,11 +122,10 @@ | |
| 108 | href="any/xinetd.md"><tt>xinetd</tt></a>, <a id="stunnel" |
| 109 | href="any/stunnel.md"><tt>stunnel</tt></a>, <a |
| 110 | href="macos/service.md"><tt>launchd</tt></a>, and <a |
| 111 | href="debian/service.md"><tt>systemd</tt></a>.</p> |
| 112 | |
| 113 | |
| 114 | <h3>SCGI</h3> |
| 115 | |
| 116 | <p>The Fossil standalone server can also run <a href="any/scgi.md">in |
| 117 | SCGI mode</a> — <a href="/help/server"><tt>fossil server --scgi</tt></a> |
| 118 | — instead of <a href="any/none.md">HTTP mode</a>, which allows it to |
| @@ -123,51 +136,22 @@ | |
| 123 | up because you also have to set up an SCGI-to-HTTP proxy for it. It is |
| 124 | worth taking on this difficulty only when you need to integrate Fossil |
| 125 | into an existing web site already being served by an SCGI-capable web |
| 126 | server.</p> |
| 127 | |
| 128 | |
| 129 | <h3>CGI</h3> |
| 130 | |
| 131 | <p>Most ordinary web servers can <a href="any/cgi.md">run Fossil as a |
| 132 | CGI script</a>. This method is known to work with Apache, <a |
| 133 | href="windows/cgi.md">IIS</a>, <tt>lighttpd</tt>, and <a |
| 134 | href="any/althttpd.md"><tt>althttpd</tt></a>. The Fossil server |
| 135 | administrator places a <a href="/help?cmd=cgi">short CGI script</a> in |
| 136 | the web server's document hierarchy, and when a client requests the |
| 137 | appropriate URL, that script runs Fossil to generate the response.</p> |
| 138 | |
| 139 | <p>Back when CGI was first created, this method was quite simple, but |
| 140 | because of all of the security barriers put up around CGI in most web |
| 141 | servers, it can actually be one of the most complicated methods to set |
| 142 | up, feature-for-feature. Reverse proxying (both HTTP and SCGI) is the |
| 143 | only more complicated method for serving Fossil, but you do get a lot of |
| 144 | additional power when doing that.</p> |
| 145 | |
| 146 | <p>CGI is a good choice for merging Fossil into an existing web site, |
| 147 | particularly on hosts that have CGI set up for you already and won't let |
| 148 | you modify the web server configuration further. The Fossil <a |
| 149 | href="../selfhost.wiki">self-hosting repositories</a> are implemented |
| 150 | with CGI underneath <tt>althttpd</tt>.</p> |
| 151 | |
| 152 | |
| 153 | |
| 154 | <h2 id="matrix">Setup Tutorials</h2> |
| 155 | |
| 156 | <p>We've broken the configuration for each method out into a series of |
| 157 | sub-articles. Some of these are generic, while others depend on |
| 158 | particular operating systems or front-end software:</p> |
| 159 | |
| 160 | <div id="tutpick" class="show"></div> |
| 161 | |
| 162 | <!-- Define alternative to JS tutorial picker below. When updating this |
| 163 | table, update "matrix" in the JS code below to match! --> |
| 164 | <noscript id="tutmatrix"> |
| 165 | <table style="margin-left: 6em;"> |
| 166 | <tr> |
| 167 | <th class="host">⇩ OS / Method ⇨</th> |
| 168 | <th class="fep">none</th> |
| 169 | <th class="fep">inetd</th> |
| 170 | <th class="fep">stunnel</th> |
| 171 | <th class="fep">CGI</th> |
| 172 | <th class="fep">SCGI</th> |
| 173 | <th class="fep">althttpd</th> |
| @@ -250,106 +234,5 @@ | |
| 250 | <li><a id="about" href="../aboutcgi.wiki" >How CGI Works In Fossil</a> |
| 251 | <li><a id="sync" href="../sync.wiki" >The Fossil Sync Protocol</a> |
| 252 | </ul> |
| 253 | |
| 254 | </div> |
| 255 | |
| 256 | <script type="text/javascript" nonce="$NONCE"> |
| 257 | (function() { |
| 258 | // Define data structure analog to <table> above. Matrix elements |
| 259 | // can have one of these constant values or a string for a one-off |
| 260 | // custom value. Values outside the <table> above go at the end of |
| 261 | // the rows we define here. |
| 262 | const YES = 1; // host-specific doc provided |
| 263 | const IFA = 2; // inherit doc from "any" |
| 264 | const NO = 3; // method invalid or undocumented for this host OS |
| 265 | const methods = [ |
| 266 | "none", "inetd", "stunnel", "CGI", "SCGI", "althttpd", "proxy", "service" |
| 267 | ]; |
| 268 | const matrix = { |
| 269 | "any OS": [ YES, YES, YES, YES, YES, YES, NO, NO ], |
| 270 | "Debian or Ubuntu": [ IFA, IFA, IFA, IFA, IFA, IFA, "nginx", YES ], |
| 271 | "macOS": [ IFA, NO, IFA, IFA, IFA, IFA, NO, YES ], |
| 272 | "Windows": [ YES, NO, YES, YES, NO, NO, "IIS", NO ], |
| 273 | } |
| 274 | const osNames = Object.keys(matrix).sort((e) => { |
| 275 | return e.toLowerCase() |
| 276 | }).map((longName, i) => { |
| 277 | var shortName = longName.toLowerCase().split(' ')[0]; |
| 278 | return [ longName, shortName ]; |
| 279 | }); |
| 280 | const osNameMap = Object.fromEntries(osNames); |
| 281 | //console.log("OS name map: " + JSON.stringify(osNameMap)); |
| 282 | |
| 283 | // Build initial tutorial chooser HTML, and insert it into doc where |
| 284 | // the static HTML <table> matrix normally goes. |
| 285 | var html = '<p><b>I want to run Fossil on</b> <select id="os">'; |
| 286 | for (var os of osNames) { |
| 287 | const longName = os[0]; |
| 288 | const shortName = os[1]; |
| 289 | html += '<option name="' + shortName + '">' + longName + '</option>'; |
| 290 | } |
| 291 | html += '</select> <b>underneath</b> <select id="fep"></select>' |
| 292 | html += '<a id="all">SHOW ALL</a></p>'; |
| 293 | const picker = document.querySelector('div#tutpick'); |
| 294 | picker.innerHTML = html; |
| 295 | |
| 296 | // Slide noscript <table> in place of JS tutorial chooser on |
| 297 | // "SHOW ALL" click. |
| 298 | document.querySelector('a#all').addEventListener('click', () => { |
| 299 | picker.classList.remove('show'); |
| 300 | picker.innerHTML = document.querySelector('#tutmatrix').innerHTML; |
| 301 | setTimeout(() => { |
| 302 | // Let doc update to set new height, so transition happens. |
| 303 | picker.classList.add('show'); |
| 304 | }, 10); |
| 305 | }); |
| 306 | |
| 307 | // Attach event handlers to drop-downs. Have to wait until the page |
| 308 | // loads, else we'll get null back from querySelector(('select#foo')). |
| 309 | window.addEventListener('load', () => { |
| 310 | // Set up the FEP choice drop-down on initial page load and |
| 311 | // update it when the OS choice drop-down changes. |
| 312 | const osSel = document.querySelector('select#os'); |
| 313 | const fepSel = document.querySelector('select#fep'); |
| 314 | function osClickHandler() { |
| 315 | var osLong = osSel.value; |
| 316 | var osShort = osNameMap[osLong]; |
| 317 | |
| 318 | var html = '<option>---</option>'; |
| 319 | matrix[osLong].forEach((choice, i) => { |
| 320 | var mu; |
| 321 | if (typeof(choice) === 'string') { |
| 322 | mu = choice; |
| 323 | choice = YES; |
| 324 | } |
| 325 | else { |
| 326 | mu = methods[i]; |
| 327 | } |
| 328 | const ml = mu.toLowerCase(); |
| 329 | |
| 330 | if (choice != NO) { |
| 331 | if (choice == YES) { |
| 332 | html += '<option value="' + osShort + '/' + ml + '.md">'; |
| 333 | } |
| 334 | else if (choice == IFA) { |
| 335 | html += '<option value="any/' + ml + '.md">'; |
| 336 | } |
| 337 | html += mu + '</option>'; |
| 338 | } |
| 339 | }); |
| 340 | |
| 341 | fepSel.innerHTML = html; |
| 342 | } |
| 343 | osSel.addEventListener('change', osClickHandler); |
| 344 | osClickHandler(); // load fepSel initial content |
| 345 | |
| 346 | // Go to selected document when user changes FEP drop-down |
| 347 | fepSel.addEventListener('change', () => { |
| 348 | var doc = fepSel.value; |
| 349 | if (doc) location.href = doc; |
| 350 | // else it's the --- entry, either because we just reloaded the |
| 351 | // <option> set or because the user re-selected it. |
| 352 | }); |
| 353 | }); |
| 354 | })(); |
| 355 | </script> |
| 356 |
| --- www/server/index.html | |
| +++ www/server/index.html | |
| @@ -1,8 +1,8 @@ | |
| 1 | <div class='fossil-doc' data-title="How To Configure A Fossil Server"> |
| 2 | |
| 3 | <style type="text/css"> |
| 4 | p { |
| 5 | margin-left: 4em; |
| 6 | margin-right: 3em; |
| 7 | } |
| 8 | |
| @@ -64,14 +64,14 @@ | |
| 64 | <h2 id="methods">Methods</h2> |
| 65 | |
| 66 | <p>There are basically four ways to set up a Fossil server:</p> |
| 67 | |
| 68 | <ol> |
| 69 | <li><a id="cgi" href="any/cgi.md">CGI</a> |
| 70 | <li><a id="standalone" href="any/none.md">Stand-alone HTTP server</a> |
| 71 | <li>Socket listener |
| 72 | <li><a id="scgi" href="any/scgi.md">SCGI</a> |
| 73 | </ol> |
| 74 | |
| 75 | <p>All of these methods can serve either a single repository or a |
| 76 | directory containing repositories named "<tt>*.fossil</tt>".</p> |
| 77 | |
| @@ -80,10 +80,25 @@ | |
| 80 | the same time. These methods use clean, well-defined, standard |
| 81 | interfaces (CGI, SCGI, and HTTP) which allow you to easily migrate from |
| 82 | one method to another to accommodate changes in hosting providers or |
| 83 | administrator preferences.</p> |
| 84 | |
| 85 | <h3>CGI</h3> |
| 86 | |
| 87 | <p>Most ordinary web servers can <a href="any/cgi.md">run Fossil as a |
| 88 | CGI script</a>. This method is known to work with Apache, <a |
| 89 | href="windows/cgi.md">IIS</a>, <tt>lighttpd</tt>, and <a |
| 90 | href="any/althttpd.md"><tt>althttpd</tt></a>. The Fossil server |
| 91 | administrator places a <a href="/help?cmd=cgi">short CGI script</a> in |
| 92 | the web server's document hierarchy, and when a client requests the |
| 93 | appropriate URL, that script runs Fossil to generate the response.</p> |
| 94 | |
| 95 | <p>CGI is a good choice for merging Fossil into an existing web site, |
| 96 | particularly on hosts that have CGI set up for you already and won't let |
| 97 | you modify the web server configuration further. The Fossil <a |
| 98 | href="../selfhost.wiki">self-hosting repositories</a> are implemented |
| 99 | with CGI underneath <tt>althttpd</tt>.</p> |
| 100 | |
| 101 | <h3>Stand-alone HTTP Server</h3> |
| 102 | |
| 103 | <p>This is the <a href="any/none.md">easiest method</a>. |
| 104 | A stand-alone server uses the <a |
| @@ -91,11 +106,10 @@ | |
| 106 | process that listens for incoming HTTP requests on a socket and then |
| 107 | dispatches a copy of itself to deal with each incoming request. You can |
| 108 | expose Fossil directly to the clients in this way or you can interpose a |
| 109 | <a href="https://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a> |
| 110 | layer between the clients and Fossil.</p> |
| 111 | |
| 112 | <h3>Socket Listener</h3> |
| 113 | |
| 114 | <p>Only slightly more complicated is the socket listener method. |
| 115 | Instead of letting Fossil run in the background continuously to handle |
| @@ -108,11 +122,10 @@ | |
| 122 | href="any/xinetd.md"><tt>xinetd</tt></a>, <a id="stunnel" |
| 123 | href="any/stunnel.md"><tt>stunnel</tt></a>, <a |
| 124 | href="macos/service.md"><tt>launchd</tt></a>, and <a |
| 125 | href="debian/service.md"><tt>systemd</tt></a>.</p> |
| 126 | |
| 127 | <h3>SCGI</h3> |
| 128 | |
| 129 | <p>The Fossil standalone server can also run <a href="any/scgi.md">in |
| 130 | SCGI mode</a> — <a href="/help/server"><tt>fossil server --scgi</tt></a> |
| 131 | — instead of <a href="any/none.md">HTTP mode</a>, which allows it to |
| @@ -123,51 +136,22 @@ | |
| 136 | up because you also have to set up an SCGI-to-HTTP proxy for it. It is |
| 137 | worth taking on this difficulty only when you need to integrate Fossil |
| 138 | into an existing web site already being served by an SCGI-capable web |
| 139 | server.</p> |
| 140 | |
| 141 | <h2 id="matrix">Setup Tutorials</h2> |
| 142 | |
| 143 | <p>We've broken the configuration for each method out into a series of |
| 144 | sub-articles. Some of these are generic, while others depend on |
| 145 | particular operating systems or front-end software:</p> |
| 146 | |
| 147 | <div id="tutpick" class="show"></div> |
| 148 | |
| 149 | <table style="margin-left: 6em;"> |
| 150 | <tr> |
| 151 | <th class="host">⇩ OS / Method ⇨</th> |
| 152 | <th class="fep">direct</th> |
| 153 | <th class="fep">inetd</th> |
| 154 | <th class="fep">stunnel</th> |
| 155 | <th class="fep">CGI</th> |
| 156 | <th class="fep">SCGI</th> |
| 157 | <th class="fep">althttpd</th> |
| @@ -250,106 +234,5 @@ | |
| 234 | <li><a id="about" href="../aboutcgi.wiki" >How CGI Works In Fossil</a> |
| 235 | <li><a id="sync" href="../sync.wiki" >The Fossil Sync Protocol</a> |
| 236 | </ul> |
| 237 | |
| 238 | </div> |
| 239 |