Documentation
¶
Overview ¶
Package rack is a pure-Go (no cgo) reimplementation of the deterministic, interpreter-independent core of Ruby's Rack — the SPEC value types and the pure-compute utilities — matching MRI's `rack` gem (Rack 3.x) byte-for-byte.
It models a Rack environment as a Env (a string-keyed map), and exposes Request and Response over it, plus the [Utils], [MediaType] and header helpers. The HTTP server itself (the socket accept loop, Rack::Handler) is NOT part of this package: it is the host's job. The body-reading seam — the `rack.input` IO — is supplied by the host through the Input interface, so this package stays free of any Ruby runtime or network dependency.
The package is the Rack backend for go-embedded-ruby, but is a standalone, reusable module — a sibling of go-ruby-regexp, go-ruby-erb and go-ruby-yaml.
Index ¶
- Constants
- Variables
- func BestQMatch(header string, available []string) string
- func BuildNestedQuery(value any, prefix string) (string, error)
- func BuildQuery(p *Params) string
- func CleanPathInfo(pathInfo string) string
- func DeleteCookieHeaderInto(h *Headers, key string, c CookieValue) error
- func Escape(s string) string
- func EscapeHTML(s string) string
- func EscapePath(s string) string
- func ForwardedValues(forwardedHeader string, hasHeader bool) (map[string][]string, bool)
- func MakeCookieHeader(key string, c CookieValue) (string, error)
- func MakeDeleteCookieHeader(key string, c CookieValue) (string, error)
- func MediaTypeOf(contentType string) string
- func SecureCompare(a, b string) bool
- func SelectBestEncoding(available []string, accept []QValue) (string, bool)
- func SetCookieHeaderInto(h *Headers, key string, c CookieValue) error
- func StatusWithNoEntityBody(status int) bool
- func SymbolToStatusCode(sym string) (code int, ok bool)
- func TrustedProxy(ip string) bool
- func Unescape(s string) (string, error)
- func UnescapeHTML(s string) string
- func UnescapePath(s string) string
- func ValidPath(path string) bool
- type ByteRange
- type CookieValue
- type Env
- type ErrInvalidCookieKey
- type ErrInvalidSameSite
- type Headers
- func (h *Headers) Delete(key string) bool
- func (h *Headers) Each(fn func(key string, val any) bool)
- func (h *Headers) Get(key string) any
- func (h *Headers) GetOK(key string) (any, bool)
- func (h *Headers) Has(key string) bool
- func (h *Headers) Keys() []string
- func (h *Headers) Len() int
- func (h *Headers) Set(key string, val any)
- func (h *Headers) ToMap() map[string]any
- type Input
- type InvalidParameterError
- type ParameterTypeError
- type Params
- func (p *Params) Delete(key string) (any, bool)
- func (p *Params) Each(fn func(key string, val any) bool)
- func (p *Params) Get(key string) (any, bool)
- func (p *Params) Has(key string) bool
- func (p *Params) Keys() []string
- func (p *Params) Len() int
- func (p *Params) Merge(other *Params) *Params
- func (p *Params) Set(key string, val any)
- func (p *Params) ToMap() map[string]any
- type ParamsTooDeepError
- type QValue
- type Request
- func (r *Request) Authority() string
- func (r *Request) BaseURL() string
- func (r *Request) Body() Input
- func (r *Request) ContentCharset() string
- func (r *Request) ContentType() string
- func (r *Request) Cookies() *Params
- func (r *Request) DeleteHeader(name string) any
- func (r *Request) Env() Env
- func (r *Request) Fullpath() string
- func (r *Request) GET() (*Params, error)
- func (r *Request) GetHeader(name string) string
- func (r *Request) GetHeaderRaw(name string) (any, bool)
- func (r *Request) HasHeader(name string) bool
- func (r *Request) Host() string
- func (r *Request) HostWithPort() string
- func (r *Request) Hostname() string
- func (r *Request) IP() string
- func (r *Request) IsDelete() bool
- func (r *Request) IsGet() bool
- func (r *Request) IsHead() bool
- func (r *Request) IsLink() bool
- func (r *Request) IsOptions() bool
- func (r *Request) IsPatch() bool
- func (r *Request) IsPost() bool
- func (r *Request) IsPut() bool
- func (r *Request) IsTrace() bool
- func (r *Request) IsUnlink() bool
- func (r *Request) MediaType() string
- func (r *Request) MediaTypeParams() *Params
- func (r *Request) POST() (*Params, error)
- func (r *Request) Params() (*Params, error)
- func (r *Request) Path() string
- func (r *Request) PathInfo() string
- func (r *Request) Port() int
- func (r *Request) QueryString() string
- func (r *Request) RequestMethod() string
- func (r *Request) SSL() bool
- func (r *Request) Scheme() string
- func (r *Request) ScriptName() string
- func (r *Request) ServerName() string
- func (r *Request) ServerPort() string
- func (r *Request) SetHeader(name string, v any)
- func (r *Request) URL() string
- func (r *Request) XHR() bool
- type Response
- func (r *Response) Accepted() bool
- func (r *Response) AddHeader(key string, value any) any
- func (r *Response) BadRequest() bool
- func (r *Response) Body() []string
- func (r *Response) ClientError() bool
- func (r *Response) ContentLength() int
- func (r *Response) ContentType() string
- func (r *Response) Created() bool
- func (r *Response) DeleteCookie(key string, cookie CookieValue) error
- func (r *Response) DeleteHeader(key string)
- func (r *Response) Empty() bool
- func (r *Response) Finish() (status int, headers *Headers, body []string)
- func (r *Response) Forbidden() bool
- func (r *Response) GetHeader(key string) any
- func (r *Response) HasHeader(key string) bool
- func (r *Response) Headers() *Headers
- func (r *Response) Informational() bool
- func (r *Response) Invalid() bool
- func (r *Response) IsRedirect() bool
- func (r *Response) Location() string
- func (r *Response) MediaType() string
- func (r *Response) MediaTypeParams() *Params
- func (r *Response) MethodNotAllowed() bool
- func (r *Response) MovedPermanently() bool
- func (r *Response) NoContent() bool
- func (r *Response) NotAcceptable() bool
- func (r *Response) NotFound() bool
- func (r *Response) OK() bool
- func (r *Response) PreconditionFailed() bool
- func (r *Response) Redirect(target string, status int)
- func (r *Response) Redirection() bool
- func (r *Response) RequestTimeout() bool
- func (r *Response) ServerError() bool
- func (r *Response) SetContentType(ct string)
- func (r *Response) SetCookie(key string, cookie CookieValue) error
- func (r *Response) SetHeader(key string, value any)
- func (r *Response) SetLocation(loc string)
- func (r *Response) SetStatus(status int)
- func (r *Response) Status() int
- func (r *Response) Successful() bool
- func (r *Response) ToA() (int, *Headers, []string)
- func (r *Response) Unauthorized() bool
- func (r *Response) Unprocessable() bool
- func (r *Response) Write(chunk string)
Constants ¶
const ( HTTPHost = "HTTP_HOST" HTTPPort = "HTTP_PORT" HTTPS = "HTTPS" PathInfo = "PATH_INFO" RequestMethod = "REQUEST_METHOD" RequestPath = "REQUEST_PATH" ScriptName = "SCRIPT_NAME" QueryString = "QUERY_STRING" ServerProtocol = "SERVER_PROTOCOL" ServerName = "SERVER_NAME" ServerPort = "SERVER_PORT" HTTPCookie = "HTTP_COOKIE" // Response header keys (already lower-case, per the Rack 3 SPEC). CacheControl = "cache-control" ContentLengthKey = "content-length" ContentTypeKey = "content-type" ETagKey = "etag" Expires = "expires" SetCookie = "set-cookie" TransferEncoding = "transfer-encoding" // HTTP method verbs. MethodGet = "GET" MethodPost = "POST" MethodPut = "PUT" MethodPatch = "PATCH" MethodDelete = "DELETE" MethodHead = "HEAD" MethodOptions = "OPTIONS" MethodConnect = "CONNECT" MethodLink = "LINK" MethodUnlink = "UNLINK" MethodTrace = "TRACE" // Rack environment variables. RackURLScheme = "rack.url_scheme" RackInput = "rack.input" RackErrors = "rack.errors" RackSession = "rack.session" RackRequestQueryHash = "rack.request.query_hash" RackRequestQueryString = "rack.request.query_string" RackRequestCookieHash = "rack.request.cookie_hash" RackRequestCookieString = "rack.request.cookie_string" RackRequestFormHash = "rack.request.form_hash" RackRequestFormInput = "rack.request.form_input" RackRequestFormVars = "rack.request.form_vars" RackMethodOverrideOrigMethod = "rack.methodoverride.original_method" )
Request env keys (Rack::* constants from constants.rb).
const DefaultParamDepthLimit = 32
DefaultParamDepthLimit is the default nesting depth allowed by parse_nested_query, matching Rack::Utils.default_query_parser (32). It guards against a rogue client triggering a stack overflow.
const DeleteCookieHeaderValue = "; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT"
DeleteCookieHeaderValue is the standard expired-cookie payload Rack uses to instruct a client to drop a cookie: max-age 0 and an epoch expiry.
Variables ¶
var HTTPStatusCodes = map[int]string{
100: "Continue",
101: "Switching Protocols",
102: "Processing",
103: "Early Hints",
200: "OK",
201: "Created",
202: "Accepted",
203: "Non-Authoritative Information",
204: "No Content",
205: "Reset Content",
206: "Partial Content",
207: "Multi-Status",
208: "Already Reported",
226: "IM Used",
300: "Multiple Choices",
301: "Moved Permanently",
302: "Found",
303: "See Other",
304: "Not Modified",
305: "Use Proxy",
307: "Temporary Redirect",
308: "Permanent Redirect",
400: "Bad Request",
401: "Unauthorized",
402: "Payment Required",
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
406: "Not Acceptable",
407: "Proxy Authentication Required",
408: "Request Timeout",
409: "Conflict",
410: "Gone",
411: "Length Required",
412: "Precondition Failed",
413: "Content Too Large",
414: "URI Too Long",
415: "Unsupported Media Type",
416: "Range Not Satisfiable",
417: "Expectation Failed",
421: "Misdirected Request",
422: "Unprocessable Content",
423: "Locked",
424: "Failed Dependency",
425: "Too Early",
426: "Upgrade Required",
428: "Precondition Required",
429: "Too Many Requests",
431: "Request Header Fields Too Large",
451: "Unavailable For Legal Reasons",
500: "Internal Server Error",
501: "Not Implemented",
502: "Bad Gateway",
503: "Service Unavailable",
504: "Gateway Timeout",
505: "HTTP Version Not Supported",
506: "Variant Also Negotiates",
507: "Insufficient Storage",
508: "Loop Detected",
511: "Network Authentication Required",
}
HTTPStatusCodes maps every standard HTTP status code to its reason phrase, matching Rack::Utils::HTTP_STATUS_CODES.
Functions ¶
func BestQMatch ¶
BestQMatch returns the best available mime type for a quality-value Accept header, matching Rack::Utils.best_q_match. available is the server's set of concrete types; it returns "" when nothing matches.
func BuildNestedQuery ¶
BuildNestedQuery builds a query string from nested structural types, matching Rack::Utils.build_nested_query. value may be a *Params (Hash), []any (Array), a string scalar, or nil. prefix is the key prefix ("" at the top level).
func BuildQuery ¶
BuildQuery builds a flat query string from an ordered map of values, matching Rack::Utils.build_query: a []any value repeats the key, a nil value emits a bare key, and keys/values are escaped with Escape. Keys are emitted in p's insertion order.
func CleanPathInfo ¶
CleanPathInfo canonicalises a PATH_INFO the way Rack::Utils.clean_path_info does: it splits on '/', drops empty and "." segments, pops the last kept segment for each "..", and rejoins with '/'. A leading '/' is restored when the input was empty or began with a separator. This is the traversal-safe normalisation Rack::Files and the static middleware rely on.
func DeleteCookieHeaderInto ¶
func DeleteCookieHeaderInto(h *Headers, key string, c CookieValue) error
DeleteCookieHeaderInto sets an expired cookie in the Headers, matching Rack::Utils.delete_cookie_header!.
func Escape ¶
Escape escapes a string the way Rack::Utils.escape does — i.e. URI.encode_www_form_component: CGI form encoding where space becomes '+', the unreserved set (alphanumerics and *-._) is preserved, and every other byte is percent-encoded with upper-case hex.
func EscapeHTML ¶
EscapeHTML escapes ampersands, angle brackets and quotes to their HTML/XML entities, matching Rack::Utils.escape_html (CGI.escapeHTML). The single quote becomes the numeric reference "'", exactly as MRI emits.
It mirrors the table-driven native path of MRI's cgi/escape C core: a single pass over the bytes bulk-copies each verbatim run and splices in the entity for each escapable byte, straight into one output buffer. Inputs with nothing to escape return the original string with no allocation at all.
func EscapePath ¶
EscapePath escapes a string like Rack::Utils.escape_path — RFC2396 URI path escaping, where (unlike Escape) space becomes "%20" rather than '+' and the path-safe punctuation set is preserved.
func ForwardedValues ¶
ForwardedValues parses an RFC 7239 Forwarded header into its parameter lists, matching Rack::Utils.forwarded_values. It returns (nil, false) when the header is absent, contains a disallowed parameter, or exceeds the DoS guards (more than 1024 parameters or 1024 quoted escapes); otherwise it returns a map from the lower-cased parameter name ("by", "for", "host", "proto") to the ordered list of its values. present is false exactly when the Ruby method returns nil.
func MakeCookieHeader ¶
func MakeCookieHeader(key string, c CookieValue) (string, error)
MakeCookieHeader builds the encoded set-cookie string for the given key and cookie, matching Rack::Utils.set_cookie_header. The cookie value(s) are escaped with Escape and joined with '&'. An invalid key yields an error.
func MakeDeleteCookieHeader ¶
func MakeDeleteCookieHeader(key string, c CookieValue) (string, error)
MakeDeleteCookieHeader builds an encoded set-cookie string that deletes the named cookie, matching Rack::Utils.delete_set_cookie_header: an empty value, max-age 0 and an epoch expiry, plus any supplied attributes.
func MediaTypeOf ¶
MediaTypeOf returns the media type (type/subtype) portion of a CONTENT_TYPE string without parameters — e.g. "text/plain;charset=utf-8" → "text/plain" — matching Rack::MediaType.type. An empty content type yields "".
Ruby returns nil here; in Go we use the empty string to mean "no media type".
func SecureCompare ¶
SecureCompare reports whether a and b are equal using a constant-time comparison, matching Rack::Utils.secure_compare. It returns false immediately when the lengths differ (as MRI does before the fixed-length compare), so it leaks length but not content, and is safe for comparing secrets such as CSRF tokens.
func SelectBestEncoding ¶
SelectBestEncoding picks the best available content-coding for an Accept-Encoding preference list, matching Rack::Utils.select_best_encoding. available is the server's ordered coding list (its order breaks quality ties); accept is the parsed Accept-Encoding as value/quality pairs (typically from QValues). Only the first 16 accept entries are considered. A "*" expands to every available coding not named explicitly; "identity" is always an implicit candidate unless disqualified by a q=0. It returns ("", false) when nothing is acceptable (the Ruby nil).
func SetCookieHeaderInto ¶
func SetCookieHeaderInto(h *Headers, key string, c CookieValue) error
SetCookieHeaderInto appends a set-cookie value to a Headers, converting an existing single value to a []any list, matching Rack::Utils.set_cookie_header!.
func StatusWithNoEntityBody ¶
StatusWithNoEntityBody reports whether a response with the given status code must not carry an entity body — the 1xx range plus 204 and 304 — matching Rack::Utils::STATUS_WITH_NO_ENTITY_BODY. This is the predicate form the `status_with_no_entity_body?` helper exposes.
func SymbolToStatusCode ¶
SymbolToStatusCode returns the HTTP code for a status symbol (e.g. "not_found" → 404), resolving the deprecated aliases too. ok is false for an unrecognised symbol, mirroring how Rack::Utils.status_code raises ArgumentError in that case.
func TrustedProxy ¶
TrustedProxy reports whether ip is a trusted proxy / loopback / private address, matching Rack::Request.ip_filter. Hosts that terminate TLS behind a reverse proxy can rely on this when deciding which forwarded address to trust.
func Unescape ¶
Unescape reverses Rack::Utils.escape (URI.decode_www_form_component): '+' becomes a space and %XX is decoded. An invalid percent-escape (a '%' not followed by two hex digits) makes the whole operation fail the way MRI raises ArgumentError, which this surfaces as a non-nil error.
func UnescapeHTML ¶
UnescapeHTML reverses EscapeHTML, decoding the named and numeric character references CGI.unescapeHTML understands for the bytes EscapeHTML emits, plus the common decimal/hex numeric forms.
func UnescapePath ¶
UnescapePath reverses EscapePath, decoding %XX escapes. Unlike Unescape it does not turn '+' into a space (mirroring URI::RFC2396_PARSER.unescape, which only undoes percent-encoding). An invalid escape is left verbatim, matching Ruby's lenient path unescaper.
Types ¶
type ByteRange ¶
ByteRange is a satisfiable byte range [Start, End] (inclusive), the Go analogue of the Ruby Range objects get_byte_ranges returns.
func GetByteRanges ¶
GetByteRanges parses a Range header value against a resource of the given size, matching Rack::Utils.get_byte_ranges. It returns (nil, false) when the header is missing or syntactically invalid, and an empty slice when no range is satisfiable. maxRanges caps the number of comma-separated ranges (use 100 for the Rack default).
type CookieValue ¶
type CookieValue struct {
Value string
Values []string // multiple values, joined with '&' (Ruby Array form)
HasValues bool // use Values instead of Value
Domain string
Path string
MaxAge string
Expires string // pre-formatted httpdate (host supplies it)
Secure bool
HTTPOnly bool
Partitioned bool
SameSite string // "", "none", "lax" or "strict"
}
CookieValue holds the cookie payload and attributes for SetCookieHeader, mirroring the Hash form Rack::Utils.set_cookie_header accepts. A zero CookieValue with only Value set produces a bare "key=value" cookie. The HTTPOnlySet/SecureSet/PartitionedSet booleans gate emission of those valueless attributes.
type Env ¶
Env is a Rack environment: a string-keyed map of CGI-style variables and rack.* entries. It is the substrate Request reads from and writes to. Values are usually strings; rack.input is an Input.
type ErrInvalidCookieKey ¶
type ErrInvalidCookieKey struct{ Key string }
ErrInvalidCookieKey is returned by SetCookieHeader for a key that violates RFC6265, matching the ArgumentError Ruby raises.
func (*ErrInvalidCookieKey) Error ¶
func (e *ErrInvalidCookieKey) Error() string
type ErrInvalidSameSite ¶
type ErrInvalidSameSite struct{ Value string }
ErrInvalidSameSite is returned for an unrecognised SameSite value.
func (*ErrInvalidSameSite) Error ¶
func (e *ErrInvalidSameSite) Error() string
type Headers ¶
type Headers struct {
// contains filtered or unexported fields
}
Headers is the Go analogue of Rack::Headers — an insertion-ordered map that downcases every string key on the way in, so a Rack-2-style "Content-Type" and a Rack-3-style "content-type" address the same slot. A value is typically a string or a []any (a header with multiple values, e.g. several set-cookie lines). Non-string keys are not used by Rack response headers, so Headers keys are always strings.
func HeadersOf ¶
HeadersOf builds a Headers from a plain map, downcasing keys. It mirrors constructing Rack::Headers and assigning each pair. Iteration order of a Go map is unspecified, so callers needing deterministic order should Set keys individually.
func (*Headers) Delete ¶
Delete removes the (case-insensitive) key, returning whether it was present.
func (*Headers) Each ¶
Each iterates key/value pairs in insertion order. Returning false from fn stops iteration.
type Input ¶
type Input interface {
// Read returns up to n bytes, or all remaining bytes when n < 0. It returns
// nil at EOF with no bytes read, matching IO#read's nil-at-EOF behaviour.
Read(n int) ([]byte, error)
}
Input is the body-reading seam (env["rack.input"]). The host supplies an implementation backed by whatever IO it has; this package never reads the network itself. It mirrors the subset of the Ruby IO contract Rack relies on.
type InvalidParameterError ¶
type InvalidParameterError struct {
// contains filtered or unexported fields
}
InvalidParameterError is raised when a parameter has an invalid byte sequence or %-encoding, corresponding to Rack::QueryParser::InvalidParameterError.
func (*InvalidParameterError) Error ¶
func (e *InvalidParameterError) Error() string
type ParameterTypeError ¶
type ParameterTypeError struct {
// contains filtered or unexported fields
}
ParameterTypeError is raised when nested parameters parsed by ParseNestedQuery contain conflicting structural types (e.g. a key used both as a scalar and as an array/hash). It corresponds to Rack::QueryParser::ParameterTypeError.
func (*ParameterTypeError) Error ¶
func (e *ParameterTypeError) Error() string
type Params ¶
type Params struct {
// contains filtered or unexported fields
}
Params is an insertion-ordered string-keyed map, the Go analogue of Ruby's Hash (which preserves insertion order). parse_query / parse_nested_query and the Request param accessors return values built from Params, []any, string and nil — the same small value model the rack gem produces. A nested value is one of:
- nil (a bare key with no '=')
- string (a scalar value)
- []any (an array, from foo[] nesting or repeated parse_query keys)
- *Params (a sub-hash, from foo[bar] nesting)
func MediaTypeParams ¶
MediaTypeParams parses the parameters of a CONTENT_TYPE string into an ordered map — e.g. "text/plain;charset=utf-8" → {"charset" => "utf-8"} — matching Rack::MediaType.params. Parameter names are down-cased; a parameter with no value (or an empty value) maps to "". Surrounding double quotes on a value are stripped.
func ParseCookies ¶
ParseCookies extracts and parses the Cookie header (env["HTTP_COOKIE"]) from a Rack environment, matching Rack::Utils.parse_cookies. A missing or non-string HTTP_COOKIE parses as an empty header.
func ParseCookiesHeader ¶
ParseCookiesHeader parses a Cookie header value into an ordered map of cookie key to value, matching Rack::Utils.parse_cookies_header (RFC6265, splitting on ';'). The first occurrence of a key wins. A cookie with no '=' maps to a nil value; a value is unescaped, falling back to the raw bytes if it cannot be.
func ParseNestedQuery ¶
ParseNestedQuery parses a query string into structural types — *Params, []any and string — expanding foo[bar] and foo[] bracket nesting exactly like Rack::Utils.parse_nested_query. depthLimit caps nesting (use DefaultParamDepthLimit). Conflicting types raise ParameterTypeError and over-deep nesting raises ParamsTooDeepError.
func ParseQuery ¶
ParseQuery parses a query string into a *Params, collapsing repeated keys into a []any (in order) the way Rack::Utils.parse_query does. A bare key (no '=') maps to nil; an empty value maps to "". The sep argument is the delimiter set, defaulting to "&" when empty.
func (*Params) Delete ¶
Delete removes key, returning its value (or nil) and whether it was present.
func (*Params) Each ¶
Each iterates key/value pairs in insertion order. If fn returns false the iteration stops.
func (*Params) Keys ¶
Keys returns the keys in insertion order. The slice is a copy and safe to mutate.
func (*Params) Merge ¶
Merge returns a new *Params containing this map's pairs overlaid with other's (other wins on a key collision), mirroring Hash#merge used by Request#params.
type ParamsTooDeepError ¶
type ParamsTooDeepError struct {
// contains filtered or unexported fields
}
ParamsTooDeepError is raised when nested parameters exceed the configured depth limit, corresponding to Rack::QueryParser::ParamsTooDeepError.
func (*ParamsTooDeepError) Error ¶
func (e *ParamsTooDeepError) Error() string
type QValue ¶
QValue is one entry of an Accept-style header: a media/encoding value and its quality weight.
type Request ¶
type Request struct {
// contains filtered or unexported fields
}
Request provides a convenient, stateless interface over a Rack Env. It is a faithful port of the pure-compute parts of Rack::Request; the env passed in is referenced directly and may be mutated by the setters and the GET/POST memoisation, exactly like the Ruby class.
func NewRequest ¶
NewRequest wraps env in a Request. env must be non-nil.
func (*Request) Authority ¶
Authority returns the request authority (host[:port]), preferring HTTP_HOST then SERVER_NAME/SERVER_PORT, matching Request#authority (without the Forwarded header, which the host can layer on).
func (*Request) ContentCharset ¶
ContentCharset returns the charset media-type parameter, or "" if none.
func (*Request) ContentType ¶
ContentType returns CONTENT_TYPE, or "" if absent or empty (Request#content_type returns nil there; we use "").
func (*Request) Cookies ¶
Cookies returns the parsed Cookie header, memoised into rack.request.cookie_hash, matching Request#cookies.
func (*Request) DeleteHeader ¶
DeleteHeader removes name from the env, returning its prior value.
func (*Request) Fullpath ¶
Fullpath returns the path plus the query string when present, matching Request#fullpath.
func (*Request) GET ¶
GET returns the parsed query-string parameters, memoised into rack.request.query_hash, matching Request#GET.
func (*Request) GetHeader ¶
GetHeader returns the env value for name (string-typed), or "" if absent or non-string. Use GetHeaderRaw for the untyped value.
func (*Request) GetHeaderRaw ¶
GetHeaderRaw returns the raw env value for name and whether it was present.
func (*Request) HostWithPort ¶
HostWithPort returns the host, including the port only when it differs from the scheme's default, matching Request#host_with_port.
func (*Request) Hostname ¶
Hostname returns the address portion (IPv6 brackets removed), matching Request#hostname.
func (*Request) IP ¶
IP returns the originating client IP, walking REMOTE_ADDR and the X-Forwarded-For chain past trusted proxies, matching Request#ip.
func (*Request) MediaType ¶
MediaType returns the media type of CONTENT_TYPE, matching Request#media_type.
func (*Request) MediaTypeParams ¶
MediaTypeParams returns the CONTENT_TYPE parameters, matching Request#media_type_params.
func (*Request) POST ¶
POST parses the request body as form data when the content type is a form-data media type, memoising into rack.request.form_hash. It returns an empty Params when there is no rack.input or the body is not form data, matching Request#POST. The body is read through the Input seam.
func (*Request) Params ¶
Params returns the union of GET and POST, with POST winning on collisions, matching Request#params.
func (*Request) Port ¶
Port returns the request port, falling back through the authority, the scheme's default port and SERVER_PORT, matching Request#port.
func (*Request) QueryString ¶
QueryString returns QUERY_STRING, defaulting to "".
func (*Request) RequestMethod ¶
RequestMethod returns the REQUEST_METHOD (e.g. "GET").
func (*Request) Scheme ¶
Scheme returns the request scheme, honouring HTTPS, X-Forwarded-SSL and rack.url_scheme, matching Request#scheme (the forwarded-Proto header path is covered by ForwardedScheme below).
func (*Request) ScriptName ¶
ScriptName returns SCRIPT_NAME, defaulting to "".
type Response ¶
type Response struct {
// contains filtered or unexported fields
}
Response is a convenient builder for a Rack response — a faithful port of the pure-compute parts of Rack::Response. It accumulates a status, a Headers and a buffered body, and produces the SPEC `[status, headers, body]` tuple via Response.Finish / Response.ToA.
func NewResponse ¶
NewResponse builds a Response with the given body, status and headers, like Rack::Response.new(body, status, headers). A nil body yields an empty, length-unknown buffered response; a single string body is buffered with its byte length recorded. status defaults are the caller's responsibility (pass 200 for the Ruby default). headers may be nil.
func NewResponseString ¶
NewResponseString is the common case of a single string body.
func ResponseTuple ¶
ResponseTuple builds a Response from the SPEC `[status, headers, body]` argument order, matching Rack::Response.[](status, headers, body).
func (*Response) AddHeader ¶
AddHeader adds value to key, promoting an existing single value to a list when a second value is added, matching Response#add_header. A nil value is a no-op (returns the current value).
func (*Response) BadRequest ¶
func (*Response) ClientError ¶
func (*Response) ContentLength ¶
ContentLength returns the content-length header as an int, or -1 if unset.
func (*Response) ContentType ¶
ContentType returns the content-type header value, or "" if unset.
func (*Response) DeleteCookie ¶
func (r *Response) DeleteCookie(key string, cookie CookieValue) error
DeleteCookie sets an expiring set-cookie header for key, matching Response#delete_cookie.
func (*Response) DeleteHeader ¶
DeleteHeader removes key.
func (*Response) Empty ¶
Empty reports whether the buffered body has no parts, matching Response#empty?.
func (*Response) Finish ¶
Finish produces the SPEC `[status, headers, body]` tuple, matching Response#finish. For a no-entity-body status it strips content-type and content-length and returns an empty body; otherwise it sets content-length from the buffered length (unless chunked).
func (*Response) Informational ¶
func (*Response) IsRedirect ¶
IsRedirect reports whether the status is a redirect code, matching Response#redirect?.
func (*Response) MediaTypeParams ¶
MediaTypeParams returns the content-type parameters.
func (*Response) MethodNotAllowed ¶
func (*Response) MovedPermanently ¶
func (*Response) NotAcceptable ¶
func (*Response) PreconditionFailed ¶
func (*Response) Redirect ¶
Redirect sets the status (default 302) and location header, matching Response#redirect.
func (*Response) Redirection ¶
func (*Response) RequestTimeout ¶
func (*Response) ServerError ¶
func (*Response) SetContentType ¶
SetContentType sets the content-type header (Response#content_type=).
func (*Response) SetCookie ¶
func (r *Response) SetCookie(key string, cookie CookieValue) error
SetCookie appends a set-cookie header for key/cookie, matching Response#set_cookie.
func (*Response) SetLocation ¶
SetLocation sets the location header.
