diff --git a/documentation/manuals/archiver.1.man b/documentation/manuals/archiver.1.man index 0b1e7b9..c404234 100644 --- a/documentation/manuals/archiver.1.man +++ b/documentation/manuals/archiver.1.man @@ -71,6 +71,8 @@ kawipiko -- blazingly fast static HTTP server \- kawipiko-archiver \-\-sources\-md5 (dump an \(ga\(gamd5sum\(ga\(ga of the sources) \-\-sources\-cpio (dump a \(ga\(gacpio.gz\(ga\(ga of the sources) + +\-\-sbom \-\-sbom\-text \-\-sbom\-json .ft P .fi .UNINDENT diff --git a/documentation/manuals/archiver.html b/documentation/manuals/archiver.html new file mode 100644 index 0000000..09a4d4e --- /dev/null +++ b/documentation/manuals/archiver.html @@ -0,0 +1,514 @@ + + + + + + +kawipiko -- blazingly fast static HTTP server + + + +
+

kawipiko -- blazingly fast static HTTP server

+

kawipiko-archiver

+ +
+>> kawipiko-archiver --help
+>> kawipiko-archiver --man
+
+
+--sources <path>
+
+--archive <path>
+
+--compress <gzip | zopfli | brotli | identity>
+--compress-level <number>
+--compress-cache <path>
+
+--exclude-index
+--exclude-strip
+--exclude-cache
+--include-etag
+
+--exclude-slash-redirects
+--include-folder-listing
+--exclude-paths-index
+
+--progress  --debug
+
+--version
+--help          (show this short help)
+--man           (show the full manual)
+
+--sources-md5   (dump an ``md5sum`` of the sources)
+--sources-cpio  (dump a ``cpio.gz`` of the sources)
+
+--sbom  --sbom-text  --sbom-json
+
+
+
+

Flags

+

--sources

+
+The path to the source folder that is the root of the static website content.
+

--archive

+
+The path to the target CDB file that contains the archived static content.
+

--compress, and --compress-level

+
+

Each individual file (and consequently of the corresponding HTTP response body) is compressed with either gzip, zopfli or brotli; by default (or alternatively with identity) no compression is used.

+

Even if compression is explicitly requested, if the compression ratio is bellow a certain threshold (depending on the uncompressed size), the file is stored without any compression. +(It's senseless to force the client to spend time and decompress the response body if that time is not recovered during network transmission.)

+

The compression level can be chosen, the value depending on the algorithm:

+
    +
  • gzip -- -1 for algorithm default, -2 for Huffman only, 0 to 9 for fast to slow;
  • +
  • zopfli -- -1 for algorithm default, 0 to 30 iterations for fast to slow;
  • +
  • brotli -- -1 for algorithm default, 0 to 9 for fast to slow, -2 for extreme;
  • +
  • (by "algorithm default", it is meant "what that algorithm considers the recommended default compression level";)
  • +
  • kawipiko by default uses the maximum compression level for each algorithm; (i.e. 9 for gzip, 30 for zopfli, and -2 for brotli;)
  • +
+
+

--sources-cache <path>, and --compress-cache <path>

+
+

At the given path a single file is created (that is an BBolt database), that will be used to cache the following information:

+
    +
  • in case of --sources-cache, the fingerprint of each file contents is stored, so that if the file was not changed, re-reading it shouldn't be attempted unless it is absolutely necessary; also if the file is small enough, its contents is stored in this database (deduplicated by its fingerprint);
  • +
  • in case of --compress-cache the compression outcome of each file contents is stored (deduplicated by its fingerprint), so that compression is done only once over multiple runs;
  • +
+

Each of these caches can be safely reused between multiple related archives, especially when they have many files in common. +Each of these caches can be independently used (or shared).

+

Using these caches allows one to very quickly rebuild an archive when only a couple of files have been changed, without even touching the file-system for the unchanged ones.

+
+

--exclude-index

+
+Disables using _index.* and index.* files (where .* is one of .html, .htm, .xhtml, .xht, .txt, .json, and .xml) to respond to a request whose URL path ends in / (corresponding to the folder wherein _index.* or index.* file is located). +(This can be used to implement "slash" blog style URL's like /blog/whatever/ which maps to /blog/whatever/index.html.)
+

--exclude-strip

+
+Disables using a file with the suffix .html, .htm, .xhtml, .xht, and .txt to respond to a request whose URL does not exactly match an existing file. +(This can be used to implement "suffix-less" blog style URL's like /blog/whatever which maps to /blog/whatever.html.)
+

--exclude-cache

+
+Disables adding an Cache-Control: public, immutable, max-age=3600 header that forces the browser (and other intermediary proxies) to cache the response for an hour (the public and max-age=3600 arguments), and furthermore not request it even on reloads (the immutable argument).
+

--include-etag

+
+

Enables adding an ETag response header that contains the SHA256 of the response body.

+

By not including the ETag header (i.e. the default), and because identical headers are stored only one, if one has many files of the same type (that in turn without ETag generates the same headers), this can lead to significant reduction in stored headers blocks, including reducing RAM usage. +(At this moment it does not support HTTP conditional requests, i.e. the If-None-Match, If-Modified-Since and their counterparts; however this ETag header might be used in conjuction with HEAD requests to see if the resource has changed.)

+
+

--exclude-slash-redirects

+
+Disables adding redirects to/from paths with/without / +(For example, by default, if /file exists, then there is also a /file/ redirect towards /file; and vice-versa from /folder towards /folder/.)
+

--include-folder-listing

+
+Enables the creation of an internal list of folders.
+

--exclude-paths-index

+
+Disables the creation of an internal list of references that can be used in conjunction with the --index-all flag of the kawipiko-server.
+

--progress

+
+Enables periodic reporting of various metrics.
+

--debug

+
+Enables verbose logging. +It will log various information about the archived files (including compression statistics).
+
+
+

Ignored files

+ +
+
+

Wildcard files

+

By placing a file whose name matches _wildcard.* (i.e. with the prefix _wildcard. and any other suffix), it will be used to respond to any request whose URL fails to find a "better" match.

+

These wildcard files respect the folder hierarchy, in that wildcard files in (direct or transitive) subfolders override the wildcard file in their parents (direct or transitive).

+

In addition to _wildcard.*, there is also support for _200.html (or just 200.html), plus _404.html (or just 404.html).

+
+
+

Redirect files

+

By placing a file whose name is _redirects (or _redirects.txt), it instructs the archiver to create redirect responses.

+

The syntax is quite simple:

+
+# This is a comment.
+
+# NOTE:  Absolute paths are allowed only at the top of the sources folder.
+/some-path     https://example.com/     301
+
+# NOTE:  Relative paths are always, and are reinterpreted as relative to the containing folder.
+./some-path    https://example.com/     302
+
+# NOTE:  Redirects only for a specific domain.  (The protocol is irelevant.)
+#        (Allowed only at the top of the sources folder.)
+://example.com/some-path         https://example.com/    303
+http://example.com/some-path     https://example.com/    307
+https://example.com/some-path    https://example.com/    308
+
+
+ +
+ + diff --git a/documentation/manuals/archiver.rst b/documentation/manuals/archiver.rst index a8a6b38..1d86fdc 100644 --- a/documentation/manuals/archiver.rst +++ b/documentation/manuals/archiver.rst @@ -44,6 +44,8 @@ kawipiko -- blazingly fast static HTTP server --sources-md5 (dump an ``md5sum`` of the sources) --sources-cpio (dump a ``cpio.gz`` of the sources) + --sbom --sbom-text --sbom-json + diff --git a/documentation/manuals/archiver.txt b/documentation/manuals/archiver.txt index dccb035..5f47313 100644 --- a/documentation/manuals/archiver.txt +++ b/documentation/manuals/archiver.txt @@ -34,6 +34,8 @@ NAME --sources-md5 (dump an ``md5sum`` of the sources) --sources-cpio (dump a ``cpio.gz`` of the sources) + --sbom --sbom-text --sbom-json + ---- diff --git a/documentation/manuals/server.1.man b/documentation/manuals/server.1.man index b54dd11..eaeff8e 100644 --- a/documentation/manuals/server.1.man +++ b/documentation/manuals/server.1.man @@ -98,6 +98,8 @@ kawipiko -- blazingly fast static HTTP server \- kawipiko-server \-\-sources\-md5 (dump an \(gamd5sum\(ga of the sources) \-\-sources\-cpio (dump a \(gacpio.gz\(ga of the sources) + +\-\-sbom \-\-sbom\-text \-\-sbom\-json .ft P .fi .UNINDENT @@ -228,13 +230,22 @@ Disables the virtual\-hosts feature by ignoring the \fIHost\fP header. Disables serving a few special pages internal to the server like: .INDENT 0.0 .INDENT 3.5 -/__/about -/__/version +.sp +.nf +.ft C /__/heartbeat -/__/sources.md5 -/__/sources.cpio -/__/banners/errors/403 -/__/banners/errors/... +/__/kawipiko/about +/__/kawipiko/version +/__/kawipiko/manual.txt +/__/kawipiko/manual.html +/__/kawipiko/sbom.txt +/__/kawipiko/sbom.json +/__/kawipiko/sources.md5 +/__/kawipiko/sources.cpio +/__/kawipiko/banners/errors/403 +/__/kawipiko/banners/errors/... +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT diff --git a/documentation/manuals/server.html b/documentation/manuals/server.html new file mode 100644 index 0000000..4c92f2d --- /dev/null +++ b/documentation/manuals/server.html @@ -0,0 +1,555 @@ + + + + + + +kawipiko -- blazingly fast static HTTP server + + + +
+

kawipiko -- blazingly fast static HTTP server

+

kawipiko-server

+ +
+>> kawipiko-server --help
+>> kawipiko-server --man
+
+
+--archive <path>
+--archive-inmem           (memory-loaded archive file)
+--archive-mmap            (memory-mapped archive file)
+--archive-preload         (preload archive in OS cache)
+
+--bind <ip>:<port>        (HTTP, only HTTP/1.1, FastHTTP)
+--bind-2 <ip>:<port>      (HTTP, only HTTP/1.1, Go net/http)
+--bind-tls <ip>:<port>    (HTTPS, only HTTP/1.1, FastHTTP)
+--bind-tls-2 <ip>:<port>  (HTTPS, with HTTP/2, Go net/http)
+--bind-quic <ip>:<port>   (HTTPS, with HTTP/3)
+
+--http1-disable
+--http2-disable
+--http3-alt-svc <ip>:<port>
+
+--tls-bundle <path>       (TLS certificate bundle)
+--tls-public <path>       (TLS certificate public)
+--tls-private <path>      (TLS certificate private)
+--tls-self-rsa            (use self-signed RSA)
+--tls-self-ed25519        (use self-signed Ed25519)
+
+--processes <count>       (of slave processes)
+--threads <count>         (of threads per process)
+--index-all
+--index-paths
+--index-data-meta
+--index-data-content
+
+--hosts-disable           (ignore `Host` header)
+
+--special-pages-disable
+--security-headers-disable
+--security-headers-tls
+
+--limit-memory <MiB>
+--timeout-disable
+
+--report  --quiet  --debug
+
+--dummy
+--dummy-empty
+--dummy-delay <duration>
+
+--profile-cpu <path>
+--profile-mem <path>
+
+--version
+--help          (show this short help)
+--man           (show the full manual)
+
+--sources-md5   (dump an `md5sum` of the sources)
+--sources-cpio  (dump a `cpio.gz` of the sources)
+
+--sbom  --sbom-text  --sbom-json
+
+
+
+

Flags

+

--bind <ip:port>, --bind-tls <ip:port>, --bind-2 <ip:port>, --bind-tls-2 <ip:port>, and --bind-quic <ip:port>

+
+

The IP and port to listen for requests with:

+
    +
  • (insecure) HTTP/1.1 for --bind, leveraging fasthttp library;
  • +
  • (secure) HTTP/1.1 over TLS for --bind-tls, leveraging fasthttp library;
  • +
  • (insecure) HTTP/1.1 for --bind-2, leveraging Go's net/http library; (not as performant as the fasthttp powered endpoint;)
  • +
  • (secure) H2 or HTTP/1.1 over TLS for --bind-tls-2, leveraging Go's net/http; (not as performant as the fasthttp powered endpoint;)
  • +
  • (secure) H3 over QUIC for --bind-quic, leveraging github.com/lucas-clemente/quic-go library; (given that H3 is still a new protocol, this must be used with caution; also one should use the --http3-alt-svc <ip:port>;)
  • +
  • if one uses just --bind-tls (without --bind-tls-2, and without --http2-disabled), then the TLS endpoint is split between fasthttp for HTTP/1.1 and Go's net/http for H2;
  • +
+
+

--tls-bundle <path>, --tls-public <path>, and --tls-private <path> (optional)

+
+

If TLS is enabled, these options allows one to specify the certificate to use, either as a single file (a bundle) or separate files (the actual public certificate and the private key).

+

If one doesn't specify any of these options, an embedded self-signed certificate will be used. In such case, one can choose between RSA (the --tls-self-rsa flag) or Ed25519 (the --tls-self-ed25519 flag);

+
+

--http1-disable, --http2-disable

+
+Disables that particular protocol. +(It can be used only with --bind-tls-2, given that fasthttp only supports HTTP/1.)
+

--processes <count> and --threads <count>

+
+

The number of processes and threads per each process to start. (Given Go's concurrency model, the threads count is somewhat a soft limit, hinting to the runtime the desired parallelism level.)

+

It is highly recommended to use one process and as many threads as there are cores.

+

Depending on the use-case, one can use multiple processes each with a single thread; this would reduce goroutine contention if it causes problems. +(However note that if using --archive-inmem, then each process will allocate its own copy of the database in RAM; in such cases it is highly recommended to use --archive-mmap.)

+
+

--archive <path>

+
+The path of the CDB file that contains the archived static content. +(It can be created with the kawipiko-archiver tool.)
+

--archive-inmem

+
+Reads the CDB file in RAM, and thus all requests are served from RAM without touching the file-system. +(The memory impact is equal to the size of the CDB archive. This can be used if enough RAM is available to avoid swapping.)
+

--archive-mmap

+
+(recommended) The CDB file is memory mapped, thus reading its data uses the kernel's file-system cache, as opposed to issuing read syscalls.
+

--archive-preload

+
+Before starting to serve requests, read the CDB file so that its data is buffered in the kernel's file-system cache. (This option can be used with or without --archive-mmap.)
+

--index-all, --index-paths, --index-data-meta, and --index-data-content

+
+

In order to serve a request kawipiko does the following:

+
    +
  • given the request's path, it is used to locate the corresponding resource's metadata (i.e. response headers) and data (i.e. response body) references; +by using --index-paths a RAM-based lookup table is created to eliminate a CDB read operation for this purpose; (the memory impact is proportional to the size of all resource paths combined; given that the number of resources is acceptable, say up to a couple hundred thousand, one could safely use this option;)
  • +
  • based on the resource's metadata reference, the actual metadata (i.e. the response headers) is located; +by using --index-data-meta a RAM-based lookup table is created to eliminate a CDB read operation for this purpose; (the memory impact is proportional to the size of all resource metadata blocks combined; given that the metadata blocks are deduplicated, one could safely use this option; if one also uses --archive-mmap or --archive-inmem, then the memory impact is only proportional to the number of resource metadata blocks;)
  • +
  • based on the resource's data reference, the actual data (i.e. the response body) is located; +by using --index-data-content a RAM-based lookup table is created to eliminate a CDB operation operation for this purpose; (the memory impact is proportional to the size of all resource data blocks combined; one can use this option to obtain the best performance; if one also uses --archive-mmap or --archive-inmem, then the memory impact is only proportional to the number of resource data blocks;)
  • +
  • --index-all enables all the options above;
  • +
  • (depending on the use-case) it is recommended to use --index-paths; if --exclude-etag was used during archival, one can also use --index-data-meta;
  • +
  • it is recommended to use either --archive-mmap or --archive-inmem, else (especially if data is indexed) the resulting effect is that of loading everything in RAM;
  • +
+
+

--hosts-disable

+
+Disables the virtual-hosts feature by ignoring the Host header.
+

--special-pages-disable

+
+

Disables serving a few special pages internal to the server like:

+
+/__/heartbeat
+/__/kawipiko/about
+/__/kawipiko/version
+/__/kawipiko/manual.txt
+/__/kawipiko/manual.html
+/__/kawipiko/sbom.txt
+/__/kawipiko/sbom.json
+/__/kawipiko/sources.md5
+/__/kawipiko/sources.cpio
+/__/kawipiko/banners/errors/403
+/__/kawipiko/banners/errors/...
+
+
+

--security-headers-disable

+
+

Disables adding a few security related headers:

+
+Referrer-Policy: strict-origin-when-cross-origin
+X-Content-Type-Options: nosniff
+X-XSS-Protection: 1; mode=block
+X-Frame-Options: sameorigin
+
+
+

--security-headers-tls

+
+

Enables adding the following TLS related headers to the response:

+
+Strict-Transport-Security: max-age=31536000
+Content-Security-Policy: upgrade-insecure-requests
+
+

These instruct the browser to always use HTTPS for the served domain. +(Useful even without HTTPS, when used behind a TLS terminator, load-balancer or proxy that do support HTTPS.)

+
+

--report

+
+Enables periodic reporting of various metrics. +Also enables reporting a selection of metrics if certain thresholds are matched (which most likely is a sign of high-load).
+

--quiet

+
+Disables most logging messages.
+

--debug

+
+Enables all logging messages.
+

--dummy, --dummy-empty

+
+

It starts the server in a "dummy" mode, ignoring all archive related arguments and always responding with hello world!\n (unless --dummy-empty was used) and without additional headers except the HTTP status line and Content-Length.

+

This argument can be used to benchmark the raw performance of the underlying fasthttp, Go's net/http, or QUIC performance; this is the upper limit of the achievable performance given the underlying technologies. +(From my own benchmarks kawipiko's adds only about ~15% overhead when actually serving the hello-world.cdb archive.)

+
+

--dummy-delay <duration>

+
+

Enables delaying each response with a certain amount (for example 1s, 1ms, etc.)

+

It can be used to simulate the real-world network latencies, perhaps to see how a site with many resources loads in various conditions. +(For example, see an experiment I made with an image made out of 1425 tiles.)

+
+

--profile-cpu <path>, and --profile-mem <path>

+
+Enables CPU and memory profiling using Go's profiling infrastructure.
+
+
+ + diff --git a/documentation/manuals/server.rst b/documentation/manuals/server.rst index 5235584..b1a678e 100644 --- a/documentation/manuals/server.rst +++ b/documentation/manuals/server.rst @@ -70,6 +70,8 @@ kawipiko -- blazingly fast static HTTP server --sources-md5 (dump an `md5sum` of the sources) --sources-cpio (dump a `cpio.gz` of the sources) + --sbom --sbom-text --sbom-json + @@ -157,15 +159,19 @@ Flags ``--special-pages-disable`` - Disables serving a few special pages internal to the server like: + Disables serving a few special pages internal to the server like: :: - /__/about - /__/version /__/heartbeat - /__/sources.md5 - /__/sources.cpio - /__/banners/errors/403 - /__/banners/errors/... + /__/kawipiko/about + /__/kawipiko/version + /__/kawipiko/manual.txt + /__/kawipiko/manual.html + /__/kawipiko/sbom.txt + /__/kawipiko/sbom.json + /__/kawipiko/sources.md5 + /__/kawipiko/sources.cpio + /__/kawipiko/banners/errors/403 + /__/kawipiko/banners/errors/... ``--security-headers-disable`` diff --git a/documentation/manuals/server.txt b/documentation/manuals/server.txt index a0fbb3f..2437089 100644 --- a/documentation/manuals/server.txt +++ b/documentation/manuals/server.txt @@ -61,6 +61,8 @@ NAME --sources-md5 (dump an `md5sum` of the sources) --sources-cpio (dump a `cpio.gz` of the sources) + --sbom --sbom-text --sbom-json + ---- @@ -187,8 +189,18 @@ FLAGS --special-pages-disable Disables serving a few special pages internal to the server like: - /__/about /__/version /__/heartbeat /__/sources.md5 - /__/sources.cpio /__/banners/errors/403 /__/banners/errors/... + + /__/heartbeat + /__/kawipiko/about + /__/kawipiko/version + /__/kawipiko/manual.txt + /__/kawipiko/manual.html + /__/kawipiko/sbom.txt + /__/kawipiko/sbom.json + /__/kawipiko/sources.md5 + /__/kawipiko/sources.cpio + /__/kawipiko/banners/errors/403 + /__/kawipiko/banners/errors/... --security-headers-disable Disables adding a few security related headers: diff --git a/scripts/documentation.z-run b/scripts/documentation.z-run index 896a537..6e595b2 100644 --- a/scripts/documentation.z-run +++ b/scripts/documentation.z-run @@ -38,7 +38,17 @@ printf -- '[ii] rendering `%s`...\n' "${_manual}" >&2 - rst2man --strict \ + rst2html --strict --no-generator --embed-stylesheet \ + < "./documentation/manuals/${_manual}.rst" \ + >| "./documentation/manuals/${_manual}.html.tmp" \ + # + + mv -T -- \ + "./documentation/manuals/${_manual}.html.tmp" \ + "./documentation/manuals/${_manual}.html" \ + # + + rst2man --strict --no-generator \ < "./documentation/manuals/${_manual}.rst" \ | sed -r \ -e 's#^\.TH .*#.TH "KAWIPIKO\-'"${_manual^^}"'" "1" "'"${_date}"'" "volution.ro" "kawipiko"#' \ diff --git a/scripts/sources.z-run b/scripts/sources.z-run index 753e87f..1f2a37c 100644 --- a/scripts/sources.z-run +++ b/scripts/sources.z-run @@ -57,9 +57,17 @@ cp -T -- ./documentation/manuals/server.txt ./sources/cmd/server/manual.txt fi + if ! cmp -s -- ./documentation/manuals/server.html ./sources/cmd/server/manual.html ; then + cp -T -- ./documentation/manuals/server.html ./sources/cmd/server/manual.html + fi + if ! cmp -s -- ./documentation/manuals/archiver.txt ./sources/cmd/archiver/manual.txt ; then cp -T -- ./documentation/manuals/archiver.txt ./sources/cmd/archiver/manual.txt fi + + if ! cmp -s -- ./documentation/manuals/server.html ./sources/cmd/server/manual.html ; then + cp -T -- ./documentation/manuals/server.html ./sources/cmd/server/manual.html + fi !! diff --git a/sources/cmd/archiver/archiver.go b/sources/cmd/archiver/archiver.go index 85ca202..ac6e451 100644 --- a/sources/cmd/archiver/archiver.go +++ b/sources/cmd/archiver/archiver.go @@ -1269,6 +1269,14 @@ func Main () () { version.Main ("kawipiko-archiver", "sources.cpio") return + case "--sbom-text", "--sbom-txt", "--sbom" : + version.Main ("kawipiko-archiver", "sbom.txt") + return + + case "--sbom-json" : + version.Main ("kawipiko-archiver", "sbom.json") + return + case "--help", "-h" : if _, _error := os.Stdout.WriteString (usageText); _error == nil { return diff --git a/sources/cmd/archiver/manual.html b/sources/cmd/archiver/manual.html new file mode 100644 index 0000000..e69de29 diff --git a/sources/cmd/archiver/manual.txt b/sources/cmd/archiver/manual.txt index dccb035..5f47313 100644 --- a/sources/cmd/archiver/manual.txt +++ b/sources/cmd/archiver/manual.txt @@ -34,6 +34,8 @@ NAME --sources-md5 (dump an ``md5sum`` of the sources) --sources-cpio (dump a ``cpio.gz`` of the sources) + --sbom --sbom-text --sbom-json + ---- diff --git a/sources/cmd/archiver/usage.txt b/sources/cmd/archiver/usage.txt index a490a84..a25159b 100644 --- a/sources/cmd/archiver/usage.txt +++ b/sources/cmd/archiver/usage.txt @@ -22,8 +22,10 @@ --progress --debug - --help (show this short help) - --man (show the full manual) + --version + --help (show this short help) + --man (show the full manual) + --sources-md5 --sources-cpio --sbom --sbom-json ** supported archive version: @{SCHEMA} diff --git a/sources/cmd/server/manual.html b/sources/cmd/server/manual.html new file mode 100644 index 0000000..4c92f2d --- /dev/null +++ b/sources/cmd/server/manual.html @@ -0,0 +1,555 @@ + + + + + + +kawipiko -- blazingly fast static HTTP server + + + +
+

kawipiko -- blazingly fast static HTTP server

+

kawipiko-server

+ +
+>> kawipiko-server --help
+>> kawipiko-server --man
+
+
+--archive <path>
+--archive-inmem           (memory-loaded archive file)
+--archive-mmap            (memory-mapped archive file)
+--archive-preload         (preload archive in OS cache)
+
+--bind <ip>:<port>        (HTTP, only HTTP/1.1, FastHTTP)
+--bind-2 <ip>:<port>      (HTTP, only HTTP/1.1, Go net/http)
+--bind-tls <ip>:<port>    (HTTPS, only HTTP/1.1, FastHTTP)
+--bind-tls-2 <ip>:<port>  (HTTPS, with HTTP/2, Go net/http)
+--bind-quic <ip>:<port>   (HTTPS, with HTTP/3)
+
+--http1-disable
+--http2-disable
+--http3-alt-svc <ip>:<port>
+
+--tls-bundle <path>       (TLS certificate bundle)
+--tls-public <path>       (TLS certificate public)
+--tls-private <path>      (TLS certificate private)
+--tls-self-rsa            (use self-signed RSA)
+--tls-self-ed25519        (use self-signed Ed25519)
+
+--processes <count>       (of slave processes)
+--threads <count>         (of threads per process)
+--index-all
+--index-paths
+--index-data-meta
+--index-data-content
+
+--hosts-disable           (ignore `Host` header)
+
+--special-pages-disable
+--security-headers-disable
+--security-headers-tls
+
+--limit-memory <MiB>
+--timeout-disable
+
+--report  --quiet  --debug
+
+--dummy
+--dummy-empty
+--dummy-delay <duration>
+
+--profile-cpu <path>
+--profile-mem <path>
+
+--version
+--help          (show this short help)
+--man           (show the full manual)
+
+--sources-md5   (dump an `md5sum` of the sources)
+--sources-cpio  (dump a `cpio.gz` of the sources)
+
+--sbom  --sbom-text  --sbom-json
+
+
+
+

Flags

+

--bind <ip:port>, --bind-tls <ip:port>, --bind-2 <ip:port>, --bind-tls-2 <ip:port>, and --bind-quic <ip:port>

+
+

The IP and port to listen for requests with:

+
    +
  • (insecure) HTTP/1.1 for --bind, leveraging fasthttp library;
  • +
  • (secure) HTTP/1.1 over TLS for --bind-tls, leveraging fasthttp library;
  • +
  • (insecure) HTTP/1.1 for --bind-2, leveraging Go's net/http library; (not as performant as the fasthttp powered endpoint;)
  • +
  • (secure) H2 or HTTP/1.1 over TLS for --bind-tls-2, leveraging Go's net/http; (not as performant as the fasthttp powered endpoint;)
  • +
  • (secure) H3 over QUIC for --bind-quic, leveraging github.com/lucas-clemente/quic-go library; (given that H3 is still a new protocol, this must be used with caution; also one should use the --http3-alt-svc <ip:port>;)
  • +
  • if one uses just --bind-tls (without --bind-tls-2, and without --http2-disabled), then the TLS endpoint is split between fasthttp for HTTP/1.1 and Go's net/http for H2;
  • +
+
+

--tls-bundle <path>, --tls-public <path>, and --tls-private <path> (optional)

+
+

If TLS is enabled, these options allows one to specify the certificate to use, either as a single file (a bundle) or separate files (the actual public certificate and the private key).

+

If one doesn't specify any of these options, an embedded self-signed certificate will be used. In such case, one can choose between RSA (the --tls-self-rsa flag) or Ed25519 (the --tls-self-ed25519 flag);

+
+

--http1-disable, --http2-disable

+
+Disables that particular protocol. +(It can be used only with --bind-tls-2, given that fasthttp only supports HTTP/1.)
+

--processes <count> and --threads <count>

+
+

The number of processes and threads per each process to start. (Given Go's concurrency model, the threads count is somewhat a soft limit, hinting to the runtime the desired parallelism level.)

+

It is highly recommended to use one process and as many threads as there are cores.

+

Depending on the use-case, one can use multiple processes each with a single thread; this would reduce goroutine contention if it causes problems. +(However note that if using --archive-inmem, then each process will allocate its own copy of the database in RAM; in such cases it is highly recommended to use --archive-mmap.)

+
+

--archive <path>

+
+The path of the CDB file that contains the archived static content. +(It can be created with the kawipiko-archiver tool.)
+

--archive-inmem

+
+Reads the CDB file in RAM, and thus all requests are served from RAM without touching the file-system. +(The memory impact is equal to the size of the CDB archive. This can be used if enough RAM is available to avoid swapping.)
+

--archive-mmap

+
+(recommended) The CDB file is memory mapped, thus reading its data uses the kernel's file-system cache, as opposed to issuing read syscalls.
+

--archive-preload

+
+Before starting to serve requests, read the CDB file so that its data is buffered in the kernel's file-system cache. (This option can be used with or without --archive-mmap.)
+

--index-all, --index-paths, --index-data-meta, and --index-data-content

+
+

In order to serve a request kawipiko does the following:

+
    +
  • given the request's path, it is used to locate the corresponding resource's metadata (i.e. response headers) and data (i.e. response body) references; +by using --index-paths a RAM-based lookup table is created to eliminate a CDB read operation for this purpose; (the memory impact is proportional to the size of all resource paths combined; given that the number of resources is acceptable, say up to a couple hundred thousand, one could safely use this option;)
  • +
  • based on the resource's metadata reference, the actual metadata (i.e. the response headers) is located; +by using --index-data-meta a RAM-based lookup table is created to eliminate a CDB read operation for this purpose; (the memory impact is proportional to the size of all resource metadata blocks combined; given that the metadata blocks are deduplicated, one could safely use this option; if one also uses --archive-mmap or --archive-inmem, then the memory impact is only proportional to the number of resource metadata blocks;)
  • +
  • based on the resource's data reference, the actual data (i.e. the response body) is located; +by using --index-data-content a RAM-based lookup table is created to eliminate a CDB operation operation for this purpose; (the memory impact is proportional to the size of all resource data blocks combined; one can use this option to obtain the best performance; if one also uses --archive-mmap or --archive-inmem, then the memory impact is only proportional to the number of resource data blocks;)
  • +
  • --index-all enables all the options above;
  • +
  • (depending on the use-case) it is recommended to use --index-paths; if --exclude-etag was used during archival, one can also use --index-data-meta;
  • +
  • it is recommended to use either --archive-mmap or --archive-inmem, else (especially if data is indexed) the resulting effect is that of loading everything in RAM;
  • +
+
+

--hosts-disable

+
+Disables the virtual-hosts feature by ignoring the Host header.
+

--special-pages-disable

+
+

Disables serving a few special pages internal to the server like:

+
+/__/heartbeat
+/__/kawipiko/about
+/__/kawipiko/version
+/__/kawipiko/manual.txt
+/__/kawipiko/manual.html
+/__/kawipiko/sbom.txt
+/__/kawipiko/sbom.json
+/__/kawipiko/sources.md5
+/__/kawipiko/sources.cpio
+/__/kawipiko/banners/errors/403
+/__/kawipiko/banners/errors/...
+
+
+

--security-headers-disable

+
+

Disables adding a few security related headers:

+
+Referrer-Policy: strict-origin-when-cross-origin
+X-Content-Type-Options: nosniff
+X-XSS-Protection: 1; mode=block
+X-Frame-Options: sameorigin
+
+
+

--security-headers-tls

+
+

Enables adding the following TLS related headers to the response:

+
+Strict-Transport-Security: max-age=31536000
+Content-Security-Policy: upgrade-insecure-requests
+
+

These instruct the browser to always use HTTPS for the served domain. +(Useful even without HTTPS, when used behind a TLS terminator, load-balancer or proxy that do support HTTPS.)

+
+

--report

+
+Enables periodic reporting of various metrics. +Also enables reporting a selection of metrics if certain thresholds are matched (which most likely is a sign of high-load).
+

--quiet

+
+Disables most logging messages.
+

--debug

+
+Enables all logging messages.
+

--dummy, --dummy-empty

+
+

It starts the server in a "dummy" mode, ignoring all archive related arguments and always responding with hello world!\n (unless --dummy-empty was used) and without additional headers except the HTTP status line and Content-Length.

+

This argument can be used to benchmark the raw performance of the underlying fasthttp, Go's net/http, or QUIC performance; this is the upper limit of the achievable performance given the underlying technologies. +(From my own benchmarks kawipiko's adds only about ~15% overhead when actually serving the hello-world.cdb archive.)

+
+

--dummy-delay <duration>

+
+

Enables delaying each response with a certain amount (for example 1s, 1ms, etc.)

+

It can be used to simulate the real-world network latencies, perhaps to see how a site with many resources loads in various conditions. +(For example, see an experiment I made with an image made out of 1425 tiles.)

+
+

--profile-cpu <path>, and --profile-mem <path>

+
+Enables CPU and memory profiling using Go's profiling infrastructure.
+
+
+ + diff --git a/sources/cmd/server/manual.txt b/sources/cmd/server/manual.txt index a0fbb3f..2437089 100644 --- a/sources/cmd/server/manual.txt +++ b/sources/cmd/server/manual.txt @@ -61,6 +61,8 @@ NAME --sources-md5 (dump an `md5sum` of the sources) --sources-cpio (dump a `cpio.gz` of the sources) + --sbom --sbom-text --sbom-json + ---- @@ -187,8 +189,18 @@ FLAGS --special-pages-disable Disables serving a few special pages internal to the server like: - /__/about /__/version /__/heartbeat /__/sources.md5 - /__/sources.cpio /__/banners/errors/403 /__/banners/errors/... + + /__/heartbeat + /__/kawipiko/about + /__/kawipiko/version + /__/kawipiko/manual.txt + /__/kawipiko/manual.html + /__/kawipiko/sbom.txt + /__/kawipiko/sbom.json + /__/kawipiko/sources.md5 + /__/kawipiko/sources.cpio + /__/kawipiko/banners/errors/403 + /__/kawipiko/banners/errors/... --security-headers-disable Disables adding a few security related headers: diff --git a/sources/cmd/server/server.go b/sources/cmd/server/server.go index a59588b..efc7e43 100644 --- a/sources/cmd/server/server.go +++ b/sources/cmd/server/server.go @@ -138,20 +138,32 @@ func (_server *server) ServeUnwrapped (_context *fasthttp.RequestCtx) () { if bytes.Equal (_path, StringToBytes ("/__/heartbeat")) || bytes.HasPrefix (_path, StringToBytes ("/__/heartbeat/")) { _server.ServeStatic (_context, http.StatusOK, HeartbeatDataOk, HeartbeatContentType, HeartbeatContentEncoding, false) return - } else if bytes.Equal (_path, StringToBytes ("/__/about")) || bytes.Equal (_path, StringToBytes ("/__/about/")) { + } else if bytes.Equal (_path, StringToBytes ("/__/kawipiko/about")) || bytes.Equal (_path, StringToBytes ("/__/kawipiko/about/")) { _server.ServeStatic (_context, http.StatusOK, AboutBannerData, AboutBannerContentType, AboutBannerContentEncoding, true) return - } else if bytes.Equal (_path, StringToBytes ("/__/version")) || bytes.Equal (_path, StringToBytes ("/__/version/")) { + } else if bytes.Equal (_path, StringToBytes ("/__/kawipiko/version")) || bytes.Equal (_path, StringToBytes ("/__/kawipiko/version/")) { _server.ServeSpecial (_context, "version", true) return - } else if bytes.Equal (_path, StringToBytes ("/__/sources.md5")) { + } else if bytes.Equal (_path, StringToBytes ("/__/kawipiko/manual.txt")) { + _server.ServeSpecial (_context, "manual.txt", true) + return + } else if bytes.Equal (_path, StringToBytes ("/__/kawipiko/manual.html")) { + _server.ServeSpecial (_context, "manual.html", true) + return + } else if bytes.Equal (_path, StringToBytes ("/__/kawipiko/sources.md5")) { _server.ServeSpecial (_context, "sources.md5", true) return - } else if bytes.Equal (_path, StringToBytes ("/__/sources.cpio")) { + } else if bytes.Equal (_path, StringToBytes ("/__/kawipiko/sources.cpio")) { _server.ServeSpecial (_context, "sources.cpio", true) return - } else if bytes.HasPrefix (_path, StringToBytes ("/__/banners/errors/")) { - _code := _path[len ("/__/banners/errors/") :] + } else if bytes.Equal (_path, StringToBytes ("/__/kawipiko/sbom.txt")) { + _server.ServeSpecial (_context, "sbom.txt", true) + return + } else if bytes.Equal (_path, StringToBytes ("/__/kawipiko/sbom.json")) { + _server.ServeSpecial (_context, "sbom.json", true) + return + } else if bytes.HasPrefix (_path, StringToBytes ("/__/kawipiko/banners/errors/")) { + _code := _path[len ("/__/kawipiko/banners/errors/") :] if _code, _error := strconv.Atoi (BytesToString (*NoEscapeBytes (&_code))); _error == nil { _banner, _bannerFound := ErrorBannersData[uint (_code)] if (_code > 0) && _bannerFound { @@ -522,6 +534,16 @@ func (_server *server) ServeSpecial (_context *fasthttp.RequestCtx, _special str _contentType = MimeTypeText _contentEncoding = "identity" + case "manual.txt" : + _data = StringToBytes (manualText) + _contentType = MimeTypeText + _contentEncoding = "identity" + + case "manual.html" : + _data = StringToBytes (manualHtml) + _contentType = MimeTypeHtml + _contentEncoding = "identity" + case "sources.md5" : _data = StringToBytes (embedded.BuildSourcesMd5) _contentType = MimeTypeText @@ -532,6 +554,16 @@ func (_server *server) ServeSpecial (_context *fasthttp.RequestCtx, _special str _contentType = MimeTypeText _contentEncoding = "application/x-cpio" + case "sbom.txt" : + _data = StringToBytes (embedded.SbomTxt) + _contentType = MimeTypeText + _contentEncoding = "identity" + + case "sbom.json" : + _data = StringToBytes (embedded.SbomJson) + _contentType = MimeTypeJson + _contentEncoding = "identity" + default : panic ("[8546f2bd]") } @@ -711,6 +743,14 @@ func Main () () { version.Main ("kawipiko-server", "sources.cpio") return + case "--sbom-text", "--sbom-txt", "--sbom" : + version.Main ("kawipiko-server", "sbom.txt") + return + + case "--sbom-json" : + version.Main ("kawipiko-server", "sbom.json") + return + case "--help", "-h" : if _, _error := os.Stdout.WriteString (usageText); _error == nil { return @@ -2593,6 +2633,9 @@ var usageText string //go:embed manual.txt var manualText string +//go:embed manual.html +var manualHtml string + func init () { usageText = strings.ReplaceAll (usageText, "@{SCHEMA}", CurrentSchemaVersion) } diff --git a/sources/cmd/server/usage.txt b/sources/cmd/server/usage.txt index b2252d1..4892d46 100644 --- a/sources/cmd/server/usage.txt +++ b/sources/cmd/server/usage.txt @@ -41,8 +41,10 @@ --report --quiet --debug - --help (show this short help) - --man (show the full manual) + --version + --help (show this short help) + --man (show the full manual) + --sources-md5 --sources-cpio --sbom --sbom-json ** supported archive version: @{SCHEMA} diff --git a/sources/cmd/version/version.go b/sources/cmd/version/version.go index 57394e7..afeb39c 100644 --- a/sources/cmd/version/version.go +++ b/sources/cmd/version/version.go @@ -70,6 +70,16 @@ func Main (_executableName string, _special string) () { AbortError (_error, "[292d8865] unexpected error!") } + case "sbom.txt" : + if _, _error := os.Stdout.Write (StringToBytes (SbomTxt)); _error != nil { + AbortError (_error, "[e8f9540a] unexpected error!") + } + + case "sbom.json" : + if _, _error := os.Stdout.Write (StringToBytes (SbomJson)); _error != nil { + AbortError (_error, "[9f9eb7ff] unexpected error!") + } + default : panic ("[65a6f35f]") } diff --git a/sources/cmd/wrapper.go b/sources/cmd/wrapper.go index c2032ab..b0fd1c5 100644 --- a/sources/cmd/wrapper.go +++ b/sources/cmd/wrapper.go @@ -34,6 +34,14 @@ func main () () { version.Main ("kawipiko-wrapper", "sources.cpio") return + case "--sbom-text", "--sbom-txt", "--sbom" : + version.Main ("kawipiko-wrapper", "sbom.txt") + return + + case "--sbom-json" : + version.Main ("kawipiko-wrapper", "sbom.json") + return + case "server" : server.Main () return diff --git a/sources/embedded/documentation.go b/sources/embedded/documentation.go new file mode 100644 index 0000000..ca81eb6 --- /dev/null +++ b/sources/embedded/documentation.go @@ -0,0 +1,19 @@ + + +package embedded + + +import _ "embed" + + + + +//go:embed documentation/sbom.txt +var SbomTxt string + +//go:embed documentation/sbom.html +var SbomHtml string + +//go:embed documentation/sbom.json +var SbomJson string +