Skip to content

Commit d7444e5

Browse files
Merge pull request #92 from basecamp/tls-allow-disable-redirect
Add `--tls-disable-redirect`
2 parents 545d52c + fa1991f commit d7444e5

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

internal/cmd/deploy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func newDeployCommand() *deployCommand {
3333
deployCommand.cmd.Flags().BoolVar(&deployCommand.tlsStaging, "tls-staging", false, "Use Let's Encrypt staging environment for certificate provisioning")
3434
deployCommand.cmd.Flags().StringVar(&deployCommand.args.ServiceOptions.TLSCertificatePath, "tls-certificate-path", "", "Configure custom TLS certificate path (PEM format)")
3535
deployCommand.cmd.Flags().StringVar(&deployCommand.args.ServiceOptions.TLSPrivateKeyPath, "tls-private-key-path", "", "Configure custom TLS private key path (PEM format)")
36+
deployCommand.cmd.Flags().BoolVar(&deployCommand.args.ServiceOptions.TLSDisableRedirect, "tls-disable-redirect", false, "Don't redirect HTTP traffic to HTTPS")
3637

3738
deployCommand.cmd.Flags().DurationVar(&deployCommand.args.DeployTimeout, "deploy-timeout", server.DefaultDeployTimeout, "Maximum time to wait for the new target to become healthy")
3839
deployCommand.cmd.Flags().DurationVar(&deployCommand.args.DrainTimeout, "drain-timeout", server.DefaultDrainTimeout, "Maximum time to allow existing connections to drain before removing old target")

internal/server/service.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type ServiceOptions struct {
6868
TLSEnabled bool `json:"tls_enabled"`
6969
TLSCertificatePath string `json:"tls_certificate_path"`
7070
TLSPrivateKeyPath string `json:"tls_private_key_path"`
71+
TLSDisableRedirect bool `json:"tls_disable_redirect"`
7172
ACMEDirectory string `json:"acme_directory"`
7273
ACMECachePath string `json:"acme_cache_path"`
7374
ErrorPagePath string `json:"error_page_path"`
@@ -351,7 +352,7 @@ func (s *Service) createMiddleware(options ServiceOptions, certManager CertManag
351352
func (s *Service) serviceRequestWithTarget(w http.ResponseWriter, r *http.Request) {
352353
LoggingRequestContext(r).Service = s.name
353354

354-
if s.options.TLSEnabled && r.TLS == nil {
355+
if s.shouldRedirectToHTTPS(r) {
355356
s.redirectToHTTPS(w, r)
356357
return
357358
}
@@ -374,6 +375,10 @@ func (s *Service) serviceRequestWithTarget(w http.ResponseWriter, r *http.Reques
374375
target.SendRequest(w, req)
375376
}
376377

378+
func (s *Service) shouldRedirectToHTTPS(r *http.Request) bool {
379+
return s.options.TLSEnabled && !s.options.TLSDisableRedirect && r.TLS == nil
380+
}
381+
377382
func (s *Service) handlePausedAndStoppedRequests(w http.ResponseWriter, r *http.Request) bool {
378383
if s.pauseController.GetState() != PauseStateRunning && s.ActiveTarget().IsHealthCheckRequest(r) {
379384
// When paused or stopped, return success for any health check

internal/server/service_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ func TestService_RedirectToHTTPSWhenTLSRequired(t *testing.T) {
4343
require.Equal(t, http.StatusOK, w.Result().StatusCode)
4444
}
4545

46+
func TestService_DontRedirectToHTTPSWhenTLSAndPlainHTTPAllowed(t *testing.T) {
47+
service := testCreateService(t, []string{"example.com"}, ServiceOptions{TLSEnabled: true, TLSDisableRedirect: true}, defaultTargetOptions)
48+
49+
require.True(t, service.options.TLSEnabled)
50+
51+
req := httptest.NewRequest(http.MethodGet, "http://example.com/", nil)
52+
w := httptest.NewRecorder()
53+
service.ServeHTTP(w, req)
54+
55+
require.Equal(t, http.StatusOK, w.Result().StatusCode)
56+
57+
req = httptest.NewRequest(http.MethodGet, "https://example.com", nil)
58+
w = httptest.NewRecorder()
59+
service.ServeHTTP(w, req)
60+
61+
require.Equal(t, http.StatusOK, w.Result().StatusCode)
62+
}
63+
4664
func TestService_UseStaticTLSCertificateWhenConfigured(t *testing.T) {
4765
certPath, keyPath := prepareTestCertificateFiles(t)
4866

0 commit comments

Comments
 (0)