goproxy

package module
v0.0.0-...-eba33a9 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2023 License: MIT Imports: 28 Imported by: 0

README

Goproxy

GitHub Actions codecov Go Report Card PkgGoDev

A minimalist Go module proxy handler.

Goproxy has fully implemented the GOPROXY protocol. Our goal 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. Yeah, there is no Makefile, no configuration files, no crazy file organization, no lengthy documentation, no annoying stuff, just a goproxy.Goproxy that implements the http.Handler.

Features

Installation

Open your terminal and execute

$ # Use it programmatically (RECOMMENDED).
$ go get github.com/goproxy/goproxy
$ # Or use our minimalist CLI implementation.
$ go install github.com/goproxy/goproxy/cmd/goproxy@latest
$ # Or use our minimalist Docker image.
$ docker pull ghcr.io/goproxy/goproxy

done.

The only requirement is the Go, at least v1.13.

Quick Start

Create a file named goproxy.go

package main

import (
	"net/http"

	"github.com/goproxy/goproxy"
)

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

and run it

$ go run goproxy.go

then try it by setting GOPROXY to http://localhost:8080 by following the instructions below. In addition, we also recommend that you set GO111MODULE to on instead of auto when you are working with Go modules.

Open your terminal and execute

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

done.

macOS or Linux

Open your terminal and execute

$ export GOPROXY=http://localhost:8080

or

$ echo "export GOPROXY=http://localhost:8080" >> ~/.profile && source ~/.profile

done.

Windows

Open your PowerShell and execute

C:\> $env:GOPROXY = "http://localhost:8080"

or

1. Open the Start Search, type in "env"
2. Choose the "Edit the system environment variables"
3. Click the "Environment Variables…" button
4. Under the "User variables for <YOUR_USERNAME>" section (the upper half)
5. Click the "New..." button
6. Choose the "Variable name" input bar, type in "GOPROXY"
7. Choose the "Variable value" input bar, type in "http://localhost:8080"
8. Click the "OK" button

done.

Community

If you want to discuss Goproxy, or ask questions about it, simply post questions or ideas here.

Contributing

If you want to help build Goproxy, simply follow this to send pull requests here.

License

This project is licensed under the MIT License.

License can be found here.

Documentation

Overview

Package goproxy implements a minimalist Go module proxy handler.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func StartCleanupTask

func StartCleanupTask(dirCacher DirCacher, interval time.Duration)

StartCleanupTask starts a periodic cleanup task for the cache directory. It cleans up expired cache files every duration interval.

Types

type Cacher

type Cacher interface {
	// Get gets the matched cache for the name. It returns the
	// [os.ErrNotExist] if not found.
	//
	// Note that the returned [io.ReadCloser] can optionally implement the
	// following interfaces:
	//  1. [io.Seeker], mostly for the Range request header.
	//  2. interface{ LastModified() time.Time }, mostly 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 }, mostly 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 and sets it to expire after the given duration.
	Put(ctx context.Context, name string, content io.ReadSeeker, expiration time.Duration) error

	// Cleanup removes all expired cache files.
	Cleanup() error
}

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

type DirCacher

type DirCacher string

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

func (DirCacher) Cleanup

func (dc DirCacher) Cleanup() error

Cleanup implements the Cacher.

func (DirCacher) Get

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

Get implements the Cacher.

func (DirCacher) Put

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

Put implements the Cacher.

type Goproxy

type Goproxy struct {
	// GoBinName is the name of the Go binary.
	//
	// If the GoBinName is empty, the "go" is used.
	//
	// Note that the version of the Go binary targeted by the GoBinName must
	// be at least v1.11.
	GoBinName string

	// GoBinEnv is the environment of the Go binary. Each entry is of the
	// form "key=value".
	//
	// If the GoBinEnv is nil, the [os.Environ] is used.
	//
	// If the GoBinEnv contains duplicate environment keys, only the last
	// value in the slice for each duplicate key is used.
	//
	// Note that GOPROXY, GONOPROXY, GOSUMDB, GONOSUMDB and GOPRIVATE have
	// been built-in support. Which means they can be set even the version
	// of the Go binary targeted by the [Goproxy.GoBinName] is before v1.13.
	GoBinEnv []string

	// GoBinMaxWorkers is the maximum number of commands allowed for the Go
	// binary to execute at the same time.
	//
	// If the GoBinMaxWorkers is zero, there is no limit.
	GoBinMaxWorkers int

	// PathPrefix is the prefix of all request paths. It will be used to
	// trim the request paths via the [strings.TrimPrefix].
	//
	// If the PathPrefix is not empty, it must start with "/", and usually
	// should also end with "/".
	PathPrefix string

	// Cacher is the [Cacher] that used to cache module files.
	//
	// If the Cacher is nil, the module files will be temporarily stored on
	// the local disk and discarded as the request ends.
	Cacher Cacher

	// CacherMaxCacheBytes is the maximum number of bytes allowed for the
	// [Goproxy.Cacher] to store a cache.
	//
	// If the CacherMaxCacheBytes is zero, there is no limit.
	CacherMaxCacheBytes int

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

	// Transport is used to perform all requests except those started by
	// calling the Go binary targeted by the [Goproxy.GoBinName].
	//
	// If the Transport is nil, the [http.DefaultTransport] is used.
	Transport http.RoundTripper

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

	// ErrorLogger is the [log.Logger] that logs errors that occur while
	// proxying.
	//
	// If the ErrorLogger is nil, logging is done via the [log] package's
	// standard logger.
	ErrorLogger *log.Logger
	// contains filtered or unexported fields
}

Goproxy is the top-level struct of this project.

Note that the Goproxy will still follow your environment variables. Which means you can set GOPROXY to serve the Goproxy itself under other proxies, and by setting GONOPROXY and GOPRIVATE to instruct which modules the Goproxy should fetch directly instead of using those proxies. And you can also set GOSUMDB, GONOSUMDB and GOPRIVATE to instruct how the Goproxy should verify the modules it just fetched. All of the above environment variables have been built-in support, which means less external command calls and a significant performance boost.

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

Make sure that all fields of the Goproxy have been finalized before calling any of its methods.

func (*Goproxy) ServeHTTP

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

ServeHTTP implements the http.Handler.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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