Fossil

Check-in [8264fd75]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Plan Z
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | server-docs
Files: files | file ages | folders
SHA3-256: 8264fd75bc13923fdd5cbf590bc3e97d52a4698ad0a41fa125a5ad9f00b50aa3
User & Date: drh 2019-08-19 18:24:13
References
2019-08-20
06:28
Reverted src/doc.c to the trunk version. The "Plan Z" reversion in [8264fd75] was incomplete, causing bad TH1 variable expansion. I believe this explains the symptom I worked around in [9bdf650f0b8]. This check-in also cherry-picks [3d6a4fd95c] onto the branch. check-in: 3cdf764c user: wyoung tags: server-docs
00:37
Removed documentation of the nonce="$NONCE" feature in www/embeddeddoc.wiki, removed as part of [8264fd75]. check-in: d55f6b15 user: wyoung tags: server-docs
Context
2019-08-19
19:29
Updating links in www/server/windows/stunnel.md to correct locations. check-in: 65d175ae user: ckennedy tags: server-docs
18:24
Plan Z check-in: 8264fd75 user: drh tags: server-docs
12:38
Added missing www/chroot.md file check-in: 80cd49f0 user: wyoung tags: server-docs
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/doc.c.

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
...
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551

/*
** Transfer content to the output.  During the transfer, when text of
** the following form is seen:
**
**       href="$ROOT/
**       action="$ROOT/
**       nonce="$NONCE"
**
** Convert $ROOT to the root URI of the repository and $NONCE to the 
** CSP nonce returned by style_nonce().  Allow ' in place of "
** and any case for href or action or nonce.
*/
void convert_href_and_output(Blob *pIn){
  int i, base;
  int n = blob_size(pIn);
  char *z = blob_buffer(pIn);
  for(base=0, i=7; i<n; i++){
    if( z[i]=='$'
................................................................................
      blob_append(cgi_output_blob(), &z[base], i-base);
      if( strncmp(&z[i],"$ROOT/", 6)==0
       && (fossil_strnicmp(&z[i-7]," href=", 6)==0 ||
             fossil_strnicmp(&z[i-9]," action=", 8)==0)
      ){
        blob_appendf(cgi_output_blob(), "%R");
        base = i+5;
      } else if( strncmp(&z[i],"$NONCE", 6)==0
       && (fossil_strnicmp(&z[i-8]," nonce=", 6)==0)
       && z[i+6]==z[i-1]
      ) { 
        blob_append(cgi_output_blob(), style_nonce(), -1);
        base = i+6;
      }
    }
  }
  blob_append(cgi_output_blob(), &z[base], i-base);
}

/*







<

|
|
<







 







<
<
<
<
<
<







511
512
513
514
515
516
517

518
519
520

521
522
523
524
525
526
527
...
530
531
532
533
534
535
536






537
538
539
540
541
542
543

/*
** Transfer content to the output.  During the transfer, when text of
** the following form is seen:
**
**       href="$ROOT/
**       action="$ROOT/

**
** Convert $ROOT to the root URI of the repository.
** Allow ' in place of "

*/
void convert_href_and_output(Blob *pIn){
  int i, base;
  int n = blob_size(pIn);
  char *z = blob_buffer(pIn);
  for(base=0, i=7; i<n; i++){
    if( z[i]=='$'
................................................................................
      blob_append(cgi_output_blob(), &z[base], i-base);
      if( strncmp(&z[i],"$ROOT/", 6)==0
       && (fossil_strnicmp(&z[i-7]," href=", 6)==0 ||
             fossil_strnicmp(&z[i-9]," action=", 8)==0)
      ){
        blob_appendf(cgi_output_blob(), "%R");
        base = i+5;






      }
    }
  }
  blob_append(cgi_output_blob(), &z[base], i-base);
}

/*

Changes to www/server/index.html.

1
2
3
4
5
6
7
8
9
10
..
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84















85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
<div class='fossil-doc' data-title="How To Configure A Fossil Server">

<style type="text/css" nonce="$NONCE">
  p {
    margin-left: 4em;
    margin-right: 3em;
  }

  h2 {
    margin-left: 1em;
................................................................................


<h2 id="methods">Methods</h2>

<p>There are basically four ways to set up a Fossil server:</p>

<ol>

  <li><a id="standalone" href="any/none.md">Stand-alone HTTP server</a>
  <li>Socket listener
  <li><a id="scgi"       href="any/scgi.md">SCGI</a>
  <li><a id="cgi"        href="any/cgi.md">CGI</a>
</ol>

<p>All of these methods can serve either a single repository or a
directory containing repositories named "<tt>*.fossil</tt>".</p>

<p>You are not restricted to using a single method. The same Fossil
repository can be served using two or more of the above techniques at
the same time. These methods use clean, well-defined, standard
interfaces (CGI, SCGI, and HTTP) which allow you to easily migrate from
one method to another to accommodate changes in hosting providers or
administrator preferences.</p>

















<h3>Stand-alone HTTP Server</h3>

<p>This is the <a href="any/none.md">easiest method</a>.
A stand-alone server uses the <a
href="/help?cmd=server"><tt>fossil server</tt></a> command to run a
process that listens for incoming HTTP requests on a socket and then
dispatches a copy of itself to deal with each incoming request. You can
expose Fossil directly to the clients in this way or you can interpose a
<a href="https://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a>
layer between the clients and Fossil.</p>


<h3>Socket Listener</h3>

<p>Only slightly more complicated is the socket listener method.
Instead of letting Fossil run in the background continuously to handle
HTTP requests from clients, you configure a socket listener daemon to
run a <a href="/help?cmd=http"><tt>fossil http</tt></a> command on each
................................................................................
hit.  This scheme is known to work with <a id="inetd"
href="any/inetd.md"><tt>inetd</tt></a>, <a id="xinetd"
href="any/xinetd.md"><tt>xinetd</tt></a>, <a id="stunnel"
href="any/stunnel.md"><tt>stunnel</tt></a>, <a
href="macos/service.md"><tt>launchd</tt></a>, and <a
href="debian/service.md"><tt>systemd</tt></a>.</p>


<h3>SCGI</h3>

<p>The Fossil standalone server can also run <a href="any/scgi.md">in
SCGI mode</a> — <a href="/help/server"><tt>fossil server --scgi</tt></a>
— instead of <a href="any/none.md">HTTP mode</a>, which allows it to
respond to requests from web servers <a href="debian/nginx.md">such as
nginx</a> that don't support CGI. SCGI is a simpler protocol to proxy
................................................................................
than HTTP, since the HTTP doesn't have to be re-interpreted in terms of
the proxy's existing HTTP implementation, but it's more complex to set
up because you also have to set up an SCGI-to-HTTP proxy for it. It is
worth taking on this difficulty only when you need to integrate Fossil
into an existing web site already being served by an SCGI-capable web
server.</p>


<h3>CGI</h3>

<p>Most ordinary web servers can <a href="any/cgi.md">run Fossil as a
CGI script</a>. This method is known to work with Apache, <a
href="windows/cgi.md">IIS</a>, <tt>lighttpd</tt>, and <a
href="any/althttpd.md"><tt>althttpd</tt></a>.  The Fossil server
administrator places a <a href="/help?cmd=cgi">short CGI script</a> in
the web server's document hierarchy, and when a client requests the
appropriate URL, that script runs Fossil to generate the response.</p>

<p>Back when CGI was first created, this method was quite simple, but
because of all of the security barriers put up around CGI in most web
servers, it can actually be one of the most complicated methods to set
up, feature-for-feature. Reverse proxying (both HTTP and SCGI) is the
only more complicated method for serving Fossil, but you do get a lot of
additional power when doing that.</p>

<p>CGI is a good choice for merging Fossil into an existing web site,
particularly on hosts that have CGI set up for you already and won't let
you modify the web server configuration further. The Fossil <a
href="../selfhost.wiki">self-hosting repositories</a> are implemented
with CGI underneath <tt>althttpd</tt>.</p>



<h2 id="matrix">Setup Tutorials</h2>

<p>We've broken the configuration for each method out into a series of
sub-articles. Some of these are generic, while others depend on
particular operating systems or front-end software:</p>

<div id="tutpick" class="show"></div>

<!-- Define alternative to JS tutorial picker below.  When updating this
     table, update "matrix" in the JS code below to match! -->
<noscript id="tutmatrix">
<table style="margin-left: 6em;">
    <tr>
        <th class="host">⇩ OS / Method ⇨</th>
        <th class="fep">none</th>
        <th class="fep">inetd</th>
        <th class="fep">stunnel</th>
        <th class="fep">CGI</th>
        <th class="fep">SCGI</th>
        <th class="fep">althttpd</th>
        <th class="fep">proxy</th>
        <th class="fep">service</th>
................................................................................
  <li><a id="tls"      href="../ssl.wiki"      >Securing a Repository with TLS</a>
  <li><a id="ext"      href="../serverext.wiki">CGI Server Extensions</a>
  <li><a id="about"    href="../aboutcgi.wiki" >How CGI Works In Fossil</a>
  <li><a id="sync"     href="../sync.wiki"     >The Fossil Sync Protocol</a>
</ul>

</div>

<script type="text/javascript" nonce="$NONCE">
  (function() {
    // Define data structure analog to <table> above.  Matrix elements
    // can have one of these constant values or a string for a one-off
    // custom value.  Values outside the <table> above go at the end of
    // the rows we define here.
    const YES = 1;  // host-specific doc provided
    const IFA = 2;  // inherit doc from "any"
    const NO  = 3;  // method invalid or undocumented for this host OS
    const methods = [
      "none", "inetd", "stunnel", "CGI", "SCGI", "althttpd", "proxy", "service"
    ];
    const matrix =     {
               "any OS": [ YES, YES, YES, YES, YES, YES, NO,      NO  ],
     "Debian or Ubuntu": [ IFA, IFA, IFA, IFA, IFA, IFA, "nginx", YES ],
                "macOS": [ IFA, NO,  IFA, IFA, IFA, IFA, NO,      YES ],
              "Windows": [ YES, NO,  YES, YES, NO,  NO,  "IIS",   NO  ],
    }
    const osNames = Object.keys(matrix).sort((e) => {
      return e.toLowerCase()
    }).map((longName, i) => {
      var shortName = longName.toLowerCase().split(' ')[0];
      return [ longName, shortName ];
    });
    const osNameMap = Object.fromEntries(osNames);
    //console.log("OS name map: " + JSON.stringify(osNameMap));
    
    // Build initial tutorial chooser HTML, and insert it into doc where
    // the static HTML <table> matrix normally goes.
    var html = '<p><b>I want to run Fossil on</b> <select id="os">';
    for (var os of osNames) {
      const  longName = os[0];
      const shortName = os[1];
      html += '<option name="' + shortName + '">' + longName + '</option>';
    }
    html += '</select> <b>underneath</b> <select id="fep"></select>'
    html += '<a id="all">SHOW ALL</a></p>';
    const picker = document.querySelector('div#tutpick');
    picker.innerHTML = html;

    // Slide noscript <table> in place of JS tutorial chooser on
    // "SHOW ALL" click.
    document.querySelector('a#all').addEventListener('click', () => {
      picker.classList.remove('show');
      picker.innerHTML = document.querySelector('#tutmatrix').innerHTML;
      setTimeout(() => {
        // Let doc update to set new height, so transition happens.
        picker.classList.add('show');
      }, 10);
    });

    // Attach event handlers to drop-downs.  Have to wait until the page
    // loads, else we'll get null back from querySelector(('select#foo')).
    window.addEventListener('load', () => {
      // Set up the FEP choice drop-down on initial page load and
      // update it when the OS choice drop-down changes.
      const osSel  = document.querySelector('select#os');
      const fepSel = document.querySelector('select#fep');
      function osClickHandler() {
        var osLong  = osSel.value;
        var osShort = osNameMap[osLong];

        var html = '<option>---</option>';
        matrix[osLong].forEach((choice, i) => {
          var mu;
          if (typeof(choice) === 'string') {
            mu = choice;
            choice = YES;
          }
          else {
            mu = methods[i];
          }
          const ml = mu.toLowerCase();

          if (choice != NO) {
            if (choice == YES) {
              html += '<option value="' + osShort + '/' + ml + '.md">';
            }
            else if (choice == IFA) {
              html += '<option value="any/' + ml + '.md">';
            }
            html += mu + '</option>';
          }
        });

        fepSel.innerHTML = html;
      }
      osSel.addEventListener('change', osClickHandler);
      osClickHandler();   // load fepSel initial content

      // Go to selected document when user changes FEP drop-down
      fepSel.addEventListener('change', () => {
        var doc = fepSel.value;
        if (doc) location.href = doc;
        // else it's the --- entry, either because we just reloaded the
        // <option> set or because the user re-selected it.
      });
    });
  })();
</script>


|







 







>



<












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











<







 







<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








<
<
<



|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3
4
5
6
7
8
9
10
..
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
...
120
121
122
123
124
125
126

127
128
129
130
131
132
133
...
134
135
136
137
138
139
140


























141
142
143
144
145
146
147
148



149
150
151
152
153
154
155
156
157
158
159
...
232
233
234
235
236
237
238





































































































<div class='fossil-doc' data-title="How To Configure A Fossil Server">

<style type="text/css">
  p {
    margin-left: 4em;
    margin-right: 3em;
  }

  h2 {
    margin-left: 1em;
................................................................................


<h2 id="methods">Methods</h2>

<p>There are basically four ways to set up a Fossil server:</p>

<ol>
  <li><a id="cgi"        href="any/cgi.md">CGI</a>
  <li><a id="standalone" href="any/none.md">Stand-alone HTTP server</a>
  <li>Socket listener
  <li><a id="scgi"       href="any/scgi.md">SCGI</a>

</ol>

<p>All of these methods can serve either a single repository or a
directory containing repositories named "<tt>*.fossil</tt>".</p>

<p>You are not restricted to using a single method. The same Fossil
repository can be served using two or more of the above techniques at
the same time. These methods use clean, well-defined, standard
interfaces (CGI, SCGI, and HTTP) which allow you to easily migrate from
one method to another to accommodate changes in hosting providers or
administrator preferences.</p>

<h3>CGI</h3>

<p>Most ordinary web servers can <a href="any/cgi.md">run Fossil as a
CGI script</a>. This method is known to work with Apache, <a
href="windows/cgi.md">IIS</a>, <tt>lighttpd</tt>, and <a
href="any/althttpd.md"><tt>althttpd</tt></a>.  The Fossil server
administrator places a <a href="/help?cmd=cgi">short CGI script</a> in
the web server's document hierarchy, and when a client requests the
appropriate URL, that script runs Fossil to generate the response.</p>

<p>CGI is a good choice for merging Fossil into an existing web site,
particularly on hosts that have CGI set up for you already and won't let
you modify the web server configuration further. The Fossil <a
href="../selfhost.wiki">self-hosting repositories</a> are implemented
with CGI underneath <tt>althttpd</tt>.</p>

<h3>Stand-alone HTTP Server</h3>

<p>This is the <a href="any/none.md">easiest method</a>.
A stand-alone server uses the <a
href="/help?cmd=server"><tt>fossil server</tt></a> command to run a
process that listens for incoming HTTP requests on a socket and then
dispatches a copy of itself to deal with each incoming request. You can
expose Fossil directly to the clients in this way or you can interpose a
<a href="https://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a>
layer between the clients and Fossil.</p>


<h3>Socket Listener</h3>

<p>Only slightly more complicated is the socket listener method.
Instead of letting Fossil run in the background continuously to handle
HTTP requests from clients, you configure a socket listener daemon to
run a <a href="/help?cmd=http"><tt>fossil http</tt></a> command on each
................................................................................
hit.  This scheme is known to work with <a id="inetd"
href="any/inetd.md"><tt>inetd</tt></a>, <a id="xinetd"
href="any/xinetd.md"><tt>xinetd</tt></a>, <a id="stunnel"
href="any/stunnel.md"><tt>stunnel</tt></a>, <a
href="macos/service.md"><tt>launchd</tt></a>, and <a
href="debian/service.md"><tt>systemd</tt></a>.</p>


<h3>SCGI</h3>

<p>The Fossil standalone server can also run <a href="any/scgi.md">in
SCGI mode</a> — <a href="/help/server"><tt>fossil server --scgi</tt></a>
— instead of <a href="any/none.md">HTTP mode</a>, which allows it to
respond to requests from web servers <a href="debian/nginx.md">such as
nginx</a> that don't support CGI. SCGI is a simpler protocol to proxy
................................................................................
than HTTP, since the HTTP doesn't have to be re-interpreted in terms of
the proxy's existing HTTP implementation, but it's more complex to set
up because you also have to set up an SCGI-to-HTTP proxy for it. It is
worth taking on this difficulty only when you need to integrate Fossil
into an existing web site already being served by an SCGI-capable web
server.</p>



























<h2 id="matrix">Setup Tutorials</h2>

<p>We've broken the configuration for each method out into a series of
sub-articles. Some of these are generic, while others depend on
particular operating systems or front-end software:</p>

<div id="tutpick" class="show"></div>




<table style="margin-left: 6em;">
    <tr>
        <th class="host">⇩ OS / Method ⇨</th>
        <th class="fep">direct</th>
        <th class="fep">inetd</th>
        <th class="fep">stunnel</th>
        <th class="fep">CGI</th>
        <th class="fep">SCGI</th>
        <th class="fep">althttpd</th>
        <th class="fep">proxy</th>
        <th class="fep">service</th>
................................................................................
  <li><a id="tls"      href="../ssl.wiki"      >Securing a Repository with TLS</a>
  <li><a id="ext"      href="../serverext.wiki">CGI Server Extensions</a>
  <li><a id="about"    href="../aboutcgi.wiki" >How CGI Works In Fossil</a>
  <li><a id="sync"     href="../sync.wiki"     >The Fossil Sync Protocol</a>
</ul>

</div>