httpchecksum

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Feb 6, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

README

httpchecksum

Package httpchecksum provides an HTTP client for computing checksums of remote resources with optimizations for common hosting providers.

Features

  • Optimized checksum retrieval - avoids downloading full content when possible:

    • AWS S3: Uses X-Amz-Checksum-Sha256 header
    • GitHub Releases: Uses GitHub API to fetch asset digests
    • raw.githubusercontent.com: Uses ETag header (SHA256)
    • Other servers: Downloads and computes SHA256
  • Cache validation - detects volatile content that shouldn't be pinned:

    • Checks Cache-Control, Expires, and Pragma headers
    • Returns VolatileContentError for content with no-store, no-cache, or max-age=0
  • Progress reporting - optional callback for tracking download progress

  • Header tracking - captures HTTP headers that affect response content (via Vary header)

Installation

go get github.com/wharflab/container-source-policy/httpchecksum

Usage

Basic checksum computation
import "github.com/wharflab/container-source-policy/httpchecksum"

client := httpchecksum.NewClient()
checksum, err := client.GetChecksum(ctx, "https://example.com/file.tar.gz")
if err != nil {
    log.Fatal(err)
}
fmt.Println(checksum) // Output: sha256:...
With HTTP headers
result, err := client.GetChecksumWithHeaders(ctx, "https://example.com/file.tar.gz")
if err != nil {
    log.Fatal(err)
}
fmt.Println("Checksum:", result.Checksum)
fmt.Println("Headers:", result.Headers) // Headers from Vary response header
With progress reporting
clientWithProgress := client.WithProgressFactory(func(contentLength int64) io.Writer {
    // Return a writer that receives download progress
    // You can use a progress bar library here
    bar := progressbar.NewBar(contentLength)
    return bar
})

checksum, err := clientWithProgress.GetChecksum(ctx, "https://example.com/large-file.tar.gz")
GitHub token authentication

For GitHub releases, set the GITHUB_TOKEN environment variable to increase rate limits:

export GITHUB_TOKEN=ghp_...

This increases the rate limit from 60 requests/hour (unauthenticated) to 5,000 requests/hour (authenticated).

Error Handling

The package provides specific error types for common scenarios:

Authentication errors
checksum, err := client.GetChecksum(ctx, url)
if httpchecksum.IsAuthError(err) {
    log.Println("Authentication required for", url)
}
Volatile content errors
checksum, err := client.GetChecksum(ctx, url)
if httpchecksum.IsVolatileContentError(err) {
    log.Println("Content is volatile and shouldn't be pinned:", err)
}

Testing

The package includes comprehensive tests with mock servers:

go test ./httpchecksum/...

Design Philosophy

This package is designed to minimize code ownership by heavily reusing well-maintained libraries:

  • Uses standard library net/http for HTTP operations
  • Uses github.com/pquerna/cachecontrol for RFC 7234 compliant cache header parsing

All optimizations are transparent fallbacks - if a server-provided checksum is unavailable or invalid, the client automatically falls back to downloading and computing the checksum.

Documentation

Overview

Package httpchecksum provides an HTTP client for computing checksums of remote resources with optimizations for common hosting providers (S3, GitHub, raw.githubusercontent.com).

The client attempts to retrieve checksums without downloading full content when possible:

  • AWS S3: Uses X-Amz-Checksum-Sha256 header
  • GitHub Releases: Uses GitHub API to fetch asset digests
  • raw.githubusercontent.com: Uses ETag header (SHA256)
  • Other servers: Downloads and computes SHA256

The client also validates HTTP cache headers to detect volatile content that should not be pinned for reproducible builds.

Example usage:

client := httpchecksum.NewClient()
checksum, err := client.GetChecksum(ctx, "https://example.com/file.tar.gz")
if err != nil {
    // Handle error
}
// checksum is in format "sha256:..."

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsAuthError

func IsAuthError(err error) bool

IsAuthError checks if an error is an authentication error

func IsVolatileContentError

func IsVolatileContentError(err error) bool

IsVolatileContentError checks if an error indicates volatile content

Types

type AuthError

type AuthError struct {
	URL        string
	StatusCode int
}

AuthError indicates an HTTP resource requires authentication

func (*AuthError) Error

func (e *AuthError) Error() string

type ChecksumResult

type ChecksumResult struct {
	// Checksum is the SHA256 checksum in the format "sha256:..."
	Checksum string
	// Headers contains HTTP headers that should be included in the source policy
	// These are the request headers that the response varies by (from the Vary header)
	Headers map[string]string
}

ChecksumResult contains the checksum and metadata for an HTTP resource

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client handles HTTP checksum operations

func NewClient

func NewClient() *Client

NewClient creates a new HTTP client

func (*Client) GetChecksum

func (c *Client) GetChecksum(ctx context.Context, rawURL string) (string, error)

GetChecksum fetches the SHA256 checksum for a URL It attempts to use server-provided checksums when available to avoid downloading the entire file

func (*Client) GetChecksumWithHeaders

func (c *Client) GetChecksumWithHeaders(ctx context.Context, rawURL string) (*ChecksumResult, error)

GetChecksumWithHeaders fetches the SHA256 checksum for a URL along with relevant HTTP headers It attempts to use server-provided checksums when available to avoid downloading the entire file Returns headers that should be included in the source policy based on the Vary response header

func (*Client) WithProgressFactory

func (c *Client) WithProgressFactory(factory ProgressWriterFactory) *Client

WithProgressFactory returns a copy of the client with progress reporting enabled The factory is called when a download starts, receiving the content length

type GitHubRelease

type GitHubRelease struct {
	Assets []GitHubReleaseAsset `json:"assets"`
}

GitHubRelease represents a release from the GitHub API

type GitHubReleaseAsset

type GitHubReleaseAsset struct {
	Name   string `json:"name"`
	Digest string `json:"digest"` // Available since June 2025
}

GitHubReleaseAsset represents a release asset from the GitHub API

type ProgressWriterFactory

type ProgressWriterFactory func(contentLength int64) io.Writer

ProgressWriterFactory creates a progress writer for a download contentLength is the total size in bytes (-1 if unknown) The returned writer receives all downloaded bytes

type VolatileContentError

type VolatileContentError struct {
	URL    string
	Reason string
}

VolatileContentError indicates an HTTP resource has caching headers that suggest the content changes frequently or should not be cached, making pinning unreliable.

func (*VolatileContentError) Error

func (e *VolatileContentError) Error() string

Jump to

Keyboard shortcuts

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