Documentation
¶
Overview ¶
Package httputil provides small HTTP helpers shared across handlers.
Index ¶
- func ParamID(c echo.Context, name, resource string) (int, error)
- func PublicOrigin(r *http.Request) string
- func PublicScheme(r *http.Request) string
- func ServeFile(c echo.Context, path string, notFound error, opts ...ServeOption) error
- func ServeStream(c echo.Context, body io.Reader, size int64, opts ...ServeOption) error
- func SetAttachmentFilename(w http.ResponseWriter, filename string)
- func SetAttachmentFilenames(w http.ResponseWriter, filename, ascii string)
- type NullableInt
- type ServeOption
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParamID ¶ added in v0.1.0
ParamID parses the numeric path parameter name as a row ID. A value that is not a positive integer names no row, so it returns errcodes.NotFound(resource), the same 404 as a well-formed ID with no row behind it.
func PublicOrigin ¶ added in v0.4.0
PublicOrigin returns the scheme://host[:port] a client used to reach r, for building absolute URLs that devices follow. The forwarded headers it reads are trusted because the server middleware strips them from untrusted peers.
Some clients, Kobo firmware among them, leave the port out of Host even on a non-default port. A direct request then gets the port the connection arrived on. A proxied request never does: the listener's port is not the one the client used, so a proxy must send X-Forwarded-Port or put the port in the host it forwards.
func PublicScheme ¶ added in v0.4.0
PublicScheme returns "https" or "http", whichever the client used to reach r. Session cookies are Secure exactly when this is "https", so they agree with the URLs PublicOrigin builds.
func ServeFile ¶ added in v0.1.0
ServeFile serves the file at path through http.ServeContent, which handles Range, If-Range, and conditional GETs. It differs from echo's c.File in two ways. Only a missing file or a directory returns notFound; c.File turns every open failure, including a permission error, into echo's generic 404, and here any other failure is a server fault. And the headers the options set are written only after the open succeeds, so a failure goes out as a plain JSON error rather than one cached for a year, typed as an image, or saved as the book.
A Range header with a unit other than bytes is ignored, as RFC 9110 section 14.2 requires, and the whole file is served with 200. A malformed bytes range, or one that starts past the end, is answered 416 by ServeContent.
func ServeStream ¶ added in v0.2.0
ServeStream sends body, a file still being written, as a whole-file 200 with the headers the options set (WithETag is ignored). size is the file's exact length, sent as Content-Length, or -1 when it is not known yet, in which case the response is chunked. A Range header is ignored, since bytes past what has been written do not exist yet; once the file is complete it is served with ServeFile, which handles Range. Each read is flushed to the client as it arrives, so a slow writer never leaves bytes sitting in a buffer. A nil body, as for HEAD, sends the headers alone.
Call it only once body is ready to read: the headers are sent first, so an error from body can only cut the response short. It does that by closing the connection, since a chunked response that simply ended would look complete to the client.
func SetAttachmentFilename ¶
func SetAttachmentFilename(w http.ResponseWriter, filename string)
SetAttachmentFilename writes a Content-Disposition: attachment header that works across the spectrum of HTTP clients per RFC 6266 / RFC 5987.
For ASCII-only filenames, only the legacy quoted form is emitted. When the filename contains anything outside printable ASCII, both a sanitized ASCII fallback (filename=) and a percent-encoded UTF-8 form (filename*=) are emitted; per RFC 6266 §4.3 modern clients prefer filename* while legacy clients ignore the unknown parameter and use the ASCII fallback.
This matters for OPDS clients like KOReader's "Use server filenames" mode, which parses the header to name the downloaded file on the device.
func SetAttachmentFilenames ¶ added in v0.5.0
func SetAttachmentFilenames(w http.ResponseWriter, filename, ascii string)
SetAttachmentFilenames is SetAttachmentFilename with the ASCII fallback given, as a generated download builds it from the same parts as its name (downloadcache.DownloadFilenames). An empty ascii derives it from filename.
Types ¶
type NullableInt ¶ added in v0.4.0
NullableInt distinguishes between "field absent" (Set=false), "field present as null" (Set=true, Value=nil), and "field present with value" (Set=true, Value=&n). Standard encoding/json cannot differentiate absent from null on pointer types, so we use a custom UnmarshalJSON. Payload fields of this type need a `tstype:"number | null"` tag so tygo emits the wire shape.
func (*NullableInt) UnmarshalJSON ¶ added in v0.4.0
func (n *NullableInt) UnmarshalJSON(data []byte) error
type ServeOption ¶ added in v0.1.0
type ServeOption func(*serveOptions)
ServeOption sets a header on a file ServeFile serves. Options apply only once the file has opened, so an error response never carries them.
func WithAttachment ¶ added in v0.1.0
func WithAttachment(filename string) ServeOption
WithAttachment sends the file as a download named filename, through SetAttachmentFilename (an escaped ASCII fallback plus filename* for names outside printable ASCII). An empty filename sends no Content-Disposition, which overrides an earlier WithAttachment.
func WithAttachmentNames ¶ added in v0.5.0
func WithAttachmentNames(filename, ascii string) ServeOption
WithAttachmentNames is WithAttachment with the ASCII fallback given (SetAttachmentFilenames).
func WithCacheControl ¶ added in v0.1.0
func WithCacheControl(value string) ServeOption
WithCacheControl sets the Cache-Control header.
func WithContentType ¶ added in v0.1.0
func WithContentType(contentType string) ServeOption
WithContentType sets the Content-Type instead of deriving it from the extension. Pass the type for the file type (models.FileTypeMimeType) for a book download, since the host mime table may not know .epub, .cbz, or .m4b. An empty type leaves the extension-based type in place.
func WithETag ¶ added in v0.1.0
func WithETag(etag string) ServeOption
WithETag sets an ETag and makes it the only validator: Last-Modified is omitted and If-Modified-Since ignored, while If-None-Match still answers 304. Use it when the file served at a URL can change without its mtime changing, as for a book cover selected from several files.