aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--appservice/routing/routing.go4
-rw-r--r--clientapi/routing/joinroom.go5
-rw-r--r--clientapi/routing/routing.go119
-rw-r--r--common/basecomponent/base.go2
-rw-r--r--common/routing.go35
-rw-r--r--federationapi/routing/routing.go69
-rw-r--r--go.mod2
-rw-r--r--go.sum6
-rw-r--r--mediaapi/routing/routing.go6
-rw-r--r--publicroomsapi/routing/routing.go14
-rw-r--r--syncapi/routing/routing.go19
11 files changed, 236 insertions, 45 deletions
diff --git a/appservice/routing/routing.go b/appservice/routing/routing.go
index f0b8461d..3c19c840 100644
--- a/appservice/routing/routing.go
+++ b/appservice/routing/routing.go
@@ -31,6 +31,10 @@ const pathPrefixApp = "/_matrix/app/r0"
// Setup registers HTTP handlers with the given ServeMux. It also supplies the given http.Client
// to clients which need to make outbound HTTP requests.
+//
+// Due to Setup being used to call many other functions, a gocyclo nolint is
+// applied:
+// nolint: gocyclo
func Setup(
apiMux *mux.Router, cfg config.Dendrite, // nolint: unparam
queryAPI api.RoomserverQueryAPI, aliasAPI api.RoomserverAliasAPI, // nolint: unparam
diff --git a/clientapi/routing/joinroom.go b/clientapi/routing/joinroom.go
index c98688de..9c02a93c 100644
--- a/clientapi/routing/joinroom.go
+++ b/clientapi/routing/joinroom.go
@@ -86,7 +86,10 @@ func JoinRoomByIDOrAlias(
}
return util.JSONResponse{
Code: http.StatusBadRequest,
- JSON: jsonerror.BadJSON("Invalid first character for room ID or alias"),
+ JSON: jsonerror.BadJSON(
+ fmt.Sprintf("Invalid first character '%s' for room ID or alias",
+ string([]rune(roomIDOrAlias)[0])), // Wrapping with []rune makes this call UTF-8 safe
+ ),
}
}
diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go
index b0ced79e..8135e49a 100644
--- a/clientapi/routing/routing.go
+++ b/clientapi/routing/routing.go
@@ -41,6 +41,10 @@ const pathPrefixUnstable = "/_matrix/client/unstable"
// Setup registers HTTP handlers with the given ServeMux. It also supplies the given http.Client
// to clients which need to make outbound HTTP requests.
+//
+// Due to Setup being used to call many other functions, a gocyclo nolint is
+// applied:
+// nolint: gocyclo
func Setup(
apiMux *mux.Router, cfg config.Dendrite,
producer *producers.RoomserverProducer,
@@ -90,7 +94,10 @@ func Setup(
).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/join/{roomIDOrAlias}",
common.MakeAuthAPI("join", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return JoinRoomByIDOrAlias(
req, device, vars["roomIDOrAlias"], cfg, federation, producer, queryAPI, aliasAPI, keyRing, accountDB,
)
@@ -98,19 +105,28 @@ func Setup(
).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/{membership:(?:join|kick|ban|unban|leave|invite)}",
common.MakeAuthAPI("membership", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return SendMembership(req, accountDB, device, vars["roomID"], vars["membership"], cfg, queryAPI, asAPI, producer)
}),
).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/send/{eventType}",
common.MakeAuthAPI("send_message", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return SendEvent(req, device, vars["roomID"], vars["eventType"], nil, nil, cfg, queryAPI, producer, nil)
}),
).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/send/{eventType}/{txnID}",
common.MakeAuthAPI("send_message", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
txnID := vars["txnID"]
return SendEvent(req, device, vars["roomID"], vars["eventType"], &txnID,
nil, cfg, queryAPI, producer, transactionsCache)
@@ -118,7 +134,10 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state/{eventType:[^/]+/?}",
common.MakeAuthAPI("send_message", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
emptyString := ""
eventType := vars["eventType"]
// If there's a trailing slash, remove it
@@ -130,7 +149,10 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state/{eventType}/{stateKey}",
common.MakeAuthAPI("send_message", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
stateKey := vars["stateKey"]
return SendEvent(req, device, vars["roomID"], vars["eventType"], nil, &stateKey, cfg, queryAPI, producer, nil)
}),
@@ -150,21 +172,30 @@ func Setup(
r0mux.Handle("/directory/room/{roomAlias}",
common.MakeExternalAPI("directory_room", func(req *http.Request) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return DirectoryRoom(req, vars["roomAlias"], federation, &cfg, aliasAPI)
}),
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/directory/room/{roomAlias}",
common.MakeAuthAPI("directory_room", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return SetLocalAlias(req, device, vars["roomAlias"], &cfg, aliasAPI)
}),
).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/directory/room/{roomAlias}",
common.MakeAuthAPI("directory_room", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return RemoveLocalAlias(req, device, vars["roomAlias"], aliasAPI)
}),
).Methods(http.MethodDelete, http.MethodOptions)
@@ -183,7 +214,10 @@ func Setup(
r0mux.Handle("/rooms/{roomID}/typing/{userID}",
common.MakeAuthAPI("rooms_typing", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return SendTyping(req, device, vars["roomID"], vars["userID"], accountDB, typingProducer)
}),
).Methods(http.MethodPut, http.MethodOptions)
@@ -223,14 +257,20 @@ func Setup(
r0mux.Handle("/user/{userId}/filter",
common.MakeAuthAPI("put_filter", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return PutFilter(req, device, accountDB, vars["userId"])
}),
).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/user/{userId}/filter/{filterId}",
common.MakeAuthAPI("get_filter", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetFilter(req, device, accountDB, vars["userId"], vars["filterId"])
}),
).Methods(http.MethodGet, http.MethodOptions)
@@ -239,21 +279,30 @@ func Setup(
r0mux.Handle("/profile/{userID}",
common.MakeExternalAPI("profile", func(req *http.Request) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetProfile(req, accountDB, vars["userID"], asAPI)
}),
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/profile/{userID}/avatar_url",
common.MakeExternalAPI("profile_avatar_url", func(req *http.Request) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetAvatarURL(req, accountDB, vars["userID"], asAPI)
}),
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/profile/{userID}/avatar_url",
common.MakeAuthAPI("profile_avatar_url", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return SetAvatarURL(req, accountDB, device, vars["userID"], userUpdateProducer, &cfg, producer, queryAPI)
}),
).Methods(http.MethodPut, http.MethodOptions)
@@ -262,14 +311,20 @@ func Setup(
r0mux.Handle("/profile/{userID}/displayname",
common.MakeExternalAPI("profile_displayname", func(req *http.Request) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetDisplayName(req, accountDB, vars["userID"], asAPI)
}),
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/profile/{userID}/displayname",
common.MakeAuthAPI("profile_displayname", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return SetDisplayName(req, accountDB, device, vars["userID"], userUpdateProducer, &cfg, producer, queryAPI)
}),
).Methods(http.MethodPut, http.MethodOptions)
@@ -339,28 +394,40 @@ func Setup(
r0mux.Handle("/user/{userID}/account_data/{type}",
common.MakeAuthAPI("user_account_data", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return SaveAccountData(req, accountDB, device, vars["userID"], "", vars["type"], syncProducer)
}),
).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/user/{userID}/rooms/{roomID}/account_data/{type}",
common.MakeAuthAPI("user_account_data", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return SaveAccountData(req, accountDB, device, vars["userID"], vars["roomID"], vars["type"], syncProducer)
}),
).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/members",
common.MakeAuthAPI("rooms_members", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetMemberships(req, device, vars["roomID"], false, cfg, queryAPI)
}),
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/joined_members",
common.MakeAuthAPI("rooms_members", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetMemberships(req, device, vars["roomID"], true, cfg, queryAPI)
}),
).Methods(http.MethodGet, http.MethodOptions)
@@ -380,14 +447,20 @@ func Setup(
r0mux.Handle("/devices/{deviceID}",
common.MakeAuthAPI("get_device", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetDeviceByID(req, deviceDB, device, vars["deviceID"])
}),
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/devices/{deviceID}",
common.MakeAuthAPI("device_data", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return UpdateDeviceByID(req, deviceDB, device, vars["deviceID"])
}),
).Methods(http.MethodPut, http.MethodOptions)
diff --git a/common/basecomponent/base.go b/common/basecomponent/base.go
index d1f50754..6a20aca3 100644
--- a/common/basecomponent/base.go
+++ b/common/basecomponent/base.go
@@ -71,7 +71,7 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string) *BaseDendrite {
componentName: componentName,
tracerCloser: closer,
Cfg: cfg,
- APIMux: mux.NewRouter(),
+ APIMux: mux.NewRouter().UseEncodedPath(),
KafkaConsumer: kafkaConsumer,
KafkaProducer: kafkaProducer,
}
diff --git a/common/routing.go b/common/routing.go
new file mode 100644
index 00000000..330912cd
--- /dev/null
+++ b/common/routing.go
@@ -0,0 +1,35 @@
+// Copyright 2019 The Matrix.org Foundation C.I.C.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package common
+
+import (
+ "net/url"
+)
+
+// URLDecodeMapValues is a function that iterates through each of the items in a
+// map, URL decodes the value, and returns a new map with the decoded values
+// under the same key names
+func URLDecodeMapValues(vmap map[string]string) (map[string]string, error) {
+ decoded := make(map[string]string, len(vmap))
+ for key, value := range vmap {
+ decodedVal, err := url.QueryUnescape(value)
+ if err != nil {
+ return make(map[string]string), err
+ }
+ decoded[key] = decodedVal
+ }
+
+ return decoded, nil
+}
diff --git a/federationapi/routing/routing.go b/federationapi/routing/routing.go
index 035d54aa..16704e0b 100644
--- a/federationapi/routing/routing.go
+++ b/federationapi/routing/routing.go
@@ -35,6 +35,10 @@ const (
)
// Setup registers HTTP handlers with the given ServeMux.
+//
+// Due to Setup being used to call many other functions, a gocyclo nolint is
+// applied:
+// nolint: gocyclo
func Setup(
apiMux *mux.Router,
cfg config.Dendrite,
@@ -64,7 +68,10 @@ func Setup(
v1fedmux.Handle("/send/{txnID}/", common.MakeFedAPI(
"federation_send", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return Send(
httpReq, request, gomatrixserverlib.TransactionID(vars["txnID"]),
cfg, query, producer, keys, federation,
@@ -75,7 +82,10 @@ func Setup(
v1fedmux.Handle("/invite/{roomID}/{eventID}", common.MakeFedAPI(
"federation_invite", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return Invite(
httpReq, request, vars["roomID"], vars["eventID"],
cfg, producer, keys,
@@ -92,7 +102,10 @@ func Setup(
v1fedmux.Handle("/exchange_third_party_invite/{roomID}", common.MakeFedAPI(
"exchange_third_party_invite", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return ExchangeThirdPartyInvite(
httpReq, request, vars["roomID"], query, cfg, federation, producer,
)
@@ -102,7 +115,10 @@ func Setup(
v1fedmux.Handle("/event/{eventID}", common.MakeFedAPI(
"federation_get_event", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetEvent(
httpReq.Context(), request, query, vars["eventID"],
)
@@ -112,7 +128,10 @@ func Setup(
v1fedmux.Handle("/state/{roomID}", common.MakeFedAPI(
"federation_get_event_auth", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetState(
httpReq.Context(), request, query, vars["roomID"],
)
@@ -122,7 +141,10 @@ func Setup(
v1fedmux.Handle("/state_ids/{roomID}", common.MakeFedAPI(
"federation_get_event_auth", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetStateIDs(
httpReq.Context(), request, query, vars["roomID"],
)
@@ -150,7 +172,10 @@ func Setup(
v1fedmux.Handle("/user/devices/{userID}", common.MakeFedAPI(
"federation_user_devices", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetUserDevices(
httpReq, deviceDB, vars["userID"],
)
@@ -160,7 +185,10 @@ func Setup(
v1fedmux.Handle("/make_join/{roomID}/{userID}", common.MakeFedAPI(
"federation_make_join", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
roomID := vars["roomID"]
userID := vars["userID"]
return MakeJoin(
@@ -172,7 +200,10 @@ func Setup(
v1fedmux.Handle("/send_join/{roomID}/{userID}", common.MakeFedAPI(
"federation_send_join", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
roomID := vars["roomID"]
userID := vars["userID"]
return SendJoin(
@@ -184,7 +215,10 @@ func Setup(
v1fedmux.Handle("/make_leave/{roomID}/{userID}", common.MakeFedAPI(
"federation_make_leave", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
roomID := vars["roomID"]
userID := vars["userID"]
return MakeLeave(
@@ -196,7 +230,10 @@ func Setup(
v1fedmux.Handle("/send_leave/{roomID}/{userID}", common.MakeFedAPI(
"federation_send_leave", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
roomID := vars["roomID"]
userID := vars["userID"]
return SendLeave(
@@ -215,7 +252,10 @@ func Setup(
v1fedmux.Handle("/get_missing_events/{roomID}", common.MakeFedAPI(
"federation_get_missing_events", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return GetMissingEvents(httpReq, request, query, vars["roomID"])
},
)).Methods(http.MethodPost)
@@ -223,7 +263,10 @@ func Setup(
v1fedmux.Handle("/backfill/{roomID}/", common.MakeFedAPI(
"federation_backfill", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
- vars := mux.Vars(httpReq)
+ vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return Backfill(httpReq, request, query, vars["roomID"], cfg)
},
)).Methods(http.MethodGet)
diff --git a/go.mod b/go.mod
index 57490572..072d9ef3 100644
--- a/go.mod
+++ b/go.mod
@@ -16,7 +16,7 @@ require (
github.com/golang/snappy v0.0.0-20170119014723-7db9049039a0
github.com/google/shlex v0.0.0-20150127133951-6f45313302b9
github.com/gorilla/context v1.1.1
- github.com/gorilla/mux v1.3.0
+ github.com/gorilla/mux v1.7.3
github.com/jaegertracing/jaeger-client-go v0.0.0-20170921145708-3ad49a1d839b
github.com/jaegertracing/jaeger-lib v0.0.0-20170920222118-21a3da6d66fe
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6
diff --git a/go.sum b/go.sum
index 250b300b..ce3c07dd 100644
--- a/go.sum
+++ b/go.sum
@@ -10,6 +10,7 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE
github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b/go.mod h1:v9FBN7gdVTpiD/+LZ7Po0UKvROyT87uLVxTHVky/dlQ=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eapache/go-resiliency v0.0.0-20160104191539-b86b1ec0dd42 h1:f8ERmXYuaC+kCSv2w+y3rBK/oVu6If4DEm3jywJJ0hc=
github.com/eapache/go-resiliency v0.0.0-20160104191539-b86b1ec0dd42/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
@@ -27,6 +28,8 @@ github.com/google/shlex v0.0.0-20150127133951-6f45313302b9/go.mod h1:RpwtwJQFrIE
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.3.0 h1:HwSEKGN6U5T2aAQTfu5pW8fiwjSp3IgwdRbkICydk/c=
github.com/gorilla/mux v1.3.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/jaegertracing/jaeger-client-go v0.0.0-20170921145708-3ad49a1d839b/go.mod h1:HWG7INeOG1ZE17I/S8eeb+svquXmBS/hf1Obi6hJUyQ=
github.com/jaegertracing/jaeger-lib v0.0.0-20170920222118-21a3da6d66fe/go.mod h1:VqeqQrZmZr9G4WdLw4ei9tAHU54iJRkfoFHvTTQn4jQ=
@@ -117,6 +120,7 @@ golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613 h1:MQ/ZZiDsUapFFiMS+vzwXk
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20170927055102-0a9397675ba3 h1:tTDpczhDVjW6WN3DinzKcw5juwkDTVn22I7MNlfxSXM=
golang.org/x/net v0.0.0-20170927055102-0a9397675ba3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 h1:fY7Dsw114eJN4boqzVSbpVHO6rTdhq6/GnXeu+PKnzU=
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20171012164349-43eea11bc926 h1:PY6OU86NqbyZiOzaPnDw6oOjAGtYQqIua16z6y9QkwE=
golang.org/x/sys v0.0.0-20171012164349-43eea11bc926/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -134,4 +138,6 @@ gopkg.in/macaroon.v2 v2.0.0/go.mod h1:+I6LnTMkm/uV5ew/0nsulNjL16SK4+C8yDmRUzHR17
gopkg.in/macaroon.v2 v2.1.0/go.mod h1:OUb+TQP/OP0WOerC2Jp/3CwhIKyIa9kQjuc7H24e6/o=
gopkg.in/yaml.v2 v2.0.0-20171116090243-287cf08546ab h1:yZ6iByf7GKeJ3gsd1Dr/xaj1DyJ//wxKX1Cdh8LhoAw=
gopkg.in/yaml.v2 v2.0.0-20171116090243-287cf08546ab/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+
diff --git a/mediaapi/routing/routing.go b/mediaapi/routing/routing.go
index fb983ccc..5bcce177 100644
--- a/mediaapi/routing/routing.go
+++ b/mediaapi/routing/routing.go
@@ -34,6 +34,10 @@ import (
const pathPrefixR0 = "/_matrix/media/r0"
// Setup registers the media API HTTP handlers
+//
+// Due to Setup being used to call many other functions, a gocyclo nolint is
+// applied:
+// nolint: gocyclo
func Setup(
apiMux *mux.Router,
cfg *config.Dendrite,
@@ -87,7 +91,7 @@ func makeDownloadAPI(
// Content-Type will be overridden in case of returning file data, else we respond with JSON-formatted errors
w.Header().Set("Content-Type", "application/json")
- vars := mux.Vars(req)
+ vars, _ := common.URLDecodeMapValues(mux.Vars(req))
Download(
w,
req,
diff --git a/publicroomsapi/routing/routing.go b/publicroomsapi/routing/routing.go
index 6a4b79b7..3a1c9eb5 100644
--- a/publicroomsapi/routing/routing.go
+++ b/publicroomsapi/routing/routing.go
@@ -30,6 +30,10 @@ import (
const pathPrefixR0 = "/_matrix/client/r0"
// Setup configures the given mux with publicroomsapi server listeners
+//
+// Due to Setup being used to call many other functions, a gocyclo nolint is
+// applied:
+// nolint: gocyclo
func Setup(apiMux *mux.Router, deviceDB *devices.Database, publicRoomsDB *storage.PublicRoomsServerDatabase) {
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
@@ -41,14 +45,20 @@ func Setup(apiMux *mux.Router, deviceDB *devices.Database, publicRoomsDB *storag
r0mux.Handle("/directory/list/room/{roomID}",
common.MakeExternalAPI("directory_list", func(req *http.Request) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return directory.GetVisibility(req, publicRoomsDB, vars["roomID"])
}),
).Methods(http.MethodGet, http.MethodOptions)
// TODO: Add AS support
r0mux.Handle("/directory/list/room/{roomID}",
common.MakeAuthAPI("directory_list", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return directory.SetVisibility(req, publicRoomsDB, vars["roomID"])
}),
).Methods(http.MethodPut, http.MethodOptions)
diff --git a/syncapi/routing/routing.go b/syncapi/routing/routing.go
index 93d939c3..cbdcfb6b 100644
--- a/syncapi/routing/routing.go
+++ b/syncapi/routing/routing.go
@@ -30,6 +30,10 @@ import (
const pathPrefixR0 = "/_matrix/client/r0"
// Setup configures the given mux with sync-server listeners
+//
+// Due to Setup being used to call many other functions, a gocyclo nolint is
+// applied:
+// nolint: gocyclo
func Setup(apiMux *mux.Router, srp *sync.RequestPool, syncDB *storage.SyncServerDatabase, deviceDB *devices.Database) {
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
@@ -45,17 +49,26 @@ func Setup(apiMux *mux.Router, srp *sync.RequestPool, syncDB *storage.SyncServer
})).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state", common.MakeAuthAPI("room_state", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return OnIncomingStateRequest(req, syncDB, vars["roomID"])
})).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state/{type}", common.MakeAuthAPI("room_state", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return OnIncomingStateTypeRequest(req, syncDB, vars["roomID"], vars["type"], "")
})).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state/{type}/{stateKey}", common.MakeAuthAPI("room_state", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
- vars := mux.Vars(req)
+ vars, err := common.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
return OnIncomingStateTypeRequest(req, syncDB, vars["roomID"], vars["type"], vars["stateKey"])
})).Methods(http.MethodGet, http.MethodOptions)
}