package middleware import ( "context" "net/http" "git.toowon.com/jimmy/go-commom/datetime" ) // TimezoneKey context中存储时区的key type timezoneKey struct{} // TimezoneHeaderName 时区请求头名称 const TimezoneHeaderName = "X-Timezone" // DefaultTimezone 默认时区 const DefaultTimezone = datetime.AsiaShanghai // GetTimezoneFromContext 从context中获取时区 func GetTimezoneFromContext(ctx context.Context) string { if tz, ok := ctx.Value(timezoneKey{}).(string); ok && tz != "" { return tz } return DefaultTimezone } // Timezone 时区处理中间件 // 从请求头 X-Timezone 读取时区信息,如果未传递则使用默认时区 AsiaShanghai // 时区信息会存储到context中,可以通过 GetTimezoneFromContext 获取 func Timezone(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 从请求头获取时区 timezone := r.Header.Get(TimezoneHeaderName) // 如果未传递时区信息,使用默认时区 if timezone == "" { timezone = DefaultTimezone } // 验证时区是否有效 if _, err := datetime.GetLocation(timezone); err != nil { // 如果时区无效,使用默认时区 timezone = DefaultTimezone } // 将时区存储到context中 ctx := context.WithValue(r.Context(), timezoneKey{}, timezone) next.ServeHTTP(w, r.WithContext(ctx)) }) } // TimezoneWithDefault 时区处理中间件(可自定义默认时区) // defaultTimezone: 默认时区,如果未指定则使用 AsiaShanghai func TimezoneWithDefault(defaultTimezone string) func(http.Handler) http.Handler { // 验证默认时区是否有效 if _, err := datetime.GetLocation(defaultTimezone); err != nil { defaultTimezone = DefaultTimezone } return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 从请求头获取时区 timezone := r.Header.Get(TimezoneHeaderName) // 如果未传递时区信息,使用指定的默认时区 if timezone == "" { timezone = defaultTimezone } // 验证时区是否有效 if _, err := datetime.GetLocation(timezone); err != nil { // 如果时区无效,使用默认时区 timezone = defaultTimezone } // 将时区存储到context中 ctx := context.WithValue(r.Context(), timezoneKey{}, timezone) next.ServeHTTP(w, r.WithContext(ctx)) }) } }