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

Commit

Permalink
Merge branch 'develop' of github.com:matrix-org/synapse into anoa/inf…
Browse files Browse the repository at this point in the history
…o-mainline-no-check-password-reset
  • Loading branch information
anoadragon453 committed Sep 29, 2020
2 parents fe443ac + 12f0d18 commit f43c66d
Show file tree
Hide file tree
Showing 19 changed files with 404 additions and 118 deletions.
1 change: 1 addition & 0 deletions changelog.d/8317.feature
@@ -0,0 +1 @@
Support testing the local Synapse checkout against the [Complement homeserver test suite](https://github.com/matrix-org/complement/).
1 change: 1 addition & 0 deletions changelog.d/8400.bugfix
@@ -0,0 +1 @@
Fix incorrect handling of timeouts on outgoing HTTP requests.
1 change: 1 addition & 0 deletions changelog.d/8404.misc
@@ -0,0 +1 @@
Do not include appservice users when calculating the total MAU for a server.
1 change: 1 addition & 0 deletions changelog.d/8406.feature
@@ -0,0 +1 @@
Add prometheus metrics for replication requests.
1 change: 1 addition & 0 deletions changelog.d/8417.feature
@@ -0,0 +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.
22 changes: 22 additions & 0 deletions scripts-dev/complement.sh
@@ -0,0 +1,22 @@
#! /bin/bash -eu
# This script is designed for developers who want to test their code
# against Complement.
#
# It makes a Synapse image which represents the current checkout,
# then downloads Complement and runs it with that image.

cd "$(dirname $0)/.."

# Build the base Synapse image from the local checkout
docker build -t matrixdotorg/synapse:latest -f docker/Dockerfile .

# Download Complement
wget -N https://github.com/matrix-org/complement/archive/master.tar.gz
tar -xzf master.tar.gz
cd complement-master

# Build the Synapse image from Complement, based on the above image we just built
docker build -t complement-synapse -f dockerfiles/Synapse.Dockerfile ./dockerfiles

# Run the tests on the resulting image!
COMPLEMENT_BASE_IMAGE=complement-synapse go test -v -count=1 ./tests
25 changes: 12 additions & 13 deletions synapse/handlers/identity.py
Expand Up @@ -21,15 +21,14 @@
import urllib.parse
from typing import Awaitable, Callable, Dict, List, Optional, Tuple

from twisted.internet.error import TimeoutError

from synapse.api.errors import (
CodeMessageException,
Codes,
HttpResponseException,
SynapseError,
)
from synapse.config.emailconfig import ThreepidBehaviour
from synapse.http import RequestTimedOutError
from synapse.http.client import SimpleHttpClient
from synapse.types import JsonDict, Requester
from synapse.util import json_decoder
Expand Down Expand Up @@ -93,7 +92,7 @@ async def threepid_from_creds(

try:
data = await self.http_client.get_json(url, query_params)
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")
except HttpResponseException as e:
logger.info(
Expand Down Expand Up @@ -173,7 +172,7 @@ async def bind_threepid(
if e.code != 404 or not use_v2:
logger.error("3PID bind failed with Matrix error: %r", e)
raise e.to_synapse_error()
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")
except CodeMessageException as e:
data = json_decoder.decode(e.msg) # XXX WAT?
Expand Down Expand Up @@ -273,7 +272,7 @@ async def try_unbind_threepid_with_id_server(
else:
logger.error("Failed to unbind threepid on identity server: %s", e)
raise SynapseError(500, "Failed to contact identity server")
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")

await self.store.remove_user_bound_threepid(
Expand Down Expand Up @@ -419,7 +418,7 @@ async def requestEmailToken(
except HttpResponseException as e:
logger.info("Proxied requestToken failed: %r", e)
raise e.to_synapse_error()
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")

async def requestMsisdnToken(
Expand Down Expand Up @@ -471,7 +470,7 @@ async def requestMsisdnToken(
except HttpResponseException as e:
logger.info("Proxied requestToken failed: %r", e)
raise e.to_synapse_error()
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")

assert self.hs.config.public_baseurl
Expand Down Expand Up @@ -553,7 +552,7 @@ async def proxy_msisdn_submit_token(
id_server + "/_matrix/identity/api/v1/validate/msisdn/submitToken",
body,
)
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")
except HttpResponseException as e:
logger.warning("Error contacting msisdn account_threepid_delegate: %s", e)
Expand Down Expand Up @@ -627,7 +626,7 @@ async def _lookup_3pid_v1(
# require or validate it. See the following for context:
# https://github.com/matrix-org/synapse/issues/5253#issuecomment-666246950
return data["mxid"]
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")
except IOError as e:
logger.warning("Error from v1 identity server lookup: %s" % (e,))
Expand Down Expand Up @@ -655,7 +654,7 @@ async def _lookup_3pid_v2(
"%s%s/_matrix/identity/v2/hash_details" % (id_server_scheme, id_server),
{"access_token": id_access_token},
)
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")

if not isinstance(hash_details, dict):
Expand Down Expand Up @@ -727,7 +726,7 @@ async def _lookup_3pid_v2(
},
headers=headers,
)
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")
except Exception as e:
logger.warning("Error when performing a v2 3pid lookup: %s", e)
Expand Down Expand Up @@ -823,7 +822,7 @@ async def ask_id_server_for_third_party_invite(
invite_config,
{"Authorization": create_id_access_token_header(id_access_token)},
)
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")
except HttpResponseException as e:
if e.code != 404:
Expand All @@ -841,7 +840,7 @@ async def ask_id_server_for_third_party_invite(
data = await self.blacklisting_http_client.post_json_get_json(
url, invite_config
)
except TimeoutError:
except RequestTimedOutError:
raise SynapseError(500, "Timed out contacting identity server")
except HttpResponseException as e:
logger.warning(
Expand Down
17 changes: 2 additions & 15 deletions synapse/http/__init__.py
Expand Up @@ -16,8 +16,6 @@
import re

from twisted.internet import task
from twisted.internet.defer import CancelledError
from twisted.python import failure
from twisted.web.client import FileBodyProducer

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

def __init__(self):
super().__init__(504, "Timed out")


def cancelled_to_request_timed_out_error(value, timeout):
"""Turns CancelledErrors into RequestTimedOutErrors.
For use with async.add_timeout_to_deferred
"""
if isinstance(value, failure.Failure):
value.trap(CancelledError)
raise RequestTimedOutError()
return value
def __init__(self, msg):
super().__init__(504, msg)


ACCESS_TOKEN_RE = re.compile(r"(\?.*access(_|%5[Ff])token=)[^&]*(.*)$")
Expand Down
54 changes: 33 additions & 21 deletions synapse/http/client.py
Expand Up @@ -13,7 +13,6 @@
# 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.

import logging
import urllib
from io import BytesIO
Expand All @@ -38,25 +37,26 @@

from OpenSSL import SSL
from OpenSSL.SSL import VERIFY_NONE
from twisted.internet import defer, protocol, ssl
from twisted.internet import defer, error as twisted_error, protocol, ssl
from twisted.internet.interfaces import (
IReactorPluggableNameResolver,
IResolutionReceiver,
)
from twisted.internet.task import Cooperator
from twisted.python.failure import Failure
from twisted.web._newclient import ResponseDone
from twisted.web.client import Agent, HTTPConnectionPool, readBody
from twisted.web.client import (
Agent,
HTTPConnectionPool,
ResponseNeverReceived,
readBody,
)
from twisted.web.http import PotentialDataLoss
from twisted.web.http_headers import Headers
from twisted.web.iweb import IResponse

from synapse.api.errors import Codes, HttpResponseException, SynapseError
from synapse.http import (
QuieterFileBodyProducer,
cancelled_to_request_timed_out_error,
redact_uri,
)
from synapse.http import QuieterFileBodyProducer, RequestTimedOutError, redact_uri
from synapse.http.proxyagent import ProxyAgent
from synapse.logging.context import make_deferred_yieldable
from synapse.logging.opentracing import set_tag, start_active_span, tags
Expand Down Expand Up @@ -332,8 +332,6 @@ async def request(
RequestTimedOutError if the request times out before the headers are read
"""
# A small wrapper around self.agent.request() so we can easily attach
# counters to it
outgoing_requests_counter.labels(method).inc()

# log request but strip `access_token` (AS requests for example include this)
Expand Down Expand Up @@ -362,15 +360,17 @@ async def request(
data=body_producer,
headers=headers,
**self._extra_treq_args
)
) # type: defer.Deferred

# we use our own timeout mechanism rather than treq's as a workaround
# for https://twistedmatrix.com/trac/ticket/9534.
request_deferred = timeout_deferred(
request_deferred,
60,
self.hs.get_reactor(),
cancelled_to_request_timed_out_error,
request_deferred, 60, self.hs.get_reactor(),
)

# turn timeouts into RequestTimedOutErrors
request_deferred.addErrback(_timeout_to_request_timed_out_error)

response = await make_deferred_yieldable(request_deferred)

incoming_responses_counter.labels(method, response.code).inc()
Expand Down Expand Up @@ -410,7 +410,7 @@ async def post_urlencoded_get_json(
parsed json
Raises:
RequestTimedOutException: if there is a timeout before the response headers
RequestTimedOutError: if there is a timeout before the response headers
are received. Note there is currently no timeout on reading the response
body.
Expand Down Expand Up @@ -461,7 +461,7 @@ async def post_json_get_json(
parsed json
Raises:
RequestTimedOutException: if there is a timeout before the response headers
RequestTimedOutError: if there is a timeout before the response headers
are received. Note there is currently no timeout on reading the response
body.
Expand Down Expand Up @@ -506,7 +506,7 @@ async def get_json(
Returns:
Succeeds when we get a 2xx HTTP response, with the HTTP body as JSON.
Raises:
RequestTimedOutException: if there is a timeout before the response headers
RequestTimedOutError: if there is a timeout before the response headers
are received. Note there is currently no timeout on reading the response
body.
Expand Down Expand Up @@ -538,7 +538,7 @@ async def put_json(
Returns:
Succeeds when we get a 2xx HTTP response, with the HTTP body as JSON.
Raises:
RequestTimedOutException: if there is a timeout before the response headers
RequestTimedOutError: if there is a timeout before the response headers
are received. Note there is currently no timeout on reading the response
body.
Expand Down Expand Up @@ -586,7 +586,7 @@ async def get_raw(
Succeeds when we get a 2xx HTTP response, with the
HTTP body as bytes.
Raises:
RequestTimedOutException: if there is a timeout before the response headers
RequestTimedOutError: if there is a timeout before the response headers
are received. Note there is currently no timeout on reading the response
body.
Expand Down Expand Up @@ -631,7 +631,7 @@ async def get_file(
headers, absolute URI of the response and HTTP response code.
Raises:
RequestTimedOutException: if there is a timeout before the response headers
RequestTimedOutError: if there is a timeout before the response headers
are received. Note there is currently no timeout on reading the response
body.
Expand Down Expand Up @@ -684,6 +684,18 @@ async def get_file(
)


def _timeout_to_request_timed_out_error(f: Failure):
if f.check(twisted_error.TimeoutError, twisted_error.ConnectingCancelledError):
# The TCP connection has its own timeout (set by the 'connectTimeout' param
# on the Agent), which raises twisted_error.TimeoutError exception.
raise RequestTimedOutError("Timeout connecting to remote server")
elif f.check(defer.TimeoutError, ResponseNeverReceived):
# this one means that we hit our overall timeout on the request
raise RequestTimedOutError("Timeout waiting for response from remote server")

return f


# XXX: FIXME: This is horribly copy-pasted from matrixfederationclient.
# The two should be factored out.

Expand Down

0 comments on commit f43c66d

Please sign in to comment.