@@ -193,8 +193,6 @@ func (config CORSConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
193193 res := c .Response ()
194194 origin := req .Header .Get (echo .HeaderOrigin )
195195
196- res .Header ().Add (echo .HeaderVary , echo .HeaderOrigin )
197-
198196 // Preflight request is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method,
199197 // Access-Control-Request-Headers, and the Origin header. See: https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
200198 // For simplicity we just consider method type and later `Origin` header.
@@ -217,8 +215,12 @@ func (config CORSConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
217215 // No Origin provided. This is (probably) not request from actual browser - proceed executing middleware chain
218216 if origin == "" {
219217 if preflight { // req.Method=OPTIONS
218+ addVaryHeader (res .Header (), echo .HeaderOrigin )
220219 return c .NoContent (http .StatusNoContent )
221220 }
221+ res .Before (func () {
222+ addVaryHeader (res .Header (), echo .HeaderOrigin )
223+ })
222224 return next (c ) // let non-browser calls through
223225 }
224226
@@ -239,30 +241,44 @@ func (config CORSConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
239241 // no CORS middleware should block non-preflight requests;
240242 // such requests should be let through. One reason is that not all requests that
241243 // carry an Origin header participate in the CORS protocol.
244+ res .Before (func () {
245+ addVaryHeader (res .Header (), echo .HeaderOrigin )
246+ })
242247 return next (c )
243248 }
244249
245250 // Origin existed and was allowed
246251
247- res .Header ().Set (echo .HeaderAccessControlAllowOrigin , allowedOrigin )
248- if config .AllowCredentials {
249- res .Header ().Set (echo .HeaderAccessControlAllowCredentials , "true" )
250- }
251-
252252 // Simple request will be let though
253253 if ! preflight {
254- if exposeHeaders != "" {
255- res .Header ().Set (echo .HeaderAccessControlExposeHeaders , exposeHeaders )
256- }
254+ res .Before (func () {
255+ addVaryHeader (res .Header (), echo .HeaderOrigin )
256+ res .Header ().Set (echo .HeaderAccessControlAllowOrigin , allowedOrigin )
257+ if config .AllowCredentials {
258+ res .Header ().Set (echo .HeaderAccessControlAllowCredentials , "true" )
259+ } else {
260+ res .Header ().Del (echo .HeaderAccessControlAllowCredentials )
261+ }
262+ if exposeHeaders != "" {
263+ res .Header ().Set (echo .HeaderAccessControlExposeHeaders , exposeHeaders )
264+ }
265+ })
257266 return next (c )
258267 }
259268 // Below code is for Preflight (OPTIONS) request
260269 //
261270 // Preflight will end with c.NoContent(http.StatusNoContent) as we do not know if
262271 // at the end of handler chain is actual OPTIONS route or 404/405 route which
263272 // response code will confuse browsers
264- res .Header ().Add (echo .HeaderVary , echo .HeaderAccessControlRequestMethod )
265- res .Header ().Add (echo .HeaderVary , echo .HeaderAccessControlRequestHeaders )
273+ addVaryHeader (res .Header (), echo .HeaderOrigin )
274+ res .Header ().Set (echo .HeaderAccessControlAllowOrigin , allowedOrigin )
275+ if config .AllowCredentials {
276+ res .Header ().Set (echo .HeaderAccessControlAllowCredentials , "true" )
277+ } else {
278+ res .Header ().Del (echo .HeaderAccessControlAllowCredentials )
279+ }
280+ addVaryHeader (res .Header (), echo .HeaderAccessControlRequestMethod )
281+ addVaryHeader (res .Header (), echo .HeaderAccessControlRequestHeaders )
266282
267283 if ! hasCustomAllowMethods && routerAllowMethods != "" {
268284 res .Header ().Set (echo .HeaderAccessControlAllowMethods , routerAllowMethods )
@@ -298,3 +314,18 @@ func (config CORSConfig) defaultAllowOriginFunc(c *echo.Context, origin string)
298314 }
299315 return "" , false , nil
300316}
317+
318+ func addVaryHeader (h http.Header , value string ) {
319+ if h .Get (echo .HeaderVary ) == "" {
320+ h .Set (echo .HeaderVary , value )
321+ return
322+ }
323+ for _ , v := range h .Values (echo .HeaderVary ) {
324+ for _ , part := range strings .Split (v , "," ) {
325+ if strings .EqualFold (strings .TrimSpace (part ), value ) {
326+ return
327+ }
328+ }
329+ }
330+ h .Add (echo .HeaderVary , value )
331+ }
0 commit comments