1
0
mirror of https://github.com/umputun/reproxy.git synced 2025-02-10 18:31:30 +02:00

Merge branch 'master' into master

This commit is contained in:
Umputun 2021-04-17 22:39:07 -05:00 committed by GitHub
commit 1e686ab5b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 62 additions and 14 deletions

View File

@ -38,7 +38,7 @@ Example with an automatic docker discovery:
## Install
- for a binary distribution pick the proper file in the [release section](https://github.com/umputun/reproxy/releases)
- docker container available on [Docker Hub](https://hub.docker.com/r/umputun/reproxy) as well as on [Github Container Registry](ghcr.io/umputun/reproxy).
- docker container available on [Docker Hub](https://hub.docker.com/r/umputun/reproxy) as well as on [Github Container Registry](https://ghcr.io/umputun/reproxy). I.e. `docker pull umputun/reproxy` or `docker pull ghcr.io/umputun/reproxy`.
Latest stable version has `:vX.Y.Z` tag (with `:latest` alias) and the current master has `:master` tag.

View File

@ -313,16 +313,30 @@ func NewDockerClient(host, network string) DockerClient {
}
func (d *dockerClient) ListContainers() ([]containerInfo, error) {
// const APIVersion = "v1.41"
// resp, err := d.client.Get(fmt.Sprintf("http://localhost/%s/containers/json", APIVersion))
resp, err := d.client.Get("http://localhost/containers/json")
// Minimum API version that returns attached networks
// docs.docker.com/engine/api/version-history/#v122-api-changes
const APIVersion = "v1.22"
resp, err := d.client.Get(fmt.Sprintf("http://localhost/%s/containers/json", APIVersion))
if err != nil {
return nil, fmt.Errorf("failed connection to docker socket: %w", err)
}
defer resp.Body.Close()
var response []struct {
if resp.StatusCode != http.StatusOK {
e := struct {
Message string `json:"message"`
}{}
if err := json.NewDecoder(resp.Body).Decode(&e); err != nil {
return nil, fmt.Errorf("failed to parse error from docker daemon: %w", err)
}
return nil, fmt.Errorf("unexpected error from docker daemon: %s", e.Message)
}
response := []struct {
ID string `json:"Id"`
Name string
State string

View File

@ -174,7 +174,7 @@ func TestDocker_refresh(t *testing.T) {
func TestDockerClient(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/containers/json", r.URL.Path)
require.Equal(t, `/v1.22/containers/json`, r.URL.Path)
// obtained using curl --unix-socket /var/run/docker.sock http://localhost/v1.41/containers/json
resp, err := ioutil.ReadFile("testdata/containers.json")
@ -201,3 +201,16 @@ func TestDockerClient(t *testing.T) {
assert.Empty(t, c[1].IP)
}
func TestDockerClient_error(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, `{"message": "bruh"}`, http.StatusInternalServerError)
}))
defer srv.Close()
addr := fmt.Sprintf("tcp://%s", strings.TrimPrefix(srv.URL, "http://"))
client := NewDockerClient(addr, "bridge")
_, err := client.ListContainers()
require.EqualError(t, err, "unexpected error from docker daemon: bruh")
}

View File

@ -21,6 +21,7 @@ func Test_Main(t *testing.T) {
port := chooseRandomUnusedPort()
os.Args = []string{"test", "--static.enabled",
"--static.rule=*,/svc1, https://httpbin.org/get,https://feedmaster.umputun.com/ping",
"--static.rule=*,/svc2/(.*), https://echo.umputun.com/$1,https://feedmaster.umputun.com/ping",
"--dbg", "--logger.stdout", "--listen=127.0.0.1:" + strconv.Itoa(port), "--signature"}
done := make(chan struct{})
@ -62,11 +63,21 @@ func Test_Main(t *testing.T) {
assert.Equal(t, 200, resp.StatusCode)
body, err := ioutil.ReadAll(resp.Body)
assert.NoError(t, err)
assert.Contains(t, string(body), `"Host": "127.0.0.1"`)
assert.Contains(t, string(body), `"Host": "httpbin.org"`)
}
{
client := http.Client{Timeout: 10 * time.Second}
resp, err := client.Get(fmt.Sprintf("http://127.0.0.1:%d/bas", port))
resp, err := client.Get(fmt.Sprintf("http://127.0.0.1:%d/svc2/test", port))
require.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, 200, resp.StatusCode)
body, err := ioutil.ReadAll(resp.Body)
assert.NoError(t, err)
assert.Contains(t, string(body), `echo echo 123`)
}
{
client := http.Client{Timeout: 10 * time.Second}
resp, err := client.Get(fmt.Sprintf("http://127.0.0.1:%d/bad", port))
require.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusBadGateway, resp.StatusCode)

View File

@ -151,11 +151,12 @@ func (h *Http) proxyHandler() http.HandlerFunc {
Director: func(r *http.Request) {
ctx := r.Context()
uu := ctx.Value(contextKey("url")).(*url.URL)
r.Header.Add("X-Forwarded-Host", uu.Host)
r.Header.Set("X-Origin-Host", r.Host)
r.URL.Path = uu.Path
r.URL.Host = uu.Host
r.URL.Scheme = uu.Scheme
r.Header.Add("X-Forwarded-Host", uu.Host)
r.Header.Add("X-Origin-Host", r.Host)
r.Host = uu.Host
h.setXRealIP(r)
},
Transport: &http.Transport{

2
go.mod
View File

@ -5,7 +5,7 @@ go 1.16
require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/go-pkgz/lgr v0.10.4
github.com/go-pkgz/rest v1.9.1
github.com/go-pkgz/rest v1.9.2
github.com/gorilla/handlers v1.5.1
github.com/stretchr/testify v1.7.0
github.com/umputun/go-flags v1.5.1

2
go.sum
View File

@ -8,6 +8,8 @@ github.com/go-pkgz/lgr v0.10.4 h1:l7qyFjqEZgwRgaQQSEp6tve4A3OU80VrfzpvtEX8ngw=
github.com/go-pkgz/lgr v0.10.4/go.mod h1:CD0s1z6EFpIUplV067gitF77tn25JItzwHNKAPqeCF0=
github.com/go-pkgz/rest v1.9.1 h1:JW876BgJJ/MOkAYRnnzpfX7xUqIav+ou1LSVTtQq/Lo=
github.com/go-pkgz/rest v1.9.1/go.mod h1:wZ/dGipZUaF9to0vIQl7PwDHgWQDB0jsrFg1xnAKLDw=
github.com/go-pkgz/rest v1.9.2 h1:RyBBRXBYY6eBgTW3UGYOyT4VQPDiBBFh/tesELWsryQ=
github.com/go-pkgz/rest v1.9.2/go.mod h1:wZ/dGipZUaF9to0vIQl7PwDHgWQDB0jsrFg1xnAKLDw=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

View File

@ -41,6 +41,7 @@ type logParts struct {
remoteIP string
statusCode int
respSize int
host string
prefix string
user string
@ -108,10 +109,16 @@ func (l *Middleware) Handler(next http.Handler) http.Handler {
remoteIP = l.ipFn(remoteIP)
}
server := r.URL.Hostname()
if server == "" {
server = strings.Split(r.Host, ":")[0]
}
p := &logParts{
duration: t2.Sub(t1),
rawURL: rawurl,
method: r.Method,
host: server,
remoteIP: remoteIP,
statusCode: ww.status,
respSize: ww.size,
@ -135,8 +142,8 @@ func (l *Middleware) formatDefault(r *http.Request, p *logParts) string {
_, _ = bld.WriteString(" ")
}
_, _ = bld.WriteString(fmt.Sprintf("%s - %s - %s - %d (%d) - %v",
p.method, p.rawURL, p.remoteIP, p.statusCode, p.respSize, p.duration))
_, _ = bld.WriteString(fmt.Sprintf("%s - %s - %s - %s - %d (%d) - %v",
p.method, p.rawURL, p.host, p.remoteIP, p.statusCode, p.respSize, p.duration))
if p.user != "" {
_, _ = bld.WriteString(" - ")

2
vendor/modules.txt vendored
View File

@ -7,7 +7,7 @@ github.com/felixge/httpsnoop
# github.com/go-pkgz/lgr v0.10.4
## explicit
github.com/go-pkgz/lgr
# github.com/go-pkgz/rest v1.9.1
# github.com/go-pkgz/rest v1.9.2
## explicit
github.com/go-pkgz/rest
github.com/go-pkgz/rest/logger