mirror of
https://github.com/minio/minio.git
synced 2025-04-21 19:14:39 -04:00
Disable redirect of HTTP request to a HTTPS Minio server (#4454)
Fixes #4452
This commit is contained in:
parent
9ba57a8df0
commit
64f4dbc272
@ -36,9 +36,9 @@ test_script:
|
|||||||
# Unit tests
|
# Unit tests
|
||||||
- ps: Add-AppveyorTest "Unit Tests" -Outcome Running
|
- ps: Add-AppveyorTest "Unit Tests" -Outcome Running
|
||||||
- mkdir build\coverage
|
- mkdir build\coverage
|
||||||
- go test -timeout 17m -race github.com/minio/minio/cmd...
|
- go test -v -timeout 17m -race github.com/minio/minio/cmd...
|
||||||
- go test -race github.com/minio/minio/pkg...
|
- go test -v -race github.com/minio/minio/pkg...
|
||||||
- go test -coverprofile=build\coverage\coverage.txt -covermode=atomic github.com/minio/minio/cmd
|
- go test -v -coverprofile=build\coverage\coverage.txt -covermode=atomic github.com/minio/minio/cmd
|
||||||
- ps: Update-AppveyorTest "Unit Tests" -Outcome Passed
|
- ps: Update-AppveyorTest "Unit Tests" -Outcome Passed
|
||||||
|
|
||||||
after_test:
|
after_test:
|
||||||
|
@ -149,6 +149,7 @@ const (
|
|||||||
ErrAdminInvalidAccessKey
|
ErrAdminInvalidAccessKey
|
||||||
ErrAdminInvalidSecretKey
|
ErrAdminInvalidSecretKey
|
||||||
ErrAdminConfigNoQuorum
|
ErrAdminConfigNoQuorum
|
||||||
|
ErrInsecureClientRequest
|
||||||
)
|
)
|
||||||
|
|
||||||
// error code to APIError structure, these fields carry respective
|
// error code to APIError structure, these fields carry respective
|
||||||
@ -618,6 +619,11 @@ var errorCodeResponse = map[APIErrorCode]APIError{
|
|||||||
Description: "Configuration update failed because server quorum was not met",
|
Description: "Configuration update failed because server quorum was not met",
|
||||||
HTTPStatusCode: http.StatusServiceUnavailable,
|
HTTPStatusCode: http.StatusServiceUnavailable,
|
||||||
},
|
},
|
||||||
|
ErrInsecureClientRequest: {
|
||||||
|
Code: "XMinioInsecureClientRequest",
|
||||||
|
Description: "Cannot respond to plain-text request from TLS-encrypted server",
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
},
|
||||||
|
|
||||||
// Add your error structure here.
|
// Add your error structure here.
|
||||||
}
|
}
|
||||||
|
@ -449,25 +449,9 @@ func (m *ServerMux) ListenAndServe(certFile, keyFile string) (err error) {
|
|||||||
// All http requests start to be processed by httpHandler
|
// All http requests start to be processed by httpHandler
|
||||||
httpHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
httpHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if tlsEnabled && r.TLS == nil {
|
if tlsEnabled && r.TLS == nil {
|
||||||
// It is expected that r.Host might not have port
|
// TLS is enabled but request is not TLS
|
||||||
// for standard ports such as "80" and "443".
|
// configured - return error to client.
|
||||||
host, port, _ := net.SplitHostPort(r.Host)
|
writeErrorResponse(w, ErrInsecureClientRequest, &url.URL{})
|
||||||
if port == "" {
|
|
||||||
host = net.JoinHostPort(r.Host, globalMinioPort)
|
|
||||||
} else {
|
|
||||||
host = r.Host
|
|
||||||
}
|
|
||||||
// TLS is enabled but Request is not TLS configured
|
|
||||||
u := url.URL{
|
|
||||||
Scheme: httpsScheme,
|
|
||||||
Opaque: r.URL.Opaque,
|
|
||||||
User: r.URL.User,
|
|
||||||
Host: host,
|
|
||||||
Path: r.URL.Path,
|
|
||||||
RawQuery: r.URL.RawQuery,
|
|
||||||
Fragment: r.URL.Fragment,
|
|
||||||
}
|
|
||||||
http.Redirect(w, r, u.String(), http.StatusTemporaryRedirect)
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Return ServiceUnavailable for clients which are sending requests
|
// Return ServiceUnavailable for clients which are sending requests
|
||||||
@ -481,7 +465,7 @@ func (m *ServerMux) ListenAndServe(certFile, keyFile string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Execute registered handlers, update currentReqs to keep
|
// Execute registered handlers, update currentReqs to keep
|
||||||
// tracks of current requests currently processed by the server
|
// track of concurrent requests processing on the server
|
||||||
atomic.AddInt32(&m.currentReqs, 1)
|
atomic.AddInt32(&m.currentReqs, 1)
|
||||||
m.handler.ServeHTTP(w, r)
|
m.handler.ServeHTTP(w, r)
|
||||||
atomic.AddInt32(&m.currentReqs, -1)
|
atomic.AddInt32(&m.currentReqs, -1)
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -339,6 +340,11 @@ func TestServerListenAndServePlain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerListenAndServeTLS(t *testing.T) {
|
func TestServerListenAndServeTLS(t *testing.T) {
|
||||||
|
_, err := newTestConfig(globalMinioDefaultRegion)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Init Test config failed")
|
||||||
|
}
|
||||||
|
|
||||||
wait := make(chan struct{})
|
wait := make(chan struct{})
|
||||||
addr := net.JoinHostPort("127.0.0.1", getFreePort())
|
addr := net.JoinHostPort("127.0.0.1", getFreePort())
|
||||||
errc := make(chan error)
|
errc := make(chan error)
|
||||||
@ -354,7 +360,7 @@ func TestServerListenAndServeTLS(t *testing.T) {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
// Create a cert
|
// Create a cert
|
||||||
err := createConfigDir()
|
err = createConfigDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -374,7 +380,6 @@ func TestServerListenAndServeTLS(t *testing.T) {
|
|||||||
|
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
// Keep trying the server until it's accepting connections
|
|
||||||
go func() {
|
go func() {
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
@ -384,6 +389,7 @@ func TestServerListenAndServeTLS(t *testing.T) {
|
|||||||
Transport: tr,
|
Transport: tr,
|
||||||
}
|
}
|
||||||
okTLS := false
|
okTLS := false
|
||||||
|
// Keep trying the server until it's accepting connections
|
||||||
for !okTLS {
|
for !okTLS {
|
||||||
res, _ := client.Get("https://" + addr)
|
res, _ := client.Get("https://" + addr)
|
||||||
if res != nil && res.StatusCode == http.StatusOK {
|
if res != nil && res.StatusCode == http.StatusOK {
|
||||||
@ -391,14 +397,27 @@ func TestServerListenAndServeTLS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
okNoTLS := false
|
// Once a request succeeds, subsequent requests should
|
||||||
for !okNoTLS {
|
// work fine.
|
||||||
res, _ := client.Get("http://" + addr)
|
res, err := client.Get("http://" + addr)
|
||||||
// Without TLS we expect a re-direction from http to https
|
if err != nil {
|
||||||
// And also the request is not rejected.
|
t.Errorf("Got unexpected error: %v", err)
|
||||||
if res != nil && res.StatusCode == http.StatusOK && res.Request.URL.Scheme == httpsScheme {
|
}
|
||||||
okNoTLS = true
|
// Without TLS we expect a Bad-Request response from the server.
|
||||||
}
|
if !(res != nil && res.StatusCode == http.StatusBadRequest && res.Request.URL.Scheme == httpScheme) {
|
||||||
|
t.Fatalf("Plaintext request to TLS server did not have expected response!")
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error reading body")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the expected error is received.
|
||||||
|
bodyStr := string(body)
|
||||||
|
apiErr := getAPIError(ErrInsecureClientRequest)
|
||||||
|
if !(strings.Contains(bodyStr, apiErr.Code) && strings.Contains(bodyStr, apiErr.Description)) {
|
||||||
|
t.Fatalf("Plaintext request to TLS server did not have expected response body!")
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user