# Snippet for global matchers and variables # to logically expression request conditions # E.g. for conditionally changing redirects (globals) { # Use gzip compression for all responses encode gzip # Matcher for http request scheme. E.g. "http" or "https" @http_scheme { expression {http.request.scheme}=="https" || {header.X-Forwarded-Scheme}=="https" || {header.X-Forwarded-Proto}=="https" } # If any http scheme is "https", then use "wss" vars @http_scheme WsScheme "wss" # Else default to "ws" vars WsScheme "ws" # Matcher for forwarded request headers @host_forwarded { header X-Forwarded-Host * } # If http headers exists, then use them vars @host_forwarded ReqHost {header.X-Forwarded-Host} # Else default to host in request vars ReqHost {http.request.hostport} # Matcher for websocket connection upgrade requests @websockets { # Avoid case sensitivity issues when matching field values # E.g. when values are rewritten by Codespace port forwarding header_regexp Connection (?i)(Upgrade) header Upgrade websocket } } # Snippet for redirect with given URL queries values # to simplify remote development with web apps # E.g auto redirect websocket URL to match request scheme (redirect) { # Configure redirect to match request scheme vars LayoutUrl "/assets/foxglove/nav2_layout.json" vars DataSourceUrl "{vars.WsScheme}://{vars.ReqHost}{args.0}/" redir /autoconnect "{args.0}/?ds=foxglove-websocket&ds.url={vars.DataSourceUrl}" redir /autolayout "{args.0}/?ds=foxglove-websocket&ds.url={vars.DataSourceUrl}&layoutUrl={vars.LayoutUrl}" } # Snippet for dummy imports (dummy) { } # Snippet for enabling mobile web app features # to improve user experience on small screen devices # E.g. for enabling fullscreen mode on iOS and Android (mobile) { # Match for directory redirects to index.html route / { # Inject link to manifest just after tag # https://developer.mozilla.org/docs/Web/Manifest replace `` `` } # Redirect relative handle_path'ed manifest.json to /manifests directory redir /manifest.json /assets{http.request.orig_uri.path.dir}manifest.json } # Snippet for hosted web app using websockets # to serve static files and reverse proxying connections # E.g. for serving GzWeb and Foxglove web apps (app) { # handle and strip path prefix from redirect handle_path {args.0}/* { # Set root directory for static files root * {http.vars.root}{args.0} # Enable mobile web app features import mobile # Reverse proxy websockets to backend address reverse_proxy @websockets {args.1} # Import custom snippets import {args.2} {args.0} } } # Listen for http requests on port 8080 # regardless of hostname or domain address # E.g. whatever Codespaces assigns to host :8080 { # Include global matchers and variables import globals root * {$ROOT_SRV:/srv} file_server browse # Handle root content # I.e. assets internal to workspace handle /* { # Template manifest.json files templates */manifest.json { mime application/json } } # Handle nav2 web app # I.e. main landing page handle_path /nav2/* { root * {http.vars.root}/nav2 import mobile # Render markdown files as html templates } # Matcher for requests without browse query @no_browse { path / not query browse=true } # Redirect to nav2 web app by default redir @no_browse /nav2/ # Import app snippets for web apps import app "/gzweb" "localhost:9090" "dummy" import app "/foxglove" "localhost:8765" "redirect" # Handle glances web app redir /glances /glances/ handle_path /glances/* { import mobile # Reverse proxy to glances backend reverse_proxy * "localhost:61208" } # For debugging # log { # output file /var/log/caddy/server.log # } }