blobserve

package
v1.117.0 Latest Latest
Warning

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

Go to latest
Published: Jul 29, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package blobserve writes stored binary content to an HTTP response.

Every raw-content endpoint in the platform — portal assets, asset versions, thumbnails, public share content, managed resources — serves bytes that a user uploaded or an upstream API produced, under a content type that came from the same untrusted place. They all need the same six things, and getting any of them wrong on one endpoint is a bug on that endpoint alone, which is why this is one function rather than a convention:

  • A sandbox Content-Security-Policy, so bytes that reach a browser as a document cannot script the platform's origin whatever their type.
  • X-Content-Type-Options: nosniff, so a browser cannot decide for itself that a text/plain response is really HTML and run it.
  • A Content-Type reduced to a parsed, parameter-free media type, so a stored value like `text/plain; charset=utf-8"><script>` cannot smuggle anything into the header.
  • Content-Disposition: attachment for the scriptable document families (HTML, XHTML, JSX, SVG, JavaScript, XML), which must never render inline on the platform's own origin, and inline for the passive families a viewer embeds.
  • Byte-range support, so an audio or video element can seek without downloading the whole object first.
  • A Cache-Control default of `private`, so an endpoint that authorizes its caller does not hand its bytes to a shared cache by saying nothing.

Index

Constants

View Source
const DefaultCacheControl = "private"

DefaultCacheControl is written when the caller set no Cache-Control of its own. Every endpoint reaching this package authorizes its caller first, and a response carrying no directive at all is heuristically storable by a shared cache: with ServeContent's Last-Modified as the freshness basis, a CDN or ingress cache in front of the platform may reuse one authorized fetch for every later request to the same URL, which is authorization bypass by omission. `private` says the browser that was authorized may keep it and no shared cache may.

Unlike the CSP above this is a default rather than an override: an endpoint whose bytes are genuinely anonymous — a fully public share's thumbnail — sets `public` deliberately, and that decision belongs to the handler that knows who may read the object.

It is exported because the surfaces that do not write through Serve — the gateway raw passthrough streams to its own sink — apply the same default, and the directive is the contract rather than each surface's opinion.

Variables

This section is empty.

Functions

func CachePrivate added in v1.117.0

func CachePrivate(w http.ResponseWriter, maxAge time.Duration)

CachePrivate marks the response as one only the caller that was authorized for it may keep: storable by that browser for maxAge, never by a shared cache, and keyed on the credential the browser sends so a cache that does store it cannot answer a second caller from the first one's copy.

It is one call rather than two Set lines per endpoint because the pairing is the point — a `private` that lost its Vary, or a Vary that lost its directive, is the same authorization bypass the pair exists to prevent. An endpoint whose bytes are genuinely anonymous writes `public` itself, so the exception stays visible at the one place that takes it.

func Headers added in v1.117.0

func Headers(opts Options) http.Header

Headers returns the headers that decide how a browser treats untrusted bytes: the parsed, parameter-free Content-Type, the sandbox CSP, nosniff, and a Content-Disposition whose kind follows the type's family and whose filename cannot break out of its quoted parameter.

Only Name, ContentType and ForceAttachment are read; ModTime and Data describe a body this function does not write. It is separate from Serve for the surfaces that do not answer through an http.ResponseWriter — the gateway raw passthrough streams to its own sink — so the rendering decision is made once for every byte-serving surface rather than restated per transport. Cache-Control is not included: it is a default a caller may override, not a rendering decision, and DefaultCacheControl carries it.

func Serve

func Serve(w http.ResponseWriter, r *http.Request, opts Options)

Serve writes the blob to w, honoring range requests in r.

Types

type Options

type Options struct {
	// Name is the object's display filename. It is used for the
	// Content-Disposition filename and must not be empty for downloads.
	Name string

	// ContentType is the stored media type. It is sanitized before it reaches
	// the response; an empty or unparseable value serves as
	// application/octet-stream.
	ContentType string

	// ModTime is the object's last-modified time, used for If-Range and
	// conditional-request handling. The zero value disables both.
	ModTime time.Time

	// Data is the object's full content.
	Data []byte

	// ForceAttachment serves the blob as a download regardless of family. Set
	// it on endpoints that exist to download, not to preview.
	ForceAttachment bool
}

Options describes one blob to serve.

Jump to

Keyboard shortcuts

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