cmd/syncthing: Conditionally enable CORS
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3541 LGTM: AudriusButkevicius
This commit is contained in:
parent
3e51206a6b
commit
3990014073
@ -442,10 +442,12 @@ func corsMiddleware(next http.Handler) http.Handler {
|
|||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Process OPTIONS requests
|
// Process OPTIONS requests
|
||||||
if r.Method == "OPTIONS" {
|
if r.Method == "OPTIONS" {
|
||||||
|
// Add a generous access-control-allow-origin header for CORS requests
|
||||||
|
w.Header().Add("Access-Control-Allow-Origin", "*")
|
||||||
// Only GET/POST Methods are supported
|
// Only GET/POST Methods are supported
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST")
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST")
|
||||||
// Only this custom header can be set
|
// Only these headers can be set
|
||||||
w.Header().Set("Access-Control-Allow-Headers", "X-API-Key")
|
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-API-Key")
|
||||||
// The request is meant to be cached 10 minutes
|
// The request is meant to be cached 10 minutes
|
||||||
w.Header().Set("Access-Control-Max-Age", "600")
|
w.Header().Set("Access-Control-Max-Age", "600")
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,9 @@ func csrfMiddleware(unique string, prefix string, cfg config.GUIConfiguration, n
|
|||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Allow requests carrying a valid API key
|
// Allow requests carrying a valid API key
|
||||||
if cfg.IsValidAPIKey(r.Header.Get("X-API-Key")) {
|
if cfg.IsValidAPIKey(r.Header.Get("X-API-Key")) {
|
||||||
|
// Set the access-control-allow-origin header for CORS requests
|
||||||
|
// since a valid API key has been provided
|
||||||
|
w.Header().Add("Access-Control-Allow-Origin", "*")
|
||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -857,3 +857,64 @@ func TestAddressIsLocalhost(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccessControlAllowOriginHeader(t *testing.T) {
|
||||||
|
const testAPIKey = "foobarbaz"
|
||||||
|
cfg := new(mockedConfig)
|
||||||
|
cfg.gui.APIKey = testAPIKey
|
||||||
|
baseURL, err := startHTTP(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
cli := &http.Client{
|
||||||
|
Timeout: time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("GET", baseURL+"/rest/system/status", nil)
|
||||||
|
req.Header.Set("X-API-Key", testAPIKey)
|
||||||
|
resp, err := cli.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
t.Fatal("GET on /rest/system/status should succeed, not", resp.Status)
|
||||||
|
}
|
||||||
|
if resp.Header.Get("Access-Control-Allow-Origin") != "*" {
|
||||||
|
t.Fatal("GET on /rest/system/status should return a 'Access-Control-Allow-Origin: *' header")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOptionsRequest(t *testing.T) {
|
||||||
|
const testAPIKey = "foobarbaz"
|
||||||
|
cfg := new(mockedConfig)
|
||||||
|
cfg.gui.APIKey = testAPIKey
|
||||||
|
baseURL, err := startHTTP(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
cli := &http.Client{
|
||||||
|
Timeout: time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("OPTIONS", baseURL+"/rest/system/status", nil)
|
||||||
|
resp, err := cli.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusNoContent {
|
||||||
|
t.Fatal("OPTIONS on /rest/system/status should succeed, not", resp.Status)
|
||||||
|
}
|
||||||
|
if resp.Header.Get("Access-Control-Allow-Origin") != "*" {
|
||||||
|
t.Fatal("OPTIONS on /rest/system/status should return a 'Access-Control-Allow-Origin: *' header")
|
||||||
|
}
|
||||||
|
if resp.Header.Get("Access-Control-Allow-Methods") != "GET, POST" {
|
||||||
|
t.Fatal("OPTIONS on /rest/system/status should return a 'Access-Control-Allow-Methods: GET, POST' header")
|
||||||
|
}
|
||||||
|
if resp.Header.Get("Access-Control-Allow-Headers") != "Content-Type, X-API-Key" {
|
||||||
|
t.Fatal("OPTIONS on /rest/system/status should return a 'Access-Control-Allow-Headers: Content-Type, X-API-KEY' header")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user