-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathvhost_handler.go
102 lines (88 loc) · 2.89 KB
/
vhost_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright 2021 xgfone
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ship
import (
"net/http"
"sync/atomic"
)
// HostHandler is a http handler to dispatch the request to the host handler
// by the request host, which may be used to implement the virtual hosts.
type HostHandler interface {
http.Handler
HostManager
}
type defaultHostHandler struct {
Handler http.Handler
Host string
}
// HostManagerHandler is an implementation of HostHandler.
type HostManagerHandler struct {
HostManager
// HandleHTTP is used to handle the matched host and handler.
//
// If not found the matched host and handler, matchedHost and matchedHandler
// are ZERO, that's, "" and nil.
//
// Default: w.WriteHeader(404)
HandleHTTP func(w http.ResponseWriter, r *http.Request,
matchedHost string, matchedHandler http.Handler)
defaultHost atomic.Value
}
// NewHostManagerHandler returns a new HostManagerHandler.
//
// If hostManager is nil, it is NewHostManager(nil) by default.
func NewHostManagerHandler(hostManager HostManager) *HostManagerHandler {
if hostManager == nil {
hostManager = NewHostManager(nil)
}
return &HostManagerHandler{HostManager: hostManager}
}
// GetDefaultHost returns the default host and handler.
//
// Return ("", nil) if the default host is not set.
func (h *HostManagerHandler) GetDefaultHost() (host string, handler http.Handler) {
if v := h.defaultHost.Load(); v != nil {
d := v.(defaultHostHandler)
host, handler = d.Host, d.Handler
}
return
}
// SetDefaultHost sets the default host and handler.
func (h *HostManagerHandler) SetDefaultHost(host string, handler http.Handler) {
h.defaultHost.Store(defaultHostHandler{Host: host, Handler: handler})
}
// ServeHTTP implements the interface http.Handler.
func (h *HostManagerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var matchedHost string
var matchedHandler http.Handler
if r.Host != "" && h.Len() > 0 {
matchedHost, matchedHandler = h.MatchHost(r.Host)
}
if matchedHandler == nil {
matchedHost, matchedHandler = h.GetDefaultHost()
}
if h.HandleHTTP == nil {
h.handleHTTP(w, r, matchedHost, matchedHandler)
} else {
h.HandleHTTP(w, r, matchedHost, matchedHandler)
}
}
func (h *HostManagerHandler) handleHTTP(w http.ResponseWriter, r *http.Request,
matchedHost string, matchedHandler http.Handler) {
if matchedHandler == nil {
w.WriteHeader(404)
} else {
matchedHandler.ServeHTTP(w, r)
}
}