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  }