New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

github.com/bartventer/httpcache

Package Overview
Dependencies
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/bartventer/httpcache

Source
Go Modules
Version
v0.10.2
Version published
Created
Source

httpcache

Go Reference Go Report Card Test codecov

httpcache is a Go package that provides a standards-compliant http.RoundTripper for transparent HTTP response caching, following RFC 9111 (HTTP Caching).

Note: This package is intended for use as a private (client-side) cache. It is not a shared or proxy cache. It is designed to be used with an HTTP client to cache responses from origin servers, improving performance and reducing load on those servers.

Features

  • Plug-and-Play: Just swap in as your HTTP client's transport; no extra configuration needed. 1
  • RFC 9111 Compliance: Handles validation, expiration, and revalidation (see details).
  • Cache Control: Supports all required HTTP cache control directives, as well as extensions like stale-while-revalidate, stale-if-error, and immutable (view details).
  • Cache Backends: Built-in support for file system and memory caches, with the ability to implement custom backends (see Cache Backends).
  • Cache Maintenance API: Optional REST endpoints for listing, retrieving, and deleting cache entries (see Cache Maintenance API).
  • Extensible: Options for logging, transport and timeouts (see Options).
  • Debuggable: Adds a cache status header to every response (see Cache Status Headers).
  • Zero Dependencies: No external dependencies, pure Go implementation.

Made with VHS

Demonstration of HTTP caching in action. See _examples/app for code.

Installation

To install the package, run:

go get github.com/bartventer/httpcache

Quick Start

To get started, create a new HTTP client with the httpcache transport, specifying a cache backend DSN. You'll need to register the desired cache backend before using it. Here's an example using the built-in file system cache:

package main

import (
    "log/slog"
    "net/http"
    "time"

    "github.com/bartventer/httpcache"
    // Register the file system cache backend
    _ "github.com/bartventer/httpcache/store/fscache"
)

func main() {
    // Example DSN for the file system cache backend
    dsn := "fscache://?appname=myapp"
    client := &http.Client{
        Transport: httpcache.NewTransport(
            dsn,
            httpcache.WithSWRTimeout(10*time.Second),
            httpcache.WithLogger(slog.Default()),
        ),
    }
    // ... Use the client as usual
}

Note: The DSN format and options depend on the cache backend you choose. Refer to the Cache Backends section for details on available backends and their DSN formats.

Cache Backends

The following built-in cache backends are available:

BackendDSN ExampleDescription
fscachefscache://?appname=myappFile system cache, stores responses on disk. Suitable for persistent caching across restarts. Supports context cancellation, as well as optional AES-GCM encryption.
memcachememcache://In-memory cache, suitable for ephemeral caching. Does not persist across restarts.

Consult the documentation for each backend for specific configuration options and usage details.

Custom Cache Backends

To implement a custom cache backend, create a type that satisfies the store/driver.Conn interface, then register it using the store.Register function. Refer to the built-in backends for examples of how to implement this interface.

Cache Maintenance API (Debug Only)

A REST API is available for cache inspection and maintenance, intended for debugging and development use only. Do not expose these endpoints in production.

Endpoints:

  • GET /debug/httpcache — List cache keys (if supported)
  • GET /debug/httpcache/{key} — Retrieve a cache entry
  • DELETE /debug/httpcache/{key} — Delete a cache entry

All endpoints require a dsn query parameter to select the cache backend.

Usage Example:

import (
    "net/http"
    "github.com/bartventer/httpcache/store/expapi"
)

func main() {
    expapi.Register()
    http.ListenAndServe(":8080", nil)
}

To use a custom ServeMux, pass expapi.WithServeMux(mux) to expapi.Register().

Options

OptionDescriptionDefault Value
WithUpstream(http.RoundTripper)Set a custom transport for upstream/origin requestshttp.DefaultTransport
WithSWRTimeout(time.Duration)Set the stale-while-revalidate timeout5 * time.Second
WithLogger(*slog.Logger)Set a logger for debug outputslog.New(slog.DiscardHandler)

Cache Status Headers

This package sets a cache status header on every response:

  • X-Httpcache-Status: The primary, detailed cache status header (always set).
  • X-From-Cache: (Legacy) Provided for compatibility with gregjones/httpcache. Only set for cache hits/stale/revalidated responses.

Header Value Mapping

X-Httpcache-StatusX-From-CacheDescription
HIT1Served from cache
STALE1Served from cache but stale
REVALIDATED1Revalidated with origin
MISS(not set)Served from origin
BYPASS(not set)Bypassed cache, served from origin

Example: Stale cache hit

HTTP/1.1 200 OK
X-Httpcache-Status: STALE
X-From-Cache: 1
Content-Type: application/json

Limitations

  • Range Requests & Partial Content: This cache does not support HTTP range requests or partial/incomplete responses (e.g., status code 206, Range/Content-Range headers). All requests with a Range header are bypassed, and 206 responses are not cached. For example:

    GET /example.txt HTTP/1.1
    Host: example.com
    Range: bytes=0-99
    

    The above request will bypass the cache and fetch the response directly from the origin server. See RFC 9111 §3.3-3.4 for details.

RFC 9111 Compliance Matrix

RFC 9111

§TitleRequirementImplementedNotes
1.IntroductionN/AN/ANothing to implement
2.Overview of Cache OperationN/AN/ANothing to implement
3.Storing Responses in CachesRequired✔️Details
4.Constructing Responses from CachesRequired✔️Details
5.Field DefinitionsRequired✔️Details
6.Relationship to Applications and Other CachesN/AN/ANothing to implement
7.Security ConsiderationsN/AN/ANothing to implement
8.IANA ConsiderationsN/AN/ANothing to implement
9.ReferencesN/AN/ANothing to implement

Legend for Requirements:

RequirementDescription
RequiredMust be implemented for RFC compliance
OptionalMay be implemented, but not required for compliance
ObsoleteDirective is no longer relevant as per RFC 9111
DeprecatedDirective is deprecated as per RFC 9111, but can still be implemented
N/ANothing to implement or not applicable to private caches
§3. Storing Responses in Caches (Details)
§TitleRequirementImplementedNotes
3.1.Storing Header and Trailer FieldsRequired✔️
3.2.Updating Stored Header FieldsRequired✔️
3.3.Storing Incomplete ResponsesOptionalSee Limitations
3.4.Combining Partial ContentOptionalSee Limitations
3.5.Storing Responses to Authenticated RequestsN/AN/ANot applicable to private client-side caches
§4. Constructing Responses from Caches (Details)
§TitleRequirementImplementedNotes
4.1.Calculating Cache Keys with the Vary Header FieldRequired✔️
4.2.FreshnessRequired✔️Details
§4.2. Freshness (Subsections)
§TitleRequirementImplementedNotes
4.2.1.Calculating Freshness LifetimeRequired✔️
4.2.2.Calculating Heuristic FreshnessRequired✔️
4.2.3.Calculating AgeRequired✔️
4.2.4.Serving Stale ResponsesRequired✔️
§TitleRequirementImplementedNotes
4.3.ValidationRequired✔️Details
§4.3. Validation (Subsections)
§TitleRequirementImplementedNotes
4.3.1.Sending a Validation RequestRequired✔️
4.3.2.Handling Received Validation RequestN/AN/ANot applicable to private client-side caches
4.3.3.Handling a Validation ResponseRequired✔️
4.3.4.Freshening Stored Responses upon ValidationRequired✔️
4.3.5.Freshening Responses with HEADOptionalPointless, rather use conditional GETs; see RFC 9110 §13.2.1 last para
§TitleRequirementImplementedNotes
4.4.Invalidating Stored ResponsesRequired✔️
§5. Field Definitions (Details)
§TitleRequirementImplementedNotes
5.1.AgeRequired✔️
5.2.Cache-ControlRequired✔️Details
5.3.ExpiresRequired✔️
5.4.PragmaDeprecatedDeprecated by RFC 9111; not implemented
5.5.WarningObsoleteObsoleted by RFC 9111; not implemented
§5.2. Cache-Control Directives
§TitleRequirementImplementedNotes
5.2.1.Request DirectivesOptional✔️Details
§5.2.1. Request Directives (Details)
§Title/DirectiveRequirementImplementedNotes
5.2.1.1.max-ageOptional✔️
5.2.1.2.max-staleOptional✔️
5.2.1.3.min-freshOptional✔️
5.2.1.4.no-cacheOptional✔️
5.2.1.5.no-storeOptional✔️
5.2.1.6.no-transformOptional✔️Compliant by default - implementation never transforms content
5.2.1.7.only-if-cachedOptional✔️
SectionRequirementImplementedNotes
5.2.2. Response DirectivesRequired✔️Details
§5.2.2. Response Directives (Details)
§Title/DirectiveRequirementImplementedNotes
5.2.2.1.max-ageRequired✔️
5.2.2.2.must-revalidateRequired✔️
5.2.2.3.must-understandRequired✔️
5.2.2.4.no-cacheRequired✔️Both qualified and unqualified forms supported
5.2.2.5.no-storeRequired✔️
5.2.2.6.no-transformRequired✔️Compliant by default - implementation never transforms content
5.2.2.7.privateN/AN/AIntended for shared caches; not applicable to private caches
5.2.2.8.proxy-revalidateN/AN/AIntended for shared caches; not applicable to private caches
5.2.2.9.publicOptional✔️
5.2.2.10.s-maxageN/AN/AIntended for shared caches; not applicable to private caches
§TitleRequirementImplementedNotes
5.2.3.Extension DirectivesOptionalpartiallyDetails
§5.2.3. Extension Directives (Details)

The following additional cache control directives are supported, as defined in various RFCs:

ReferenceDirectiveNotes
RFC 5861, §3stale-while-revalidateOnly applies to responses
RFC 5861, §4stale-if-errorApplies to both requests and responses
RFC 8246, §2immutableOnly applies to responses

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.

Notes

Footnotes

  • No configuration is needed beyond the cache backend DSN. Caching is handled automatically based on HTTP headers and directives. To use a custom upstream transport, pass it with the WithUpstream option. This lets you add httpcache to your existing HTTP client with minimal changes. See Options for details.

FAQs

Package last updated on 03 Jul 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts