package config_test import ( "io" "log" "os" "path/filepath" "strings" "testing" "time" "git.yuntuo.hk/k2safe/go-omni/config" ) func TestHTTPFileAndEnvironment(t *testing.T) { for _, file := range []struct{ name, body string }{ {"server.json", `{"http":{"readHeaderTimeout":"2s","readTimeout":"3s","writeTimeout":"4s","idleTimeout":"5s","maxHeaderBytes":8192}}`}, {"server.yaml", "http:\n readHeaderTimeout: 2s\n readTimeout: 3s\n writeTimeout: 4s\n idleTimeout: 5s\n maxHeaderBytes: 8192\n"}, } { t.Run(file.name, func(t *testing.T) { path := filepath.Join(t.TempDir(), file.name) if err := os.WriteFile(path, []byte(file.body), 0600); err != nil { t.Fatal(err) } cfg, err := config.LoadFile(path) if err != nil { t.Fatal(err) } want := config.HTTPConfig{ReadHeaderTimeout: 2 * time.Second, ReadTimeout: 3 * time.Second, WriteTimeout: 4 * time.Second, IdleTimeout: 5 * time.Second, MaxHeaderBytes: 8192} if cfg.HTTP != want { t.Fatalf("HTTP: %+v", cfg.HTTP) } t.Setenv("HTTP_TEST_HTTP_READ_HEADER_TIMEOUT", "6s") t.Setenv("HTTP_TEST_HTTP_READ_TIMEOUT", "7s") t.Setenv("HTTP_TEST_HTTP_WRITE_TIMEOUT", "8s") t.Setenv("HTTP_TEST_HTTP_IDLE_TIMEOUT", "9s") t.Setenv("HTTP_TEST_HTTP_MAX_HEADER_BYTES", "16384") if err := os.WriteFile(path, []byte(`{"http":{"readHeaderTimeout":"${HTTP_TEST_HTTP_READ_HEADER_TIMEOUT}","readTimeout":"${HTTP_TEST_HTTP_READ_TIMEOUT}","writeTimeout":"${HTTP_TEST_HTTP_WRITE_TIMEOUT}","idleTimeout":"${HTTP_TEST_HTTP_IDLE_TIMEOUT}","maxHeaderBytes":"${HTTP_TEST_HTTP_MAX_HEADER_BYTES}"}}`), 0600); err != nil { t.Fatal(err) } got, err := config.LoadProject(path, cfg) if err != nil { t.Fatal(err) } want = config.HTTPConfig{ReadHeaderTimeout: 6 * time.Second, ReadTimeout: 7 * time.Second, WriteTimeout: 8 * time.Second, IdleTimeout: 9 * time.Second, MaxHeaderBytes: 16384} if got.HTTP != want { t.Fatalf("overlay: %+v", got.HTTP) } }) } } func TestHTTPInvalidAndUnsupportedSettings(t *testing.T) { for _, key := range []string{"READ_HEADER_TIMEOUT", "READ_TIMEOUT", "WRITE_TIMEOUT", "IDLE_TIMEOUT", "MAX_HEADER_BYTES"} { for _, value := range []string{"invalid", "-1"} { t.Run(key+value, func(t *testing.T) { if value == "-1" && key != "MAX_HEADER_BYTES" { value = "-1s" } t.Setenv("HTTP_INVALID_HTTP_"+key, value) names := map[string]string{"READ_HEADER_TIMEOUT": "readHeaderTimeout", "READ_TIMEOUT": "readTimeout", "WRITE_TIMEOUT": "writeTimeout", "IDLE_TIMEOUT": "idleTimeout", "MAX_HEADER_BYTES": "maxHeaderBytes"} path := filepath.Join(t.TempDir(), "config.json") if err := os.WriteFile(path, []byte(`{"http":{"`+names[key]+`":"${HTTP_INVALID_HTTP_`+key+`}"}}`), 0600); err != nil { t.Fatal(err) } if _, err := config.LoadFile(path); err == nil { t.Fatal("invalid HTTP value accepted") } }) } } for _, http := range []config.HTTPConfig{{ReadHeaderTimeout: time.Second}, {ReadTimeout: time.Second}, {WriteTimeout: time.Second}} { cfg := config.Default() cfg.Transport = config.TransportHTTP2 cfg.TLS = config.TLSConfig{CertFile: "c", KeyFile: "k"} cfg.HTTP = http if err := cfg.ValidateTransport(); err == nil || !strings.Contains(err.Error(), "not supported") { t.Fatalf("HTTP/2: %v", err) } } cfg := config.Default() cfg.Transport = config.TransportHTTP2 cfg.TLS = config.TLSConfig{CertFile: "c", KeyFile: "k"} cfg.HTTP = config.HTTPConfig{IdleTimeout: time.Minute, MaxHeaderBytes: 8192} if err := cfg.ValidateTransport(); err != nil { t.Fatal(err) } for _, transport := range []string{config.TransportNative, config.TransportHTTP2} { cfg.Transport = transport cfg.HTTP = config.HTTPConfig{ErrorLog: log.New(io.Discard, "", 0)} if err := cfg.ValidateTransport(); err == nil || !strings.Contains(err.Error(), "http.errorLog") { t.Fatalf("ErrorLog silently ignored: %v", err) } } }