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