/
server.go
185 lines (161 loc) · 5.83 KB
/
server.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
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
package config
import (
"os"
"strconv"
"strings"
"time"
"github.com/imdario/mergo"
"github.com/valyala/fasthttp"
)
// Default values for base Server conf
const (
// DefaultServerHostname returns the default hostname which is 0.0.0.0
DefaultServerHostname = "0.0.0.0"
// DefaultServerPort returns the default port which is 8080
DefaultServerPort = 8080
// DefaultMaxRequestBodySize is 8MB
DefaultMaxRequestBodySize = 2 * fasthttp.DefaultMaxRequestBodySize
// Per-connection buffer size for requests' reading.
// This also limits the maximum header size.
//
// Increase this buffer if your clients send multi-KB RequestURIs
// and/or multi-KB headers (for example, BIG cookies).
//
// Default buffer size is 8MB
DefaultReadBufferSize = 8096
// Per-connection buffer size for responses' writing.
//
// Default buffer size is 8MB
DefaultWriteBufferSize = 8096
// DefaultServerName the response header of the 'Server' value when writes to the client
DefaultServerName = "iris"
)
var (
// DefaultServerAddr the default server addr which is: 0.0.0.0:8080
DefaultServerAddr = DefaultServerHostname + ":" + strconv.Itoa(DefaultServerPort)
)
// Server used inside server for listening
type Server struct {
// ListenningAddr the addr that server listens to
ListeningAddr string
CertFile string
KeyFile string
// AutoTLS enable to get certifications from the Letsencrypt
// when this configuration field is true, the CertFile & KeyFile are empty, no need to provide a key.
//
// example: https://github.com/iris-contrib/examples/blob/master/letsencyrpt/main.go
AutoTLS bool
// Mode this is for unix only
Mode os.FileMode
// MaxRequestBodySize Maximum request body size.
//
// The server rejects requests with bodies exceeding this limit.
//
// By default request body size is 8MB.
MaxRequestBodySize int
// Per-connection buffer size for requests' reading.
// This also limits the maximum header size.
//
// Increase this buffer if your clients send multi-KB RequestURIs
// and/or multi-KB headers (for example, BIG cookies).
//
// Default buffer size is used if not set.
ReadBufferSize int
// Per-connection buffer size for responses' writing.
//
// Default buffer size is used if not set.
WriteBufferSize int
// Maximum duration for reading the full request (including body).
//
// This also limits the maximum duration for idle keep-alive
// connections.
//
// By default request read timeout is unlimited.
ReadTimeout time.Duration
// Maximum duration for writing the full response (including body).
//
// By default response write timeout is unlimited.
WriteTimeout time.Duration
// RedirectTo, defaults to empty, set it in order to override the station's handler and redirect all requests to this address which is of form(HOST:PORT or :PORT)
//
// NOTE: the http status is 'StatusMovedPermanently', means one-time-redirect(the browser remembers the new addr and goes to the new address without need to request something from this server
// which means that if you want to change this address you have to clear your browser's cache in order this to be able to change to the new addr.
//
// example: https://github.com/iris-contrib/examples/tree/master/multiserver_listening2
RedirectTo string
// Virtual If this server is not really listens to a real host, it mostly used in order to achieve testing without system modifications
Virtual bool
// VListeningAddr, can be used for both virtual = true or false,
// if it's setted to not empty, then the server's Host() will return this addr instead of the ListeningAddr.
// server's Host() is used inside global template helper funcs
// set it when you are sure you know what it does.
//
// Default is empty ""
VListeningAddr string
// VScheme if setted to not empty value then all template's helper funcs prepends that as the url scheme instead of the real scheme
// server's .Scheme returns VScheme if not empty && differs from real scheme
//
// Default is empty ""
VScheme string
// Name the server's name, defaults to "iris".
// You're free to change it, but I will trust you to don't, this is the only setting whose somebody, like me, can see if iris web framework is used
Name string
}
// ServerParseAddr parses the listening addr and returns this
func ServerParseAddr(listeningAddr string) string {
// check if addr has :port, if not do it +:80 ,we need the hostname for many cases
a := listeningAddr
if a == "" {
// check for os environments
if oshost := os.Getenv("HOST"); oshost != "" {
a = oshost
} else if oshost := os.Getenv("ADDR"); oshost != "" {
a = oshost
} else if osport := os.Getenv("PORT"); osport != "" {
a = ":" + osport
}
if a == "" {
a = DefaultServerAddr
}
}
if portIdx := strings.IndexByte(a, ':'); portIdx == 0 {
// if contains only :port ,then the : is the first letter, so we dont have setted a hostname, lets set it
a = DefaultServerHostname + a
}
if portIdx := strings.IndexByte(a, ':'); portIdx < 0 {
// missing port part, add it
a = a + ":80"
}
return a
}
// DefaultServer returns the default configs for the server
func DefaultServer() Server {
return Server{
ListeningAddr: DefaultServerAddr,
Name: DefaultServerName,
MaxRequestBodySize: DefaultMaxRequestBodySize,
ReadBufferSize: DefaultReadBufferSize,
WriteBufferSize: DefaultWriteBufferSize,
RedirectTo: "",
Virtual: false,
VListeningAddr: "",
VScheme: "",
}
}
// Merge merges the default with the given config and returns the result
func (c Server) Merge(cfg []Server) (config Server) {
if len(cfg) > 0 {
config = cfg[0]
mergo.Merge(&config, c)
} else {
_default := c
config = _default
}
return
}
// MergeSingle merges the default with the given config and returns the result
func (c Server) MergeSingle(cfg Server) (config Server) {
config = cfg
mergo.Merge(&config, c)
return
}