/
t3
/
s3-server
Обзор
Документация
Войти
/
t3
/
s3-server
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
internal/api/cache.go
45 строк
2 KB
Ivan
etag cache
16 июл 2026, 18:29
16 июл 2026, 18:29
f853b02
Код
Авторство
О чём код?
package api import ( "fmt" "net/http" "time" "gitverse.ru/t3/s3-server/internal/storage" ) func checkConditionalRequests(w http.ResponseWriter, r *http.Request, meta *storage.ObjectMeta) bool { etag := fmt.Sprintf(`"%s"`, meta.Hash) // 1. If-None-Match (возвращает 304, если ETag совпадает) // S3 также поддерживает "*", что означает "если объект существует" if noneMatch := r.Header.Get("If-None-Match"); noneMatch != "" { if noneMatch == "*" || noneMatch == etag { w.Header().Set("ETag", etag) w.Header().Set("Last-Modified", meta.UpdatedAt.Format(http.TimeFormat)) w.WriteHeader(http.StatusNotModified) return false } } // 2. If-Modified-Since (возвращает 304, если объект не менялся с указанной даты) if modSince := r.Header.Get("If-Modified-Since"); modSince != "" { if t, err := http.ParseTime(modSince); err == nil { // HTTP даты имеют точность до секунды, поэтому обрезаем время до секунды if !meta.UpdatedAt.Truncate(time.Second).After(t) { w.Header().Set("ETag", etag) w.Header().Set("Last-Modified", meta.UpdatedAt.Format(http.TimeFormat)) w.WriteHeader(http.StatusNotModified) return false } } } // (Опционально) If-Match и If-Unmodified-Since — возвращают 412 Precondition Failed // if match := r.Header.Get("If-Match"); match != "" && match != "*" && match != etag { // writeXMLError(w, r, http.StatusPreconditionFailed, "PreconditionFailed", "If-Match failed") // return false // } return true }