httputil

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package httputil provides small HTTP helpers shared across handlers.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParamID added in v0.1.0

func ParamID(c echo.Context, name, resource string) (int, error)

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 ServeFile added in v0.1.0

func ServeFile(c echo.Context, path string, notFound error, opts ...ServeOption) error

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

func ServeStream(c echo.Context, body io.Reader, size int64, opts ...ServeOption) error

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.

Types

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 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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL