mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 01:38:30 +02:00
perf(mem): replace Scheme and ExcludedReason string with uint8 type to reduce mem usage
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
|||||||
. "github.com/yusing/godoxy/internal/entrypoint"
|
. "github.com/yusing/godoxy/internal/entrypoint"
|
||||||
"github.com/yusing/godoxy/internal/route"
|
"github.com/yusing/godoxy/internal/route"
|
||||||
"github.com/yusing/godoxy/internal/route/routes"
|
"github.com/yusing/godoxy/internal/route/routes"
|
||||||
|
routeTypes "github.com/yusing/godoxy/internal/route/types"
|
||||||
"github.com/yusing/godoxy/internal/types"
|
"github.com/yusing/godoxy/internal/types"
|
||||||
"github.com/yusing/goutils/task"
|
"github.com/yusing/goutils/task"
|
||||||
)
|
)
|
||||||
@@ -78,7 +79,7 @@ func BenchmarkEntrypointReal(b *testing.B) {
|
|||||||
|
|
||||||
r := &route.Route{
|
r := &route.Route{
|
||||||
Alias: "test",
|
Alias: "test",
|
||||||
Scheme: "http",
|
Scheme: routeTypes.SchemeHTTP,
|
||||||
Host: host,
|
Host: host,
|
||||||
Port: route.Port{Proxy: portInt},
|
Port: route.Port{Proxy: portInt},
|
||||||
HealthCheck: &types.HealthCheckConfig{Disable: true},
|
HealthCheck: &types.HealthCheckConfig{Disable: true},
|
||||||
@@ -119,7 +120,7 @@ func BenchmarkEntrypoint(b *testing.B) {
|
|||||||
|
|
||||||
r := &route.Route{
|
r := &route.Route{
|
||||||
Alias: "test",
|
Alias: "test",
|
||||||
Scheme: "http",
|
Scheme: routeTypes.SchemeHTTP,
|
||||||
Host: "localhost",
|
Host: "localhost",
|
||||||
Port: route.Port{
|
Port: route.Port{
|
||||||
Proxy: 8080,
|
Proxy: 8080,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package route
|
package route
|
||||||
|
|
||||||
|
import route "github.com/yusing/godoxy/internal/route/types"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ImageNamePortMapTCP = map[string]int{
|
ImageNamePortMapTCP = map[string]int{
|
||||||
"mssql": 1433,
|
"mssql": 1433,
|
||||||
@@ -57,25 +59,25 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func getSchemePortByImageName(imageName string) (scheme string, port int, ok bool) {
|
func getSchemePortByImageName(imageName string) (scheme route.Scheme, port int, ok bool) {
|
||||||
if port, ok := ImageNamePortMapHTTP[imageName]; ok {
|
if port, ok := ImageNamePortMapHTTP[imageName]; ok {
|
||||||
return "http", port, true
|
return route.SchemeHTTP, port, true
|
||||||
}
|
}
|
||||||
if port, ok := ImageNamePortMapHTTPS[imageName]; ok {
|
if port, ok := ImageNamePortMapHTTPS[imageName]; ok {
|
||||||
return "https", port, true
|
return route.SchemeHTTPS, port, true
|
||||||
}
|
}
|
||||||
if port, ok := ImageNamePortMapTCP[imageName]; ok {
|
if port, ok := ImageNamePortMapTCP[imageName]; ok {
|
||||||
return "tcp", port, true
|
return route.SchemeTCP, port, true
|
||||||
}
|
}
|
||||||
return scheme, port, ok
|
return scheme, port, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSchemePortByAlias(alias string) (scheme string, port int, ok bool) {
|
func getSchemePortByAlias(alias string) (scheme route.Scheme, port int, ok bool) {
|
||||||
if port, ok := AliasPortMapHTTP[alias]; ok {
|
if port, ok := AliasPortMapHTTP[alias]; ok {
|
||||||
return "http", port, true
|
return route.SchemeHTTP, port, true
|
||||||
}
|
}
|
||||||
if port, ok := AliasPortMapHTTPS[alias]; ok {
|
if port, ok := AliasPortMapHTTPS[alias]; ok {
|
||||||
return "https", port, true
|
return route.SchemeHTTPS, port, true
|
||||||
}
|
}
|
||||||
return scheme, port, ok
|
return scheme, port, ok
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
D "github.com/yusing/godoxy/internal/docker"
|
D "github.com/yusing/godoxy/internal/docker"
|
||||||
"github.com/yusing/godoxy/internal/route"
|
"github.com/yusing/godoxy/internal/route"
|
||||||
T "github.com/yusing/godoxy/internal/route/types"
|
routeTypes "github.com/yusing/godoxy/internal/route/types"
|
||||||
expect "github.com/yusing/goutils/testing"
|
expect "github.com/yusing/goutils/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -91,8 +91,8 @@ func TestApplyLabel(t *testing.T) {
|
|||||||
b, ok := entries["b"]
|
b, ok := entries["b"]
|
||||||
expect.True(t, ok)
|
expect.True(t, ok)
|
||||||
|
|
||||||
expect.Equal(t, a.Scheme, "https")
|
expect.Equal(t, a.Scheme, routeTypes.SchemeHTTPS)
|
||||||
expect.Equal(t, b.Scheme, "https")
|
expect.Equal(t, b.Scheme, routeTypes.SchemeHTTPS)
|
||||||
|
|
||||||
expect.Equal(t, a.Host, "app")
|
expect.Equal(t, a.Host, "app")
|
||||||
expect.Equal(t, b.Host, "app")
|
expect.Equal(t, b.Host, "app")
|
||||||
@@ -152,12 +152,12 @@ func TestApplyLabelWithAlias(t *testing.T) {
|
|||||||
c, ok := entries["c"]
|
c, ok := entries["c"]
|
||||||
expect.True(t, ok)
|
expect.True(t, ok)
|
||||||
|
|
||||||
expect.Equal(t, a.Scheme, "http")
|
expect.Equal(t, a.Scheme, routeTypes.SchemeHTTP)
|
||||||
expect.Equal(t, a.Port.Proxy, 3333)
|
expect.Equal(t, a.Port.Proxy, 3333)
|
||||||
expect.Equal(t, a.NoTLSVerify, true)
|
expect.Equal(t, a.NoTLSVerify, true)
|
||||||
expect.Equal(t, b.Scheme, "http")
|
expect.Equal(t, b.Scheme, routeTypes.SchemeHTTP)
|
||||||
expect.Equal(t, b.Port.Proxy, 1234)
|
expect.Equal(t, b.Port.Proxy, 1234)
|
||||||
expect.Equal(t, c.Scheme, "https")
|
expect.Equal(t, c.Scheme, routeTypes.SchemeHTTPS)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApplyLabelWithRef(t *testing.T) {
|
func TestApplyLabelWithRef(t *testing.T) {
|
||||||
@@ -180,11 +180,11 @@ func TestApplyLabelWithRef(t *testing.T) {
|
|||||||
c, ok := entries["c"]
|
c, ok := entries["c"]
|
||||||
expect.True(t, ok)
|
expect.True(t, ok)
|
||||||
|
|
||||||
expect.Equal(t, a.Scheme, "http")
|
expect.Equal(t, a.Scheme, routeTypes.SchemeHTTP)
|
||||||
expect.Equal(t, a.Host, "localhost")
|
expect.Equal(t, a.Host, "localhost")
|
||||||
expect.Equal(t, a.Port.Proxy, 4444)
|
expect.Equal(t, a.Port.Proxy, 4444)
|
||||||
expect.Equal(t, b.Port.Proxy, 9999)
|
expect.Equal(t, b.Port.Proxy, 9999)
|
||||||
expect.Equal(t, c.Scheme, "https")
|
expect.Equal(t, c.Scheme, routeTypes.SchemeHTTPS)
|
||||||
expect.Equal(t, c.Port.Proxy, 1111)
|
expect.Equal(t, c.Port.Proxy, 1111)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,12 +229,12 @@ func TestDynamicAliases(t *testing.T) {
|
|||||||
|
|
||||||
r, ok := entries["app1"]
|
r, ok := entries["app1"]
|
||||||
expect.True(t, ok)
|
expect.True(t, ok)
|
||||||
expect.Equal(t, r.Scheme, "http")
|
expect.Equal(t, r.Scheme, routeTypes.SchemeHTTP)
|
||||||
expect.Equal(t, r.Port.Proxy, 1234)
|
expect.Equal(t, r.Port.Proxy, 1234)
|
||||||
|
|
||||||
r, ok = entries["app1_backend"]
|
r, ok = entries["app1_backend"]
|
||||||
expect.True(t, ok)
|
expect.True(t, ok)
|
||||||
expect.Equal(t, r.Scheme, "http")
|
expect.Equal(t, r.Scheme, routeTypes.SchemeHTTP)
|
||||||
expect.Equal(t, r.Port.Proxy, 5678)
|
expect.Equal(t, r.Port.Proxy, 5678)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@ func TestStreamDefaultValues(t *testing.T) {
|
|||||||
r, ok := makeRoutes(cont)["a"]
|
r, ok := makeRoutes(cont)["a"]
|
||||||
expect.True(t, ok)
|
expect.True(t, ok)
|
||||||
expect.NoError(t, r.Validate())
|
expect.NoError(t, r.Validate())
|
||||||
expect.Equal(t, r.Scheme, T.Scheme("udp"))
|
expect.Equal(t, r.Scheme, routeTypes.SchemeUDP)
|
||||||
expect.Equal(t, r.TargetURL().Hostname(), privIP)
|
expect.Equal(t, r.TargetURL().Hostname(), privIP)
|
||||||
expect.Equal(t, r.Port.Listening, 0)
|
expect.Equal(t, r.Port.Listening, 0)
|
||||||
expect.Equal(t, r.Port.Proxy, int(privPort))
|
expect.Equal(t, r.Port.Proxy, int(privPort))
|
||||||
@@ -337,7 +337,7 @@ func TestStreamDefaultValues(t *testing.T) {
|
|||||||
r, ok := makeRoutes(cont, testIP)["a"]
|
r, ok := makeRoutes(cont, testIP)["a"]
|
||||||
expect.True(t, ok)
|
expect.True(t, ok)
|
||||||
expect.NoError(t, r.Validate())
|
expect.NoError(t, r.Validate())
|
||||||
expect.Equal(t, r.Scheme, T.Scheme("udp"))
|
expect.Equal(t, r.Scheme, routeTypes.SchemeUDP)
|
||||||
expect.Equal(t, r.TargetURL().Hostname(), testIP)
|
expect.Equal(t, r.TargetURL().Hostname(), testIP)
|
||||||
expect.Equal(t, r.Port.Listening, 0)
|
expect.Equal(t, r.Port.Listening, 0)
|
||||||
expect.Equal(t, r.Port.Proxy, int(pubPort))
|
expect.Equal(t, r.Port.Proxy, int(pubPort))
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -40,7 +41,7 @@ type (
|
|||||||
_ utils.NoCopy
|
_ utils.NoCopy
|
||||||
|
|
||||||
Alias string `json:"alias"`
|
Alias string `json:"alias"`
|
||||||
Scheme route.Scheme `json:"scheme,omitempty"`
|
Scheme route.Scheme `json:"scheme,omitempty" swaggertype:"string"`
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
Port route.Port `json:"port"`
|
Port route.Port `json:"port"`
|
||||||
Root string `json:"root,omitempty"`
|
Root string `json:"root,omitempty"`
|
||||||
@@ -71,8 +72,8 @@ type (
|
|||||||
LisURL *nettypes.URL `json:"lurl,omitempty" swaggertype:"string" extensions:"x-nullable"`
|
LisURL *nettypes.URL `json:"lurl,omitempty" swaggertype:"string" extensions:"x-nullable"`
|
||||||
ProxyURL *nettypes.URL `json:"purl,omitempty" swaggertype:"string"`
|
ProxyURL *nettypes.URL `json:"purl,omitempty" swaggertype:"string"`
|
||||||
|
|
||||||
Excluded bool `json:"excluded,omitempty" extensions:"x-nullable"`
|
Excluded bool `json:"excluded,omitempty" extensions:"x-nullable"`
|
||||||
ExcludedReason string `json:"excluded_reason,omitempty" extensions:"x-nullable"`
|
ExcludedReason ExcludedReason `json:"excluded_reason,omitempty" extensions:"x-nullable"`
|
||||||
|
|
||||||
HealthMon types.HealthMonitor `json:"health,omitempty" swaggerignore:"true"`
|
HealthMon types.HealthMonitor `json:"health,omitempty" swaggerignore:"true"`
|
||||||
// for swagger
|
// for swagger
|
||||||
@@ -272,7 +273,7 @@ func (r *Route) Validate() gperr.Error {
|
|||||||
r.impl = impl
|
r.impl = impl
|
||||||
r.Excluded = r.ShouldExclude()
|
r.Excluded = r.ShouldExclude()
|
||||||
if r.Excluded {
|
if r.Excluded {
|
||||||
r.ExcludedReason = r.GetExcludedReason()
|
r.ExcludedReason = r.findExcludedReason()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -518,31 +519,73 @@ func (r *Route) ShouldExclude() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Route) GetExcludedReason() string {
|
type ExcludedReason uint8
|
||||||
if r.lastError != nil {
|
|
||||||
return string(gperr.Plain(r.lastError))
|
const (
|
||||||
|
ExcludedReasonNone ExcludedReason = iota
|
||||||
|
ExcludedReasonError
|
||||||
|
ExcludedReasonManual
|
||||||
|
ExcludedReasonNoPortContainer
|
||||||
|
ExcludedReasonNoPortSpecified
|
||||||
|
ExcludedReasonBlacklisted
|
||||||
|
ExcludedReasonBuildx
|
||||||
|
ExcludedReasonOld
|
||||||
|
)
|
||||||
|
|
||||||
|
func (re ExcludedReason) String() string {
|
||||||
|
switch re {
|
||||||
|
case ExcludedReasonNone:
|
||||||
|
return ""
|
||||||
|
case ExcludedReasonError:
|
||||||
|
return "Error"
|
||||||
|
case ExcludedReasonManual:
|
||||||
|
return "Manual exclusion"
|
||||||
|
case ExcludedReasonNoPortContainer:
|
||||||
|
return "No port exposed in container"
|
||||||
|
case ExcludedReasonNoPortSpecified:
|
||||||
|
return "No port specified"
|
||||||
|
case ExcludedReasonBlacklisted:
|
||||||
|
return "Blacklisted (backend service or database)"
|
||||||
|
case ExcludedReasonBuildx:
|
||||||
|
return "Buildx"
|
||||||
|
case ExcludedReasonOld:
|
||||||
|
return "Container renaming intermediate state"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
}
|
}
|
||||||
if r.ExcludedReason != "" {
|
}
|
||||||
|
|
||||||
|
func (re ExcludedReason) MarshalJSON() ([]byte, error) {
|
||||||
|
return strconv.AppendQuote(nil, re.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to unmarshal json because we don't store this
|
||||||
|
|
||||||
|
func (r *Route) findExcludedReason() ExcludedReason {
|
||||||
|
if r.lastError != nil {
|
||||||
|
return ExcludedReasonError
|
||||||
|
}
|
||||||
|
if r.ExcludedReason != ExcludedReasonNone {
|
||||||
return r.ExcludedReason
|
return r.ExcludedReason
|
||||||
}
|
}
|
||||||
if r.Container != nil {
|
if r.Container != nil {
|
||||||
switch {
|
switch {
|
||||||
case r.Container.IsExcluded:
|
case r.Container.IsExcluded:
|
||||||
return "Manual exclusion"
|
return ExcludedReasonManual
|
||||||
case r.IsZeroPort() && !r.UseIdleWatcher():
|
case r.IsZeroPort() && !r.UseIdleWatcher():
|
||||||
return "No port exposed in container"
|
return ExcludedReasonNoPortContainer
|
||||||
case !r.Container.IsExplicit && docker.IsBlacklisted(r.Container):
|
case !r.Container.IsExplicit && docker.IsBlacklisted(r.Container):
|
||||||
return "Blacklisted (backend service or database)"
|
return ExcludedReasonBlacklisted
|
||||||
case strings.HasPrefix(r.Container.ContainerName, "buildx_"):
|
case strings.HasPrefix(r.Container.ContainerName, "buildx_"):
|
||||||
return "Buildx"
|
return ExcludedReasonBuildx
|
||||||
}
|
}
|
||||||
} else if r.IsZeroPort() && r.Scheme != route.SchemeFileServer {
|
} else if r.IsZeroPort() && r.Scheme != route.SchemeFileServer {
|
||||||
return "No port specified"
|
return ExcludedReasonNoPortSpecified
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(r.Alias, "-old") {
|
if strings.HasSuffix(r.Alias, "-old") {
|
||||||
return "Container renaming intermediate state"
|
return ExcludedReasonOld
|
||||||
}
|
}
|
||||||
return ""
|
return ExcludedReasonNone
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Route) UseLoadBalance() bool {
|
func (r *Route) UseLoadBalance() bool {
|
||||||
@@ -594,8 +637,8 @@ func (r *Route) Finalize() {
|
|||||||
if isDocker {
|
if isDocker {
|
||||||
scheme, port, ok := getSchemePortByImageName(cont.Image.Name)
|
scheme, port, ok := getSchemePortByImageName(cont.Image.Name)
|
||||||
if ok {
|
if ok {
|
||||||
if r.Scheme == "" {
|
if r.Scheme == route.SchemeNone {
|
||||||
r.Scheme = route.Scheme(scheme)
|
r.Scheme = scheme
|
||||||
}
|
}
|
||||||
if pp == 0 {
|
if pp == 0 {
|
||||||
pp = port
|
pp = port
|
||||||
@@ -604,8 +647,8 @@ func (r *Route) Finalize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if scheme, port, ok := getSchemePortByAlias(r.Alias); ok {
|
if scheme, port, ok := getSchemePortByAlias(r.Alias); ok {
|
||||||
if r.Scheme == "" {
|
if r.Scheme == route.SchemeNone {
|
||||||
r.Scheme = route.Scheme(scheme)
|
r.Scheme = scheme
|
||||||
}
|
}
|
||||||
if pp == 0 {
|
if pp == 0 {
|
||||||
pp = port
|
pp = port
|
||||||
@@ -620,7 +663,7 @@ func (r *Route) Finalize() {
|
|||||||
} else {
|
} else {
|
||||||
pp = preferredPort(cont.PrivatePortMapping)
|
pp = preferredPort(cont.PrivatePortMapping)
|
||||||
}
|
}
|
||||||
case r.Scheme == "https":
|
case r.Scheme == route.SchemeHTTPS:
|
||||||
pp = 443
|
pp = 443
|
||||||
default:
|
default:
|
||||||
pp = 80
|
pp = 80
|
||||||
@@ -628,10 +671,10 @@ func (r *Route) Finalize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isDocker {
|
if isDocker {
|
||||||
if r.Scheme == "" {
|
if r.Scheme == route.SchemeNone {
|
||||||
for _, p := range cont.PublicPortMapping {
|
for _, p := range cont.PublicPortMapping {
|
||||||
if int(p.PrivatePort) == pp && p.Type == "udp" {
|
if int(p.PrivatePort) == pp && p.Type == "udp" {
|
||||||
r.Scheme = "udp"
|
r.Scheme = route.SchemeUDP
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -649,14 +692,14 @@ func (r *Route) Finalize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Scheme == "" {
|
if r.Scheme == route.SchemeNone {
|
||||||
switch {
|
switch {
|
||||||
case lp != 0:
|
case lp != 0:
|
||||||
r.Scheme = "tcp"
|
r.Scheme = route.SchemeTCP
|
||||||
case pp%1000 == 443:
|
case pp%1000 == 443:
|
||||||
r.Scheme = "https"
|
r.Scheme = route.SchemeHTTPS
|
||||||
default: // assume its http
|
default: // assume its http
|
||||||
r.Scheme = "http"
|
r.Scheme = route.SchemeHTTP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ func TestRouteValidate(t *testing.T) {
|
|||||||
t.Run("InvalidScheme", func(t *testing.T) {
|
t.Run("InvalidScheme", func(t *testing.T) {
|
||||||
r := &Route{
|
r := &Route{
|
||||||
Alias: "test",
|
Alias: "test",
|
||||||
Scheme: "invalid",
|
Scheme: 123,
|
||||||
Host: "example.com",
|
Host: "example.com",
|
||||||
Port: route.Port{Proxy: 80},
|
Port: route.Port{Proxy: 80},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,82 @@
|
|||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/bytedance/sonic"
|
||||||
gperr "github.com/yusing/goutils/errs"
|
gperr "github.com/yusing/goutils/errs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Scheme string
|
type Scheme uint8
|
||||||
|
|
||||||
var ErrInvalidScheme = gperr.New("invalid scheme")
|
var ErrInvalidScheme = gperr.New("invalid scheme")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SchemeHTTP Scheme = "http"
|
SchemeHTTP Scheme = 1 << iota
|
||||||
SchemeHTTPS Scheme = "https"
|
SchemeHTTPS
|
||||||
SchemeTCP Scheme = "tcp"
|
SchemeTCP
|
||||||
SchemeUDP Scheme = "udp"
|
SchemeUDP
|
||||||
SchemeFileServer Scheme = "fileserver"
|
SchemeFileServer
|
||||||
|
SchemeNone Scheme = 0
|
||||||
|
|
||||||
|
schemeReverseProxy = SchemeHTTP | SchemeHTTPS
|
||||||
|
schemeStream = SchemeTCP | SchemeUDP
|
||||||
|
|
||||||
|
schemeStrHTTP = "http"
|
||||||
|
schemeStrHTTPS = "https"
|
||||||
|
schemeStrTCP = "tcp"
|
||||||
|
schemeStrUDP = "udp"
|
||||||
|
schemeStrFileServer = "fileserver"
|
||||||
|
schemeStrUnknown = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s Scheme) Validate() gperr.Error {
|
func (s Scheme) String() string {
|
||||||
switch s {
|
switch s {
|
||||||
case SchemeHTTP, SchemeHTTPS,
|
case SchemeHTTP:
|
||||||
SchemeTCP, SchemeUDP, SchemeFileServer:
|
return schemeStrHTTP
|
||||||
return nil
|
case SchemeHTTPS:
|
||||||
|
return schemeStrHTTPS
|
||||||
|
case SchemeTCP:
|
||||||
|
return schemeStrTCP
|
||||||
|
case SchemeUDP:
|
||||||
|
return schemeStrUDP
|
||||||
|
case SchemeFileServer:
|
||||||
|
return schemeStrFileServer
|
||||||
|
default:
|
||||||
|
return schemeStrUnknown
|
||||||
}
|
}
|
||||||
return ErrInvalidScheme.Subject(string(s))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Scheme) IsReverseProxy() bool { return s == SchemeHTTP || s == SchemeHTTPS }
|
func (s Scheme) MarshalJSON() ([]byte, error) {
|
||||||
func (s Scheme) IsStream() bool { return s == SchemeTCP || s == SchemeUDP }
|
return strconv.AppendQuote(nil, s.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Scheme) UnmarshalJSON(data []byte) error {
|
||||||
|
var v string
|
||||||
|
if err := sonic.Unmarshal(data, &v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.Parse(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse implements strutils.Parser
|
||||||
|
func (s *Scheme) Parse(v string) error {
|
||||||
|
switch v {
|
||||||
|
case schemeStrHTTP:
|
||||||
|
*s = SchemeHTTP
|
||||||
|
case schemeStrHTTPS:
|
||||||
|
*s = SchemeHTTPS
|
||||||
|
case schemeStrTCP:
|
||||||
|
*s = SchemeTCP
|
||||||
|
case schemeStrUDP:
|
||||||
|
*s = SchemeUDP
|
||||||
|
case schemeStrFileServer:
|
||||||
|
*s = SchemeFileServer
|
||||||
|
default:
|
||||||
|
return ErrInvalidScheme.Subject(v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Scheme) IsReverseProxy() bool { return s&schemeReverseProxy != 0 }
|
||||||
|
func (s Scheme) IsStream() bool { return s&schemeStream != 0 }
|
||||||
|
|||||||
Reference in New Issue
Block a user