Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit f04efbf

Browse files
committed
Allowed headers on errors to be conditional based on config setting.
1 parent b26a203 commit f04efbf

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

synapse/api/errors.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,12 @@ class CodeMessageException(RuntimeError):
127127
Attributes:
128128
code: HTTP error code
129129
msg: string describing the error
130-
headers: optional response headers to send
131130
"""
132131

133132
def __init__(
134133
self,
135134
code: Union[int, HTTPStatus],
136135
msg: str,
137-
headers: Optional[Dict[str, str]] = None,
138136
):
139137
super().__init__("%d: %s" % (code, msg))
140138

@@ -146,7 +144,11 @@ def __init__(
146144
# To eliminate this behaviour, we convert them to their integer equivalents here.
147145
self.code = int(code)
148146
self.msg = msg
149-
self.headers = headers
147+
148+
def headers_dict(
149+
self, config: Optional["HomeServerConfig"]
150+
) -> Optional[Dict[str, str]]:
151+
return None
150152

151153

152154
class RedirectException(CodeMessageException):
@@ -192,7 +194,6 @@ def __init__(
192194
msg: str,
193195
errcode: str = Codes.UNKNOWN,
194196
additional_fields: Optional[Dict] = None,
195-
headers: Optional[Dict[str, str]] = None,
196197
):
197198
"""Constructs a synapse error.
198199
@@ -201,7 +202,7 @@ def __init__(
201202
msg: The human-readable error message.
202203
errcode: The matrix error code e.g 'M_FORBIDDEN'
203204
"""
204-
super().__init__(code, msg, headers)
205+
super().__init__(code, msg)
205206
self.errcode = errcode
206207
if additional_fields is None:
207208
self._additional_fields: Dict = {}
@@ -360,11 +361,14 @@ def __init__(
360361
self,
361362
required_scopes: List[str],
362363
):
363-
headers = {
364+
self.required_scopes = required_scopes
365+
super().__init__(401, "Insufficient scope", Codes.FORBIDDEN, None)
366+
367+
def headers_dict(self, config: Optional["HomeServerConfig"]) -> Dict[str, str]:
368+
return {
364369
"WWW-Authenticate": 'Bearer error="insufficient_scope", scope="%s"'
365-
% (" ".join(required_scopes))
370+
% (" ".join(self.required_scopes))
366371
}
367-
super().__init__(401, "Insufficient scope", Codes.FORBIDDEN, None, headers)
368372

369373

370374
class UnstableSpecAuthError(AuthError):
@@ -511,17 +515,23 @@ def __init__(
511515
retry_after_ms: Optional[int] = None,
512516
errcode: str = Codes.LIMIT_EXCEEDED,
513517
):
514-
headers = (
515-
None
516-
if retry_after_ms is None
517-
else {"Retry-After": str(math.ceil(retry_after_ms / 1000))}
518-
)
519-
super().__init__(code, msg, errcode, headers=headers)
518+
super().__init__(code, msg, errcode)
520519
self.retry_after_ms = retry_after_ms
521520

522521
def error_dict(self, config: Optional["HomeServerConfig"]) -> "JsonDict":
523522
return cs_error(self.msg, self.errcode, retry_after_ms=self.retry_after_ms)
524523

524+
def headers_dict(
525+
self, config: Optional["HomeServerConfig"]
526+
) -> Optional[Dict[str, str]]:
527+
if (
528+
self.retry_after_ms is not None
529+
and config
530+
and config.experimental.msc4041_enabled
531+
):
532+
return {"Retry-After": str(math.ceil(self.retry_after_ms / 1000))}
533+
return None
534+
525535

526536
class RoomKeysVersionError(SynapseError):
527537
"""A client has tried to upload to a non-current version of the room_keys store"""

synapse/config/experimental.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,3 +398,6 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
398398
self.msc4010_push_rules_account_data = experimental.get(
399399
"msc4010_push_rules_account_data", False
400400
)
401+
402+
# MSC4041: Use http header Retry-After to enable library-assisted retry handling
403+
self.msc4041_enabled: bool = experimental.get("msc4041_enabled", False)

synapse/http/server.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ def return_json_error(
112112
exc: SynapseError = f.value
113113
error_code = exc.code
114114
error_dict = exc.error_dict(config)
115-
if exc.headers is not None:
116-
for header, value in exc.headers.items():
115+
headers_dict = exc.headers_dict(config)
116+
if headers_dict is not None:
117+
for header, value in headers_dict.items():
117118
request.setHeader(header, value)
118119
logger.info("%s SynapseError: %s - %s", request, error_code, exc.msg)
119120
elif f.check(CancelledError):
@@ -176,8 +177,9 @@ def return_html_error(
176177
cme: CodeMessageException = f.value
177178
code = cme.code
178179
msg = cme.msg
179-
if cme.headers is not None:
180-
for header, value in cme.headers.items():
180+
headers = cme.headers_dict(None)
181+
if headers is not None:
182+
for header, value in headers.items():
181183
request.setHeader(header, value)
182184

183185
if isinstance(cme, RedirectException):

0 commit comments

Comments
 (0)