Skip to content

Commit 70134c4

Browse files
committed
all: implement /s and /x redirector
Fixes #1 Fixes #2
1 parent 97afd08 commit 70134c4

23 files changed

+1288
-1
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
# Output of the go coverage tool, specifically when used with LiteIDE
1212
*.out
13+
*.app
14+
*.rdb
1315

1416
# Dependency directories (remove the comment below to include it)
15-
# vendor/
17+
vendor/

Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright 2020 The golang.design Initiative authors.
2+
# All rights reserved. Use of this source code is governed
3+
# by a MIT license that can be found in the LICENSE file.
4+
5+
VERSION = $(shell git describe --always --tags)
6+
BUILDTIME = $(shell date +%FT%T%z)
7+
GOPATH=$(shell go env GOPATH)
8+
IMAGE = golang-design/redir
9+
BINARY = redir.app
10+
TARGET = -o $(BINARY)
11+
BUILD_SETTINGS = -ldflags="-X main.Version=$(VERSION) -X main.BuildTime=$(BUILDTIME)"
12+
BUILD_FLAGS = $(TARGET) $(BUILD_SETTINGS)
13+
14+
all: native
15+
native:
16+
GO111MODULE=on go build $(BUILD_FLAGS)
17+
run:
18+
./$(BINARY) -s
19+
build:
20+
docker build -t $(IMAGE):$(VERSION) -t $(IMAGE):latest -f docker/Dockerfile .
21+
compose:
22+
docker-compose -f docker/docker-compose.yml up -d
23+
compose-down:
24+
docker-compose -f docker/docker-compose.yml down
25+
clean:
26+
rm redir.app
27+
docker rmi -f $(shell docker images -f "dangling=true" -q) 2> /dev/null; true
28+
docker rmi -f $(IMAGE):latest $(IMAGE):$(VERSION) 2> /dev/null; true
29+
.PHONY: native run build compose clean

README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,82 @@
11
# redir
2+
23
a request redirector that is dedicated for golang.design
4+
5+
## Design Purpose
6+
7+
The current `redir` implementation talks to a redis data store for PV/UV counting,
8+
as well as short alias storage. In the booting phase, it will read `REDIR_CONF`
9+
from environment variable to identify configuration file (default: `./config.yml`).
10+
11+
`redir` is designed for the following purpose: serve two major
12+
redirectors `/s` and `/x` (at the moment).
13+
14+
### 1. Redirect `golang.design/x/pkg` to the `pkg`'s actual VCS.
15+
16+
This is based on the `go get` vanity import path convention. With this
17+
feature, all packages issued by [golang.design](https://golang.design)
18+
requires to use `golang.design/x/` import path.
19+
That is saying, any `pkg` will be redirected to `github.com/golang-design/pkg`
20+
if exist. The website itself will redirect the request to [pkg.go.dev](https://pkg.go.dev).
21+
22+
There is a reserved ping router for debugging purpose `/x/.ping` which will
23+
give you a pong.
24+
25+
### 2. Redirect `golang.design/s/alias`
26+
27+
The served alias can be allocated by [golang.design](https://golang.design/) members.
28+
The current approach is to use `redir` command on the [golang.design](https://golang.design/)
29+
server. Here is the overview of its usage:
30+
31+
```
32+
usage: redir [-s] [-op <operator> -a <alias> -l <link>]
33+
options:
34+
-a string
35+
alias for a new link
36+
-l string
37+
actual link for the alias, optional for delete/fetch
38+
-op string
39+
operators, create/update/delete/fetch (default "create")
40+
-s run redir service
41+
example:
42+
redir -s run the redir service
43+
redir -a alias -l link allocate new short link if possible
44+
redir -op fetch -a alias fetch alias information
45+
```
46+
47+
For the command line usage, one only need to use `-a`, `-l` and `-op` if needed.
48+
The command will talk to the redis data store and issue a new allocated alias.
49+
For instance, the following command:
50+
51+
```
52+
redir -a changkun -l https://changkun.de
53+
```
54+
55+
creates a new alias under [golang.design/s/changkun](https://golang.design/s/changkun).
56+
57+
Moreover, it is possible to visit [`/s`](https://golang.design/s) directly listing all exist aliases under [golang.design](https://golang.design/).
58+
59+
## Build
60+
61+
`Makefile` defines different ways to build the service:
62+
63+
```bash
64+
make # build native binary
65+
make run # assume your local redis is running
66+
make build # build docker images
67+
make compose # run via docker-compose
68+
make compose-down # remove compose stuff
69+
make clean # cleanup
70+
```
71+
72+
## Troubleshooting
73+
74+
### private golang.design projects `go get` failure
75+
76+
1. make sure you are a member of golang.design
77+
2. add ssh public key to your account
78+
3. `git config --global url."[email protected]:".insteadOf "https://github.com/"`
79+
80+
## License
81+
82+
MIT &copy; The golang.design Initiative Authors

config.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2020 The golang.design Initiative authors.
2+
// All rights reserved. Use of this source code is governed
3+
// by a MIT license that can be found in the LICENSE file.
4+
5+
package main
6+
7+
import (
8+
"io/ioutil"
9+
"log"
10+
"os"
11+
"runtime"
12+
13+
"gopkg.in/yaml.v2"
14+
)
15+
16+
// build info, assign by compile time or runtime.
17+
var (
18+
Version string
19+
BuildTime string
20+
GoVersion = runtime.Version()
21+
)
22+
23+
type config struct {
24+
Host string `json:"host"`
25+
Addr string `json:"addr"`
26+
Store string `json:"store"`
27+
Log string `json:"log"`
28+
S struct {
29+
Prefix string `json:"prefix"`
30+
} `json:"s"`
31+
X struct {
32+
Prefix string `json:"prefix"`
33+
VCS string `json:"vcs"`
34+
ImportPath string `json:"import_path"`
35+
RepoPath string `json:"repo_path"`
36+
} `json:"x"`
37+
}
38+
39+
func (c *config) parse() {
40+
f := os.Getenv("REDIR_CONF")
41+
d, err := ioutil.ReadFile(f)
42+
if err != nil {
43+
// Just try again with default setting.
44+
d, err = ioutil.ReadFile("./config.yml")
45+
if err != nil {
46+
log.Fatalf("cannot read configuration, err: %v\n", err)
47+
}
48+
}
49+
err = yaml.Unmarshal(d, c)
50+
if err != nil {
51+
log.Fatalf("cannot parse configuration, err: %v\n", err)
52+
}
53+
}
54+
55+
var conf config
56+
57+
func init() {
58+
conf.parse()
59+
}

config.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright 2020 The golang.design Initiative authors.
2+
# All rights reserved. Use of this source code is governed
3+
# by a MIT license that can be found in the LICENSE file.
4+
5+
---
6+
host: https://golang.design
7+
addr: :8080
8+
store: redis://localhost:6379/9
9+
log: "golang.design/redir: "
10+
s:
11+
prefix: /s/
12+
x:
13+
prefix: /x/
14+
vcs: git
15+
import_path: golang.design/x/*
16+
repo_path: https://github.com/golang-design/*

config_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2020 The golang.design Initiative authors.
2+
// All rights reserved. Use of this source code is governed
3+
// by a MIT license that can be found in the LICENSE file.
4+
5+
package main
6+
7+
import (
8+
"reflect"
9+
"testing"
10+
)
11+
12+
func TestParseConfig(t *testing.T) {
13+
conf.parse()
14+
15+
// Test if all fields are filled.
16+
v := reflect.ValueOf(conf)
17+
for i := 0; i < v.NumField(); i++ {
18+
if v.Field(i).Kind() == reflect.Struct {
19+
continue
20+
}
21+
vv, ok := v.Field(i).Interface().(string)
22+
if ok && len(vv) > 0 {
23+
continue
24+
}
25+
t.Fatalf("read empty from config, field: %v", v.Type().Field(i).Name)
26+
}
27+
}

data/container.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright 2020 The golang.design Initiative authors.
2+
# All rights reserved. Use of this source code is governed
3+
# by a MIT license that can be found in the LICENSE file.
4+
5+
---
6+
host: https://golang.design/
7+
addr: :8080
8+
store: redis://redis:6379/9
9+
log: "golang.design/redir: "
10+
s:
11+
prefix: /s/
12+
x:
13+
prefix: /x/
14+
vcs: git
15+
import_path: golang.design/x/*
16+
repo_path: https://github.com/golang-design/*

0 commit comments

Comments
 (0)