govanityurls

package module
v0.1.0 Latest Latest
Warning

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

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

README

Go Vanity URLs

Go Vanity URLs is a simple Go server that allows you to set custom import paths for your Go packages. It also can run on Google App Engine and Google Cloud Run.

Quickstart

  1. Download the source code:
$ git clone https://github.com/markxp/govanityurls
$ cd govanityurls/cmd
  1. Build the container image:
# The `location` is the region of your docker artifact registry, e.g. `us-central1`, `europe-west1` for regional registry, or `asia` for multi-regional registry.

# In this example, we use buildpacks to build the container.

# a. build locally with buildpacks
$ pack build ${location}-docker.pkg.dev/<your-project>/<repository-name>/<image-name>:<tag> --builder gcr.io/buildpacks/builder:latest

# ... and push it to the artifact registry
$ docker push ${location}-docker.pkg.dev/<your-project>/<repository-name>/<image-name>:<tag>


# or
# b. you prefer build image remotely on cloud build
$ gcloud builds submit --pack="builder=gcr.io/buildpacks/builder:latest,image=${location}-docker.pkg.dev/<your-project>/<repository-name>/<image-name>:<tag>"
  1. Deploy the application:
# If you use App Engine(standard environment), you do not need to build the container image.
a. Deploy to App Engine(standard environment)
# write a app.yaml file....
$ gcloud app deploy .

b. Deploy to Clou Run
$ gcloud run deploy --image {image-from-step-2} --platform managed
...OR deploy without building the image (directly from source code)
$ cd ../
$ gcloud run deploy {service-name} --source . --platform managed --region {region} --allow-unauthenticated
  1. Prepare the storage and Cloud Tasks queue (optional):
# We use firestore as the storage. Create the database.

# (optional) Create the queue. Noting that the service account of the queue should have permission to hit the server's endpoint `POST {host}/_internal/createRepo`.

(deprecated) View vanity.yaml to know how to add repos. E.g., custom-domain.com/portmidi will serve the https://github.com/rakyll/portmidi repo.

paths:
  /portmidi:
    repo: https://github.com/rakyll/portmidi

And use the module with go get:

$ go get customdomain.com/portmidi

App Configuration

host: example.com
cache_max_age: 3600
Key Required Description
cache_max_age optional The amount of time to cache package pages in seconds. Controls the max-age directive sent in the Cache-Control HTTP header.
host optional Host name to use in meta tags. If omitted, uses the request "host" haeder to derive host name. You can use this option to fix the host when using this service behind a reverse proxy or a custom dispatch file.
Path Configuration
Key Required Description
display optional The last three fields of the go-source meta tag. If omitted, it is inferred from the code hosting service if possible.
repo required Root URL of the repository as it would appear in go-import meta tag.
vcs required If the version control system cannot be inferred (e.g. for Bitbucket or a custom domain), then this specifies the version control system as it would appear in go-import meta tag. This can be one of git, hg, svn, or bzr.A special value mod can be used to specify the module uses Go Module Proxy to serve bundled source code directly instead of using version control system.

Documentation

Overview

govanityurls serves Go vanity URLs.

Index

Constants

This section is empty.

Variables

View Source
var IAPHeaderNotExist = errors.New("x-goog-iap-jwt-assertion header is not present")

Functions

This section is empty.

Types

type App

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

func NewApp

func NewApp(host string, cacheMaxAge int, store storage.Storage, fallback *FallbackConfig, registries []registry.Registry, asyncCfg *AsyncRegisterConfig, logger slogLimitedLogger) *App

NewServer creates a new http.Server which responds to Go's import meta tags. The `addr` is http.Server.Addr. It is required, and the format "host:port" is not recommended here. please just use ":port". The `host` is the host name that will be used in the import meta tags. This is required if your app sets behind a reverse proxy, or environment like App Engine or Cloud Run but you only allows the source code to be retrived through the canonical custom domain URL. Besides, you can modify the timeouts of the server, just like a normal `http.Server`.

func (*App) GetPrivateHandlers

func (app *App) GetPrivateHandlers() iter.Seq2[string, http.Handler]

GetPrivateHandlers returns a sequence of private handlers. It returns a string: http.Handler pair. The string is the path of the handler, which has the compatiable format for http.ServeMux (Go1.22+).

func (*App) GetPublicHandlers

func (app *App) GetPublicHandlers() iter.Seq2[string, http.Handler]

GetPublicHandlers returns a sequence of public handlers. It returns a string: http.Handler pair. The string is the path of the handler, which has the compatiable format for http.ServeMux (Go1.22+).

func (*App) RegisterShutdownFunc

func (app *App) RegisterShutdownFunc(s *http.Server)

type AsyncRegisterConfig

type AsyncRegisterConfig struct {
	TaskClient               TaskSubmitter
	TaskClientServiceAccount string
}

type CloudTasksSubmitter

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

CloudTasksSubmitter implements TaskSubmitter. It uses Cloud Tasks to do asynchrous calls. It manages submitting tasks to Google Cloud Tasks.

func NewCloudTasksSubmitter

func NewCloudTasksSubmitter(client *cloudtasks.Client, queuePath, targetURL, serviceAccountEmail string, opts ...CloudTasksSubmitterOption) *CloudTasksSubmitter

NewCloudTasksSubmitter creates a new CloudTasksSubmitter. It uses `client`, `queuePath` to push requests to `targetURL`, on the behalf of `serviceAccountEmail`.

func (*CloudTasksSubmitter) Close

func (s *CloudTasksSubmitter) Close(ctx context.Context) error

Close closes the underlying client.

func (*CloudTasksSubmitter) CreateTask

func (s *CloudTasksSubmitter) CreateTask(ctx context.Context, payload *WriteConfigPayload) error

CreateTask submits a task to write the configuration to storage.

type CloudTasksSubmitterOption

type CloudTasksSubmitterOption func(*CloudTasksSubmitter)

CloudTasksSubmitterOption is an option for CloudTasksSubmitter.

func WithAudience

func WithAudience(audience string) CloudTasksSubmitterOption

WithAudience is a CloudTasksSubmitterOption that sets the audience for the task.

type FallbackConfig

type FallbackConfig struct {
	RepoChecker registry.RepoChecker
	Registry    registry.Registry
}

type IAP

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

IAP validates IAP JWT tokens.

func NewIAP

func NewIAP(audience string, logger slogLimitedLogger) *IAP

func (*IAP) Middleware

func (iap *IAP) Middleware(next http.Handler) http.Handler

func (*IAP) ValidateIAPToken

func (iap *IAP) ValidateIAPToken(r *http.Request) (*idtoken.Payload, error)

type TaskSubmitter

type TaskSubmitter interface {
	CreateTask(ctx context.Context, payload *WriteConfigPayload) error
	Close(ctx context.Context) error
}

TaskSubmitter let us do asynchrous write-back to storage.

type WriteConfigPayload

type WriteConfigPayload struct {
	Path   string              `json:"path"`
	Config *storage.RepoConfig `json:"config"`
}

WriteConfigPayload defines the payload for creating a repo configuration.

Directories

Path Synopsis
contrib

Jump to

Keyboard shortcuts

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