goproxy

package module
v0.16.4 Latest Latest
Warning

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

Go to latest
Published: Feb 7, 2024 License: MIT Imports: 29 Imported by: 13

README

Goproxy

Test codecov Go Report Card PkgGoDev

A minimalist Go module proxy handler.

Goproxy has fully implemented the GOPROXY protocol. The goal of this project is to find the most dead simple way to provide a minimalist handler that can act as a full-featured Go module proxy for those who want to build their own proxies.

Features

Installation

  • To use this project programmatically, go get it:
go get github.com/goproxy/goproxy
  • To use this project from the command line, download the pre-built binaries from here or build it from source:
go install github.com/goproxy/goproxy/cmd/goproxy@latest
  • To use this project with Docker, pull the pre-built images from here:
docker pull ghcr.io/goproxy/goproxy

Quick Start

Write code

Create a file named goproxy.go:

package main

import (
	"net/http"

	"github.com/goproxy/goproxy"
)

func main() {
	http.ListenAndServe("localhost:8080", &goproxy.Goproxy{})
}

Then run it with a GOMODCACHE that differs from go env GOMODCACHE:

GOMODCACHE=/tmp/goproxy-gomodcache go run goproxy.go

Finally, set GOPROXY to try it out:

go env -w GOPROXY=http://localhost:8080,direct

For more details, refer to the documentation.

Run from command line

Refer to the Installation section to download the binary.

Then run it with a GOMODCACHE that differs from go env GOMODCACHE:

GOMODCACHE=/tmp/goproxy-gomodcache goproxy server --address localhost:8080

Finally, set GOPROXY to try it out:

go env -w GOPROXY=http://localhost:8080,direct

For more details, check its usage:

goproxy --help
Run with Docker

Refer to the Installation section to pull the image.

Then run it:

docker run -p 8080:8080 ghcr.io/goproxy/goproxy server --address :8080

Finally, set GOPROXY to try it out:

go env -w GOPROXY=http://localhost:8080,direct

For more details, check its usage:

docker run ghcr.io/goproxy/goproxy --help

Community

If you have any questions or ideas about this project, feel free to discuss them here.

Contributing

If you would like to contribute to this project, please submit issues here or pull requests here.

License

This project is licensed under the MIT License.

Documentation

Overview

Package goproxy implements a minimalist Go module proxy handler.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cacher

type Cacher interface {
	// Get gets the matched cache for the name. It returns [fs.ErrNotExist]
	// if not found.
	//
	// The returned [io.ReadCloser] may optionally implement the following
	// interfaces:
	//  1. [io.Seeker], mainly for the Range request header.
	//  2. interface{ LastModified() time.Time }, mainly for the
	//     Last-Modified response header. Also for the If-Unmodified-Since,
	//     If-Modified-Since, and If-Range request headers when 1 is
	//     implemented.
	//  3. interface{ ModTime() time.Time }, same as 2 but with lower
	//     priority.
	//  4. interface{ ETag() string }, mainly for the ETag response header.
	//     Also for the If-Match, If-None-Match, and If-Range request
	//     headers when 1 is implemented. Note that the return value will be
	//     assumed to have complied with RFC 7232, section 2.3, so it will
	//     be used directly without further processing.
	Get(ctx context.Context, name string) (io.ReadCloser, error)

	// Put puts a cache for the name with the content.
	Put(ctx context.Context, name string, content io.ReadSeeker) error
}

Cacher defines a set of intuitive methods used to cache module files for Goproxy.

type DirCacher added in v0.4.0

type DirCacher string

DirCacher implements Cacher using a directory on the local disk. If the directory does not exist, it will be created with 0755 permissions. Cache files will be created with 0644 permissions.

func (DirCacher) Get added in v0.4.0

func (dc DirCacher) Get(ctx context.Context, name string) (io.ReadCloser, error)

Get implements Cacher.

func (DirCacher) Put added in v0.14.0

func (dc DirCacher) Put(ctx context.Context, name string, content io.ReadSeeker) error

Put implements Cacher.

type Fetcher added in v0.16.0

type Fetcher interface {
	// Query performs the version query for the given module path.
	//
	// The version query can be one of the following:
	//   - A fully-specified semantic version, such as "v1.2.3", which
	//     selects a specific version.
	//   - A semantic version prefix, such as "v1" or "v1.2", which selects
	//     the highest available version with that prefix.
	//   - A revision identifier for the underlying source repository, such
	//     as a commit hash prefix, revision tag, or branch name. If the
	//     revision is tagged with a semantic version, this query selects
	//     that version. Otherwise, this query selects a pseudo-version for
	//     the underlying commit. Note that branches and tags with names
	//     matched by other version queries cannot be selected this way. For
	//     example, the query "v2" selects the latest version starting with
	//     "v2", not the branch named "v2".
	//   - The string "latest", which selects the highest available release
	//     version. If there are no release versions, "latest" selects the
	//     highest pre-release version. If there are no tagged versions,
	//     "latest" selects a pseudo-version for the commit at the tip of
	//     the repository's default branch.
	Query(ctx context.Context, path, query string) (version string, time time.Time, err error)

	// List lists the available versions for the given module path.
	//
	// The returned versions contains only tagged versions, not
	// pseudo-versions. Versions covered by "retract" directives in the
	// "go.mod" file from the "latest" version of the same module are also
	// ignored.
	List(ctx context.Context, path string) (versions []string, err error)

	// Download downloads the module files for the given module path and
	// version.
	//
	// The returned error is nil only if all three kinds of module files
	// are successfully downloaded.
	Download(ctx context.Context, path, version string) (info, mod, zip io.ReadSeekCloser, err error)
}

Fetcher defines a set of intuitive methods used to fetch module files for Goproxy.

Note that any error returned by Fetcher that matches fs.ErrNotExist indicates that the module cannot be fetched.

type GoFetcher added in v0.16.0

type GoFetcher struct {
	// Env is the environment. Each entry is in the form "key=value".
	//
	// If Env is nil, [os.Environ] is used.
	//
	// If Env contains duplicate environment keys, only the last value in
	// the slice for each duplicate key is used.
	//
	// Make sure that all environment values are valid, particularly for
	// GOPROXY and GOSUMDB, to prevent constant fetch failures.
	Env []string

	// GoBin is the path to the Go binary that is used to execute direct
	// fetches.
	//
	// If GoBin is empty, "go" is used.
	GoBin string

	// MaxDirectFetches is the maximum number of concurrent direct fetches.
	//
	// If MaxDirectFetches is zero, there is no limit.
	MaxDirectFetches int

	// TempDir is the directory for storing temporary files.
	//
	// If TempDir is empty, [os.TempDir] is used.
	TempDir string

	// Transport is used to execute outgoing requests, excluding those
	// initiated by direct fetches.
	//
	// If Transport is nil, [http.DefaultTransport] is used.
	Transport http.RoundTripper
	// contains filtered or unexported fields
}

GoFetcher implements Fetcher using the local Go binary.

Make sure that the Go binary and the version control systems (such as Git) that need to be supported are installed and properly configured in your environment, as they are required for direct module fetching.

During a direct module fetch, the Go binary is called while holding a lock file in the module cache directory (specified by GOMODCACHE) to prevent potential conflicts. Misuse of a shared GOMODCACHE may lead to deadlocks.

Note that GoFetcher will still adhere to your environment variables. This means you can set GOPROXY to run GoFetcher itself under other proxies. By setting GONOPROXY and GOPRIVATE, you can instruct GoFetcher on which modules to fetch directly, rather than using those proxies. Additionally, you can set GOSUMDB, GONOSUMDB, and GOPRIVATE to specify how GoFetcher should verify the modules it has just fetched. Importantly, all of these mentioned environment variables are built-in supported, resulting in fewer external command calls and a significant performance boost.

func (*GoFetcher) Download added in v0.16.0

func (gf *GoFetcher) Download(ctx context.Context, path, version string) (info, mod, zip io.ReadSeekCloser, err error)

Download implements Fetcher.

func (*GoFetcher) List added in v0.16.0

func (gf *GoFetcher) List(ctx context.Context, path string) (versions []string, err error)

List implements Fetcher.

func (*GoFetcher) Query added in v0.16.0

func (gf *GoFetcher) Query(ctx context.Context, path, query string) (version string, time time.Time, err error)

Query implements Fetcher.

type Goproxy

type Goproxy struct {
	// Fetcher is used to fetch module files.
	//
	// If Fetcher is nil, [GoFetcher] is used.
	//
	// Note that any error returned by Fetcher that matches [fs.ErrNotExist]
	// will result in a 404 response with the error message in the response
	// body.
	Fetcher Fetcher

	// ProxiedSumDBs is a list of proxied checksum databases (see
	// https://go.dev/design/25530-sumdb#proxying-a-checksum-database). Each
	// entry is in the form "<sumdb-name>" or "<sumdb-name> <sumdb-URL>".
	// The first form is a shorthand for the second, where the corresponding
	// <sumdb-URL> will be the <sumdb-name> itself as a host with an "https"
	// scheme. Invalid entries will be silently ignored.
	//
	// If ProxiedSumDBs contains duplicate checksum database names, only the
	// last value in the slice for each duplicate checksum database name is
	// used.
	ProxiedSumDBs []string

	// Cacher is used to cache module files.
	//
	// If Cacher is nil, caching is disabled.
	Cacher Cacher

	// TempDir is the directory for storing temporary files.
	//
	// If TempDir is empty, [os.TempDir] is used.
	TempDir string

	// Transport is used to execute outgoing requests.
	//
	// If Transport is nil, [http.DefaultTransport] is used.
	Transport http.RoundTripper

	// ErrorLogger is used to log errors that occur during proxying.
	//
	// If ErrorLogger is nil, [log.Default] is used.
	ErrorLogger *log.Logger
	// contains filtered or unexported fields
}

Goproxy is the top-level struct of this project.

For requests involving the download of a large number of modules (e.g., for bulk static analysis), Goproxy supports a non-standard header, "Disable-Module-Fetch: true", which instructs it to return only cached content.

func (*Goproxy) ServeHTTP

func (g *Goproxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)

ServeHTTP implements http.Handler.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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