proxy

package
v1.43.0 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 31 Imported by: 0

Documentation

Overview

Package proxy provides HTTP proxy handlers for Git protocol requests.

This package includes a basic proxy handler that forwards requests to an upstream Git server, and a caching handler that intercepts git-upload-pack requests to provide intelligent caching with request coalescing for shallow clones.

Index

Constants

View Source
const HeaderCorrelationID = "X-Request-Id"

HeaderCorrelationID carries the ID that ties one git fetch together across services. httpserver.CorrelationIDMiddleware resolves the inbound value (adopting the client's if it is well-formed, minting one otherwise), puts it in the request context and echoes it on the response. The helpers below carry that resolved value out to upstream.

View Source
const (
	// HeaderPackhorseUpstream is set on every request Packhorse forwards to its
	// upstream URL. The ci-gateway HAProxy uses this header to detect cache-miss
	// requests and skip routing them back to Packhorse, preventing an infinite
	// routing loop when upstreamUrl points at the ci-gateway ILB.
	HeaderPackhorseUpstream = "X-Packhorse-Upstream"
)

Variables

View Source
var (
	ErrFailedToCreateUpstreamRequest = errors.New("failed to create upstream request")
	ErrUpstreamRequestFailed         = errors.New("upstream request failed")
	ErrUpstreamReturnedBadStatus     = errors.New("upstream returned bad status")
	ErrFailedToStoreInCache          = errors.New("failed to store in cache")
	ErrBlobBucketNotConfigured       = errors.New("blob bucket not configured")
	// ErrUpstreamInBandFailure means upstream returned HTTP 200 but the git
	// stream carried an in-band error or was truncated, so it must not be cached.
	ErrUpstreamInBandFailure = errors.New("upstream returned an in-band git error")
)

Functions

func DefaultTransportConfigurator

func DefaultTransportConfigurator(base *http.Transport) http.RoundTripper

DefaultTransportConfigurator is a no-op configurator that returns the base transport as-is.

Types

type FallbackHandler

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

FallbackHandler handles all requests that don't match specific routes. This handler is responsible for proxying non-cacheable requests to upstream.

func NewFallbackHandler

func NewFallbackHandler(upstreamURL *url.URL, transportConfig TransportConfigurator) *FallbackHandler

NewFallbackHandler creates a new FallbackHandler.

func (*FallbackHandler) ServeHTTP

func (h *FallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface. This handler proxies non-cacheable requests to upstream.

type GitUploadPackHandler

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

GitUploadPackHandler handles POST requests to */git-upload-pack endpoints. This handler is responsible for git-upload-pack requests with caching support.

func NewGitUploadPackHandler

func NewGitUploadPackHandler(
	upstreamURL *url.URL,
	transportConfig TransportConfigurator,
	cacheManager *cache.Manager,
	coalescer *coalesce.Coalescer,
	metrics observability.AppMetrics,
	fallbackHandler http.Handler,
	injectedFetchHandler *InjectedGitFetchHandler,
	blobBucket *blob.Bucket,
	labelByRepo bool,
) *GitUploadPackHandler

NewGitUploadPackHandler creates a new GitUploadPackHandler.

func (*GitUploadPackHandler) ServeHTTP

func (h *GitUploadPackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface for git-upload-pack requests. This handler processes POST requests to git-upload-pack with caching support.

type InfoRefsHandler

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

InfoRefsHandler handles GET requests to */info/refs endpoints. This handler is responsible for proxying info/refs requests to upstream and injecting packfile-uris capability support.

func NewInfoRefsHandler

func NewInfoRefsHandler(upstreamURL *url.URL, transportConfig TransportConfigurator, addXForwardedFor bool) *InfoRefsHandler

NewInfoRefsHandler creates a new InfoRefsHandler using httputil.ReverseProxy.

func (*InfoRefsHandler) ServeHTTP

func (h *InfoRefsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface. This handler proxies info/refs requests to upstream via ReverseProxy.

type InjectedGitFetchHandler

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

InjectedGitFetchHandler handles POST requests to */git-upload-pack endpoints. This handler is responsible for git-upload-pack requests with caching support.

func NewGitUploadPackInjectedFetchHandler

func NewGitUploadPackInjectedFetchHandler(
	upstreamURL *url.URL,
	transportConfig TransportConfigurator,
	cacheManager *cache.Manager,
	coalescer *coalesce.Coalescer,
	metrics observability.AppMetrics,
	prenegotiator *prenegotiation.Prenegotiator,
	basePackfileManager packfile.BasePackfileManager,
	blobBucket *blob.Bucket,
	blobBucketURL string,
	labelByRepo bool,
) *InjectedGitFetchHandler

NewGitUploadPackInjectedFetchHandler creates a new InjectedGitFetchHandler.

func (*InjectedGitFetchHandler) AttemptInjection

func (h *InjectedGitFetchHandler) AttemptInjection(w http.ResponseWriter, r *http.Request, repoPath string, fetchCmd *parser.FetchCommand) (bool, error)

type SimpleCachedGitFetchHandler

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

SimpleCachedGitFetchHandler handles simple caching of git-upload-pack responses without packfile injection..

func NewSimpleCachedGitFetchHandler

func NewSimpleCachedGitFetchHandler(
	upstreamURL *url.URL,
	client *http.Client,
	cache *cache.Manager,
	coalescer *coalesce.Coalescer,
	metrics observability.AppMetrics,
	labelByRepo bool,
) *SimpleCachedGitFetchHandler

NewSimpleCachedGitFetchHandler creates a new SimpleCachedGitFetchHandler.

type TransportConfigurator

type TransportConfigurator func(*http.Transport) http.RoundTripper

TransportConfigurator is a function that wraps a base http.Transport with additional RoundTrippers.

type URICachedGitFetchHandler added in v1.42.0

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

URICachedGitFetchHandler serves cacheable fetches through object storage, which holds the de-sidebanded pack for a cache key alongside the metadata needed to frame a response around it.

A miss falls back to the local cache handler, which fetches from upstream, serves the client inline, and leaves the response on disk. The pack is then offloaded to object storage in the background. The local copy stays on disk, bounded by the cache's size limit and sliding TTL.

A hit is served from whichever tier still has the pack, and how depends on the client. One that can download packfile-uris gets a signed URL and an empty inline pack, so the pack never travels through Packhorse. One that cannot is served inline from the local copy, and once that has expired the local entry is rebuilt from the pack in object storage rather than re-fetched from upstream.

func NewURICachedGitFetchHandler added in v1.42.0

func NewURICachedGitFetchHandler(
	simple *SimpleCachedGitFetchHandler,
	cacheManager *cache.Manager,
	metaStore packmeta.Store,
	blobBucket *blob.Bucket,
	metrics observability.AppMetrics,
	labelByRepo bool,
) *URICachedGitFetchHandler

NewURICachedGitFetchHandler creates a URICachedGitFetchHandler.

func (*URICachedGitFetchHandler) Handle added in v1.42.0

func (h *URICachedGitFetchHandler) Handle(w http.ResponseWriter, r *http.Request, repoPath string, fetchCmd *parser.FetchCommand) bool

Handle serves the fetch through the object-storage cache. It returns true when it took responsibility for the response, and false to let the caller fall back to the plain local cache path, which happens when no bucket is configured.

Both client kinds are served from the same cached pack. A client that can download packfile-uris gets a signed URL, and one that cannot gets the pack inline, rebuilt into the local cache from object storage when the local copy has expired.

Jump to

Keyboard shortcuts

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