This class handles all functionality involved in crafting a http response.
Much of the functionality is inspired by the Request class in Express.js, so
the documentation for this will
complement this document. As reqres
is build on top of the
Rook specifications
the Response
object can be converted to a compliant list object to be
passed on to e.g. the httpuv
handler.
# S3 method for Response
as.list(x, ...)
is.Response(x)
A Response
object
Ignored
A rook-compliant list-response (in case of as.list()
) or a logical
indicating whether the object is a Response
(in case of is.Response()
)
A Response
object is always created
as a response to a Request
object and contains a reference to the
originating Request
object. A Response
is always initialized with a
404 Not Found code, an empty string as body and the Content-Type
header set
to text/plain
. As the Content-Type
header is required for httpuv
to
function, it will be inferred if missing when converting to a list. If the
body is a raw vector it will be set to application/octet-stream
and
otherwise it will be set to text/plain
. It is always advised to consciously
set the Content-Type
header though. The only exception is when attaching a
standard file where the type is inferred from the file extension
automatically. Unless the body is a raw vector it will automatically be
converted to a character vector and collapsed to a single string with "\n"
separating the individual elements before the Response
object is converted
to a list (that is, the body can exist as any type of object up until the
moment where the Response
object is converted to a list). To facilitate
communication between different middleware the Response
object contains
a data store where information can be stored during the lifetime of the
response.
A new 'Response'-object is initialized using the new()
method on the
generator:
Usage
res <- Response$new(request) |
But often it will be provided by the request using the respond()
method,
which will provide the response, creating one if it doesn't exist
Usage
res <- request$respond() |
Arguments
request | The Request object that the Response is responding to |
The following fields are accessible in a Response
object:
status
Gets or sets the status code of the response. Is initialised
with 404L
body
Set or get he body of the response. If it is a character
vector with a single element named 'file'
it will be interpreted as the
location of a file. It is better to use the file
field for creating a
response referencing a file as it will automatically set the correct
headers.
file
Set or get the location of a file that should be used as the
body of the response. If the body is not referencing a file (but contains
something else) it will return NULL
. The Content-Type
header will
automatically be inferred from the file extension, if known. If unknown it
will defaults to application/octet-stream
. If the file has no extension it
will be text/plain
. Existence of the file will be checked.
type
Get or sets the Content-Type
header of the response based on
a file extension or mime-type.
request
Get the original Request
object that the object is
responding to.
The following methods are available in a Response
object:
set_header(name, value)
Sets the header given by name
. value
will be converted to character. A header will be added for each element in
value
. Use append_header()
for setting headers without overwriting
existing ones.
get_header(name)
Returns the header(s) given by name
remove_header(name)
Removes all headers given by name
has_header(name)
Test for the existence of any header given by
name
append_header(name, value)
Adds an additional header given by
name
with the value given by value
. If the header does not exist yet it
will be created.
set_data(key, value)
Adds value
to the internal data store and
stores it with key
get_data(key)
Retrieves the data stored under key
in the internal
data store.
remove_data(key)
Removes the data stored under key
in the
internal data store.
has_data(key)
Queries whether the data store has an entry given by
key
attach(file, filename=basename(file), type=NULL)
Sets the body to
the file given by file
and marks the response as a download by setting the
Content-Disposition
to attachment; filename=<filename>
. Use the type
argument to overwrite the automatic type inference from the file extension.
status_with_text(code)
Sets the status to code
and sets the body
to the associated status code description (e.g. Bad Gateway
for 502L
)
set_cookie(name, value, encode = TRUE, expires = NULL, http_only = NULL, max_age = NULL, path = NULL, secure = NULL, same_site = NULL)
Adds
the cookie given by name
to the given value
, optionally url encoding it,
along with any additional directives. See
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie for a
description of the different directives. If the cookie already exists it
will be overwritten. The validity of the directives will automatically be
checked. expires
expects a POSIXct object, http_only
and secure
expect
a logical, max_age
expects an integer, path
a string, and same_site
either "Lax"
or "Strict"
remove_cookie(name)
Removes the cookie named name
from the
response.
has_cookie(name)
Queries whether the response contains a cookie
named name
set_links(...)
Sets the Link
header based on the named arguments
passed to ...
. The names will be used for the rel
directive.
format(..., autofail = TRUE, compress = TRUE)
Based on the
formatters passed in through ...
content negotiation is performed with
request and the preferred formatter is chosen. The Content-Type
header is
set automatically. If compress = TRUE
the
compress()
method will be called after formatting. If an error is
encountered and autofail = TRUE
the response will be set to 500
. If a
formatter is not found and autofail = TRUE
the response will be set to
406
. If formatting is successful it will return TRUE
, if not it will
return FALSE
compress(priority = c('gzip', 'deflate', 'br', 'identity'))
Based
on the provided priority, an encoding is negotiated with the request and
applied. The Content-Encoding
header is set to the chosen compression
algorithm.
content_length()
Calculates the length (in bytes) of the body.
This is the number that goes into the Content-Length
header. Note that the
Content-Length
header is set automatically by httpuv
so this method
should only be called if the response size is needed for other reasons.
as_list()
Converts the object to a list for further processing by
a Rook compliant server such as httpuv
. Will set Content-Type
header if
missing and convert a non-raw body to a single character string.
Request
for handling http requests
new()
Response$new(request)
print()
timestamp()
format()
compress()
Response$compress(priority = c("gzip", "deflate", "br", "identity"))
fake_rook <- fiery::fake_request(
'http://example.com/test?id=34632&question=who+is+hadley',
content = 'This is elaborate ruse',
headers = list(
Accept = 'application/json; text/*',
Content_Type = 'text/plain'
)
)
req <- Request$new(fake_rook)
res <- Response$new(req)
res
#> A HTTP response
#> ===============
#> Status: 404 - Not Found
#> Content type: text/plain
#>
#> In response to: http://example.com:80/test?id=34632&question=who+is+hadley
# Set the body to the associated status text
res$status_with_text(200L)
res$body
#> [1] "OK"
# Infer Content-Type from file extension
res$type <- 'json'
res$type
#> [1] "application/json"
# Prepare a file for download
res$attach(system.file('DESCRIPTION', package = 'reqres'))
res$type
#> [1] "text/plain"
res$body
#> file
#> "/home/runner/work/_temp/Library/reqres/DESCRIPTION"
res$get_header('Content-Disposition')
#> [1] "attachment; filename=DESCRIPTION"
# Cleaning up connections
rm(fake_rook, req, res)
gc()
#> used (Mb) gc trigger (Mb) max used (Mb)
#> Ncells 972356 52.0 1934632 103.4 1934632 103.4
#> Vcells 1815994 13.9 8388608 64.0 2565683 19.6