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"Botserver",
|
||||||
r"Cookie Bot",
|
r"Cookie Bot",
|
||||||
r"DevAuthBackend",
|
r"DevAuthBackend",
|
||||||
|
r"DSN",
|
||||||
r"GCM",
|
r"GCM",
|
||||||
r"GitHub",
|
r"GitHub",
|
||||||
r"Gravatar",
|
r"Gravatar",
|
||||||
|
|
|
@ -137,6 +137,8 @@ not_yet_fully_covered = [
|
||||||
"zerver/webhooks/teamcity/view.py",
|
"zerver/webhooks/teamcity/view.py",
|
||||||
"zerver/webhooks/travis/view.py",
|
"zerver/webhooks/travis/view.py",
|
||||||
"zerver/webhooks/zapier/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
|
# Cannot have coverage, as tests run in a transaction
|
||||||
"zerver/lib/safe_session_cached_db.py",
|
"zerver/lib/safe_session_cached_db.py",
|
||||||
"zerver/lib/singleton_bmemcached.py",
|
"zerver/lib/singleton_bmemcached.py",
|
||||||
|
|
|
@ -47,6 +47,7 @@ if (page_params.server_sentry_dsn) {
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
dsn: page_params.server_sentry_dsn,
|
dsn: page_params.server_sentry_dsn,
|
||||||
environment: page_params.server_sentry_environment || "development",
|
environment: page_params.server_sentry_environment || "development",
|
||||||
|
tunnel: "/error_tracing",
|
||||||
|
|
||||||
release: "zulip-server@" + ZULIP_VERSION,
|
release: "zulip-server@" + ZULIP_VERSION,
|
||||||
integrations: [
|
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_send_times,
|
||||||
report_unnarrow_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.storage import get_storage, remove_storage, update_storage
|
||||||
from zerver.views.streams import (
|
from zerver.views.streams import (
|
||||||
add_default_stream,
|
add_default_stream,
|
||||||
|
@ -790,6 +791,10 @@ urls += [
|
||||||
path("scim/v2/", include("django_scim.urls", namespace="scim")),
|
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
|
# User documentation site
|
||||||
help_documentation_view = MarkdownDirectoryView.as_view(
|
help_documentation_view = MarkdownDirectoryView.as_view(
|
||||||
template_name="zerver/documentation_main.html",
|
template_name="zerver/documentation_main.html",
|
||||||
|
|
Loading…
Reference in New Issue