github.com/gofiber/fiber/v2@v2.47.0/listen_test.go (about) 1 // ⚡️ Fiber is an Express inspired web framework written in Go with ☕️ 2 // 🤖 Github Repository: https://github.com/gofiber/fiber 3 // 📌 API Documentation: https://docs.gofiber.io 4 5 package fiber 6 7 import ( 8 "bytes" 9 "crypto/tls" 10 "crypto/x509" 11 "io" 12 "log" 13 "os" 14 "path/filepath" 15 "strings" 16 "sync" 17 "testing" 18 "time" 19 20 "github.com/gofiber/fiber/v2/utils" 21 22 "github.com/valyala/fasthttp/fasthttputil" 23 ) 24 25 // go test -run Test_App_Listen 26 func Test_App_Listen(t *testing.T) { 27 t.Parallel() 28 app := New(Config{DisableStartupMessage: true}) 29 30 utils.AssertEqual(t, false, app.Listen(":99999") == nil) 31 32 go func() { 33 time.Sleep(1000 * time.Millisecond) 34 utils.AssertEqual(t, nil, app.Shutdown()) 35 }() 36 37 utils.AssertEqual(t, nil, app.Listen(":4003")) 38 } 39 40 // go test -run Test_App_Listen_Prefork 41 func Test_App_Listen_Prefork(t *testing.T) { 42 testPreforkMaster = true 43 44 app := New(Config{DisableStartupMessage: true, Prefork: true}) 45 46 utils.AssertEqual(t, nil, app.Listen(":99999")) 47 } 48 49 // go test -run Test_App_ListenTLS 50 func Test_App_ListenTLS(t *testing.T) { 51 t.Parallel() 52 app := New() 53 54 // invalid port 55 utils.AssertEqual(t, false, app.ListenTLS(":99999", "./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") == nil) 56 // missing perm/cert file 57 utils.AssertEqual(t, false, app.ListenTLS(":0", "", "./.github/testdata/ssl.key") == nil) 58 59 go func() { 60 time.Sleep(1000 * time.Millisecond) 61 utils.AssertEqual(t, nil, app.Shutdown()) 62 }() 63 64 utils.AssertEqual(t, nil, app.ListenTLS(":0", "./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")) 65 } 66 67 // go test -run Test_App_ListenTLS_Prefork 68 func Test_App_ListenTLS_Prefork(t *testing.T) { 69 testPreforkMaster = true 70 71 app := New(Config{DisableStartupMessage: true, Prefork: true}) 72 73 // invalid key file content 74 utils.AssertEqual(t, false, app.ListenTLS(":0", "./.github/testdata/ssl.pem", "./.github/testdata/template.tmpl") == nil) 75 76 utils.AssertEqual(t, nil, app.ListenTLS(":99999", "./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")) 77 } 78 79 // go test -run Test_App_ListenMutualTLS 80 func Test_App_ListenMutualTLS(t *testing.T) { 81 t.Parallel() 82 app := New() 83 84 // invalid port 85 utils.AssertEqual(t, false, app.ListenMutualTLS(":99999", "./.github/testdata/ssl.pem", "./.github/testdata/ssl.key", "./.github/testdata/ca-chain.cert.pem") == nil) 86 // missing perm/cert file 87 utils.AssertEqual(t, false, app.ListenMutualTLS(":0", "", "./.github/testdata/ssl.key", "") == nil) 88 89 go func() { 90 time.Sleep(1000 * time.Millisecond) 91 utils.AssertEqual(t, nil, app.Shutdown()) 92 }() 93 94 utils.AssertEqual(t, nil, app.ListenMutualTLS(":0", "./.github/testdata/ssl.pem", "./.github/testdata/ssl.key", "./.github/testdata/ca-chain.cert.pem")) 95 } 96 97 // go test -run Test_App_ListenMutualTLS_Prefork 98 func Test_App_ListenMutualTLS_Prefork(t *testing.T) { 99 testPreforkMaster = true 100 101 app := New(Config{DisableStartupMessage: true, Prefork: true}) 102 103 // invalid key file content 104 utils.AssertEqual(t, false, app.ListenMutualTLS(":0", "./.github/testdata/ssl.pem", "./.github/testdata/template.html", "") == nil) 105 106 utils.AssertEqual(t, nil, app.ListenMutualTLS(":99999", "./.github/testdata/ssl.pem", "./.github/testdata/ssl.key", "./.github/testdata/ca-chain.cert.pem")) 107 } 108 109 // go test -run Test_App_Listener 110 func Test_App_Listener(t *testing.T) { 111 t.Parallel() 112 app := New() 113 114 go func() { 115 time.Sleep(500 * time.Millisecond) 116 utils.AssertEqual(t, nil, app.Shutdown()) 117 }() 118 119 ln := fasthttputil.NewInmemoryListener() 120 utils.AssertEqual(t, nil, app.Listener(ln)) 121 } 122 123 func Test_App_Listener_TLS_Listener(t *testing.T) { 124 t.Parallel() 125 // Create tls certificate 126 cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") 127 if err != nil { 128 utils.AssertEqual(t, nil, err) 129 } 130 //nolint:gosec // We're in a test so using old ciphers is fine 131 config := &tls.Config{Certificates: []tls.Certificate{cer}} 132 133 //nolint:gosec // We're in a test so listening on all interfaces is fine 134 ln, err := tls.Listen(NetworkTCP4, ":0", config) 135 utils.AssertEqual(t, nil, err) 136 137 app := New() 138 139 go func() { 140 time.Sleep(time.Millisecond * 500) 141 utils.AssertEqual(t, nil, app.Shutdown()) 142 }() 143 144 utils.AssertEqual(t, nil, app.Listener(ln)) 145 } 146 147 // go test -run Test_App_ListenTLSWithCertificate 148 func Test_App_ListenTLSWithCertificate(t *testing.T) { 149 t.Parallel() 150 151 // Create tls certificate 152 cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") 153 if err != nil { 154 utils.AssertEqual(t, nil, err) 155 } 156 157 app := New() 158 159 // invalid port 160 utils.AssertEqual(t, false, app.ListenTLSWithCertificate(":99999", cer) == nil) 161 162 go func() { 163 time.Sleep(1000 * time.Millisecond) 164 utils.AssertEqual(t, nil, app.Shutdown()) 165 }() 166 167 utils.AssertEqual(t, nil, app.ListenTLSWithCertificate(":0", cer)) 168 } 169 170 // go test -run Test_App_ListenTLSWithCertificate_Prefork 171 func Test_App_ListenTLSWithCertificate_Prefork(t *testing.T) { 172 testPreforkMaster = true 173 174 // Create tls certificate 175 cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") 176 if err != nil { 177 utils.AssertEqual(t, nil, err) 178 } 179 180 app := New(Config{DisableStartupMessage: true, Prefork: true}) 181 182 utils.AssertEqual(t, nil, app.ListenTLSWithCertificate(":99999", cer)) 183 } 184 185 // go test -run Test_App_ListenMutualTLSWithCertificate 186 func Test_App_ListenMutualTLSWithCertificate(t *testing.T) { 187 t.Parallel() 188 189 // Create tls certificate 190 cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") 191 if err != nil { 192 utils.AssertEqual(t, nil, err) 193 } 194 195 // Create pool 196 clientCACert, err := os.ReadFile(filepath.Clean("./.github/testdata/ca-chain.cert.pem")) 197 if err != nil { 198 utils.AssertEqual(t, nil, err) 199 } 200 clientCertPool := x509.NewCertPool() 201 clientCertPool.AppendCertsFromPEM(clientCACert) 202 203 app := New() 204 205 // invalid port 206 utils.AssertEqual(t, false, app.ListenMutualTLSWithCertificate(":99999", cer, clientCertPool) == nil) 207 208 go func() { 209 time.Sleep(1000 * time.Millisecond) 210 utils.AssertEqual(t, nil, app.Shutdown()) 211 }() 212 213 utils.AssertEqual(t, nil, app.ListenMutualTLSWithCertificate(":0", cer, clientCertPool)) 214 } 215 216 // go test -run Test_App_ListenMutualTLS_Prefork 217 func Test_App_ListenMutualTLSWithCertificate_Prefork(t *testing.T) { 218 testPreforkMaster = true 219 220 // Create tls certificate 221 cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") 222 if err != nil { 223 utils.AssertEqual(t, nil, err) 224 } 225 226 // Create pool 227 clientCACert, err := os.ReadFile(filepath.Clean("./.github/testdata/ca-chain.cert.pem")) 228 if err != nil { 229 utils.AssertEqual(t, nil, err) 230 } 231 clientCertPool := x509.NewCertPool() 232 clientCertPool.AppendCertsFromPEM(clientCACert) 233 234 app := New(Config{DisableStartupMessage: true, Prefork: true}) 235 236 utils.AssertEqual(t, nil, app.ListenMutualTLSWithCertificate(":99999", cer, clientCertPool)) 237 } 238 239 func captureOutput(f func()) string { 240 reader, writer, err := os.Pipe() 241 if err != nil { 242 panic(err) 243 } 244 stdout := os.Stdout 245 stderr := os.Stderr 246 defer func() { 247 os.Stdout = stdout 248 os.Stderr = stderr 249 log.SetOutput(os.Stderr) 250 }() 251 os.Stdout = writer 252 os.Stderr = writer 253 log.SetOutput(writer) 254 out := make(chan string) 255 wg := new(sync.WaitGroup) 256 wg.Add(1) 257 go func() { 258 var buf bytes.Buffer 259 wg.Done() 260 _, err := io.Copy(&buf, reader) 261 if err != nil { 262 panic(err) 263 } 264 out <- buf.String() 265 }() 266 wg.Wait() 267 f() 268 err = writer.Close() 269 if err != nil { 270 panic(err) 271 } 272 return <-out 273 } 274 275 func Test_App_Master_Process_Show_Startup_Message(t *testing.T) { 276 startupMessage := captureOutput(func() { 277 New(Config{Prefork: true}). 278 startupMessage(":3000", true, strings.Repeat(",11111,22222,33333,44444,55555,60000", 10)) 279 }) 280 utils.AssertEqual(t, true, strings.Contains(startupMessage, "https://127.0.0.1:3000")) 281 utils.AssertEqual(t, true, strings.Contains(startupMessage, "(bound on host 0.0.0.0 and port 3000)")) 282 utils.AssertEqual(t, true, strings.Contains(startupMessage, "Child PIDs")) 283 utils.AssertEqual(t, true, strings.Contains(startupMessage, "11111, 22222, 33333, 44444, 55555, 60000")) 284 utils.AssertEqual(t, true, strings.Contains(startupMessage, "Prefork ........ Enabled")) 285 } 286 287 func Test_App_Master_Process_Show_Startup_MessageWithAppName(t *testing.T) { 288 app := New(Config{Prefork: true, AppName: "Test App v1.0.1"}) 289 startupMessage := captureOutput(func() { 290 app.startupMessage(":3000", true, strings.Repeat(",11111,22222,33333,44444,55555,60000", 10)) 291 }) 292 utils.AssertEqual(t, "Test App v1.0.1", app.Config().AppName) 293 utils.AssertEqual(t, true, strings.Contains(startupMessage, app.Config().AppName)) 294 } 295 296 func Test_App_Master_Process_Show_Startup_MessageWithAppNameNonAscii(t *testing.T) { 297 appName := "Serveur de vérification des données" 298 app := New(Config{Prefork: true, AppName: appName}) 299 startupMessage := captureOutput(func() { 300 app.startupMessage(":3000", false, "") 301 }) 302 utils.AssertEqual(t, true, strings.Contains(startupMessage, "│ Serveur de vérification des données │")) 303 } 304 305 func Test_App_print_Route(t *testing.T) { 306 t.Parallel() 307 app := New(Config{EnablePrintRoutes: true}) 308 app.Get("/", emptyHandler).Name("routeName") 309 printRoutesMessage := captureOutput(func() { 310 app.printRoutesMessage() 311 }) 312 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, MethodGet)) 313 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "/")) 314 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "emptyHandler")) 315 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "routeName")) 316 } 317 318 func Test_App_print_Route_with_group(t *testing.T) { 319 t.Parallel() 320 app := New(Config{EnablePrintRoutes: true}) 321 app.Get("/", emptyHandler) 322 323 v1 := app.Group("v1") 324 v1.Get("/test", emptyHandler).Name("v1") 325 v1.Post("/test/fiber", emptyHandler) 326 v1.Put("/test/fiber/*", emptyHandler) 327 328 printRoutesMessage := captureOutput(func() { 329 app.printRoutesMessage() 330 }) 331 332 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, MethodGet)) 333 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "/")) 334 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "emptyHandler")) 335 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "/v1/test")) 336 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, MethodPost)) 337 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "/v1/test/fiber")) 338 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "PUT")) 339 utils.AssertEqual(t, true, strings.Contains(printRoutesMessage, "/v1/test/fiber/*")) 340 } 341 342 func emptyHandler(_ *Ctx) error { 343 return nil 344 }