media: cache errors

This commit is contained in:
Tulir Asokan 2024-10-08 23:47:59 +03:00
parent da675fb578
commit 23478caa6e
3 changed files with 47 additions and 5 deletions

2
go.mod
View file

@ -11,7 +11,7 @@ require (
go.mau.fi/util v0.8.1-0.20241003092848-3b49d3e0b9ee
go.mau.fi/zeroconfig v0.1.3
maunium.net/go/mauflag v1.0.0
maunium.net/go/mautrix v0.21.1-0.20241007191346-1d8891fdb40e
maunium.net/go/mautrix v0.21.1-0.20241008204406-1f7f489fa97d
)
require (

4
go.sum
View file

@ -58,5 +58,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
maunium.net/go/mautrix v0.21.1-0.20241007191346-1d8891fdb40e h1:/R+hxB3+o+6iWxhBP/ibzooMF3OU0r3WRCu5m7FeKNs=
maunium.net/go/mautrix v0.21.1-0.20241007191346-1d8891fdb40e/go.mod h1:+fF5qsmXRCEXQZgW5ececC0PI3c7gISHTLcyftP4Bh0=
maunium.net/go/mautrix v0.21.1-0.20241008204406-1f7f489fa97d h1:sQ0dEq7Xvak1MPey+n72sMb2Npf3jfDtsjzdDlHSLx4=
maunium.net/go/mautrix v0.21.1-0.20241008204406-1f7f489fa97d/go.mod h1:+fF5qsmXRCEXQZgW5ececC0PI3c7gISHTLcyftP4Bh0=

View file

@ -14,6 +14,9 @@ import (
"strconv"
"github.com/rs/zerolog"
"go.mau.fi/util/jsontime"
"go.mau.fi/util/ptr"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/hicli/database"
"maunium.net/go/mautrix/id"
@ -25,13 +28,18 @@ var ErrBadGateway = mautrix.RespError{
}
func (gmx *Gomuks) downloadMediaFromCache(ctx context.Context, w http.ResponseWriter, entry *database.CachedMedia, force bool) bool {
if entry == nil || entry.Hash == nil {
if !entry.UseCache() {
if force {
mautrix.MNotFound.WithMessage("Media not found in cache").Write(w)
return true
}
return false
}
if entry.Error != nil {
w.Header().Set("Mau-Cached-Error", "true")
entry.Error.Write(w)
return true
}
log := zerolog.Ctx(ctx)
cacheFile, err := os.Open(gmx.cacheEntryToPath(entry))
if err != nil {
@ -112,7 +120,40 @@ func (gmx *Gomuks) DownloadMedia(w http.ResponseWriter, r *http.Request) {
resp, err := gmx.Client.Client.Download(ctx, mxc)
if err != nil {
log.Err(err).Msg("Failed to download media")
ErrBadGateway.WithMessage(err.Error()).Write(w)
var httpErr mautrix.HTTPError
if cacheEntry == nil {
cacheEntry = &database.CachedMedia{
MXC: mxc,
}
}
if cacheEntry.Error == nil {
cacheEntry.Error = &database.MediaError{
ReceivedAt: jsontime.UnixMilliNow(),
}
} else {
cacheEntry.Error.Attempts++
cacheEntry.Error.ReceivedAt = jsontime.UnixMilliNow()
}
if errors.As(err, &httpErr) {
if httpErr.WrappedError != nil {
cacheEntry.Error.Matrix = ptr.Ptr(ErrBadGateway.WithMessage(httpErr.WrappedError.Error()))
cacheEntry.Error.StatusCode = http.StatusBadGateway
} else if httpErr.RespError != nil {
cacheEntry.Error.Matrix = httpErr.RespError
cacheEntry.Error.StatusCode = httpErr.Response.StatusCode
} else {
cacheEntry.Error.Matrix = ptr.Ptr(mautrix.MUnknown.WithMessage("Server returned non-JSON error with status %d", httpErr.Response.StatusCode))
cacheEntry.Error.StatusCode = httpErr.Response.StatusCode
}
} else {
cacheEntry.Error.Matrix = ptr.Ptr(ErrBadGateway.WithMessage(err.Error()))
cacheEntry.Error.StatusCode = http.StatusBadGateway
}
err = gmx.Client.DB.CachedMedia.Put(ctx, cacheEntry)
if err != nil {
log.Err(err).Msg("Failed to save errored cache entry")
}
cacheEntry.Error.Write(w)
return
}
defer func() {
@ -159,6 +200,7 @@ func (gmx *Gomuks) DownloadMedia(w http.ResponseWriter, r *http.Request) {
cacheEntry.MimeType = resp.Header.Get("Content-Type")
}
cacheEntry.Hash = (*[32]byte)(fileHasher.Sum(nil))
cacheEntry.Error = nil
err = gmx.Client.DB.CachedMedia.Put(ctx, cacheEntry)
if err != nil {
log.Err(err).Msg("Failed to save cache entry")