diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index f4b4b6b2..29d119b5 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -264,3 +264,9 @@ func (f *Framework) WriteTempFile(name string, content string) string { ExpectNoError(err) return filePath } + +func (f *Framework) MakeTempDir(pattern string) string { + path, err := ioutil.TempDir(f.TempDirectory, pattern) + ExpectNoError(err) + return path +} diff --git a/test/e2e/pkg/request/request.go b/test/e2e/pkg/request/request.go index d9bd54e4..f98625cf 100644 --- a/test/e2e/pkg/request/request.go +++ b/test/e2e/pkg/request/request.go @@ -33,6 +33,9 @@ type Request struct { headers map[string]string tlsConfig *tls.Config + // for acme + tlsHandshakeTimeout time.Duration + proxyURL string } @@ -119,6 +122,11 @@ func (r *Request) Timeout(timeout time.Duration) *Request { return r } +func (r *Request) TLSHandshakeTimeout(tlsHandshakeTimeout time.Duration) *Request { + r.tlsHandshakeTimeout = tlsHandshakeTimeout + return r +} + func (r *Request) Body(content []byte) *Request { r.body = content return r @@ -195,6 +203,10 @@ func (r *Request) sendHTTPRequest(method, urlstr string, host string, headers ma for k, v := range headers { req.Header.Set(k, v) } + tlsHandshakeTimeout := 10 * time.Second + if r.tlsHandshakeTimeout > 0 { + tlsHandshakeTimeout = r.tlsHandshakeTimeout + } tr := &http.Transport{ DialContext: (&net.Dialer{ Timeout: time.Second, @@ -203,7 +215,7 @@ func (r *Request) sendHTTPRequest(method, urlstr string, host string, headers ma }).DialContext, MaxIdleConns: 100, IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, + TLSHandshakeTimeout: tlsHandshakeTimeout, ExpectContinueTimeout: 1 * time.Second, TLSClientConfig: tlsConfig, } diff --git a/test/e2e/plugin/client.go b/test/e2e/plugin/client.go index 03908956..d1c21ef8 100644 --- a/test/e2e/plugin/client.go +++ b/test/e2e/plugin/client.go @@ -3,7 +3,9 @@ package plugin import ( "crypto/tls" "fmt" + "os" "strconv" + "time" "github.com/fatedier/frp/pkg/transport" "github.com/fatedier/frp/test/e2e/framework" @@ -313,4 +315,55 @@ var _ = Describe("[Feature: Client-Plugins]", func() { ExpectResp([]byte("test")). Ensure() }) + + It("https2http_acme", func() { + domain := os.Getenv("ACME_TEST_DOMAIN") + vhostHTTPSPort, _ := strconv.Atoi(os.Getenv("ACME_TEST_PORT")) + tlsHandshakeTimeout, _ := time.ParseDuration(os.Getenv("ACME_TEST_TLS_HANDSHAKE_TIMEOUT")) + if len(domain) == 0 || vhostHTTPSPort == 0 { + Skip("ACME_TEST_DOMAIN and ACME_TEST_PORT env vars have to be set") + return + } + if tlsHandshakeTimeout == 0 { + tlsHandshakeTimeout = 100 * time.Second // ACME takes long time sometimes + } + + email := fmt.Sprintf("frp-e2e-tests@%s", domain) + certsPath := f.MakeTempDir("certs") + + serverConf := consts.DefaultServerConfig + serverConf += fmt.Sprintf(` + vhost_https_port = %d + `, vhostHTTPSPort) + + localPort := f.AllocPort() + clientConf := consts.DefaultClientConfig + fmt.Sprintf(` + [https2http_acme] + type = https + custom_domains = %s + plugin = https2http_acme + plugin_local_addr = 127.0.0.1:%d + plugin_certs_path = %s + plugin_email = %s + `, domain, localPort, certsPath, email) + + f.RunProcesses([]string{serverConf}, []string{clientConf}) + + localServer := httpserver.New( + httpserver.WithBindPort(localPort), + httpserver.WithResponse([]byte("test")), + ) + f.RunServer("", localServer) + + framework.NewRequestExpect(f). + Port(vhostHTTPSPort). + RequestModify(func(r *request.Request) { + r.TLSHandshakeTimeout(tlsHandshakeTimeout) + r.HTTPS().HTTPHost(domain).TLSConfig(&tls.Config{ + ServerName: domain, + }) + }). + ExpectResp([]byte("test")). + Ensure() + }) })