-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcors.go
More file actions
113 lines (96 loc) · 2.84 KB
/
Copy pathcors.go
File metadata and controls
113 lines (96 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package middlewares
import (
"net/http"
"net/url"
"strings"
"github.com/gin-gonic/gin"
"github.com/humanjuan/golyn/config/loaders"
"github.com/humanjuan/golyn/globals"
)
func CorsMiddleware() gin.HandlerFunc {
log := globals.GetAppLogger()
return func(c *gin.Context) {
origin := c.Request.Header.Get("Origin")
if origin == "" {
c.Next()
return
}
hostParts := strings.Split(c.Request.Host, ":")
host := strings.ToLower(hostParts[0])
var security loaders.Security
if cfg, exists := c.Get("site_config"); exists {
if siteCfg, ok := cfg.(loaders.SiteConfig); ok {
security = siteCfg.Security
}
}
if security.AllowOrigin == nil {
if vhs, ok := globals.VirtualHosts[host]; ok {
path := c.Request.URL.Path
for i := range vhs {
if vhs[i].PathPrefix == "/" || strings.HasPrefix(path, vhs[i].PathPrefix) {
security = vhs[i].Security
break
}
}
}
}
if len(security.AllowOrigin) > 0 {
allowed := false
isWildcard := false
for _, allowedOrigin := range security.AllowOrigin {
allowedOrigin = strings.TrimSpace(allowedOrigin)
if allowedOrigin == "*" {
isWildcard = true
allowed = true
}
// Exact match
if origin == allowedOrigin || (origin == "null" && allowedOrigin != "*") {
allowed = true
break
}
// Dev mode: Allow same domain with different port
config := globals.GetConfig()
if config.Server.Dev && !allowed {
parsedOrigin, err := url.Parse(origin)
parsedAllowed, err2 := url.Parse(allowedOrigin)
if err == nil && err2 == nil {
if parsedOrigin.Hostname() == parsedAllowed.Hostname() &&
parsedOrigin.Scheme == parsedAllowed.Scheme {
log.Debug("CorsMiddleware() | Allowing dev origin by hostname match | Origin: %s | AllowedBase: %s", origin, allowedOrigin)
allowed = true
break
}
}
}
}
if allowed {
// Prohibit "*" when Allow-Credentials: true.
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization, X-CSRF-Token, X-Requested-With")
if !isWildcard {
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
} else {
log.Debug("CorsMiddleware() | Credentials disabled for wildcard origin | Host: %s", host)
}
} else {
log.Warn("CorsMiddleware() | Origin not allowed | Host: %s | Origin: %s", host, origin)
}
}
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(http.StatusOK)
return
}
c.Next()
}
}
func isValidURL(u string) bool {
parsedURL, err := url.ParseRequestURI(u)
if err != nil {
return false
}
if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
return false
}
return true
}