mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-10-28 08:35:33 +08:00
55 lines
1.6 KiB
Go
55 lines
1.6 KiB
Go
package controller
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/QuantumNous/new-api/common"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// etagVersionPublicContent namespaces the public-content ETag; bump it when
|
|
// the JSON envelope served by serveRevalidatedJSON changes shape.
|
|
const etagVersionPublicContent = "public-content:v1"
|
|
|
|
type publicContentResponse struct {
|
|
Success bool `json:"success"`
|
|
Message string `json:"message"`
|
|
Data string `json:"data"`
|
|
}
|
|
|
|
// serveRevalidatedJSON writes public content as JSON with a weak
|
|
// content-derived ETag and answers conditional requests with 304 Not
|
|
// Modified. The ETag is a weak validator derived from the content, so it is
|
|
// stable across replicas and JSON encodings, and a new one is issued when
|
|
// the content changes. Cache-Control: no-cache forces revalidation before
|
|
// reuse, so an admin edit takes effect on the next request; Vary:
|
|
// Accept-Encoding keeps the gzip and identity encodings apart in shared
|
|
// caches.
|
|
func serveRevalidatedJSON(c *gin.Context, content string) {
|
|
body, err := common.Marshal(publicContentResponse{
|
|
Success: true,
|
|
Message: "",
|
|
Data: content,
|
|
})
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"success": false,
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
etag := common.ETagFor(etagVersionPublicContent, content)
|
|
|
|
c.Header("ETag", etag)
|
|
c.Header("Cache-Control", "no-cache")
|
|
c.Header("Vary", "Accept-Encoding")
|
|
|
|
if common.ETagMatches(c.GetHeader("If-None-Match"), etag) {
|
|
c.Status(http.StatusNotModified)
|
|
return
|
|
}
|
|
|
|
c.Data(http.StatusOK, "application/json; charset=utf-8", body)
|
|
}
|