mirror of https://github.com/zulip/zulip.git
sentry: Provide a server-side tunnel.
Some well-intentioned adblockers also block Sentry client-side error reporting. Provide an endpoint on the Zulip server which forwards to the Sentry server, so that these requests are not blocked.
This commit is contained in:
parent
926cb84ca5
commit
93bfd3fb5f
|
@ -15,6 +15,7 @@ IGNORED_PHRASES = [
|
|||
r"Botserver",
|
||||
r"Cookie Bot",
|
||||
r"DevAuthBackend",
|
||||
r"DSN",
|
||||
r"GCM",
|
||||
r"GitHub",
|
||||
r"Gravatar",
|
||||
|
|
|
@ -137,6 +137,8 @@ not_yet_fully_covered = [
|
|||
"zerver/webhooks/teamcity/view.py",
|
||||
"zerver/webhooks/travis/view.py",
|
||||
"zerver/webhooks/zapier/view.py",
|
||||
# This is hard to get test coverage for, and low value to do so
|
||||
"zerver/views/sentry.py",
|
||||
# Cannot have coverage, as tests run in a transaction
|
||||
"zerver/lib/safe_session_cached_db.py",
|
||||
"zerver/lib/singleton_bmemcached.py",
|
||||
|
|
|
@ -47,6 +47,7 @@ if (page_params.server_sentry_dsn) {
|
|||
Sentry.init({
|
||||
dsn: page_params.server_sentry_dsn,
|
||||
environment: page_params.server_sentry_environment || "development",
|
||||
tunnel: "/error_tracing",
|
||||
|
||||
release: "zulip-server@" + ZULIP_VERSION,
|
||||
integrations: [
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import urllib
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from zerver.lib.exceptions import JsonableError
|
||||
from zerver.lib.outgoing_http import OutgoingSession
|
||||
from zerver.lib.validator import (
|
||||
check_url,
|
||||
to_wild_value,
|
||||
)
|
||||
|
||||
|
||||
class SentryTunnelSession(OutgoingSession):
|
||||
def __init__(self) -> None:
|
||||
super().__init__(role="sentry_tunnel", timeout=5)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def sentry_tunnel(
|
||||
request: HttpRequest,
|
||||
) -> HttpResponse:
|
||||
try:
|
||||
envelope = request.body
|
||||
header = to_wild_value("envelope", envelope.split(b"\n")[0].decode("utf-8"))
|
||||
dsn = urllib.parse.urlparse(header["dsn"].tame(check_url))
|
||||
except Exception:
|
||||
raise JsonableError(_("Invalid request format"))
|
||||
|
||||
if dsn.geturl() != settings.SENTRY_FRONTEND_DSN:
|
||||
raise JsonableError(_("Invalid DSN"))
|
||||
|
||||
assert dsn.hostname
|
||||
project_id = dsn.path.strip("/")
|
||||
url = dsn._replace(netloc=dsn.hostname, path=f"/api/{project_id}/envelope/").geturl()
|
||||
SentryTunnelSession().post(
|
||||
url=url, data=envelope, headers={"Content-Type": "application/x-sentry-envelope"}
|
||||
).raise_for_status()
|
||||
return HttpResponse(status=200)
|
|
@ -137,6 +137,7 @@ from zerver.views.report import (
|
|||
report_send_times,
|
||||
report_unnarrow_times,
|
||||
)
|
||||
from zerver.views.sentry import sentry_tunnel
|
||||
from zerver.views.storage import get_storage, remove_storage, update_storage
|
||||
from zerver.views.streams import (
|
||||
add_default_stream,
|
||||
|
@ -790,6 +791,10 @@ urls += [
|
|||
path("scim/v2/", include("django_scim.urls", namespace="scim")),
|
||||
]
|
||||
|
||||
# Front-end Sentry requests tunnel through the server, if enabled
|
||||
if settings.SENTRY_FRONTEND_DSN:
|
||||
urls += [path("error_tracing", sentry_tunnel)]
|
||||
|
||||
# User documentation site
|
||||
help_documentation_view = MarkdownDirectoryView.as_view(
|
||||
template_name="zerver/documentation_main.html",
|
||||
|
|
Loading…
Reference in New Issue