FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
caddy/server/server.go at master · chakra-coder/caddy · GitHub
chakra-coder
/
caddy
Public
forked from
caddyserver/caddy
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
caddy
/
server
/
server.go
Copy path
More file actions
More file actions
Latest commit
History
History
History
187 lines (161 loc) · 5.14 KB
Breadcrumbs
caddy
/
server
/
server.go
Copy path
File metadata and controls
187 lines (161 loc) · 5.14 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Package server implements a configurable, general-purpose web server.
// It relies on configurations obtained from the adjacent config package
// and can execute middleware as defined by the adjacent middleware package.
package
server
import
(
"crypto/tls"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"github.com/bradfitz/http2"
)
// Server represents an instance of a server, which serves
// static content at a particular address (host and port).
type
Server
struct
{
HTTP2
bool
// temporary while http2 is not in std lib (TODO: remove flag when part of std lib)
address
string
// the actual address for net.Listen to listen on
tls
bool
// whether this server is serving all HTTPS hosts or not
vhosts
map
[
string
]
virtualHost
// virtual hosts keyed by their address
}
// New creates a new Server which will bind to addr and serve
// the sites/hosts configured in configs. This function does
// not start serving.
func
New
(
addr
string
,
configs
[]
Config
,
tls
bool
) (
*
Server
,
error
) {
s
:=
&
Server
{
address
:
addr
,
tls
:
tls
,
vhosts
:
make
(
map
[
string
]
virtualHost
),
}
for
_
,
conf
:=
range
configs
{
if
_
,
exists
:=
s
.
vhosts
[
conf
.
Host
];
exists
{
return
nil
,
fmt
.
Errorf
(
"Cannot serve %s - host already defined for address %s"
,
conf
.
Address
(),
s
.
address
)
}
vh
:=
virtualHost
{
config
:
conf
}
// Build middleware stack
err
:=
vh
.
buildStack
()
if
err
!=
nil
{
return
nil
,
err
}
s
.
vhosts
[
conf
.
Host
]
=
vh
}
return
s
,
nil
}
// Serve starts the server. It blocks until the server quits.
func
(
s
*
Server
)
Serve
()
error
{
server
:=
&
http.
Server
{
Addr
:
s
.
address
,
Handler
:
s
,
}
if
s
.
HTTP2
{
// TODO: This call may not be necessary after HTTP/2 is merged into std lib
http2
.
ConfigureServer
(
server
,
nil
)
}
for
_
,
vh
:=
range
s
.
vhosts
{
// Execute startup functions now
for
_
,
start
:=
range
vh
.
config
.
Startup
{
err
:=
start
()
if
err
!=
nil
{
return
err
}
}
// Execute shutdown commands on exit
if
len
(
vh
.
config
.
Shutdown
)
>
0
{
go
func
() {
interrupt
:=
make
(
chan
os.
Signal
,
1
)
signal
.
Notify
(
interrupt
,
os
.
Interrupt
,
os
.
Kill
)
// TODO: syscall.SIGQUIT? (Ctrl+\, Unix-only)
<-
interrupt
for
_
,
shutdownFunc
:=
range
vh
.
config
.
Shutdown
{
err
:=
shutdownFunc
()
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
}
os
.
Exit
(
0
)
}()
}
}
if
s
.
tls
{
var
tlsConfigs
[]
TLSConfig
for
_
,
vh
:=
range
s
.
vhosts
{
tlsConfigs
=
append
(
tlsConfigs
,
vh
.
config
.
TLS
)
}
return
ListenAndServeTLSWithSNI
(
server
,
tlsConfigs
)
}
else
{
return
server
.
ListenAndServe
()
}
}
// ListenAndServeTLSWithSNI serves TLS with Server Name Indication (SNI) support, which allows
// multiple sites (different hostnames) to be served from the same address. This method is
// adapted directly from the std lib's net/http ListenAndServeTLS function, which was
// written by the Go Authors. It has been modified to support multiple certificate/key pairs.
func
ListenAndServeTLSWithSNI
(
srv
*
http.
Server
,
tlsConfigs
[]
TLSConfig
)
error
{
addr
:=
srv
.
Addr
if
addr
==
""
{
addr
=
":https"
}
config
:=
new
(tls.
Config
)
if
srv
.
TLSConfig
!=
nil
{
*
config
=
*
srv
.
TLSConfig
}
if
config
.
NextProtos
==
nil
{
config
.
NextProtos
=
[]
string
{
"http/1.1"
}
}
// Here we diverge from the stdlib a bit by loading multiple certs/key pairs
// then we map the server names to their certs
var
err
error
config
.
Certificates
=
make
([]tls.
Certificate
,
len
(
tlsConfigs
))
for
i
,
tlsConfig
:=
range
tlsConfigs
{
config
.
Certificates
[
i
],
err
=
tls
.
LoadX509KeyPair
(
tlsConfig
.
Certificate
,
tlsConfig
.
Key
)
if
err
!=
nil
{
return
err
}
}
config
.
BuildNameToCertificate
()
// Add a session cache LRU algorithm with default capacity (64)
config
.
ClientSessionCache
=
tls
.
NewLRUClientSessionCache
(
0
)
conn
,
err
:=
net
.
Listen
(
"tcp"
,
addr
)
if
err
!=
nil
{
return
err
}
tlsListener
:=
tls
.
NewListener
(
conn
,
config
)
return
srv
.
Serve
(
tlsListener
)
}
// ServeHTTP is the entry point for every request to the address that s
// is bound to. It acts as a multiplexer for the requests hostname as
// defined in the Host header so that the correct virtualhost
// (configuration and middleware stack) will handle the request.
func
(
s
*
Server
)
ServeHTTP
(
w
http.
ResponseWriter
,
r
*
http.
Request
) {
defer
func
() {
// In case the user doesn't enable error middleware, we still
// need to make sure that we stay alive up here
if
rec
:=
recover
();
rec
!=
nil
{
http
.
Error
(
w
,
http
.
StatusText
(
http
.
StatusInternalServerError
),
http
.
StatusInternalServerError
)
}
}()
host
,
_
,
err
:=
net
.
SplitHostPort
(
r
.
Host
)
if
err
!=
nil
{
host
=
r
.
Host
// oh well
}
// Try the host as given, or try falling back to 0.0.0.0 (wildcard)
if
_
,
ok
:=
s
.
vhosts
[
host
];
!
ok
{
if
_
,
ok2
:=
s
.
vhosts
[
"0.0.0.0"
];
ok2
{
host
=
"0.0.0.0"
}
}
if
vh
,
ok
:=
s
.
vhosts
[
host
];
ok
{
w
.
Header
().
Set
(
"Server"
,
"Caddy"
)
status
,
_
:=
vh
.
stack
.
ServeHTTP
(
w
,
r
)
// Fallback error response in case error handling wasn't chained in
if
status
>=
400
{
w
.
WriteHeader
(
status
)
fmt
.
Fprintf
(
w
,
"%d %s"
,
status
,
http
.
StatusText
(
status
))
}
}
else
{
w
.
WriteHeader
(
http
.
StatusNotFound
)
fmt
.
Fprintf
(
w
,
"No such host at %s"
,
s
.
address
)
}
}
Back
|
FazBrowse Home
|
New Git URL