forked from rs/cors
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Impl gin.HandlerFunc wrappers for Cors handler * Provide an example for Gin * Update TravisCI matrix from Go 1.8 to Go 1.9 + 1.10
- Loading branch information
Showing
5 changed files
with
148 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
language: go | ||
go: | ||
- 1.8 | ||
- 1.9 | ||
- "1.10" | ||
- tip | ||
matrix: | ||
allow_failures: | ||
|
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 |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package main | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/gin-gonic/gin" | ||
cors "github.com/rs/cors/wrapper/gin" | ||
) | ||
|
||
func main() { | ||
router := gin.Default() | ||
|
||
router.Use(cors.Default()) | ||
router.GET("/", func(context *gin.Context) { | ||
context.JSON(http.StatusOK, gin.H{"hello": "world"}) | ||
}) | ||
|
||
router.Run(":8080") | ||
} |
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,50 @@ | ||
// Package cors/wrapper/gin provides gin.HandlerFunc to handle CORS related | ||
// requests as a wrapper of github.com/rs/cors handler. | ||
package gin | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/rs/cors" | ||
) | ||
|
||
// Options is a configuration container to setup the CORS middleware. | ||
type Options = cors.Options | ||
|
||
// corsWrapper is a wrapper of cors.Cors handler which preserves information | ||
// about configured 'optionPassthrough' option. | ||
type corsWrapper struct { | ||
*cors.Cors | ||
optionPassthrough bool | ||
} | ||
|
||
// build transforms wrapped cors.Cors handler into Gin middleware. | ||
func (c corsWrapper) build() gin.HandlerFunc { | ||
return func(ctx *gin.Context) { | ||
c.HandlerFunc(ctx.Writer, ctx.Request) | ||
if !c.optionPassthrough && | ||
ctx.Request.Method == http.MethodOptions && | ||
ctx.GetHeader("Access-Control-Request-Method") != "" { | ||
// Abort processing next Gin middlewares. | ||
ctx.AbortWithStatus(http.StatusOK) | ||
} | ||
} | ||
} | ||
|
||
// AllowAll creates a new CORS Gin middleware with permissive configuration | ||
// allowing all origins with all standard methods with any header and | ||
// credentials. | ||
func AllowAll() gin.HandlerFunc { | ||
return corsWrapper{Cors: cors.AllowAll()}.build() | ||
} | ||
|
||
// Default creates a new CORS Gin middleware with default options. | ||
func Default() gin.HandlerFunc { | ||
return corsWrapper{Cors: cors.Default()}.build() | ||
} | ||
|
||
// New creates a new CORS Gin middleware with the provided options. | ||
func New(options Options) gin.HandlerFunc { | ||
return corsWrapper{cors.New(options), options.OptionsPassthrough}.build() | ||
} |
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,76 @@ | ||
package gin | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/rs/cors" | ||
) | ||
|
||
func init() { | ||
gin.SetMode(gin.ReleaseMode) | ||
} | ||
|
||
func TestAllowAllNotNil(t *testing.T) { | ||
handler := AllowAll() | ||
if handler == nil { | ||
t.Error("Should not return nil Gin handler") | ||
} | ||
} | ||
|
||
func TestDefaultNotNil(t *testing.T) { | ||
handler := Default() | ||
if handler == nil { | ||
t.Error("Should not return nil Gin handler") | ||
} | ||
} | ||
|
||
func TestNewNotNil(t *testing.T) { | ||
handler := New(Options{}) | ||
if handler == nil { | ||
t.Error("Should not return nil Gin handler") | ||
} | ||
} | ||
|
||
func TestCorsWrapper_buildAbortsWhenPreflight(t *testing.T) { | ||
res := httptest.NewRecorder() | ||
ctx, _ := gin.CreateTestContext(res) | ||
ctx.Request, _ = http.NewRequest("OPTIONS", "http://example.com/foo", nil) | ||
ctx.Request.Header.Add("Origin", "http://example.com/") | ||
ctx.Request.Header.Add("Access-Control-Request-Method", "POST") | ||
ctx.Status(http.StatusAccepted) | ||
res.Code = http.StatusAccepted | ||
|
||
handler := corsWrapper{Cors: cors.New(Options{ | ||
// Intentionally left blank. | ||
})}.build() | ||
|
||
handler(ctx) | ||
|
||
if !ctx.IsAborted() { | ||
t.Error("Should abort on preflight requests") | ||
} | ||
if res.Code != http.StatusOK { | ||
t.Error("Should abort with 200 OK status") | ||
} | ||
} | ||
|
||
func TestCorsWrapper_buildNotAbortsWhenPassthrough(t *testing.T) { | ||
res := httptest.NewRecorder() | ||
ctx, _ := gin.CreateTestContext(res) | ||
ctx.Request, _ = http.NewRequest("OPTIONS", "http://example.com/foo", nil) | ||
ctx.Request.Header.Add("Origin", "http://example.com/") | ||
ctx.Request.Header.Add("Access-Control-Request-Method", "POST") | ||
|
||
handler := corsWrapper{cors.New(Options{ | ||
OptionsPassthrough: true, | ||
}), true}.build() | ||
|
||
handler(ctx) | ||
|
||
if ctx.IsAborted() { | ||
t.Error("Should not abort when OPTIONS passthrough enabled") | ||
} | ||
} |