support '0' listening port, readme update, showcase added

This commit is contained in:
yusing 2024-09-23 04:09:56 +08:00
parent 090b73d287
commit 3b597eea29
9 changed files with 271 additions and 241 deletions

View file

@ -24,7 +24,8 @@ A lightweight, easy-to-use, and [performant](docs/benchmark_result.md) reverse p
- [Use JSON Schema in VSCode](#use-json-schema-in-vscode) - [Use JSON Schema in VSCode](#use-json-schema-in-vscode)
- [Config File](#config-file) - [Config File](#config-file)
- [Provider File](#provider-file) - [Provider File](#provider-file)
- [Known issues](#known-issues) - [Showcase](#showcase)
- [idlesleeper](#idlesleeper)
- [Build it yourself](#build-it-yourself) - [Build it yourself](#build-it-yourself)
## Key Points ## Key Points
@ -35,7 +36,7 @@ A lightweight, easy-to-use, and [performant](docs/benchmark_result.md) reverse p
- Auto certificate obtaining and renewal (See [Supported DNS Challenge Providers](docs/dns_providers.md)) - Auto certificate obtaining and renewal (See [Supported DNS Challenge Providers](docs/dns_providers.md))
- Auto configuration for docker containers - Auto configuration for docker containers
- Auto hot-reload on container state / config file changes - Auto hot-reload on container state / config file changes
- Stop containers on idle, wake it up on traffic _(optional)_ - Stop containers on idle, wake it up on traffic _(optional, see [showcase](#idlesleeper))_
- HTTP(s) reserve proxy - HTTP(s) reserve proxy
- TCP and UDP port forwarding - TCP and UDP port forwarding
- Web UI for configuration and monitoring (See [screenshots](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots)) - Web UI for configuration and monitoring (See [screenshots](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots))
@ -124,9 +125,11 @@ See [providers.example.yml](providers.example.yml) for examples
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
## Known issues ## Showcase
- `autocert` config is not hot-reloadable ### idlesleeper
![idlesleeper](showcase/idlesleeper.webp)
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)

View file

@ -22,7 +22,8 @@
- [VSCode 中使用 JSON Schema](#vscode-中使用-json-schema) - [VSCode 中使用 JSON Schema](#vscode-中使用-json-schema)
- [配置文件](#配置文件) - [配置文件](#配置文件)
- [透過文件配置](#透過文件配置) - [透過文件配置](#透過文件配置)
- [已知問題](#已知問題) - [展示](#展示)
- [idlesleeper](#idlesleeper)
- [源碼編譯](#源碼編譯) - [源碼編譯](#源碼編譯)
## 重點 ## 重點
@ -120,9 +121,11 @@ providers:
[🔼 返回頂部](#目錄) [🔼 返回頂部](#目錄)
## 已知問題 ## 展示
- `autocert` 配置不能熱重載 ### idlesleeper
![idlesleeper](showcase/idlesleeper.webp)
[🔼 返回頂部](#目錄) [🔼 返回頂部](#目錄)

View file

@ -85,29 +85,29 @@
### Syntax ### Syntax
| Label | Description | Default | Accepted values | | Label | Description | Example | Default | Accepted values |
| ------------------------ | --------------------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------- | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | --------------------------- | ------------------------------------------------------------------------- |
| `proxy.aliases` | comma separated aliases for subdomain and label matching | `container_name` | any | | `proxy.aliases` | comma separated aliases for subdomain and label matching | `gitlab,gitlab-reg,gitlab-ssh` | `container_name` | any |
| `proxy.exclude` | to be excluded from `go-proxy` | false | boolean | | `proxy.exclude` | to be excluded from `go-proxy` | | false | boolean |
| `proxy.idle_timeout` | time for idle (no traffic) before put it into sleep **(http/s only)** | empty **(disabled)** | `number[unit]...`, e.g. `1m30s` | | `proxy.idle_timeout` | time for idle (no traffic) before put it into sleep **(http/s only)**<br> _**NOTE: idlewatcher will only be enabled containers that has non-empty `idle_timeout`**_ | `1h` | empty or `0` **(disabled)** | `number[unit]...`, e.g. `1m30s` |
| `proxy.wake_timeout` | time to wait for container to start before responding a loading page | empty | `number[unit]...` | | `proxy.wake_timeout` | time to wait for target site to be ready | | `10s` | `number[unit]...` |
| `proxy.stop_method` | method to stop after `idle_timeout` | `stop` | `stop`, `pause`, `kill` | | `proxy.stop_method` | method to stop after `idle_timeout` | | `stop` | `stop`, `pause`, `kill` |
| `proxy.stop_timeout` | time to wait for stop command | `10s` | `number[unit]...` | | `proxy.stop_timeout` | time to wait for stop command | | `10s` | `number[unit]...` |
| `proxy.stop_signal` | signal sent to container for `stop` and `kill` methods | docker's default | `SIGINT`, `SIGTERM`, `SIGHUP`, `SIGQUIT` and those without **SIG** prefix | | `proxy.stop_signal` | signal sent to container for `stop` and `kill` methods | | docker's default | `SIGINT`, `SIGTERM`, `SIGHUP`, `SIGQUIT` and those without **SIG** prefix |
| `proxy.<alias>.<field>` | set field for specific alias | N/A | N/A | | `proxy.<alias>.<field>` | set field for specific alias | `proxy.gitlab-ssh.scheme` | N/A | N/A |
| `proxy.$<index>.<field>` | set field for specific alias at index (starting from **1**) | N/A | N/A | | `proxy.$<index>.<field>` | set field for specific alias at index (starting from **1**) | `proxy.$3.port` | N/A | N/A |
| `proxy.*.<field>` | set field for all aliases | N/A | N/A | | `proxy.*.<field>` | set field for all aliases | `proxy.*.set_headers` | N/A | N/A |
### Fields ### Fields
| Field | Description | Default | Allowed Values / Syntax | | Field | Description | Default | Allowed Values / Syntax |
| --------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | --------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `scheme` | proxy protocol | <ul><li>`http` for numeric port</li><li>`tcp` for `x:y` port</li></ul> | `http`, `https`, `tcp`, `udp` | | `scheme` | proxy protocol | <ul><li>`http` for numeric port</li><li>`tcp` for `x:y` port</li></ul> | `http`, `https`, `tcp`, `udp` |
| `host` | proxy host | <ul><li>Docker: docker client IP / hostname </li><li>File: `localhost`</li></ul> | IP address, hostname | | `host` | proxy host | <ul><li>Docker: docker client IP / hostname </li><li>File: `localhost`</li></ul> | IP address, hostname |
| `port` | proxy port **(http/s)** | first port in `ports:` | number in range of `1 - 65535` | | `port` | proxy port **(http/s)** | first port returned from docker | number in range of `1 - 65535` |
| `port` **(required)** | proxy port **(tcp/udp)** | N/A | `x:y` <br><ul><li>x: port for `go-proxy` to listen on</li><li>y: port or [_service name_](../src/common/constants.go#L55) of target container</li></ul> | | `port` **(required)** | proxy port **(tcp/udp)** | N/A | `x:y` <br><ul><li>**x**: port for `go-proxy` to listen on.<br>**x** can be 0, which means listen on a random port</li><li>**y**: port or [_service name_](../src/common/constants.go#L55) of target container</li></ul> |
| `no_tls_verify` | whether skip tls verify **(https only)** | `false` | boolean | | `no_tls_verify` | whether skip tls verify **(https only)** | `false` | boolean |
| `path_patterns` | proxy path patterns **(http/s only)**<br> only requests that matched a pattern will be proxied | empty **(proxy all requests)** | yaml style list[<sup>1</sup>](#list-example) of path patterns ([syntax](https://pkg.go.dev/net/http#hdr-Patterns-ServeMux)) | | `path_patterns` | proxy path patterns **(http/s only)**<br> only requests that matched a pattern will be proxied | empty **(proxy all requests)** | yaml style list[<sup>1</sup>](#list-example) of ([path patterns](https://pkg.go.dev/net/http#hdr-Patterns-ServeMux)) |
| `set_headers` | header to set **(http/s only)** | empty | yaml style key-value mapping[<sup>2</sup>](#key-value-mapping-example) of header-value pairs | | `set_headers` | header to set **(http/s only)** | empty | yaml style key-value mapping[<sup>2</sup>](#key-value-mapping-example) of header-value pairs |
| `hide_headers` | header to hide **(http/s only)** | empty | yaml style list[<sup>1</sup>](#list-example) of headers | | `hide_headers` | header to hide **(http/s only)** | empty | yaml style list[<sup>1</sup>](#list-example) of headers |

View file

@ -14,8 +14,8 @@ example: # matching `app.y.z`
hide_headers: hide_headers:
- HEADER_C - HEADER_C
- HEADER_D - HEADER_D
app1: app1: # app1 -> localhost:8080
host: some_host port: 8080
app2: app2:
scheme: tcp scheme: tcp
host: 10.0.0.2 host: 10.0.0.2

View file

@ -75,7 +75,10 @@
"scheme": { "scheme": {
"anyOf": [ "anyOf": [
{ {
"enum": ["http", "https"] "enum": [
"http",
"https"
]
}, },
{ {
"type": "null" "type": "null"
@ -87,7 +90,7 @@
"then": { "then": {
"properties": { "properties": {
"port": { "port": {
"markdownDescription": "Proxy port from **1** to **65535**", "markdownDescription": "Proxy port from **0** to **65535**",
"oneOf": [ "oneOf": [
{ {
"type": "string", "type": "string",
@ -96,7 +99,7 @@
}, },
{ {
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 0,
"maximum": 65535 "maximum": 65535
} }
] ]
@ -160,7 +163,9 @@
"not": true "not": true
} }
}, },
"required": ["port"] "required": [
"port"
]
} }
}, },
{ {

BIN
showcase/idlesleeper.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 KiB

View file

@ -7,6 +7,7 @@ import (
"sync" "sync"
"time" "time"
T "github.com/yusing/go-proxy/proxy/fields"
U "github.com/yusing/go-proxy/utils" U "github.com/yusing/go-proxy/utils"
) )
@ -35,6 +36,8 @@ func (route *TCPRoute) Setup() error {
if err != nil { if err != nil {
return err return err
} }
//! this read the allocated port from orginal ':0'
route.Port.ListeningPort = T.Port(in.Addr().(*net.TCPAddr).Port)
route.listener = in route.listener = in
return nil return nil
} }

View file

@ -5,6 +5,7 @@ import (
"io" "io"
"net" "net"
T "github.com/yusing/go-proxy/proxy/fields"
U "github.com/yusing/go-proxy/utils" U "github.com/yusing/go-proxy/utils"
F "github.com/yusing/go-proxy/utils/functional" F "github.com/yusing/go-proxy/utils/functional"
) )
@ -50,6 +51,9 @@ func (route *UDPRoute) Setup() error {
return err return err
} }
//! this read the allocated listeningPort from orginal ':0'
route.Port.ListeningPort = T.Port(laddr.Port)
route.listeningConn = source route.listeningConn = source
route.targetAddr = raddr route.targetAddr = raddr
return nil return nil

View file

@ -1,6 +1,10 @@
package utils package utils
import "strings" import (
"net/url"
"strconv"
"strings"
)
func CommaSeperatedList(s string) []string { func CommaSeperatedList(s string) []string {
res := strings.Split(s, ",") res := strings.Split(s, ",")
@ -9,3 +13,11 @@ func CommaSeperatedList(s string) []string {
} }
return res return res
} }
func ExtractPort(fullURL string) (int, error) {
url, err := url.Parse(fullURL)
if err != nil {
return 0, err
}
return strconv.Atoi(url.Port())
}