docs: extend readme, add inline docs
This commit is contained in:
parent
778c92c3b9
commit
1d688d0263
12
go.mod
12
go.mod
@ -3,22 +3,10 @@ module github.com/emeralt/npm-cache-proxy
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/gzip v0.0.1
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect
|
||||
github.com/gin-contrib/zap v0.0.0-20190405225521-7c4b822813e7
|
||||
github.com/gin-gonic/gin v1.3.0
|
||||
github.com/go-redis/redis v6.15.2+incompatible
|
||||
github.com/golang/protobuf v1.3.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.6 // indirect
|
||||
github.com/mattn/go-isatty v0.0.7 // indirect
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.3 // indirect
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
go.uber.org/zap v1.9.1
|
||||
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 // indirect
|
||||
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6 // indirect
|
||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84 // indirect
|
||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
)
|
||||
|
29
go.sum
29
go.sum
@ -1,11 +1,6 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=
|
||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/zap v0.0.0-20190405225521-7c4b822813e7 h1:v6rNWmMnVDBVMc1pUUSCTobu2p4BukiPMwoj0pLqBhA=
|
||||
github.com/gin-contrib/zap v0.0.0-20190405225521-7c4b822813e7/go.mod h1:pQKeeey3PeRN2SbZe1jWiIkTJkylO9hL1K0Hf4Wbtt4=
|
||||
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
|
||||
@ -14,16 +9,9 @@ github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDA
|
||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -32,11 +20,7 @@ github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 h1:EICbibRW4JNKMcY+LsWmuwob+CRS1BmdRdjphAm9mH4=
|
||||
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||
@ -45,25 +29,12 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a h1:XCr/YX7O0uxRkLq2k1ApNQMims9eCioF9UpzIPBDmuo=
|
||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetMetadata returns cached NPM response for a given package path
|
||||
// GetMetadata returns cached NPM response for a given package path.
|
||||
func (proxy Proxy) GetMetadata(name string, originalPath string, request *http.Request) ([]byte, error) {
|
||||
options, err := proxy.GetOptions()
|
||||
if err != nil {
|
||||
@ -93,7 +93,7 @@ func (proxy Proxy) ListMetadata() ([]string, error) {
|
||||
return deprefixedMetadata, nil
|
||||
}
|
||||
|
||||
// PurgeMetadata deletes all cached packages
|
||||
// PurgeMetadata deletes all cached packages.
|
||||
func (proxy Proxy) PurgeMetadata() error {
|
||||
options, err := proxy.GetOptions()
|
||||
if err != nil {
|
||||
|
@ -6,26 +6,32 @@ import (
|
||||
"github.com/go-redis/redis"
|
||||
)
|
||||
|
||||
// DatabaseRedis implements Database interface for Redis database.
|
||||
type DatabaseRedis struct {
|
||||
Client *redis.Client
|
||||
}
|
||||
|
||||
// Get returns data by key.
|
||||
func (db DatabaseRedis) Get(key string) (string, error) {
|
||||
return db.Client.Get(key).Result()
|
||||
}
|
||||
|
||||
// Set stores value identified by key with expiration timeout.
|
||||
func (db DatabaseRedis) Set(key string, value string, expiration time.Duration) error {
|
||||
return db.Client.Set(key, value, expiration).Err()
|
||||
}
|
||||
|
||||
// Delete deletes data by key.
|
||||
func (db DatabaseRedis) Delete(key string) error {
|
||||
return db.Client.Del(key).Err()
|
||||
}
|
||||
|
||||
// Keys returns stored keys filtered by prefix.
|
||||
func (db DatabaseRedis) Keys(prefix string) ([]string, error) {
|
||||
return db.Client.Keys(prefix + "*").Result()
|
||||
}
|
||||
|
||||
// Health returns an error if database connection cannot be estabilished.
|
||||
func (db DatabaseRedis) Health() error {
|
||||
return db.Client.Ping().Err()
|
||||
}
|
||||
|
5
proxy/doc.go
Normal file
5
proxy/doc.go
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Package proxy implements a HTTP caching proxy for Node package registry (NPM).
|
||||
// See https://github.com/emeralt/npm-cache-proxy/ for more information about proxy.
|
||||
//
|
||||
package proxy // import "https://github.com/emeralt/npm-cache-proxy/proxy"
|
@ -5,6 +5,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Proxy is the proxy instance, it contains Database and HttpClient as static options
|
||||
// and GetOptions as dynamic options provider
|
||||
type Proxy struct {
|
||||
Database Database
|
||||
HttpClient *http.Client
|
||||
@ -12,12 +14,16 @@ type Proxy struct {
|
||||
GetOptions func() (Options, error)
|
||||
}
|
||||
|
||||
// Options provides dynamic options for Proxy.
|
||||
// This can be used for namespace separation,
|
||||
// allowing multiple users use the same proxy instance simultaneously.
|
||||
type Options struct {
|
||||
DatabasePrefix string
|
||||
DatabaseExpiration time.Duration
|
||||
UpstreamAddress string
|
||||
}
|
||||
|
||||
// Database provides interface for data storage.
|
||||
type Database interface {
|
||||
Get(key string) (string, error)
|
||||
Set(key string, value string, ttl time.Duration) error
|
||||
|
@ -13,15 +13,16 @@ type ServerOptions struct {
|
||||
ListenAddress string
|
||||
}
|
||||
|
||||
// Server creates http proxy server
|
||||
func (proxy Proxy) Server(options ServerOptions) *http.Server {
|
||||
router := gin.New()
|
||||
|
||||
logger, _ := zap.NewProduction()
|
||||
router.Use(ginzap.Ginzap(logger, time.RFC3339, true))
|
||||
|
||||
router.GET("/:scope/:name", proxy.GetPackageHandler)
|
||||
router.GET("/:scope", proxy.GetPackageHandler)
|
||||
router.NoRoute(proxy.NoRouteHandler)
|
||||
router.GET("/:scope/:name", proxy.getPackageHandler)
|
||||
router.GET("/:scope", proxy.getPackageHandler)
|
||||
router.NoRoute(proxy.noRouteHandler)
|
||||
|
||||
return &http.Server{
|
||||
Handler: router,
|
||||
@ -29,7 +30,7 @@ func (proxy Proxy) Server(options ServerOptions) *http.Server {
|
||||
}
|
||||
}
|
||||
|
||||
func (proxy Proxy) GetPackageHandler(c *gin.Context) {
|
||||
func (proxy Proxy) getPackageHandler(c *gin.Context) {
|
||||
var name string
|
||||
if c.Param("name") != "" {
|
||||
name = c.Param("scope") + "/" + c.Param("name")
|
||||
@ -47,7 +48,7 @@ func (proxy Proxy) GetPackageHandler(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (proxy Proxy) NoRouteHandler(c *gin.Context) {
|
||||
func (proxy Proxy) noRouteHandler(c *gin.Context) {
|
||||
if c.Request.URL.Path == "/" {
|
||||
err := proxy.Database.Health()
|
||||
|
||||
|
39
readme.md
39
readme.md
@ -3,16 +3,26 @@
|
||||

|
||||
|
||||
- [npm-cache-proxy](#npm-cache-proxy)
|
||||
- [Download](#download)
|
||||
- [Quick start](#quick-start)
|
||||
- [Deployment](#deployment)
|
||||
- [Usage](#usage)
|
||||
- [`ncp`](#ncp)
|
||||
- [`ncp list`](#ncp-list)
|
||||
- [`ncp purge`](#ncp-purge)
|
||||
- [Programmatic usage](#programmatic-usage)
|
||||
- [Example](#example)
|
||||
- [Benchmark](#benchmark)
|
||||
- [License](#license)
|
||||
|
||||
## Download
|
||||
You can download binary for your platform on the [Releases](https://github.com/emeralt/npm-cache-proxy/releases) page. Alternatively, you can use [Docker Image](https://cloud.docker.com/u/emeralt/repository/docker/emeralt/npm-cache-proxy).
|
||||
## Quick start
|
||||
Release binaries for different platforms can be downloaded on the [Releases](https://github.com/emeralt/npm-cache-proxy/releases) page. Also, [Docker Image](https://cloud.docker.com/u/emeralt/repository/docker/emeralt/npm-cache-proxy) is provided.
|
||||
|
||||
```bash
|
||||
docker run -e REDIS_ADDRESS=host.docker.internal:6379 -p 8080:8080 -it emeralt/npm-cache-proxy
|
||||
```
|
||||
|
||||
## Deployment
|
||||
NCP can be deployed using Kubernetes, Docker Compose or any other container orchestration platform. NCP supports running indefinite amount of instances simultaneously.
|
||||
|
||||
## Usage
|
||||
|
||||
@ -40,7 +50,13 @@ List cached packages.
|
||||
Purge cached packages.
|
||||
|
||||
## Programmatic usage
|
||||
Along with the CLI, go package is provided. Documentation is available on [godoc.org](https://godoc.org/github.com/emeralt/npm-cache-proxy/proxy).
|
||||
|
||||
```bash
|
||||
go get -u github.com/emeralt/npm-cache-proxy/proxy
|
||||
```
|
||||
|
||||
### Example
|
||||
```golang
|
||||
package main
|
||||
|
||||
@ -75,6 +91,23 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
|
||||
```bash
|
||||
# GOMAXPROCS=1 GIN_MODE=release ncp --listen localhost:8080
|
||||
|
||||
$ go-wrk -c 100 -d 5 http://localhost:8080/ascii
|
||||
Running 5s test @ http://localhost:8080/ascii
|
||||
100 goroutine(s) running concurrently
|
||||
33321 requests in 5.00537759s, 212.69MB read
|
||||
Requests/sec: 6657.04
|
||||
Transfer/sec: 42.49MB
|
||||
Avg Req Time: 15.02169ms
|
||||
Fastest Request: 230.514µs
|
||||
Slowest Request: 571.420487ms
|
||||
Number of Errors: 0
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./license)
|
||||
|
Loading…
x
Reference in New Issue
Block a user