richcms在管理后台已经支持etag与last-modified的header输出实现,在站点配置处设置时间即可。以下是richcms etag的实现源码:


/*
etag middleware
*/

type EtagFlag struct {
	lastTimeUnix int64
	lastTime     time.Time
}

var (
	ef = &EtagFlag{
		lastTimeUnix: time.Now().Unix(),
		lastTime:     time.Now(),
	}
)

// Etag etag and last-modified writer
func Etag() gow.HandlerFunc {
	return func(c *gow.Context) {
		config := new(model.Config)
		objConfig, ok := c.GetKey(constname.KeyConfig)
		if ok {
			config = objConfig.(*model.Config)
		}
		//配置中设置etag_timeout>0时才有效
		var etagTimeout int
		if config != nil && config.EtagTimeout > 0 {
			etagTimeout = config.EtagTimeout
		} else {
			return
		}
		key := fmt.Sprintf("%s-%s-%s-%d", c.Request.Host, c.Request.Method, c.FullPath(), ef.lastTimeUnix)
		sum := getHash(key)
		now := time.Now()
		reqSum := c.GetHeader("If-None-Match")
		reqSum = strings.ReplaceAll(reqSum, "\"", "")
		if reqSum == sum {
			c.Header("Etag", `"`+sum+`"`)
			c.Writer.WriteHeader(304)
			c.Abort()
		} else {
			sum = getHash(key)
			lastModified := getGMTDateTime(ef.lastTime)
			c.Header("Etag", `"`+sum+`"`)
			c.Header("Last-Modified", lastModified)
			if now.Unix()-ef.lastTimeUnix > int64(etagTimeout) {
				ef.lastTimeUnix = now.Unix()
				ef.lastTime = now
			}
		}
		c.Next()
	}
}

代码说明:

  • 定义 EtagFlag 结构体;
  • 声明 EtagFlag的全局变量;
  • Etag()是在前端用户页面路由上调用的中间件函数