This function creates a route mapping different paths to files on the server
filesystem. Different subpaths can be mapped to different locations on the
server so that e.g. /data/
maps to /path/to/data/
and /assets/
maps to
/a/completely/different/path/
. The route support automatic expansion of
paths to a default extension or file, using compressed versions of files if
the request permits it, and setting the correct headers so that results are
cached.
ressource_route(
...,
default_file = "index.html",
default_ext = "html",
finalize = NULL,
continue = FALSE
)
Named arguments mapping a subpath in the URL to a location on the file system. These mappings will be checked in sequence
The default file to look for if the path does not map to a file directly (see Details)
The default file extension to add to the file if a file cannot be found at the provided path and the path does not have an extension (see Details)
An optional function to run if a file is found. The function
will recieve the request as the first argument, the response as the second,
and anything passed on through ...
in the dispatch
method. Any return
value from the function is discarded.
A logical that should be returned if a file is found.
Defaults to FALSE
indicating that the response should be send unmodified.
Either TRUE
if no file is found or continue = TRUE
or FALSE
if
a file is found and continue = FALSE
The way paths are resolved to a file is, for every mounted location,
Check if the path contains the mount point. If not, continue to the next mount point
substitute the mount point for the local location in the path
if the path ends with /
add the default_file
(defaults to index.html
)
see if the file exists along with compressed versions (versions with
.gz
, .zip
, .br
, .zz
appended)
if any version exists, chose the prefered encoding based on the
Accept-Encoding
header in the request, and return.
if none exists and the path does not specify a file extension, add
default_ext
to the path and repeat 3-4
if none exists still and the path does not specify a file extension, add
default_file
to the path and repeat 3-4
if none exists still, continue to the next mount point
This means that for the path /data/mtcars
, the following locations will be
tested (assuming the /data/
-> /path/to/data/
mapping):
/path/to/data/mtcars
, /path/to/data/mtcars.gz
,
/path/to/data/mtcars.zip
, /path/to/data/mtcars.br
,
/path/to/data/mtcars.zz
/path/to/data/mtcars.html
, /path/to/data/mtcars.html.gz
,
/path/to/data/mtcars.html.zip
, /path/to/data/mtcars.html.br
,
/path/to/data/mtcars.html.zz
/path/to/data/mtcars/index.html
, /path/to/data/mtcars/index.html.gz
,
/path/to/data/mtcars/index.html.zip
, /path/to/data/mtcars/index.html.br
,
/path/to/data/mtcars/index.html.zz
Assuming the default values of default_file
and default_ext
If a file is not found, the route will simply return TRUE
to hand of
control to subsequent routes in the stack, otherwise it will return the
logical value in the continue
argument (defaults to FALSE
, thus
shortcutting any additional routes in the stack).
If a file is found the request headers If-Modified-Since
and
If-None-Match
, will be fetched and, if exist, will be used to determine
whether a 304 - Not Modified
response should be send instead of the file.
If the file should be send, it will be added to the response along with the
following headers:
Content-Type
based on the extension of the file (without any encoding
extensions)
Content-Encoding
based on the negotiated file encoding
ETag
based on digest::digest()
of the last modified date
Cache-Control
set to max-age=3600
Furthermore Content-Length
will be set automatically by httpuv
Lastly, if found, the finalize function will be called, forwarding the
request
, response
and ...
from the dispatch
method.
Other Route constructors:
sizelimit_route()
# Map package files
res_route <- ressource_route(
'/package_files/' = system.file(package = 'routr')
)
rook <- fiery::fake_request('http://example.com/package_files/DESCRIPTION')
req <- reqres::Request$new(rook)
res_route$dispatch(req)
#> [1] FALSE
req$response$as_list()
#> $status
#> [1] 200
#>
#> $headers
#> $headers$`Content-Type`
#> [1] "text/plain"
#>
#> $headers$Date
#> [1] "Fri, 19 Aug 2022 13:46:16 GMT"
#>
#> $headers$ETag
#> [1] "44d845d823fbad587a79be08d5b8ccc5"
#>
#> $headers$`Content-Encoding`
#> [1] "identity"
#>
#> $headers$`Cache-Control`
#> [1] "max-age=3600"
#>
#> $headers$`Last-Modified`
#> [1] "Fri, 19 Aug 2022 13:46:12 GMT"
#>
#>
#> $body
#> file
#> "/home/runner/work/_temp/Library/routr/DESCRIPTION"
#>