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

Commit ab26b58

Browse files
committed
Merge commit 'f43c66d23' into anoa/dinsic_release_1_21_x
* commit 'f43c66d23': Add support for running Complement against the local checkout (#8317) Filter out appservices from mau count (#8404) Only assert valid next_link params when provided (#8417) Add metrics to track success/otherwise of replication requests (#8406) Fix handling of connection timeouts in outgoing http requests (#8400) Changelog Don't check whether a 3pid is allowed to register during password reset Add checks for postgres sequence consistency (#8402) Create a mechanism for marking tests "logcontext clean" (#8399) Add `ui_auth_sessions_ips` table to `synapse_port_db` ignore list (#8410) A pair of tiny cleanups in the federation request code. (#8401) typo
2 parents 5b0b103 + f43c66d commit ab26b58

36 files changed

+602
-150
lines changed

changelog.d/8317.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support testing the local Synapse checkout against the [Complement homeserver test suite](https://github.com/matrix-org/complement/).

changelog.d/8399.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Create a mechanism for marking tests "logcontext clean".

changelog.d/8400.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix incorrect handling of timeouts on outgoing HTTP requests.

changelog.d/8401.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A pair of tiny cleanups in the federation request code.

changelog.d/8402.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add checks on startup that PostgreSQL sequences are consistent with their associated tables.

changelog.d/8404.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not include appservice users when calculating the total MAU for a server.

changelog.d/8406.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add prometheus metrics for replication requests.

changelog.d/8410.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a v1.20.0 regression in the `synapse_port_db` script regarding the `ui_auth_sessions_ips` table.

changelog.d/8414.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove unnecessary 3PID registration check when resetting password via an email address. Bug introduced in v0.34.0rc2.

changelog.d/8417.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add a config option to specify a whitelist of domains that a user can be redirected to after validating their email or phone number.

docs/postgres.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ Note that the above may fail with an error about duplicate rows if corruption
106106
has already occurred, and such duplicate rows will need to be manually removed.
107107

108108

109+
## Fixing inconsistent sequences error
110+
111+
Synapse uses Postgres sequences to generate IDs for various tables. A sequence
112+
and associated table can get out of sync if, for example, Synapse has been
113+
downgraded and then upgraded again.
114+
115+
To fix the issue shut down Synapse (including any and all workers) and run the
116+
SQL command included in the error message. Once done Synapse should start
117+
successfully.
118+
119+
109120
## Tuning Postgres
110121

111122
The default settings should be fine for most deployments. For larger

scripts-dev/complement.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#! /bin/bash -eu
2+
# This script is designed for developers who want to test their code
3+
# against Complement.
4+
#
5+
# It makes a Synapse image which represents the current checkout,
6+
# then downloads Complement and runs it with that image.
7+
8+
cd "$(dirname $0)/.."
9+
10+
# Build the base Synapse image from the local checkout
11+
docker build -t matrixdotorg/synapse:latest -f docker/Dockerfile .
12+
13+
# Download Complement
14+
wget -N https://github.com/matrix-org/complement/archive/master.tar.gz
15+
tar -xzf master.tar.gz
16+
cd complement-master
17+
18+
# Build the Synapse image from Complement, based on the above image we just built
19+
docker build -t complement-synapse -f dockerfiles/Synapse.Dockerfile ./dockerfiles
20+
21+
# Run the tests on the resulting image!
22+
COMPLEMENT_BASE_IMAGE=complement-synapse go test -v -count=1 ./tests

scripts/synapse_port_db

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ IGNORED_TABLES = {
146146
# the sessions are transient anyway, so ignore them.
147147
"ui_auth_sessions",
148148
"ui_auth_sessions_credentials",
149+
"ui_auth_sessions_ips",
149150
}
150151

151152

synapse/handlers/federation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ async def on_receive_pdu(self, origin, pdu, sent_to_us_directly=False) -> None:
281281
raise Exception(
282282
"Error fetching missing prev_events for %s: %s"
283283
% (event_id, e)
284-
)
284+
) from e
285285

286286
# Update the set of things we've seen after trying to
287287
# fetch the missing stuff

synapse/handlers/identity.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import urllib.parse
2222
from typing import Awaitable, Callable, Dict, List, Optional, Tuple
2323

24-
from twisted.internet.error import TimeoutError
25-
2624
from synapse.api.errors import (
2725
AuthError,
2826
CodeMessageException,
@@ -32,6 +30,7 @@
3230
SynapseError,
3331
)
3432
from synapse.config.emailconfig import ThreepidBehaviour
33+
from synapse.http import RequestTimedOutError
3534
from synapse.http.client import SimpleHttpClient
3635
from synapse.types import JsonDict, Requester
3736
from synapse.util import json_decoder
@@ -107,7 +106,7 @@ async def threepid_from_creds(
107106

108107
try:
109108
data = await self.http_client.get_json(url, query_params)
110-
except TimeoutError:
109+
except RequestTimedOutError:
111110
raise SynapseError(500, "Timed out contacting identity server")
112111
except HttpResponseException as e:
113112
logger.info(
@@ -192,7 +191,7 @@ async def bind_threepid(
192191
if e.code != 404 or not use_v2:
193192
logger.error("3PID bind failed with Matrix error: %r", e)
194193
raise e.to_synapse_error()
195-
except TimeoutError:
194+
except RequestTimedOutError:
196195
raise SynapseError(500, "Timed out contacting identity server")
197196
except CodeMessageException as e:
198197
data = json_decoder.decode(e.msg) # XXX WAT?
@@ -299,7 +298,7 @@ async def try_unbind_threepid_with_id_server(
299298
else:
300299
logger.error("Failed to unbind threepid on identity server: %s", e)
301300
raise SynapseError(500, "Failed to contact identity server")
302-
except TimeoutError:
301+
except RequestTimedOutError:
303302
raise SynapseError(500, "Timed out contacting identity server")
304303

305304
await self.store.remove_user_bound_threepid(
@@ -470,7 +469,7 @@ async def requestEmailToken(
470469
except HttpResponseException as e:
471470
logger.info("Proxied requestToken failed: %r", e)
472471
raise e.to_synapse_error()
473-
except TimeoutError:
472+
except RequestTimedOutError:
474473
raise SynapseError(500, "Timed out contacting identity server")
475474

476475
async def requestMsisdnToken(
@@ -526,7 +525,7 @@ async def requestMsisdnToken(
526525
except HttpResponseException as e:
527526
logger.info("Proxied requestToken failed: %r", e)
528527
raise e.to_synapse_error()
529-
except TimeoutError:
528+
except RequestTimedOutError:
530529
raise SynapseError(500, "Timed out contacting identity server")
531530

532531
assert self.hs.config.public_baseurl
@@ -608,7 +607,7 @@ async def proxy_msisdn_submit_token(
608607
id_server + "/_matrix/identity/api/v1/validate/msisdn/submitToken",
609608
body,
610609
)
611-
except TimeoutError:
610+
except RequestTimedOutError:
612611
raise SynapseError(500, "Timed out contacting identity server")
613612
except HttpResponseException as e:
614613
logger.warning("Error contacting msisdn account_threepid_delegate: %s", e)
@@ -766,7 +765,7 @@ async def _lookup_3pid_v1(
766765
# require or validate it. See the following for context:
767766
# https://github.com/matrix-org/synapse/issues/5253#issuecomment-666246950
768767
return data["mxid"]
769-
except TimeoutError:
768+
except RequestTimedOutError:
770769
raise SynapseError(500, "Timed out contacting identity server")
771770
except IOError as e:
772771
logger.warning("Error from v1 identity server lookup: %s" % (e,))
@@ -793,7 +792,7 @@ async def _lookup_3pid_v2(
793792
"%s/_matrix/identity/v2/hash_details" % (id_server_url,),
794793
{"access_token": id_access_token},
795794
)
796-
except TimeoutError:
795+
except RequestTimedOutError:
797796
raise SynapseError(500, "Timed out contacting identity server")
798797

799798
if not isinstance(hash_details, dict):
@@ -864,7 +863,7 @@ async def _lookup_3pid_v2(
864863
},
865864
headers=headers,
866865
)
867-
except TimeoutError:
866+
except RequestTimedOutError:
868867
raise SynapseError(500, "Timed out contacting identity server")
869868
except Exception as e:
870869
logger.warning("Error when performing a v2 3pid lookup: %s", e)
@@ -962,7 +961,7 @@ async def ask_id_server_for_third_party_invite(
962961
invite_config,
963962
{"Authorization": create_id_access_token_header(id_access_token)},
964963
)
965-
except TimeoutError:
964+
except RequestTimedOutError:
966965
raise SynapseError(500, "Timed out contacting identity server")
967966
except HttpResponseException as e:
968967
if e.code != 404:
@@ -979,7 +978,7 @@ async def ask_id_server_for_third_party_invite(
979978
data = await self.blacklisting_http_client.post_json_get_json(
980979
url, invite_config
981980
)
982-
except TimeoutError:
981+
except RequestTimedOutError:
983982
raise SynapseError(500, "Timed out contacting identity server")
984983
except HttpResponseException as e:
985984
logger.warning(

synapse/http/__init__.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
import re
1717

1818
from twisted.internet import task
19-
from twisted.internet.defer import CancelledError
20-
from twisted.python import failure
2119
from twisted.web.client import FileBodyProducer
2220

2321
from synapse.api.errors import SynapseError
@@ -26,19 +24,8 @@
2624
class RequestTimedOutError(SynapseError):
2725
"""Exception representing timeout of an outbound request"""
2826

29-
def __init__(self):
30-
super().__init__(504, "Timed out")
31-
32-
33-
def cancelled_to_request_timed_out_error(value, timeout):
34-
"""Turns CancelledErrors into RequestTimedOutErrors.
35-
36-
For use with async.add_timeout_to_deferred
37-
"""
38-
if isinstance(value, failure.Failure):
39-
value.trap(CancelledError)
40-
raise RequestTimedOutError()
41-
return value
27+
def __init__(self, msg):
28+
super().__init__(504, msg)
4229

4330

4431
ACCESS_TOKEN_RE = re.compile(r"(\?.*access(_|%5[Ff])token=)[^&]*(.*)$")

synapse/http/client.py

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
16-
1716
import logging
1817
import urllib
1918
from io import BytesIO
@@ -38,25 +37,26 @@
3837

3938
from OpenSSL import SSL
4039
from OpenSSL.SSL import VERIFY_NONE
41-
from twisted.internet import defer, protocol, ssl
40+
from twisted.internet import defer, error as twisted_error, protocol, ssl
4241
from twisted.internet.interfaces import (
4342
IReactorPluggableNameResolver,
4443
IResolutionReceiver,
4544
)
4645
from twisted.internet.task import Cooperator
4746
from twisted.python.failure import Failure
4847
from twisted.web._newclient import ResponseDone
49-
from twisted.web.client import Agent, HTTPConnectionPool, readBody
48+
from twisted.web.client import (
49+
Agent,
50+
HTTPConnectionPool,
51+
ResponseNeverReceived,
52+
readBody,
53+
)
5054
from twisted.web.http import PotentialDataLoss
5155
from twisted.web.http_headers import Headers
5256
from twisted.web.iweb import IResponse
5357

5458
from synapse.api.errors import Codes, HttpResponseException, SynapseError
55-
from synapse.http import (
56-
QuieterFileBodyProducer,
57-
cancelled_to_request_timed_out_error,
58-
redact_uri,
59-
)
59+
from synapse.http import QuieterFileBodyProducer, RequestTimedOutError, redact_uri
6060
from synapse.http.proxyagent import ProxyAgent
6161
from synapse.logging.context import make_deferred_yieldable
6262
from synapse.logging.opentracing import set_tag, start_active_span, tags
@@ -332,8 +332,6 @@ async def request(
332332
RequestTimedOutError if the request times out before the headers are read
333333
334334
"""
335-
# A small wrapper around self.agent.request() so we can easily attach
336-
# counters to it
337335
outgoing_requests_counter.labels(method).inc()
338336

339337
# log request but strip `access_token` (AS requests for example include this)
@@ -362,15 +360,17 @@ async def request(
362360
data=body_producer,
363361
headers=headers,
364362
**self._extra_treq_args
365-
)
363+
) # type: defer.Deferred
364+
366365
# we use our own timeout mechanism rather than treq's as a workaround
367366
# for https://twistedmatrix.com/trac/ticket/9534.
368367
request_deferred = timeout_deferred(
369-
request_deferred,
370-
60,
371-
self.hs.get_reactor(),
372-
cancelled_to_request_timed_out_error,
368+
request_deferred, 60, self.hs.get_reactor(),
373369
)
370+
371+
# turn timeouts into RequestTimedOutErrors
372+
request_deferred.addErrback(_timeout_to_request_timed_out_error)
373+
374374
response = await make_deferred_yieldable(request_deferred)
375375

376376
incoming_responses_counter.labels(method, response.code).inc()
@@ -410,7 +410,7 @@ async def post_urlencoded_get_json(
410410
parsed json
411411
412412
Raises:
413-
RequestTimedOutException: if there is a timeout before the response headers
413+
RequestTimedOutError: if there is a timeout before the response headers
414414
are received. Note there is currently no timeout on reading the response
415415
body.
416416
@@ -461,7 +461,7 @@ async def post_json_get_json(
461461
parsed json
462462
463463
Raises:
464-
RequestTimedOutException: if there is a timeout before the response headers
464+
RequestTimedOutError: if there is a timeout before the response headers
465465
are received. Note there is currently no timeout on reading the response
466466
body.
467467
@@ -506,7 +506,7 @@ async def get_json(
506506
Returns:
507507
Succeeds when we get a 2xx HTTP response, with the HTTP body as JSON.
508508
Raises:
509-
RequestTimedOutException: if there is a timeout before the response headers
509+
RequestTimedOutError: if there is a timeout before the response headers
510510
are received. Note there is currently no timeout on reading the response
511511
body.
512512
@@ -538,7 +538,7 @@ async def put_json(
538538
Returns:
539539
Succeeds when we get a 2xx HTTP response, with the HTTP body as JSON.
540540
Raises:
541-
RequestTimedOutException: if there is a timeout before the response headers
541+
RequestTimedOutError: if there is a timeout before the response headers
542542
are received. Note there is currently no timeout on reading the response
543543
body.
544544
@@ -586,7 +586,7 @@ async def get_raw(
586586
Succeeds when we get a 2xx HTTP response, with the
587587
HTTP body as bytes.
588588
Raises:
589-
RequestTimedOutException: if there is a timeout before the response headers
589+
RequestTimedOutError: if there is a timeout before the response headers
590590
are received. Note there is currently no timeout on reading the response
591591
body.
592592
@@ -631,7 +631,7 @@ async def get_file(
631631
headers, absolute URI of the response and HTTP response code.
632632
633633
Raises:
634-
RequestTimedOutException: if there is a timeout before the response headers
634+
RequestTimedOutError: if there is a timeout before the response headers
635635
are received. Note there is currently no timeout on reading the response
636636
body.
637637
@@ -684,6 +684,18 @@ async def get_file(
684684
)
685685

686686

687+
def _timeout_to_request_timed_out_error(f: Failure):
688+
if f.check(twisted_error.TimeoutError, twisted_error.ConnectingCancelledError):
689+
# The TCP connection has its own timeout (set by the 'connectTimeout' param
690+
# on the Agent), which raises twisted_error.TimeoutError exception.
691+
raise RequestTimedOutError("Timeout connecting to remote server")
692+
elif f.check(defer.TimeoutError, ResponseNeverReceived):
693+
# this one means that we hit our overall timeout on the request
694+
raise RequestTimedOutError("Timeout waiting for response from remote server")
695+
696+
return f
697+
698+
687699
# XXX: FIXME: This is horribly copy-pasted from matrixfederationclient.
688700
# The two should be factored out.
689701

0 commit comments

Comments
 (0)