Skip to content

Commit 85fc0ca

Browse files
authored
Make Gin wrapper's status configurable and use 204 as default (fixes #145) (#173)
1 parent 4c32059 commit 85fc0ca

File tree

4 files changed

+116
-104
lines changed

4 files changed

+116
-104
lines changed

wrapper/gin/gin.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,19 @@ type Options = cors.Options
1616
// about configured 'optionPassthrough' option.
1717
type corsWrapper struct {
1818
*cors.Cors
19-
optionPassthrough bool
19+
optionsSuccessStatus int
20+
optionsPassthrough bool
2021
}
2122

2223
// build transforms wrapped cors.Cors handler into Gin middleware.
2324
func (c corsWrapper) build() gin.HandlerFunc {
2425
return func(ctx *gin.Context) {
2526
c.HandlerFunc(ctx.Writer, ctx.Request)
26-
if !c.optionPassthrough &&
27+
if !c.optionsPassthrough &&
2728
ctx.Request.Method == http.MethodOptions &&
2829
ctx.GetHeader("Access-Control-Request-Method") != "" {
2930
// Abort processing next Gin middlewares.
30-
ctx.AbortWithStatus(http.StatusOK)
31+
ctx.AbortWithStatus(c.optionsSuccessStatus)
3132
}
3233
}
3334
}
@@ -46,5 +47,14 @@ func Default() gin.HandlerFunc {
4647

4748
// New creates a new CORS Gin middleware with the provided options.
4849
func New(options Options) gin.HandlerFunc {
49-
return corsWrapper{cors.New(options), options.OptionsPassthrough}.build()
50+
status := options.OptionsSuccessStatus
51+
if status == 0 {
52+
status = http.StatusNoContent
53+
}
54+
wrapper := corsWrapper{
55+
Cors: cors.New(options),
56+
optionsSuccessStatus: status,
57+
optionsPassthrough: options.OptionsPassthrough,
58+
}
59+
return wrapper.build()
5060
}

wrapper/gin/gin_test.go

+7-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"testing"
77

88
"github.com/gin-gonic/gin"
9-
"github.com/rs/cors"
109
)
1110

1211
func init() {
@@ -38,35 +37,33 @@ func TestCorsWrapper_buildAbortsWhenPreflight(t *testing.T) {
3837
res := httptest.NewRecorder()
3938
ctx, _ := gin.CreateTestContext(res)
4039
ctx.Request, _ = http.NewRequest("OPTIONS", "http://example.com/foo", nil)
41-
ctx.Request.Header.Add("Origin", "http://example.com/")
40+
ctx.Request.Header.Add("Origin", "http://example.org")
4241
ctx.Request.Header.Add("Access-Control-Request-Method", "POST")
4342
ctx.Status(http.StatusAccepted)
4443
res.Code = http.StatusAccepted
4544

46-
handler := corsWrapper{Cors: cors.New(Options{
47-
// Intentionally left blank.
48-
})}.build()
45+
handler := New(Options{ /* Intentionally left blank. */ })
4946

5047
handler(ctx)
5148

5249
if !ctx.IsAborted() {
5350
t.Error("Should abort on preflight requests")
5451
}
55-
if res.Code != http.StatusOK {
56-
t.Error("Should abort with 200 OK status")
52+
if res.Code != http.StatusNoContent {
53+
t.Error("Should abort with 204 Non Content status")
5754
}
5855
}
5956

6057
func TestCorsWrapper_buildNotAbortsWhenPassthrough(t *testing.T) {
6158
res := httptest.NewRecorder()
6259
ctx, _ := gin.CreateTestContext(res)
6360
ctx.Request, _ = http.NewRequest("OPTIONS", "http://example.com/foo", nil)
64-
ctx.Request.Header.Add("Origin", "http://example.com/")
61+
ctx.Request.Header.Add("Origin", "http://example.org")
6562
ctx.Request.Header.Add("Access-Control-Request-Method", "POST")
6663

67-
handler := corsWrapper{cors.New(Options{
64+
handler := New(Options{
6865
OptionsPassthrough: true,
69-
}), true}.build()
66+
})
7067

7168
handler(ctx)
7269

wrapper/gin/go.mod

+22-14
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,35 @@ module github.com/rs/cors/wrapper/gin
33
go 1.17
44

55
require (
6-
github.com/gin-gonic/gin v1.7.7
7-
github.com/rs/cors v1.8.1
6+
github.com/gin-gonic/gin v1.9.1
7+
github.com/rs/cors v1.11.0
88
)
99

1010
require (
11+
github.com/bytedance/sonic v1.9.1 // indirect
12+
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
13+
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
1114
github.com/gin-contrib/sse v0.1.0 // indirect
12-
github.com/go-playground/locales v0.14.0 // indirect
13-
github.com/go-playground/universal-translator v0.18.0 // indirect
14-
github.com/go-playground/validator/v10 v10.9.0 // indirect
15-
github.com/golang/protobuf v1.5.2 // indirect
15+
github.com/go-playground/locales v0.14.1 // indirect
16+
github.com/go-playground/universal-translator v0.18.1 // indirect
17+
github.com/go-playground/validator/v10 v10.14.0 // indirect
18+
github.com/goccy/go-json v0.10.2 // indirect
1619
github.com/json-iterator/go v1.1.12 // indirect
17-
github.com/leodido/go-urn v1.2.1 // indirect
18-
github.com/mattn/go-isatty v0.0.14 // indirect
20+
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
21+
github.com/leodido/go-urn v1.2.4 // indirect
22+
github.com/mattn/go-isatty v0.0.19 // indirect
1923
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
2024
github.com/modern-go/reflect2 v1.0.2 // indirect
21-
github.com/ugorji/go/codec v1.2.6 // indirect
22-
golang.org/x/crypto v0.1.0 // indirect
23-
golang.org/x/sys v0.1.0 // indirect
24-
golang.org/x/text v0.4.0 // indirect
25-
google.golang.org/protobuf v1.27.1 // indirect
26-
gopkg.in/yaml.v2 v2.4.0 // indirect
25+
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
26+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
27+
github.com/ugorji/go/codec v1.2.11 // indirect
28+
golang.org/x/arch v0.3.0 // indirect
29+
golang.org/x/crypto v0.9.0 // indirect
30+
golang.org/x/net v0.10.0 // indirect
31+
golang.org/x/sys v0.8.0 // indirect
32+
golang.org/x/text v0.9.0 // indirect
33+
google.golang.org/protobuf v1.30.0 // indirect
34+
gopkg.in/yaml.v3 v3.0.1 // indirect
2735
)
2836

2937
replace github.com/rs/cors => ../../

0 commit comments

Comments
 (0)