-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #141 from launchdarkly/eb/ch83491/relay-base
(v6 - #9) create RelayCore and move most of the core logic into it
- Loading branch information
Showing
17 changed files
with
872 additions
and
414 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,67 @@ | ||
package cors | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/launchdarkly/ld-relay/v6/internal/events" | ||
) | ||
|
||
const ( | ||
// The default origin string to use in CORS response headers. | ||
DefaultAllowedOrigin = "*" | ||
) | ||
|
||
type contextKeyType string | ||
|
||
const ( | ||
contextKey contextKeyType = "context" | ||
maxAge string = "300" | ||
) | ||
|
||
var allowedHeadersList = []string{ | ||
"Cache-Control", | ||
"Content-Type", | ||
"Content-Length", | ||
"Accept-Encoding", | ||
"X-LaunchDarkly-User-Agent", | ||
"X-LaunchDarkly-Payload-ID", | ||
"X-LaunchDarkly-Wrapper", | ||
events.EventSchemaHeader, | ||
} | ||
|
||
var allowedHeaders = strings.Join(allowedHeadersList, ",") | ||
|
||
// RequestContext represents a scope that has a specific set of allowed origins for CORS requests. This | ||
// can be attached to a request context with WithCORSContext(). | ||
type RequestContext interface { | ||
AllowedOrigins() []string | ||
} | ||
|
||
// GetCORSContext returns the CORSContext that has been attached to this Context with WithCORSContext(), | ||
// or nil if none. | ||
func GetCORSContext(ctx context.Context) RequestContext { | ||
if cc, ok := ctx.Value(contextKey).(RequestContext); ok { | ||
return cc | ||
} | ||
return nil | ||
} | ||
|
||
// WithCORSContext returns a copy of the parent context with the specified CORSContext attached. | ||
func WithCORSContext(parent context.Context, cc RequestContext) context.Context { | ||
if cc == nil { | ||
return parent | ||
} | ||
return context.WithValue(parent, contextKey, cc) | ||
} | ||
|
||
// SetCORSHeaders sets a standard set of CORS headers on an HTTP response. This is meant to be the same | ||
// behavior that the LaunchDarkly service endpoints uses for client-side JS requests. | ||
func SetCORSHeaders(w http.ResponseWriter, origin string) { | ||
w.Header().Set("Access-Control-Allow-Origin", origin) | ||
w.Header().Set("Access-Control-Allow-Credentials", "false") | ||
w.Header().Set("Access-Control-Max-Age", maxAge) | ||
w.Header().Set("Access-Control-Allow-Headers", allowedHeaders) | ||
w.Header().Set("Access-Control-Expose-Headers", "Date") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package cors | ||
|
||
import ( | ||
"context" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
type mockCORSContext struct{} | ||
|
||
func (m mockCORSContext) AllowedOrigins() []string { | ||
return nil | ||
} | ||
|
||
func TestCORSContext(t *testing.T) { | ||
t.Run("GetCORSContext when there is no RequestContext returns nil", func(t *testing.T) { | ||
assert.Nil(t, GetCORSContext(context.Background())) | ||
}) | ||
|
||
t.Run("WithCORSContext adds RequestContext to context", func(t *testing.T) { | ||
m := mockCORSContext{} | ||
ctx := WithCORSContext(context.Background(), m) | ||
assert.Equal(t, m, GetCORSContext(ctx)) | ||
}) | ||
|
||
t.Run("WithCORSContext has no effect with nil parameter", func(t *testing.T) { | ||
ctx := WithCORSContext(context.Background(), nil) | ||
assert.Equal(t, context.Background(), ctx) | ||
}) | ||
|
||
t.Run("SetCORSHeaders", func(t *testing.T) { | ||
origin := "http://good.cat" | ||
rr := httptest.ResponseRecorder{} | ||
SetCORSHeaders(&rr, origin) | ||
assert.Equal(t, origin, rr.Header().Get("Access-Control-Allow-Origin")) | ||
assert.Equal(t, "false", rr.Header().Get("Access-Control-Allow-Credentials")) | ||
assert.Equal(t, maxAge, rr.Header().Get("Access-Control-Max-Age")) | ||
assert.Equal(t, allowedHeaders, rr.Header().Get("Access-Control-Allow-Headers")) | ||
assert.Equal(t, "Date", rr.Header().Get("Access-Control-Expose-Headers")) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.