From e19471c92b1cebff496744b37742991babf3d592 Mon Sep 17 00:00:00 2001 From: Chris Meyers <6556105+chrismeyers@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:36:13 -0600 Subject: [PATCH] Prevent empty Access-Control-Expose-Headers header (#160) Fixes #159 --- cors.go | 4 +++- cors_test.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/cors.go b/cors.go index c2959f2..69f89d8 100644 --- a/cors.go +++ b/cors.go @@ -215,7 +215,9 @@ func New(options Options) *Cors { } // Pre-compute exposed headers header value - c.exposedHeaders = []string{strings.Join(convert(options.ExposedHeaders, http.CanonicalHeaderKey), ", ")} + if len(options.ExposedHeaders) > 0 { + c.exposedHeaders = []string{strings.Join(convert(options.ExposedHeaders, http.CanonicalHeaderKey), ", ")} + } // Pre-compute prefight Vary header to save allocations if c.allowPrivateNetwork { diff --git a/cors_test.go b/cors_test.go index d2d0541..05ccf3b 100644 --- a/cors_test.go +++ b/cors_test.go @@ -752,3 +752,56 @@ func TestCorsAreHeadersAllowed(t *testing.T) { }) } } + +func TestAccessControlExposeHeadersPresence(t *testing.T) { + cases := []struct { + name string + options Options + want bool + }{ + { + name: "omit", + options: Options{}, + want: false, + }, + { + name: "include", + options: Options{ + ExposedHeaders: []string{"X-Something"}, + }, + want: true, + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + s := New(tt.options) + + req, _ := http.NewRequest("GET", "http://example.com/foo", nil) + req.Header.Add("Origin", "http://foobar.com") + + assertExposeHeaders := func(t *testing.T, resHeaders http.Header) { + if _, have := resHeaders["Access-Control-Expose-Headers"]; have != tt.want { + t.Errorf("Access-Control-Expose-Headers have: %t want: %t", have, tt.want) + } + } + + t.Run("Handler", func(t *testing.T) { + res := httptest.NewRecorder() + s.Handler(testHandler).ServeHTTP(res, req) + assertExposeHeaders(t, res.Header()) + }) + t.Run("HandlerFunc", func(t *testing.T) { + res := httptest.NewRecorder() + s.HandlerFunc(res, req) + assertExposeHeaders(t, res.Header()) + }) + t.Run("Negroni", func(t *testing.T) { + res := httptest.NewRecorder() + s.ServeHTTP(res, req, testHandler) + assertExposeHeaders(t, res.Header()) + }) + }) + } + +}