aboutsummaryrefslogtreecommitdiff
path: root/mediaapi/routing/routing.go
diff options
context:
space:
mode:
Diffstat (limited to 'mediaapi/routing/routing.go')
-rw-r--r--mediaapi/routing/routing.go105
1 files changed, 93 insertions, 12 deletions
diff --git a/mediaapi/routing/routing.go b/mediaapi/routing/routing.go
index 5963eeaa..2867df60 100644
--- a/mediaapi/routing/routing.go
+++ b/mediaapi/routing/routing.go
@@ -20,11 +20,13 @@ import (
"strings"
"github.com/gorilla/mux"
+ "github.com/matrix-org/dendrite/federationapi/routing"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/mediaapi/storage"
"github.com/matrix-org/dendrite/mediaapi/types"
"github.com/matrix-org/dendrite/setup/config"
userapi "github.com/matrix-org/dendrite/userapi/api"
+ "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/matrix-org/gomatrixserverlib/spec"
"github.com/matrix-org/util"
@@ -45,15 +47,19 @@ type configResponse struct {
// applied:
// nolint: gocyclo
func Setup(
- publicAPIMux *mux.Router,
+ routers httputil.Routers,
cfg *config.Dendrite,
db storage.Database,
userAPI userapi.MediaUserAPI,
client *fclient.Client,
+ federationClient fclient.FederationClient,
+ keyRing gomatrixserverlib.JSONVerifier,
) {
rateLimits := httputil.NewRateLimits(&cfg.ClientAPI.RateLimiting)
- v3mux := publicAPIMux.PathPrefix("/{apiversion:(?:r0|v1|v3)}/").Subrouter()
+ v3mux := routers.Media.PathPrefix("/{apiversion:(?:r0|v1|v3)}/").Subrouter()
+ v1mux := routers.Client.PathPrefix("/v1/media/").Subrouter()
+ v1fedMux := routers.Federation.PathPrefix("/v1/media/").Subrouter()
activeThumbnailGeneration := &types.ActiveThumbnailGeneration{
PathToResult: map[string]*types.ThumbnailGenerationResult{},
@@ -90,33 +96,103 @@ func Setup(
MXCToResult: map[string]*types.RemoteRequestResult{},
}
- downloadHandler := makeDownloadAPI("download", &cfg.MediaAPI, rateLimits, db, client, activeRemoteRequests, activeThumbnailGeneration)
+ downloadHandler := makeDownloadAPI("download_unauthed", &cfg.MediaAPI, rateLimits, db, client, federationClient, activeRemoteRequests, activeThumbnailGeneration, false)
v3mux.Handle("/download/{serverName}/{mediaId}", downloadHandler).Methods(http.MethodGet, http.MethodOptions)
v3mux.Handle("/download/{serverName}/{mediaId}/{downloadName}", downloadHandler).Methods(http.MethodGet, http.MethodOptions)
v3mux.Handle("/thumbnail/{serverName}/{mediaId}",
- makeDownloadAPI("thumbnail", &cfg.MediaAPI, rateLimits, db, client, activeRemoteRequests, activeThumbnailGeneration),
+ makeDownloadAPI("thumbnail_unauthed", &cfg.MediaAPI, rateLimits, db, client, federationClient, activeRemoteRequests, activeThumbnailGeneration, false),
).Methods(http.MethodGet, http.MethodOptions)
+
+ // v1 client endpoints requiring auth
+ downloadHandlerAuthed := httputil.MakeHTTPAPI("download", userAPI, cfg.Global.Metrics.Enabled, makeDownloadAPI("download_authed_client", &cfg.MediaAPI, rateLimits, db, client, federationClient, activeRemoteRequests, activeThumbnailGeneration, false), httputil.WithAuth())
+ v1mux.Handle("/config", configHandler).Methods(http.MethodGet, http.MethodOptions)
+ v1mux.Handle("/download/{serverName}/{mediaId}", downloadHandlerAuthed).Methods(http.MethodGet, http.MethodOptions)
+ v1mux.Handle("/download/{serverName}/{mediaId}/{downloadName}", downloadHandlerAuthed).Methods(http.MethodGet, http.MethodOptions)
+
+ v1mux.Handle("/thumbnail/{serverName}/{mediaId}",
+ httputil.MakeHTTPAPI("thumbnail", userAPI, cfg.Global.Metrics.Enabled, makeDownloadAPI("thumbnail_authed_client", &cfg.MediaAPI, rateLimits, db, client, federationClient, activeRemoteRequests, activeThumbnailGeneration, false), httputil.WithAuth()),
+ ).Methods(http.MethodGet, http.MethodOptions)
+
+ // same, but for federation
+ v1fedMux.Handle("/download/{mediaId}", routing.MakeFedHTTPAPI(cfg.Global.ServerName, cfg.Global.IsLocalServerName, keyRing,
+ makeDownloadAPI("download_authed_federation", &cfg.MediaAPI, rateLimits, db, client, federationClient, activeRemoteRequests, activeThumbnailGeneration, true),
+ )).Methods(http.MethodGet, http.MethodOptions)
+ v1fedMux.Handle("/thumbnail/{mediaId}", routing.MakeFedHTTPAPI(cfg.Global.ServerName, cfg.Global.IsLocalServerName, keyRing,
+ makeDownloadAPI("thumbnail_authed_federation", &cfg.MediaAPI, rateLimits, db, client, federationClient, activeRemoteRequests, activeThumbnailGeneration, true),
+ )).Methods(http.MethodGet, http.MethodOptions)
}
+var thumbnailCounter = promauto.NewCounterVec(
+ prometheus.CounterOpts{
+ Namespace: "dendrite",
+ Subsystem: "mediaapi",
+ Name: "thumbnail",
+ Help: "Total number of media_api requests for thumbnails",
+ },
+ []string{"code", "type"},
+)
+
+var thumbnailSize = promauto.NewHistogramVec(
+ prometheus.HistogramOpts{
+ Namespace: "dendrite",
+ Subsystem: "mediaapi",
+ Name: "thumbnail_size_bytes",
+ Help: "Total size of media_api requests for thumbnails",
+ Buckets: []float64{50, 100, 200, 500, 900, 1500, 3000, 6000},
+ },
+ []string{"code", "type"},
+)
+
+var downloadCounter = promauto.NewCounterVec(
+ prometheus.CounterOpts{
+ Namespace: "dendrite",
+ Subsystem: "mediaapi",
+ Name: "download",
+ Help: "Total size of media_api requests for full downloads",
+ },
+ []string{"code", "type"},
+)
+
+var downloadSize = promauto.NewHistogramVec(
+ prometheus.HistogramOpts{
+ Namespace: "dendrite",
+ Subsystem: "mediaapi",
+ Name: "download_size_bytes",
+ Help: "Total size of media_api requests for full downloads",
+ Buckets: []float64{1500, 3000, 6000, 10_000, 50_000, 100_000},
+ },
+ []string{"code", "type"},
+)
+
func makeDownloadAPI(
name string,
cfg *config.MediaAPI,
rateLimits *httputil.RateLimits,
db storage.Database,
client *fclient.Client,
+ fedClient fclient.FederationClient,
activeRemoteRequests *types.ActiveRemoteRequests,
activeThumbnailGeneration *types.ActiveThumbnailGeneration,
+ forFederation bool,
) http.HandlerFunc {
var counterVec *prometheus.CounterVec
+ var sizeVec *prometheus.HistogramVec
+ var requestType string
if cfg.Matrix.Metrics.Enabled {
- counterVec = promauto.NewCounterVec(
- prometheus.CounterOpts{
- Name: name,
- Help: "Total number of media_api requests for either thumbnails or full downloads",
- },
- []string{"code"},
- )
+ split := strings.Split(name, "_")
+ // The first part of the split is either "download" or "thumbnail"
+ name = split[0]
+ // The remainder of the split is something like "authed_download" or "unauthed_thumbnail", etc.
+ // This is used to curry the metrics with the given types.
+ requestType = strings.Join(split[1:], "_")
+
+ counterVec = thumbnailCounter
+ sizeVec = thumbnailSize
+ if name != "thumbnail" {
+ counterVec = downloadCounter
+ sizeVec = downloadSize
+ }
}
httpHandler := func(w http.ResponseWriter, req *http.Request) {
req = util.RequestWithLogging(req)
@@ -164,16 +240,21 @@ func makeDownloadAPI(
cfg,
db,
client,
+ fedClient,
activeRemoteRequests,
activeThumbnailGeneration,
- name == "thumbnail",
+ strings.HasPrefix(name, "thumbnail"),
vars["downloadName"],
+ forFederation,
)
}
var handlerFunc http.HandlerFunc
if counterVec != nil {
+ counterVec = counterVec.MustCurryWith(prometheus.Labels{"type": requestType})
+ sizeVec2 := sizeVec.MustCurryWith(prometheus.Labels{"type": requestType})
handlerFunc = promhttp.InstrumentHandlerCounter(counterVec, http.HandlerFunc(httpHandler))
+ handlerFunc = promhttp.InstrumentHandlerResponseSize(sizeVec2, handlerFunc).ServeHTTP
} else {
handlerFunc = http.HandlerFunc(httpHandler)
}