matrix-synapse 1.142.0rc3__cp314-abi3-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of matrix-synapse might be problematic. Click here for more details.
- matrix_synapse-1.142.0rc3.dist-info/AUTHORS.rst +51 -0
- matrix_synapse-1.142.0rc3.dist-info/LICENSE-AGPL-3.0 +661 -0
- matrix_synapse-1.142.0rc3.dist-info/LICENSE-COMMERCIAL +6 -0
- matrix_synapse-1.142.0rc3.dist-info/METADATA +375 -0
- matrix_synapse-1.142.0rc3.dist-info/RECORD +1057 -0
- matrix_synapse-1.142.0rc3.dist-info/WHEEL +4 -0
- matrix_synapse-1.142.0rc3.dist-info/entry_points.txt +14 -0
- matrix_synapse.libs/libgcc_s-2d945d6c.so.1 +0 -0
- synapse/__init__.py +97 -0
- synapse/_scripts/__init__.py +0 -0
- synapse/_scripts/export_signing_key.py +109 -0
- synapse/_scripts/generate_config.py +83 -0
- synapse/_scripts/generate_log_config.py +56 -0
- synapse/_scripts/generate_signing_key.py +55 -0
- synapse/_scripts/generate_workers_map.py +318 -0
- synapse/_scripts/hash_password.py +95 -0
- synapse/_scripts/move_remote_media_to_new_store.py +128 -0
- synapse/_scripts/register_new_matrix_user.py +374 -0
- synapse/_scripts/review_recent_signups.py +212 -0
- synapse/_scripts/synapse_port_db.py +1603 -0
- synapse/_scripts/synctl.py +365 -0
- synapse/_scripts/update_synapse_database.py +130 -0
- synapse/api/__init__.py +20 -0
- synapse/api/auth/__init__.py +207 -0
- synapse/api/auth/base.py +406 -0
- synapse/api/auth/internal.py +299 -0
- synapse/api/auth/mas.py +457 -0
- synapse/api/auth/msc3861_delegated.py +617 -0
- synapse/api/auth_blocking.py +144 -0
- synapse/api/constants.py +362 -0
- synapse/api/errors.py +907 -0
- synapse/api/filtering.py +539 -0
- synapse/api/presence.py +104 -0
- synapse/api/ratelimiting.py +482 -0
- synapse/api/room_versions.py +535 -0
- synapse/api/urls.py +119 -0
- synapse/app/__init__.py +60 -0
- synapse/app/_base.py +866 -0
- synapse/app/admin_cmd.py +388 -0
- synapse/app/appservice.py +30 -0
- synapse/app/client_reader.py +30 -0
- synapse/app/complement_fork_starter.py +206 -0
- synapse/app/event_creator.py +29 -0
- synapse/app/federation_reader.py +30 -0
- synapse/app/federation_sender.py +30 -0
- synapse/app/frontend_proxy.py +30 -0
- synapse/app/generic_worker.py +475 -0
- synapse/app/homeserver.py +504 -0
- synapse/app/media_repository.py +30 -0
- synapse/app/phone_stats_home.py +296 -0
- synapse/app/pusher.py +30 -0
- synapse/app/synchrotron.py +30 -0
- synapse/app/user_dir.py +31 -0
- synapse/appservice/__init__.py +461 -0
- synapse/appservice/api.py +569 -0
- synapse/appservice/scheduler.py +567 -0
- synapse/config/__init__.py +27 -0
- synapse/config/__main__.py +62 -0
- synapse/config/_base.py +1108 -0
- synapse/config/_base.pyi +217 -0
- synapse/config/_util.py +99 -0
- synapse/config/account_validity.py +116 -0
- synapse/config/api.py +141 -0
- synapse/config/appservice.py +210 -0
- synapse/config/auth.py +80 -0
- synapse/config/auto_accept_invites.py +43 -0
- synapse/config/background_updates.py +44 -0
- synapse/config/cache.py +231 -0
- synapse/config/captcha.py +90 -0
- synapse/config/cas.py +116 -0
- synapse/config/consent.py +73 -0
- synapse/config/database.py +184 -0
- synapse/config/emailconfig.py +367 -0
- synapse/config/experimental.py +595 -0
- synapse/config/federation.py +114 -0
- synapse/config/homeserver.py +141 -0
- synapse/config/jwt.py +55 -0
- synapse/config/key.py +447 -0
- synapse/config/logger.py +390 -0
- synapse/config/mas.py +191 -0
- synapse/config/matrixrtc.py +66 -0
- synapse/config/metrics.py +84 -0
- synapse/config/modules.py +40 -0
- synapse/config/oembed.py +185 -0
- synapse/config/oidc.py +509 -0
- synapse/config/password_auth_providers.py +82 -0
- synapse/config/push.py +64 -0
- synapse/config/ratelimiting.py +254 -0
- synapse/config/redis.py +74 -0
- synapse/config/registration.py +296 -0
- synapse/config/repository.py +311 -0
- synapse/config/retention.py +162 -0
- synapse/config/room.py +88 -0
- synapse/config/room_directory.py +165 -0
- synapse/config/saml2.py +251 -0
- synapse/config/server.py +1170 -0
- synapse/config/server_notices.py +84 -0
- synapse/config/spam_checker.py +66 -0
- synapse/config/sso.py +121 -0
- synapse/config/stats.py +54 -0
- synapse/config/third_party_event_rules.py +40 -0
- synapse/config/tls.py +192 -0
- synapse/config/tracer.py +71 -0
- synapse/config/user_directory.py +47 -0
- synapse/config/user_types.py +44 -0
- synapse/config/voip.py +59 -0
- synapse/config/workers.py +642 -0
- synapse/crypto/__init__.py +20 -0
- synapse/crypto/context_factory.py +278 -0
- synapse/crypto/event_signing.py +194 -0
- synapse/crypto/keyring.py +931 -0
- synapse/event_auth.py +1266 -0
- synapse/events/__init__.py +668 -0
- synapse/events/auto_accept_invites.py +216 -0
- synapse/events/builder.py +387 -0
- synapse/events/presence_router.py +245 -0
- synapse/events/snapshot.py +559 -0
- synapse/events/utils.py +928 -0
- synapse/events/validator.py +305 -0
- synapse/federation/__init__.py +22 -0
- synapse/federation/federation_base.py +383 -0
- synapse/federation/federation_client.py +2134 -0
- synapse/federation/federation_server.py +1544 -0
- synapse/federation/persistence.py +71 -0
- synapse/federation/send_queue.py +532 -0
- synapse/federation/sender/__init__.py +1165 -0
- synapse/federation/sender/per_destination_queue.py +884 -0
- synapse/federation/sender/transaction_manager.py +210 -0
- synapse/federation/transport/__init__.py +28 -0
- synapse/federation/transport/client.py +1201 -0
- synapse/federation/transport/server/__init__.py +334 -0
- synapse/federation/transport/server/_base.py +429 -0
- synapse/federation/transport/server/federation.py +912 -0
- synapse/federation/units.py +133 -0
- synapse/handlers/__init__.py +20 -0
- synapse/handlers/account.py +162 -0
- synapse/handlers/account_data.py +362 -0
- synapse/handlers/account_validity.py +361 -0
- synapse/handlers/admin.py +618 -0
- synapse/handlers/appservice.py +991 -0
- synapse/handlers/auth.py +2494 -0
- synapse/handlers/cas.py +413 -0
- synapse/handlers/deactivate_account.py +363 -0
- synapse/handlers/delayed_events.py +635 -0
- synapse/handlers/device.py +1873 -0
- synapse/handlers/devicemessage.py +399 -0
- synapse/handlers/directory.py +554 -0
- synapse/handlers/e2e_keys.py +1834 -0
- synapse/handlers/e2e_room_keys.py +455 -0
- synapse/handlers/event_auth.py +390 -0
- synapse/handlers/events.py +201 -0
- synapse/handlers/federation.py +2043 -0
- synapse/handlers/federation_event.py +2420 -0
- synapse/handlers/identity.py +812 -0
- synapse/handlers/initial_sync.py +528 -0
- synapse/handlers/jwt.py +120 -0
- synapse/handlers/message.py +2347 -0
- synapse/handlers/oidc.py +1803 -0
- synapse/handlers/pagination.py +768 -0
- synapse/handlers/password_policy.py +102 -0
- synapse/handlers/presence.py +2638 -0
- synapse/handlers/profile.py +655 -0
- synapse/handlers/push_rules.py +164 -0
- synapse/handlers/read_marker.py +79 -0
- synapse/handlers/receipts.py +351 -0
- synapse/handlers/register.py +1060 -0
- synapse/handlers/relations.py +624 -0
- synapse/handlers/reports.py +98 -0
- synapse/handlers/room.py +2447 -0
- synapse/handlers/room_list.py +632 -0
- synapse/handlers/room_member.py +2365 -0
- synapse/handlers/room_member_worker.py +146 -0
- synapse/handlers/room_policy.py +186 -0
- synapse/handlers/room_summary.py +1057 -0
- synapse/handlers/saml.py +524 -0
- synapse/handlers/search.py +723 -0
- synapse/handlers/send_email.py +209 -0
- synapse/handlers/set_password.py +71 -0
- synapse/handlers/sliding_sync/__init__.py +1701 -0
- synapse/handlers/sliding_sync/extensions.py +970 -0
- synapse/handlers/sliding_sync/room_lists.py +2266 -0
- synapse/handlers/sliding_sync/store.py +128 -0
- synapse/handlers/sso.py +1292 -0
- synapse/handlers/state_deltas.py +82 -0
- synapse/handlers/stats.py +322 -0
- synapse/handlers/sync.py +3109 -0
- synapse/handlers/thread_subscriptions.py +190 -0
- synapse/handlers/typing.py +606 -0
- synapse/handlers/ui_auth/__init__.py +48 -0
- synapse/handlers/ui_auth/checkers.py +332 -0
- synapse/handlers/user_directory.py +783 -0
- synapse/handlers/worker_lock.py +365 -0
- synapse/http/__init__.py +106 -0
- synapse/http/additional_resource.py +62 -0
- synapse/http/client.py +1360 -0
- synapse/http/connectproxyclient.py +309 -0
- synapse/http/federation/__init__.py +19 -0
- synapse/http/federation/matrix_federation_agent.py +490 -0
- synapse/http/federation/srv_resolver.py +196 -0
- synapse/http/federation/well_known_resolver.py +367 -0
- synapse/http/matrixfederationclient.py +1875 -0
- synapse/http/proxy.py +290 -0
- synapse/http/proxyagent.py +497 -0
- synapse/http/replicationagent.py +203 -0
- synapse/http/request_metrics.py +309 -0
- synapse/http/server.py +1114 -0
- synapse/http/servlet.py +1019 -0
- synapse/http/site.py +825 -0
- synapse/http/types.py +27 -0
- synapse/logging/__init__.py +31 -0
- synapse/logging/_remote.py +261 -0
- synapse/logging/_terse_json.py +95 -0
- synapse/logging/context.py +1211 -0
- synapse/logging/formatter.py +63 -0
- synapse/logging/handlers.py +99 -0
- synapse/logging/loggers.py +25 -0
- synapse/logging/opentracing.py +1132 -0
- synapse/logging/scopecontextmanager.py +161 -0
- synapse/media/_base.py +827 -0
- synapse/media/filepath.py +417 -0
- synapse/media/media_repository.py +1580 -0
- synapse/media/media_storage.py +704 -0
- synapse/media/oembed.py +277 -0
- synapse/media/preview_html.py +559 -0
- synapse/media/storage_provider.py +195 -0
- synapse/media/thumbnailer.py +833 -0
- synapse/media/url_previewer.py +875 -0
- synapse/metrics/__init__.py +754 -0
- synapse/metrics/_gc.py +219 -0
- synapse/metrics/_reactor_metrics.py +171 -0
- synapse/metrics/_types.py +38 -0
- synapse/metrics/background_process_metrics.py +556 -0
- synapse/metrics/common_usage_metrics.py +94 -0
- synapse/metrics/jemalloc.py +248 -0
- synapse/module_api/__init__.py +2154 -0
- synapse/module_api/callbacks/__init__.py +50 -0
- synapse/module_api/callbacks/account_validity_callbacks.py +106 -0
- synapse/module_api/callbacks/media_repository_callbacks.py +160 -0
- synapse/module_api/callbacks/ratelimit_callbacks.py +79 -0
- synapse/module_api/callbacks/spamchecker_callbacks.py +1113 -0
- synapse/module_api/callbacks/third_party_event_rules_callbacks.py +599 -0
- synapse/module_api/errors.py +42 -0
- synapse/notifier.py +972 -0
- synapse/push/__init__.py +212 -0
- synapse/push/bulk_push_rule_evaluator.py +637 -0
- synapse/push/clientformat.py +126 -0
- synapse/push/emailpusher.py +333 -0
- synapse/push/httppusher.py +564 -0
- synapse/push/mailer.py +1012 -0
- synapse/push/presentable_names.py +216 -0
- synapse/push/push_tools.py +114 -0
- synapse/push/push_types.py +141 -0
- synapse/push/pusher.py +87 -0
- synapse/push/pusherpool.py +501 -0
- synapse/push/rulekinds.py +33 -0
- synapse/py.typed +0 -0
- synapse/replication/__init__.py +20 -0
- synapse/replication/http/__init__.py +68 -0
- synapse/replication/http/_base.py +468 -0
- synapse/replication/http/account_data.py +297 -0
- synapse/replication/http/deactivate_account.py +81 -0
- synapse/replication/http/delayed_events.py +62 -0
- synapse/replication/http/devices.py +254 -0
- synapse/replication/http/federation.py +334 -0
- synapse/replication/http/login.py +106 -0
- synapse/replication/http/membership.py +364 -0
- synapse/replication/http/presence.py +133 -0
- synapse/replication/http/push.py +156 -0
- synapse/replication/http/register.py +172 -0
- synapse/replication/http/send_events.py +182 -0
- synapse/replication/http/state.py +82 -0
- synapse/replication/http/streams.py +101 -0
- synapse/replication/tcp/__init__.py +56 -0
- synapse/replication/tcp/client.py +552 -0
- synapse/replication/tcp/commands.py +569 -0
- synapse/replication/tcp/context.py +41 -0
- synapse/replication/tcp/external_cache.py +156 -0
- synapse/replication/tcp/handler.py +942 -0
- synapse/replication/tcp/protocol.py +608 -0
- synapse/replication/tcp/redis.py +509 -0
- synapse/replication/tcp/resource.py +348 -0
- synapse/replication/tcp/streams/__init__.py +96 -0
- synapse/replication/tcp/streams/_base.py +766 -0
- synapse/replication/tcp/streams/events.py +287 -0
- synapse/replication/tcp/streams/federation.py +92 -0
- synapse/replication/tcp/streams/partial_state.py +80 -0
- synapse/res/providers.json +29 -0
- synapse/res/templates/_base.html +29 -0
- synapse/res/templates/account_previously_renewed.html +6 -0
- synapse/res/templates/account_renewed.html +6 -0
- synapse/res/templates/add_threepid.html +8 -0
- synapse/res/templates/add_threepid.txt +6 -0
- synapse/res/templates/add_threepid_failure.html +7 -0
- synapse/res/templates/add_threepid_success.html +6 -0
- synapse/res/templates/already_in_use.html +12 -0
- synapse/res/templates/already_in_use.txt +10 -0
- synapse/res/templates/auth_success.html +21 -0
- synapse/res/templates/invalid_token.html +6 -0
- synapse/res/templates/mail-Element.css +7 -0
- synapse/res/templates/mail-Vector.css +7 -0
- synapse/res/templates/mail-expiry.css +4 -0
- synapse/res/templates/mail.css +156 -0
- synapse/res/templates/notice_expiry.html +46 -0
- synapse/res/templates/notice_expiry.txt +7 -0
- synapse/res/templates/notif.html +51 -0
- synapse/res/templates/notif.txt +22 -0
- synapse/res/templates/notif_mail.html +59 -0
- synapse/res/templates/notif_mail.txt +10 -0
- synapse/res/templates/password_reset.html +10 -0
- synapse/res/templates/password_reset.txt +7 -0
- synapse/res/templates/password_reset_confirmation.html +15 -0
- synapse/res/templates/password_reset_failure.html +7 -0
- synapse/res/templates/password_reset_success.html +6 -0
- synapse/res/templates/recaptcha.html +42 -0
- synapse/res/templates/registration.html +12 -0
- synapse/res/templates/registration.txt +10 -0
- synapse/res/templates/registration_failure.html +6 -0
- synapse/res/templates/registration_success.html +6 -0
- synapse/res/templates/registration_token.html +18 -0
- synapse/res/templates/room.html +33 -0
- synapse/res/templates/room.txt +9 -0
- synapse/res/templates/sso.css +129 -0
- synapse/res/templates/sso_account_deactivated.html +25 -0
- synapse/res/templates/sso_auth_account_details.html +186 -0
- synapse/res/templates/sso_auth_account_details.js +116 -0
- synapse/res/templates/sso_auth_bad_user.html +26 -0
- synapse/res/templates/sso_auth_confirm.html +27 -0
- synapse/res/templates/sso_auth_success.html +26 -0
- synapse/res/templates/sso_error.html +71 -0
- synapse/res/templates/sso_footer.html +19 -0
- synapse/res/templates/sso_login_idp_picker.html +60 -0
- synapse/res/templates/sso_new_user_consent.html +30 -0
- synapse/res/templates/sso_partial_profile.html +19 -0
- synapse/res/templates/sso_redirect_confirm.html +39 -0
- synapse/res/templates/style.css +33 -0
- synapse/res/templates/terms.html +27 -0
- synapse/rest/__init__.py +197 -0
- synapse/rest/admin/__init__.py +390 -0
- synapse/rest/admin/_base.py +72 -0
- synapse/rest/admin/background_updates.py +171 -0
- synapse/rest/admin/devices.py +221 -0
- synapse/rest/admin/event_reports.py +173 -0
- synapse/rest/admin/events.py +69 -0
- synapse/rest/admin/experimental_features.py +137 -0
- synapse/rest/admin/federation.py +243 -0
- synapse/rest/admin/media.py +540 -0
- synapse/rest/admin/registration_tokens.py +358 -0
- synapse/rest/admin/rooms.py +1061 -0
- synapse/rest/admin/scheduled_tasks.py +70 -0
- synapse/rest/admin/server_notice_servlet.py +132 -0
- synapse/rest/admin/statistics.py +132 -0
- synapse/rest/admin/username_available.py +58 -0
- synapse/rest/admin/users.py +1608 -0
- synapse/rest/client/__init__.py +20 -0
- synapse/rest/client/_base.py +113 -0
- synapse/rest/client/account.py +930 -0
- synapse/rest/client/account_data.py +319 -0
- synapse/rest/client/account_validity.py +103 -0
- synapse/rest/client/appservice_ping.py +125 -0
- synapse/rest/client/auth.py +218 -0
- synapse/rest/client/auth_metadata.py +122 -0
- synapse/rest/client/capabilities.py +121 -0
- synapse/rest/client/delayed_events.py +111 -0
- synapse/rest/client/devices.py +587 -0
- synapse/rest/client/directory.py +211 -0
- synapse/rest/client/events.py +116 -0
- synapse/rest/client/filter.py +112 -0
- synapse/rest/client/initial_sync.py +65 -0
- synapse/rest/client/keys.py +678 -0
- synapse/rest/client/knock.py +104 -0
- synapse/rest/client/login.py +754 -0
- synapse/rest/client/login_token_request.py +127 -0
- synapse/rest/client/logout.py +93 -0
- synapse/rest/client/matrixrtc.py +52 -0
- synapse/rest/client/media.py +286 -0
- synapse/rest/client/mutual_rooms.py +93 -0
- synapse/rest/client/notifications.py +137 -0
- synapse/rest/client/openid.py +109 -0
- synapse/rest/client/password_policy.py +69 -0
- synapse/rest/client/presence.py +131 -0
- synapse/rest/client/profile.py +291 -0
- synapse/rest/client/push_rule.py +331 -0
- synapse/rest/client/pusher.py +181 -0
- synapse/rest/client/read_marker.py +104 -0
- synapse/rest/client/receipts.py +165 -0
- synapse/rest/client/register.py +1067 -0
- synapse/rest/client/relations.py +138 -0
- synapse/rest/client/rendezvous.py +76 -0
- synapse/rest/client/reporting.py +207 -0
- synapse/rest/client/room.py +1669 -0
- synapse/rest/client/room_keys.py +426 -0
- synapse/rest/client/room_upgrade_rest_servlet.py +112 -0
- synapse/rest/client/sendtodevice.py +85 -0
- synapse/rest/client/sync.py +1131 -0
- synapse/rest/client/tags.py +129 -0
- synapse/rest/client/thirdparty.py +130 -0
- synapse/rest/client/thread_subscriptions.py +247 -0
- synapse/rest/client/tokenrefresh.py +52 -0
- synapse/rest/client/transactions.py +149 -0
- synapse/rest/client/user_directory.py +90 -0
- synapse/rest/client/versions.py +191 -0
- synapse/rest/client/voip.py +88 -0
- synapse/rest/consent/__init__.py +0 -0
- synapse/rest/consent/consent_resource.py +210 -0
- synapse/rest/health.py +38 -0
- synapse/rest/key/__init__.py +20 -0
- synapse/rest/key/v2/__init__.py +40 -0
- synapse/rest/key/v2/local_key_resource.py +125 -0
- synapse/rest/key/v2/remote_key_resource.py +302 -0
- synapse/rest/media/__init__.py +0 -0
- synapse/rest/media/config_resource.py +53 -0
- synapse/rest/media/create_resource.py +90 -0
- synapse/rest/media/download_resource.py +110 -0
- synapse/rest/media/media_repository_resource.py +113 -0
- synapse/rest/media/preview_url_resource.py +77 -0
- synapse/rest/media/thumbnail_resource.py +142 -0
- synapse/rest/media/upload_resource.py +187 -0
- synapse/rest/media/v1/__init__.py +39 -0
- synapse/rest/media/v1/_base.py +23 -0
- synapse/rest/media/v1/media_storage.py +23 -0
- synapse/rest/media/v1/storage_provider.py +23 -0
- synapse/rest/synapse/__init__.py +20 -0
- synapse/rest/synapse/client/__init__.py +93 -0
- synapse/rest/synapse/client/federation_whitelist.py +66 -0
- synapse/rest/synapse/client/jwks.py +77 -0
- synapse/rest/synapse/client/new_user_consent.py +115 -0
- synapse/rest/synapse/client/oidc/__init__.py +45 -0
- synapse/rest/synapse/client/oidc/backchannel_logout_resource.py +42 -0
- synapse/rest/synapse/client/oidc/callback_resource.py +48 -0
- synapse/rest/synapse/client/password_reset.py +129 -0
- synapse/rest/synapse/client/pick_idp.py +107 -0
- synapse/rest/synapse/client/pick_username.py +153 -0
- synapse/rest/synapse/client/rendezvous.py +58 -0
- synapse/rest/synapse/client/saml2/__init__.py +42 -0
- synapse/rest/synapse/client/saml2/metadata_resource.py +46 -0
- synapse/rest/synapse/client/saml2/response_resource.py +52 -0
- synapse/rest/synapse/client/sso_register.py +56 -0
- synapse/rest/synapse/client/unsubscribe.py +88 -0
- synapse/rest/synapse/mas/__init__.py +71 -0
- synapse/rest/synapse/mas/_base.py +55 -0
- synapse/rest/synapse/mas/devices.py +239 -0
- synapse/rest/synapse/mas/users.py +469 -0
- synapse/rest/well_known.py +148 -0
- synapse/server.py +1258 -0
- synapse/server_notices/__init__.py +0 -0
- synapse/server_notices/consent_server_notices.py +136 -0
- synapse/server_notices/resource_limits_server_notices.py +215 -0
- synapse/server_notices/server_notices_manager.py +388 -0
- synapse/server_notices/server_notices_sender.py +67 -0
- synapse/server_notices/worker_server_notices_sender.py +46 -0
- synapse/spam_checker_api/__init__.py +31 -0
- synapse/state/__init__.py +1022 -0
- synapse/state/v1.py +370 -0
- synapse/state/v2.py +985 -0
- synapse/static/client/login/index.html +47 -0
- synapse/static/client/login/js/jquery-3.4.1.min.js +2 -0
- synapse/static/client/login/js/login.js +291 -0
- synapse/static/client/login/spinner.gif +0 -0
- synapse/static/client/login/style.css +79 -0
- synapse/static/index.html +63 -0
- synapse/storage/__init__.py +43 -0
- synapse/storage/_base.py +245 -0
- synapse/storage/admin_client_config.py +26 -0
- synapse/storage/background_updates.py +1189 -0
- synapse/storage/controllers/__init__.py +57 -0
- synapse/storage/controllers/persist_events.py +1239 -0
- synapse/storage/controllers/purge_events.py +456 -0
- synapse/storage/controllers/state.py +954 -0
- synapse/storage/controllers/stats.py +119 -0
- synapse/storage/database.py +2720 -0
- synapse/storage/databases/__init__.py +175 -0
- synapse/storage/databases/main/__init__.py +424 -0
- synapse/storage/databases/main/account_data.py +1060 -0
- synapse/storage/databases/main/appservice.py +473 -0
- synapse/storage/databases/main/cache.py +911 -0
- synapse/storage/databases/main/censor_events.py +225 -0
- synapse/storage/databases/main/client_ips.py +817 -0
- synapse/storage/databases/main/delayed_events.py +560 -0
- synapse/storage/databases/main/deviceinbox.py +1272 -0
- synapse/storage/databases/main/devices.py +2581 -0
- synapse/storage/databases/main/directory.py +212 -0
- synapse/storage/databases/main/e2e_room_keys.py +690 -0
- synapse/storage/databases/main/end_to_end_keys.py +1896 -0
- synapse/storage/databases/main/event_federation.py +2509 -0
- synapse/storage/databases/main/event_push_actions.py +1937 -0
- synapse/storage/databases/main/events.py +3746 -0
- synapse/storage/databases/main/events_bg_updates.py +2910 -0
- synapse/storage/databases/main/events_forward_extremities.py +126 -0
- synapse/storage/databases/main/events_worker.py +2784 -0
- synapse/storage/databases/main/experimental_features.py +130 -0
- synapse/storage/databases/main/filtering.py +231 -0
- synapse/storage/databases/main/keys.py +291 -0
- synapse/storage/databases/main/lock.py +553 -0
- synapse/storage/databases/main/media_repository.py +1070 -0
- synapse/storage/databases/main/metrics.py +460 -0
- synapse/storage/databases/main/monthly_active_users.py +443 -0
- synapse/storage/databases/main/openid.py +61 -0
- synapse/storage/databases/main/presence.py +511 -0
- synapse/storage/databases/main/profile.py +541 -0
- synapse/storage/databases/main/purge_events.py +511 -0
- synapse/storage/databases/main/push_rule.py +972 -0
- synapse/storage/databases/main/pusher.py +794 -0
- synapse/storage/databases/main/receipts.py +1342 -0
- synapse/storage/databases/main/registration.py +3076 -0
- synapse/storage/databases/main/rejections.py +38 -0
- synapse/storage/databases/main/relations.py +1118 -0
- synapse/storage/databases/main/room.py +2781 -0
- synapse/storage/databases/main/roommember.py +2112 -0
- synapse/storage/databases/main/search.py +941 -0
- synapse/storage/databases/main/session.py +151 -0
- synapse/storage/databases/main/signatures.py +94 -0
- synapse/storage/databases/main/sliding_sync.py +603 -0
- synapse/storage/databases/main/state.py +1006 -0
- synapse/storage/databases/main/state_deltas.py +329 -0
- synapse/storage/databases/main/stats.py +791 -0
- synapse/storage/databases/main/stream.py +2580 -0
- synapse/storage/databases/main/tags.py +360 -0
- synapse/storage/databases/main/task_scheduler.py +225 -0
- synapse/storage/databases/main/thread_subscriptions.py +591 -0
- synapse/storage/databases/main/transactions.py +681 -0
- synapse/storage/databases/main/ui_auth.py +420 -0
- synapse/storage/databases/main/user_directory.py +1331 -0
- synapse/storage/databases/main/user_erasure_store.py +117 -0
- synapse/storage/databases/state/__init__.py +22 -0
- synapse/storage/databases/state/bg_updates.py +499 -0
- synapse/storage/databases/state/deletion.py +558 -0
- synapse/storage/databases/state/store.py +949 -0
- synapse/storage/engines/__init__.py +70 -0
- synapse/storage/engines/_base.py +154 -0
- synapse/storage/engines/postgres.py +261 -0
- synapse/storage/engines/sqlite.py +199 -0
- synapse/storage/invite_rule.py +112 -0
- synapse/storage/keys.py +40 -0
- synapse/storage/prepare_database.py +731 -0
- synapse/storage/push_rule.py +28 -0
- synapse/storage/roommember.py +89 -0
- synapse/storage/schema/README.md +4 -0
- synapse/storage/schema/__init__.py +182 -0
- synapse/storage/schema/common/delta/25/00background_updates.sql +40 -0
- synapse/storage/schema/common/delta/35/00background_updates_add_col.sql +36 -0
- synapse/storage/schema/common/delta/58/00background_update_ordering.sql +38 -0
- synapse/storage/schema/common/full_schemas/72/full.sql.postgres +8 -0
- synapse/storage/schema/common/full_schemas/72/full.sql.sqlite +6 -0
- synapse/storage/schema/common/schema_version.sql +60 -0
- synapse/storage/schema/main/delta/12/v12.sql +82 -0
- synapse/storage/schema/main/delta/13/v13.sql +38 -0
- synapse/storage/schema/main/delta/14/v14.sql +42 -0
- synapse/storage/schema/main/delta/15/appservice_txns.sql +50 -0
- synapse/storage/schema/main/delta/15/presence_indices.sql +2 -0
- synapse/storage/schema/main/delta/15/v15.sql +24 -0
- synapse/storage/schema/main/delta/16/events_order_index.sql +4 -0
- synapse/storage/schema/main/delta/16/remote_media_cache_index.sql +2 -0
- synapse/storage/schema/main/delta/16/remove_duplicates.sql +9 -0
- synapse/storage/schema/main/delta/16/room_alias_index.sql +3 -0
- synapse/storage/schema/main/delta/16/unique_constraints.sql +72 -0
- synapse/storage/schema/main/delta/16/users.sql +56 -0
- synapse/storage/schema/main/delta/17/drop_indexes.sql +37 -0
- synapse/storage/schema/main/delta/17/server_keys.sql +43 -0
- synapse/storage/schema/main/delta/17/user_threepids.sql +9 -0
- synapse/storage/schema/main/delta/18/server_keys_bigger_ints.sql +51 -0
- synapse/storage/schema/main/delta/19/event_index.sql +38 -0
- synapse/storage/schema/main/delta/20/dummy.sql +1 -0
- synapse/storage/schema/main/delta/20/pushers.py +93 -0
- synapse/storage/schema/main/delta/21/end_to_end_keys.sql +53 -0
- synapse/storage/schema/main/delta/21/receipts.sql +57 -0
- synapse/storage/schema/main/delta/22/receipts_index.sql +41 -0
- synapse/storage/schema/main/delta/22/user_threepids_unique.sql +19 -0
- synapse/storage/schema/main/delta/24/stats_reporting.sql +37 -0
- synapse/storage/schema/main/delta/25/fts.py +81 -0
- synapse/storage/schema/main/delta/25/guest_access.sql +44 -0
- synapse/storage/schema/main/delta/25/history_visibility.sql +44 -0
- synapse/storage/schema/main/delta/25/tags.sql +57 -0
- synapse/storage/schema/main/delta/26/account_data.sql +36 -0
- synapse/storage/schema/main/delta/27/account_data.sql +55 -0
- synapse/storage/schema/main/delta/27/forgotten_memberships.sql +45 -0
- synapse/storage/schema/main/delta/27/ts.py +61 -0
- synapse/storage/schema/main/delta/28/event_push_actions.sql +46 -0
- synapse/storage/schema/main/delta/28/events_room_stream.sql +39 -0
- synapse/storage/schema/main/delta/28/public_roms_index.sql +39 -0
- synapse/storage/schema/main/delta/28/receipts_user_id_index.sql +41 -0
- synapse/storage/schema/main/delta/28/upgrade_times.sql +40 -0
- synapse/storage/schema/main/delta/28/users_is_guest.sql +41 -0
- synapse/storage/schema/main/delta/29/push_actions.sql +54 -0
- synapse/storage/schema/main/delta/30/alias_creator.sql +35 -0
- synapse/storage/schema/main/delta/30/as_users.py +82 -0
- synapse/storage/schema/main/delta/30/deleted_pushers.sql +44 -0
- synapse/storage/schema/main/delta/30/presence_stream.sql +49 -0
- synapse/storage/schema/main/delta/30/public_rooms.sql +42 -0
- synapse/storage/schema/main/delta/30/push_rule_stream.sql +57 -0
- synapse/storage/schema/main/delta/30/threepid_guest_access_tokens.sql +43 -0
- synapse/storage/schema/main/delta/31/invites.sql +61 -0
- synapse/storage/schema/main/delta/31/local_media_repository_url_cache.sql +46 -0
- synapse/storage/schema/main/delta/31/pushers_0.py +92 -0
- synapse/storage/schema/main/delta/31/pushers_index.sql +41 -0
- synapse/storage/schema/main/delta/31/search_update.py +65 -0
- synapse/storage/schema/main/delta/32/events.sql +35 -0
- synapse/storage/schema/main/delta/32/openid.sql +9 -0
- synapse/storage/schema/main/delta/32/pusher_throttle.sql +42 -0
- synapse/storage/schema/main/delta/32/remove_indices.sql +52 -0
- synapse/storage/schema/main/delta/32/reports.sql +44 -0
- synapse/storage/schema/main/delta/33/access_tokens_device_index.sql +36 -0
- synapse/storage/schema/main/delta/33/devices.sql +40 -0
- synapse/storage/schema/main/delta/33/devices_for_e2e_keys.sql +38 -0
- synapse/storage/schema/main/delta/33/devices_for_e2e_keys_clear_unknown_device.sql +39 -0
- synapse/storage/schema/main/delta/33/event_fields.py +61 -0
- synapse/storage/schema/main/delta/33/remote_media_ts.py +43 -0
- synapse/storage/schema/main/delta/33/user_ips_index.sql +36 -0
- synapse/storage/schema/main/delta/34/appservice_stream.sql +42 -0
- synapse/storage/schema/main/delta/34/cache_stream.py +50 -0
- synapse/storage/schema/main/delta/34/device_inbox.sql +43 -0
- synapse/storage/schema/main/delta/34/push_display_name_rename.sql +39 -0
- synapse/storage/schema/main/delta/34/received_txn_purge.py +36 -0
- synapse/storage/schema/main/delta/35/contains_url.sql +36 -0
- synapse/storage/schema/main/delta/35/device_outbox.sql +58 -0
- synapse/storage/schema/main/delta/35/device_stream_id.sql +40 -0
- synapse/storage/schema/main/delta/35/event_push_actions_index.sql +36 -0
- synapse/storage/schema/main/delta/35/public_room_list_change_stream.sql +52 -0
- synapse/storage/schema/main/delta/35/stream_order_to_extrem.sql +56 -0
- synapse/storage/schema/main/delta/36/readd_public_rooms.sql +45 -0
- synapse/storage/schema/main/delta/37/remove_auth_idx.py +89 -0
- synapse/storage/schema/main/delta/37/user_threepids.sql +71 -0
- synapse/storage/schema/main/delta/38/postgres_fts_gist.sql +38 -0
- synapse/storage/schema/main/delta/39/appservice_room_list.sql +48 -0
- synapse/storage/schema/main/delta/39/device_federation_stream_idx.sql +35 -0
- synapse/storage/schema/main/delta/39/event_push_index.sql +36 -0
- synapse/storage/schema/main/delta/39/federation_out_position.sql +41 -0
- synapse/storage/schema/main/delta/39/membership_profile.sql +39 -0
- synapse/storage/schema/main/delta/40/current_state_idx.sql +36 -0
- synapse/storage/schema/main/delta/40/device_inbox.sql +40 -0
- synapse/storage/schema/main/delta/40/device_list_streams.sql +79 -0
- synapse/storage/schema/main/delta/40/event_push_summary.sql +57 -0
- synapse/storage/schema/main/delta/40/pushers.sql +58 -0
- synapse/storage/schema/main/delta/41/device_list_stream_idx.sql +36 -0
- synapse/storage/schema/main/delta/41/device_outbound_index.sql +35 -0
- synapse/storage/schema/main/delta/41/event_search_event_id_idx.sql +36 -0
- synapse/storage/schema/main/delta/41/ratelimit.sql +41 -0
- synapse/storage/schema/main/delta/42/current_state_delta.sql +48 -0
- synapse/storage/schema/main/delta/42/device_list_last_id.sql +52 -0
- synapse/storage/schema/main/delta/42/event_auth_state_only.sql +36 -0
- synapse/storage/schema/main/delta/42/user_dir.py +88 -0
- synapse/storage/schema/main/delta/43/blocked_rooms.sql +40 -0
- synapse/storage/schema/main/delta/43/quarantine_media.sql +36 -0
- synapse/storage/schema/main/delta/43/url_cache.sql +35 -0
- synapse/storage/schema/main/delta/43/user_share.sql +52 -0
- synapse/storage/schema/main/delta/44/expire_url_cache.sql +60 -0
- synapse/storage/schema/main/delta/45/group_server.sql +186 -0
- synapse/storage/schema/main/delta/45/profile_cache.sql +47 -0
- synapse/storage/schema/main/delta/46/drop_refresh_tokens.sql +36 -0
- synapse/storage/schema/main/delta/46/drop_unique_deleted_pushers.sql +54 -0
- synapse/storage/schema/main/delta/46/group_server.sql +51 -0
- synapse/storage/schema/main/delta/46/local_media_repository_url_idx.sql +43 -0
- synapse/storage/schema/main/delta/46/user_dir_null_room_ids.sql +54 -0
- synapse/storage/schema/main/delta/46/user_dir_typos.sql +43 -0
- synapse/storage/schema/main/delta/47/last_access_media.sql +35 -0
- synapse/storage/schema/main/delta/47/postgres_fts_gin.sql +36 -0
- synapse/storage/schema/main/delta/47/push_actions_staging.sql +47 -0
- synapse/storage/schema/main/delta/48/add_user_consent.sql +37 -0
- synapse/storage/schema/main/delta/48/add_user_ips_last_seen_index.sql +36 -0
- synapse/storage/schema/main/delta/48/deactivated_users.sql +44 -0
- synapse/storage/schema/main/delta/48/group_unique_indexes.py +67 -0
- synapse/storage/schema/main/delta/48/groups_joinable.sql +41 -0
- synapse/storage/schema/main/delta/49/add_user_consent_server_notice_sent.sql +39 -0
- synapse/storage/schema/main/delta/49/add_user_daily_visits.sql +40 -0
- synapse/storage/schema/main/delta/49/add_user_ips_last_seen_only_index.sql +36 -0
- synapse/storage/schema/main/delta/50/add_creation_ts_users_index.sql +38 -0
- synapse/storage/schema/main/delta/50/erasure_store.sql +40 -0
- synapse/storage/schema/main/delta/50/make_event_content_nullable.py +102 -0
- synapse/storage/schema/main/delta/51/e2e_room_keys.sql +58 -0
- synapse/storage/schema/main/delta/51/monthly_active_users.sql +46 -0
- synapse/storage/schema/main/delta/52/add_event_to_state_group_index.sql +38 -0
- synapse/storage/schema/main/delta/52/device_list_streams_unique_idx.sql +55 -0
- synapse/storage/schema/main/delta/52/e2e_room_keys.sql +72 -0
- synapse/storage/schema/main/delta/53/add_user_type_to_users.sql +38 -0
- synapse/storage/schema/main/delta/53/drop_sent_transactions.sql +35 -0
- synapse/storage/schema/main/delta/53/event_format_version.sql +35 -0
- synapse/storage/schema/main/delta/53/user_dir_populate.sql +49 -0
- synapse/storage/schema/main/delta/53/user_ips_index.sql +49 -0
- synapse/storage/schema/main/delta/53/user_share.sql +63 -0
- synapse/storage/schema/main/delta/53/user_threepid_id.sql +48 -0
- synapse/storage/schema/main/delta/53/users_in_public_rooms.sql +47 -0
- synapse/storage/schema/main/delta/54/account_validity_with_renewal.sql +49 -0
- synapse/storage/schema/main/delta/54/add_validity_to_server_keys.sql +42 -0
- synapse/storage/schema/main/delta/54/delete_forward_extremities.sql +42 -0
- synapse/storage/schema/main/delta/54/drop_legacy_tables.sql +49 -0
- synapse/storage/schema/main/delta/54/drop_presence_list.sql +35 -0
- synapse/storage/schema/main/delta/54/relations.sql +46 -0
- synapse/storage/schema/main/delta/54/stats.sql +99 -0
- synapse/storage/schema/main/delta/54/stats2.sql +47 -0
- synapse/storage/schema/main/delta/55/access_token_expiry.sql +37 -0
- synapse/storage/schema/main/delta/55/track_threepid_validations.sql +50 -0
- synapse/storage/schema/main/delta/55/users_alter_deactivated.sql +38 -0
- synapse/storage/schema/main/delta/56/add_spans_to_device_lists.sql +39 -0
- synapse/storage/schema/main/delta/56/current_state_events_membership.sql +41 -0
- synapse/storage/schema/main/delta/56/current_state_events_membership_mk2.sql +43 -0
- synapse/storage/schema/main/delta/56/delete_keys_from_deleted_backups.sql +44 -0
- synapse/storage/schema/main/delta/56/destinations_failure_ts.sql +44 -0
- synapse/storage/schema/main/delta/56/destinations_retry_interval_type.sql.postgres +18 -0
- synapse/storage/schema/main/delta/56/device_stream_id_insert.sql +39 -0
- synapse/storage/schema/main/delta/56/devices_last_seen.sql +43 -0
- synapse/storage/schema/main/delta/56/drop_unused_event_tables.sql +39 -0
- synapse/storage/schema/main/delta/56/event_expiry.sql +40 -0
- synapse/storage/schema/main/delta/56/event_labels.sql +49 -0
- synapse/storage/schema/main/delta/56/event_labels_background_update.sql +36 -0
- synapse/storage/schema/main/delta/56/fix_room_keys_index.sql +37 -0
- synapse/storage/schema/main/delta/56/hidden_devices.sql +37 -0
- synapse/storage/schema/main/delta/56/hidden_devices_fix.sql.sqlite +42 -0
- synapse/storage/schema/main/delta/56/nuke_empty_communities_from_db.sql +48 -0
- synapse/storage/schema/main/delta/56/public_room_list_idx.sql +35 -0
- synapse/storage/schema/main/delta/56/redaction_censor.sql +35 -0
- synapse/storage/schema/main/delta/56/redaction_censor2.sql +41 -0
- synapse/storage/schema/main/delta/56/redaction_censor3_fix_update.sql.postgres +25 -0
- synapse/storage/schema/main/delta/56/redaction_censor4.sql +35 -0
- synapse/storage/schema/main/delta/56/remove_tombstoned_rooms_from_directory.sql +38 -0
- synapse/storage/schema/main/delta/56/room_key_etag.sql +36 -0
- synapse/storage/schema/main/delta/56/room_membership_idx.sql +37 -0
- synapse/storage/schema/main/delta/56/room_retention.sql +52 -0
- synapse/storage/schema/main/delta/56/signing_keys.sql +75 -0
- synapse/storage/schema/main/delta/56/signing_keys_nonunique_signatures.sql +41 -0
- synapse/storage/schema/main/delta/56/stats_separated.sql +175 -0
- synapse/storage/schema/main/delta/56/unique_user_filter_index.py +46 -0
- synapse/storage/schema/main/delta/56/user_external_ids.sql +43 -0
- synapse/storage/schema/main/delta/56/users_in_public_rooms_idx.sql +36 -0
- synapse/storage/schema/main/delta/57/delete_old_current_state_events.sql +41 -0
- synapse/storage/schema/main/delta/57/device_list_remote_cache_stale.sql +44 -0
- synapse/storage/schema/main/delta/57/local_current_membership.py +111 -0
- synapse/storage/schema/main/delta/57/remove_sent_outbound_pokes.sql +40 -0
- synapse/storage/schema/main/delta/57/rooms_version_column.sql +43 -0
- synapse/storage/schema/main/delta/57/rooms_version_column_2.sql.postgres +35 -0
- synapse/storage/schema/main/delta/57/rooms_version_column_2.sql.sqlite +22 -0
- synapse/storage/schema/main/delta/57/rooms_version_column_3.sql.postgres +39 -0
- synapse/storage/schema/main/delta/57/rooms_version_column_3.sql.sqlite +23 -0
- synapse/storage/schema/main/delta/58/02remove_dup_outbound_pokes.sql +41 -0
- synapse/storage/schema/main/delta/58/03persist_ui_auth.sql +55 -0
- synapse/storage/schema/main/delta/58/05cache_instance.sql.postgres +30 -0
- synapse/storage/schema/main/delta/58/06dlols_unique_idx.py +83 -0
- synapse/storage/schema/main/delta/58/07add_method_to_thumbnail_constraint.sql.postgres +33 -0
- synapse/storage/schema/main/delta/58/07add_method_to_thumbnail_constraint.sql.sqlite +44 -0
- synapse/storage/schema/main/delta/58/07persist_ui_auth_ips.sql +44 -0
- synapse/storage/schema/main/delta/58/08_media_safe_from_quarantine.sql.postgres +18 -0
- synapse/storage/schema/main/delta/58/08_media_safe_from_quarantine.sql.sqlite +18 -0
- synapse/storage/schema/main/delta/58/09shadow_ban.sql +37 -0
- synapse/storage/schema/main/delta/58/10_pushrules_enabled_delete_obsolete.sql +47 -0
- synapse/storage/schema/main/delta/58/10drop_local_rejections_stream.sql +41 -0
- synapse/storage/schema/main/delta/58/10federation_pos_instance_name.sql +41 -0
- synapse/storage/schema/main/delta/58/11dehydration.sql +39 -0
- synapse/storage/schema/main/delta/58/11fallback.sql +43 -0
- synapse/storage/schema/main/delta/58/11user_id_seq.py +38 -0
- synapse/storage/schema/main/delta/58/12room_stats.sql +51 -0
- synapse/storage/schema/main/delta/58/13remove_presence_allow_inbound.sql +36 -0
- synapse/storage/schema/main/delta/58/14events_instance_name.sql +35 -0
- synapse/storage/schema/main/delta/58/14events_instance_name.sql.postgres +28 -0
- synapse/storage/schema/main/delta/58/15_catchup_destination_rooms.sql +61 -0
- synapse/storage/schema/main/delta/58/15unread_count.sql +45 -0
- synapse/storage/schema/main/delta/58/16populate_stats_process_rooms_fix.sql +41 -0
- synapse/storage/schema/main/delta/58/17_catchup_last_successful.sql +40 -0
- synapse/storage/schema/main/delta/58/18stream_positions.sql +41 -0
- synapse/storage/schema/main/delta/58/19instance_map.sql.postgres +25 -0
- synapse/storage/schema/main/delta/58/19txn_id.sql +59 -0
- synapse/storage/schema/main/delta/58/20instance_name_event_tables.sql +36 -0
- synapse/storage/schema/main/delta/58/20user_daily_visits.sql +37 -0
- synapse/storage/schema/main/delta/58/21as_device_stream.sql +36 -0
- synapse/storage/schema/main/delta/58/21drop_device_max_stream_id.sql +1 -0
- synapse/storage/schema/main/delta/58/22puppet_token.sql +36 -0
- synapse/storage/schema/main/delta/58/22users_have_local_media.sql +2 -0
- synapse/storage/schema/main/delta/58/23e2e_cross_signing_keys_idx.sql +36 -0
- synapse/storage/schema/main/delta/58/24drop_event_json_index.sql +38 -0
- synapse/storage/schema/main/delta/58/25user_external_ids_user_id_idx.sql +36 -0
- synapse/storage/schema/main/delta/58/26access_token_last_validated.sql +37 -0
- synapse/storage/schema/main/delta/58/27local_invites.sql +37 -0
- synapse/storage/schema/main/delta/58/28drop_last_used_column.sql.postgres +16 -0
- synapse/storage/schema/main/delta/58/28drop_last_used_column.sql.sqlite +62 -0
- synapse/storage/schema/main/delta/59/01ignored_user.py +85 -0
- synapse/storage/schema/main/delta/59/02shard_send_to_device.sql +37 -0
- synapse/storage/schema/main/delta/59/03shard_send_to_device_sequence.sql.postgres +25 -0
- synapse/storage/schema/main/delta/59/04_event_auth_chains.sql +71 -0
- synapse/storage/schema/main/delta/59/04_event_auth_chains.sql.postgres +16 -0
- synapse/storage/schema/main/delta/59/04drop_account_data.sql +36 -0
- synapse/storage/schema/main/delta/59/05cache_invalidation.sql +36 -0
- synapse/storage/schema/main/delta/59/06chain_cover_index.sql +36 -0
- synapse/storage/schema/main/delta/59/06shard_account_data.sql +39 -0
- synapse/storage/schema/main/delta/59/06shard_account_data.sql.postgres +32 -0
- synapse/storage/schema/main/delta/59/07shard_account_data_fix.sql +37 -0
- synapse/storage/schema/main/delta/59/08delete_pushers_for_deactivated_accounts.sql +39 -0
- synapse/storage/schema/main/delta/59/08delete_stale_pushers.sql +39 -0
- synapse/storage/schema/main/delta/59/09rejected_events_metadata.sql +45 -0
- synapse/storage/schema/main/delta/59/10delete_purged_chain_cover.sql +36 -0
- synapse/storage/schema/main/delta/59/11add_knock_members_to_stats.sql +39 -0
- synapse/storage/schema/main/delta/59/11drop_thumbnail_constraint.sql.postgres +22 -0
- synapse/storage/schema/main/delta/59/12account_validity_token_used_ts_ms.sql +37 -0
- synapse/storage/schema/main/delta/59/12presence_stream_instance.sql +37 -0
- synapse/storage/schema/main/delta/59/12presence_stream_instance_seq.sql.postgres +20 -0
- synapse/storage/schema/main/delta/59/13users_to_send_full_presence_to.sql +53 -0
- synapse/storage/schema/main/delta/59/14refresh_tokens.sql +53 -0
- synapse/storage/schema/main/delta/59/15locks.sql +56 -0
- synapse/storage/schema/main/delta/59/16federation_inbound_staging.sql +51 -0
- synapse/storage/schema/main/delta/60/01recreate_stream_ordering.sql.postgres +45 -0
- synapse/storage/schema/main/delta/60/02change_stream_ordering_columns.sql.postgres +30 -0
- synapse/storage/schema/main/delta/61/01change_appservices_txns.sql.postgres +23 -0
- synapse/storage/schema/main/delta/61/01insertion_event_lookups.sql +68 -0
- synapse/storage/schema/main/delta/61/02drop_redundant_room_depth_index.sql +37 -0
- synapse/storage/schema/main/delta/61/03recreate_min_depth.py +74 -0
- synapse/storage/schema/main/delta/62/01insertion_event_extremities.sql +43 -0
- synapse/storage/schema/main/delta/63/01create_registration_tokens.sql +42 -0
- synapse/storage/schema/main/delta/63/02delete_unlinked_email_pushers.sql +39 -0
- synapse/storage/schema/main/delta/63/02populate-rooms-creator.sql +36 -0
- synapse/storage/schema/main/delta/63/03session_store.sql +42 -0
- synapse/storage/schema/main/delta/63/04add_presence_stream_not_offline_index.sql +37 -0
- synapse/storage/schema/main/delta/64/01msc2716_chunk_to_batch_rename.sql.postgres +23 -0
- synapse/storage/schema/main/delta/64/01msc2716_chunk_to_batch_rename.sql.sqlite +37 -0
- synapse/storage/schema/main/delta/65/01msc2716_insertion_event_edges.sql +38 -0
- synapse/storage/schema/main/delta/65/03remove_hidden_devices_from_device_inbox.sql +41 -0
- synapse/storage/schema/main/delta/65/04_local_group_updates.sql +37 -0
- synapse/storage/schema/main/delta/65/05_remove_room_stats_historical_and_user_stats_historical.sql +38 -0
- synapse/storage/schema/main/delta/65/06remove_deleted_devices_from_device_inbox.sql +53 -0
- synapse/storage/schema/main/delta/65/07_arbitrary_relations.sql +37 -0
- synapse/storage/schema/main/delta/65/08_device_inbox_background_updates.sql +37 -0
- synapse/storage/schema/main/delta/65/10_expirable_refresh_tokens.sql +47 -0
- synapse/storage/schema/main/delta/65/11_devices_auth_provider_session.sql +46 -0
- synapse/storage/schema/main/delta/67/01drop_public_room_list_stream.sql +37 -0
- synapse/storage/schema/main/delta/68/01event_columns.sql +45 -0
- synapse/storage/schema/main/delta/68/02_msc2409_add_device_id_appservice_stream_type.sql +40 -0
- synapse/storage/schema/main/delta/68/03_delete_account_data_for_deactivated_accounts.sql +39 -0
- synapse/storage/schema/main/delta/68/04_refresh_tokens_index_next_token_id.sql +47 -0
- synapse/storage/schema/main/delta/68/04partial_state_rooms.sql +60 -0
- synapse/storage/schema/main/delta/68/05_delete_non_strings_from_event_search.sql.sqlite +22 -0
- synapse/storage/schema/main/delta/68/05partial_state_rooms_triggers.py +80 -0
- synapse/storage/schema/main/delta/68/06_msc3202_add_device_list_appservice_stream_type.sql +42 -0
- synapse/storage/schema/main/delta/69/01as_txn_seq.py +54 -0
- synapse/storage/schema/main/delta/69/01device_list_oubound_by_room.sql +57 -0
- synapse/storage/schema/main/delta/69/02cache_invalidation_index.sql +37 -0
- synapse/storage/schema/main/delta/70/01clean_table_purged_rooms.sql +39 -0
- synapse/storage/schema/main/delta/71/01rebuild_event_edges.sql.postgres +43 -0
- synapse/storage/schema/main/delta/71/01rebuild_event_edges.sql.sqlite +47 -0
- synapse/storage/schema/main/delta/71/01remove_noop_background_updates.sql +80 -0
- synapse/storage/schema/main/delta/71/02event_push_summary_unique.sql +37 -0
- synapse/storage/schema/main/delta/72/01add_room_type_to_state_stats.sql +38 -0
- synapse/storage/schema/main/delta/72/01event_push_summary_receipt.sql +54 -0
- synapse/storage/schema/main/delta/72/02event_push_actions_index.sql +38 -0
- synapse/storage/schema/main/delta/72/03bg_populate_events_columns.py +57 -0
- synapse/storage/schema/main/delta/72/03drop_event_reference_hashes.sql +36 -0
- synapse/storage/schema/main/delta/72/03remove_groups.sql +50 -0
- synapse/storage/schema/main/delta/72/04drop_column_application_services_state_last_txn.sql.postgres +17 -0
- synapse/storage/schema/main/delta/72/04drop_column_application_services_state_last_txn.sql.sqlite +40 -0
- synapse/storage/schema/main/delta/72/05receipts_event_stream_ordering.sql +38 -0
- synapse/storage/schema/main/delta/72/05remove_unstable_private_read_receipts.sql +38 -0
- synapse/storage/schema/main/delta/72/06add_consent_ts_to_users.sql +35 -0
- synapse/storage/schema/main/delta/72/06thread_notifications.sql +49 -0
- synapse/storage/schema/main/delta/72/07force_update_current_state_events_membership.py +67 -0
- synapse/storage/schema/main/delta/72/07thread_receipts.sql.postgres +30 -0
- synapse/storage/schema/main/delta/72/07thread_receipts.sql.sqlite +70 -0
- synapse/storage/schema/main/delta/72/08begin_cache_invalidation_seq_at_2.sql.postgres +23 -0
- synapse/storage/schema/main/delta/72/08thread_receipts.sql +39 -0
- synapse/storage/schema/main/delta/72/09partial_indices.sql.sqlite +56 -0
- synapse/storage/schema/main/delta/73/01event_failed_pull_attempts.sql +48 -0
- synapse/storage/schema/main/delta/73/02add_pusher_enabled.sql +35 -0
- synapse/storage/schema/main/delta/73/02room_id_indexes_for_purging.sql +41 -0
- synapse/storage/schema/main/delta/73/03pusher_device_id.sql +39 -0
- synapse/storage/schema/main/delta/73/03users_approved_column.sql +39 -0
- synapse/storage/schema/main/delta/73/04partial_join_details.sql +42 -0
- synapse/storage/schema/main/delta/73/04pending_device_list_updates.sql +47 -0
- synapse/storage/schema/main/delta/73/05old_push_actions.sql.postgres +22 -0
- synapse/storage/schema/main/delta/73/05old_push_actions.sql.sqlite +24 -0
- synapse/storage/schema/main/delta/73/06thread_notifications_thread_id_idx.sql +42 -0
- synapse/storage/schema/main/delta/73/08thread_receipts_non_null.sql.postgres +23 -0
- synapse/storage/schema/main/delta/73/08thread_receipts_non_null.sql.sqlite +76 -0
- synapse/storage/schema/main/delta/73/09partial_joined_via_destination.sql +37 -0
- synapse/storage/schema/main/delta/73/09threads_table.sql +49 -0
- synapse/storage/schema/main/delta/73/10_update_sqlite_fts4_tokenizer.py +71 -0
- synapse/storage/schema/main/delta/73/10login_tokens.sql +54 -0
- synapse/storage/schema/main/delta/73/11event_search_room_id_n_distinct.sql.postgres +33 -0
- synapse/storage/schema/main/delta/73/12refactor_device_list_outbound_pokes.sql +72 -0
- synapse/storage/schema/main/delta/73/13add_device_lists_index.sql +39 -0
- synapse/storage/schema/main/delta/73/20_un_partial_stated_room_stream.sql +51 -0
- synapse/storage/schema/main/delta/73/21_un_partial_stated_room_stream_seq.sql.postgres +20 -0
- synapse/storage/schema/main/delta/73/22_rebuild_user_dir_stats.sql +48 -0
- synapse/storage/schema/main/delta/73/22_un_partial_stated_event_stream.sql +53 -0
- synapse/storage/schema/main/delta/73/23_fix_thread_index.sql +52 -0
- synapse/storage/schema/main/delta/73/23_un_partial_stated_room_stream_seq.sql.postgres +20 -0
- synapse/storage/schema/main/delta/73/24_events_jump_to_date_index.sql +36 -0
- synapse/storage/schema/main/delta/73/25drop_presence.sql +36 -0
- synapse/storage/schema/main/delta/74/01_user_directory_stale_remote_users.sql +58 -0
- synapse/storage/schema/main/delta/74/02_set_device_id_for_pushers_bg_update.sql +38 -0
- synapse/storage/schema/main/delta/74/03_membership_tables_event_stream_ordering.sql.postgres +29 -0
- synapse/storage/schema/main/delta/74/03_membership_tables_event_stream_ordering.sql.sqlite +23 -0
- synapse/storage/schema/main/delta/74/03_room_membership_index.sql +38 -0
- synapse/storage/schema/main/delta/74/04_delete_e2e_backup_keys_for_deactivated_users.sql +36 -0
- synapse/storage/schema/main/delta/74/04_membership_tables_event_stream_ordering_triggers.py +87 -0
- synapse/storage/schema/main/delta/74/05_events_txn_id_device_id.sql +72 -0
- synapse/storage/schema/main/delta/74/90COMMENTS_destinations.sql.postgres +52 -0
- synapse/storage/schema/main/delta/76/01_add_profiles_full_user_id_column.sql +39 -0
- synapse/storage/schema/main/delta/76/02_add_user_filters_full_user_id_column.sql +39 -0
- synapse/storage/schema/main/delta/76/03_per_user_experimental_features.sql +46 -0
- synapse/storage/schema/main/delta/76/04_add_room_forgetter.sql +43 -0
- synapse/storage/schema/main/delta/77/01_add_profiles_not_valid_check.sql.postgres +16 -0
- synapse/storage/schema/main/delta/77/02_add_user_filters_not_valid_check.sql.postgres +16 -0
- synapse/storage/schema/main/delta/77/03bg_populate_full_user_id_profiles.sql +35 -0
- synapse/storage/schema/main/delta/77/04bg_populate_full_user_id_user_filters.sql +35 -0
- synapse/storage/schema/main/delta/77/05thread_notifications_backfill.sql +67 -0
- synapse/storage/schema/main/delta/77/06thread_notifications_not_null.sql.sqlite +102 -0
- synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_actions.sql.postgres +27 -0
- synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_actions_staging.sql.postgres +27 -0
- synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_summary.sql.postgres +29 -0
- synapse/storage/schema/main/delta/77/14bg_indices_event_stream_ordering.sql +39 -0
- synapse/storage/schema/main/delta/78/01_validate_and_update_profiles.py +99 -0
- synapse/storage/schema/main/delta/78/02_validate_and_update_user_filters.py +100 -0
- synapse/storage/schema/main/delta/78/03_remove_unused_indexes_user_filters.py +72 -0
- synapse/storage/schema/main/delta/78/03event_extremities_constraints.py +65 -0
- synapse/storage/schema/main/delta/78/04_add_full_user_id_index_user_filters.py +32 -0
- synapse/storage/schema/main/delta/79/03_read_write_locks_triggers.sql.postgres +102 -0
- synapse/storage/schema/main/delta/79/03_read_write_locks_triggers.sql.sqlite +72 -0
- synapse/storage/schema/main/delta/79/04_mitigate_stream_ordering_update_race.py +70 -0
- synapse/storage/schema/main/delta/79/05_read_write_locks_triggers.sql.postgres +69 -0
- synapse/storage/schema/main/delta/79/05_read_write_locks_triggers.sql.sqlite +65 -0
- synapse/storage/schema/main/delta/80/01_users_alter_locked.sql +35 -0
- synapse/storage/schema/main/delta/80/02_read_write_locks_unlogged.sql.postgres +30 -0
- synapse/storage/schema/main/delta/80/02_scheduled_tasks.sql +47 -0
- synapse/storage/schema/main/delta/80/03_read_write_locks_triggers.sql.postgres +37 -0
- synapse/storage/schema/main/delta/80/04_read_write_locks_deadlock.sql.postgres +71 -0
- synapse/storage/schema/main/delta/82/02_scheduled_tasks_index.sql +35 -0
- synapse/storage/schema/main/delta/82/04_add_indices_for_purging_rooms.sql +39 -0
- synapse/storage/schema/main/delta/82/05gaps.sql +44 -0
- synapse/storage/schema/main/delta/83/01_drop_old_tables.sql +43 -0
- synapse/storage/schema/main/delta/83/03_instance_name_receipts.sql.sqlite +17 -0
- synapse/storage/schema/main/delta/83/05_cross_signing_key_update_grant.sql +34 -0
- synapse/storage/schema/main/delta/83/06_event_push_summary_room.sql +36 -0
- synapse/storage/schema/main/delta/84/01_auth_links_stats.sql.postgres +20 -0
- synapse/storage/schema/main/delta/84/02_auth_links_index.sql +16 -0
- synapse/storage/schema/main/delta/84/03_auth_links_analyze.sql.postgres +16 -0
- synapse/storage/schema/main/delta/84/04_access_token_index.sql +15 -0
- synapse/storage/schema/main/delta/85/01_add_suspended.sql +14 -0
- synapse/storage/schema/main/delta/85/02_add_instance_names.sql +27 -0
- synapse/storage/schema/main/delta/85/03_new_sequences.sql.postgres +54 -0
- synapse/storage/schema/main/delta/85/04_cleanup_device_federation_outbox.sql +15 -0
- synapse/storage/schema/main/delta/85/05_add_instance_names_converted_pos.sql +16 -0
- synapse/storage/schema/main/delta/85/06_add_room_reports.sql +20 -0
- synapse/storage/schema/main/delta/86/01_authenticate_media.sql +15 -0
- synapse/storage/schema/main/delta/86/02_receipts_event_id_index.sql +15 -0
- synapse/storage/schema/main/delta/87/01_sliding_sync_memberships.sql +169 -0
- synapse/storage/schema/main/delta/87/02_per_connection_state.sql +81 -0
- synapse/storage/schema/main/delta/87/03_current_state_index.sql +19 -0
- synapse/storage/schema/main/delta/88/01_add_delayed_events.sql +43 -0
- synapse/storage/schema/main/delta/88/01_custom_profile_fields.sql +15 -0
- synapse/storage/schema/main/delta/88/02_fix_sliding_sync_membership_snapshots_forgotten_column.sql +21 -0
- synapse/storage/schema/main/delta/88/03_add_otk_ts_added_index.sql +18 -0
- synapse/storage/schema/main/delta/88/04_current_state_delta_index.sql +18 -0
- synapse/storage/schema/main/delta/88/05_drop_old_otks.sql.postgres +19 -0
- synapse/storage/schema/main/delta/88/05_drop_old_otks.sql.sqlite +19 -0
- synapse/storage/schema/main/delta/88/05_sliding_sync_room_config_index.sql +20 -0
- synapse/storage/schema/main/delta/88/06_events_received_ts_index.sql +17 -0
- synapse/storage/schema/main/delta/89/01_sliding_sync_membership_snapshot_index.sql +15 -0
- synapse/storage/schema/main/delta/90/01_add_column_participant_room_memberships_table.sql +16 -0
- synapse/storage/schema/main/delta/91/01_media_hash.sql +28 -0
- synapse/storage/schema/main/delta/92/01_remove_trigger.sql.postgres +16 -0
- synapse/storage/schema/main/delta/92/01_remove_trigger.sql.sqlite +16 -0
- synapse/storage/schema/main/delta/92/02_remove_populate_participant_bg_update.sql +17 -0
- synapse/storage/schema/main/delta/92/04_ss_membership_snapshot_idx.sql +16 -0
- synapse/storage/schema/main/delta/92/04_thread_subscriptions.sql +59 -0
- synapse/storage/schema/main/delta/92/04_thread_subscriptions_seq.sql.postgres +19 -0
- synapse/storage/schema/main/delta/92/05_fixup_max_depth_cap.sql +17 -0
- synapse/storage/schema/main/delta/92/05_thread_subscriptions_comments.sql.postgres +18 -0
- synapse/storage/schema/main/delta/92/06_device_federation_inbox_index.sql +16 -0
- synapse/storage/schema/main/delta/92/06_threads_last_sent_stream_ordering_comments.sql.postgres +24 -0
- synapse/storage/schema/main/delta/92/07_add_user_reports.sql +22 -0
- synapse/storage/schema/main/delta/92/07_event_txn_id_device_id_txn_id2.sql +15 -0
- synapse/storage/schema/main/delta/92/08_room_ban_redactions.sql +21 -0
- synapse/storage/schema/main/delta/92/08_thread_subscriptions_seq_fixup.sql.postgres +19 -0
- synapse/storage/schema/main/delta/92/09_thread_subscriptions_update.sql +20 -0
- synapse/storage/schema/main/delta/92/09_thread_subscriptions_update.sql.postgres +18 -0
- synapse/storage/schema/main/full_schemas/72/full.sql.postgres +1344 -0
- synapse/storage/schema/main/full_schemas/72/full.sql.sqlite +646 -0
- synapse/storage/schema/state/delta/23/drop_state_index.sql +35 -0
- synapse/storage/schema/state/delta/32/remove_state_indices.sql +38 -0
- synapse/storage/schema/state/delta/35/add_state_index.sql +36 -0
- synapse/storage/schema/state/delta/35/state.sql +41 -0
- synapse/storage/schema/state/delta/35/state_dedupe.sql +36 -0
- synapse/storage/schema/state/delta/47/state_group_seq.py +38 -0
- synapse/storage/schema/state/delta/56/state_group_room_idx.sql +36 -0
- synapse/storage/schema/state/delta/61/02state_groups_state_n_distinct.sql.postgres +34 -0
- synapse/storage/schema/state/delta/70/08_state_group_edges_unique.sql +36 -0
- synapse/storage/schema/state/delta/89/01_state_groups_deletion.sql +39 -0
- synapse/storage/schema/state/delta/90/02_delete_unreferenced_state_groups.sql +16 -0
- synapse/storage/schema/state/delta/90/03_remove_old_deletion_bg_update.sql +15 -0
- synapse/storage/schema/state/full_schemas/72/full.sql.postgres +30 -0
- synapse/storage/schema/state/full_schemas/72/full.sql.sqlite +20 -0
- synapse/storage/types.py +185 -0
- synapse/storage/util/__init__.py +20 -0
- synapse/storage/util/id_generators.py +909 -0
- synapse/storage/util/partial_state_events_tracker.py +194 -0
- synapse/storage/util/sequence.py +315 -0
- synapse/streams/__init__.py +43 -0
- synapse/streams/config.py +92 -0
- synapse/streams/events.py +203 -0
- synapse/synapse_rust/__init__.pyi +3 -0
- synapse/synapse_rust/acl.pyi +20 -0
- synapse/synapse_rust/events.pyi +136 -0
- synapse/synapse_rust/http_client.pyi +32 -0
- synapse/synapse_rust/push.pyi +86 -0
- synapse/synapse_rust/rendezvous.pyi +30 -0
- synapse/synapse_rust/segmenter.pyi +1 -0
- synapse/synapse_rust.abi3.so +0 -0
- synapse/types/__init__.py +1600 -0
- synapse/types/handlers/__init__.py +93 -0
- synapse/types/handlers/policy_server.py +16 -0
- synapse/types/handlers/sliding_sync.py +909 -0
- synapse/types/rest/__init__.py +25 -0
- synapse/types/rest/client/__init__.py +415 -0
- synapse/types/state.py +635 -0
- synapse/types/storage/__init__.py +66 -0
- synapse/util/__init__.py +170 -0
- synapse/util/async_helpers.py +1067 -0
- synapse/util/batching_queue.py +202 -0
- synapse/util/caches/__init__.py +300 -0
- synapse/util/caches/cached_call.py +143 -0
- synapse/util/caches/deferred_cache.py +530 -0
- synapse/util/caches/descriptors.py +694 -0
- synapse/util/caches/dictionary_cache.py +350 -0
- synapse/util/caches/expiringcache.py +251 -0
- synapse/util/caches/lrucache.py +977 -0
- synapse/util/caches/response_cache.py +323 -0
- synapse/util/caches/stream_change_cache.py +370 -0
- synapse/util/caches/treecache.py +189 -0
- synapse/util/caches/ttlcache.py +197 -0
- synapse/util/cancellation.py +63 -0
- synapse/util/check_dependencies.py +335 -0
- synapse/util/clock.py +500 -0
- synapse/util/constants.py +22 -0
- synapse/util/daemonize.py +165 -0
- synapse/util/distributor.py +159 -0
- synapse/util/events.py +134 -0
- synapse/util/file_consumer.py +164 -0
- synapse/util/frozenutils.py +57 -0
- synapse/util/gai_resolver.py +180 -0
- synapse/util/hash.py +38 -0
- synapse/util/httpresourcetree.py +108 -0
- synapse/util/iterutils.py +189 -0
- synapse/util/json.py +56 -0
- synapse/util/linked_list.py +156 -0
- synapse/util/logcontext.py +46 -0
- synapse/util/logformatter.py +28 -0
- synapse/util/macaroons.py +325 -0
- synapse/util/manhole.py +191 -0
- synapse/util/metrics.py +340 -0
- synapse/util/module_loader.py +116 -0
- synapse/util/msisdn.py +51 -0
- synapse/util/patch_inline_callbacks.py +250 -0
- synapse/util/pydantic_models.py +56 -0
- synapse/util/ratelimitutils.py +420 -0
- synapse/util/retryutils.py +339 -0
- synapse/util/rlimit.py +42 -0
- synapse/util/rust.py +134 -0
- synapse/util/sentinel.py +21 -0
- synapse/util/stringutils.py +293 -0
- synapse/util/task_scheduler.py +493 -0
- synapse/util/templates.py +126 -0
- synapse/util/threepids.py +123 -0
- synapse/util/wheel_timer.py +112 -0
- synapse/visibility.py +836 -0
synapse/media/_base.py
ADDED
|
@@ -0,0 +1,827 @@
|
|
|
1
|
+
#
|
|
2
|
+
# This file is licensed under the Affero General Public License (AGPL) version 3.
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2019-2021 The Matrix.org Foundation C.I.C.
|
|
5
|
+
# Copyright 2014-2016 OpenMarket Ltd
|
|
6
|
+
# Copyright (C) 2023 New Vector, Ltd
|
|
7
|
+
#
|
|
8
|
+
# This program is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU Affero General Public License as
|
|
10
|
+
# published by the Free Software Foundation, either version 3 of the
|
|
11
|
+
# License, or (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# See the GNU Affero General Public License for more details:
|
|
14
|
+
# <https://www.gnu.org/licenses/agpl-3.0.html>.
|
|
15
|
+
#
|
|
16
|
+
# Originally licensed under the Apache License, Version 2.0:
|
|
17
|
+
# <http://www.apache.org/licenses/LICENSE-2.0>.
|
|
18
|
+
#
|
|
19
|
+
# [This file includes modifications made by New Vector Limited]
|
|
20
|
+
#
|
|
21
|
+
#
|
|
22
|
+
|
|
23
|
+
import logging
|
|
24
|
+
import os
|
|
25
|
+
import urllib
|
|
26
|
+
from abc import ABC, abstractmethod
|
|
27
|
+
from types import TracebackType
|
|
28
|
+
from typing import (
|
|
29
|
+
TYPE_CHECKING,
|
|
30
|
+
Awaitable,
|
|
31
|
+
BinaryIO,
|
|
32
|
+
Generator,
|
|
33
|
+
Optional,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
import attr
|
|
37
|
+
from zope.interface import implementer
|
|
38
|
+
|
|
39
|
+
from twisted.internet import interfaces
|
|
40
|
+
from twisted.internet.defer import Deferred
|
|
41
|
+
from twisted.internet.interfaces import IConsumer
|
|
42
|
+
from twisted.python.failure import Failure
|
|
43
|
+
from twisted.web.server import Request
|
|
44
|
+
|
|
45
|
+
from synapse.api.errors import Codes, cs_error
|
|
46
|
+
from synapse.http.server import finish_request, respond_with_json
|
|
47
|
+
from synapse.http.site import SynapseRequest
|
|
48
|
+
from synapse.logging.context import (
|
|
49
|
+
defer_to_threadpool,
|
|
50
|
+
make_deferred_yieldable,
|
|
51
|
+
run_in_background,
|
|
52
|
+
)
|
|
53
|
+
from synapse.util.async_helpers import DeferredEvent
|
|
54
|
+
from synapse.util.clock import Clock
|
|
55
|
+
from synapse.util.stringutils import is_ascii
|
|
56
|
+
|
|
57
|
+
if TYPE_CHECKING:
|
|
58
|
+
from synapse.server import HomeServer
|
|
59
|
+
|
|
60
|
+
logger = logging.getLogger(__name__)
|
|
61
|
+
|
|
62
|
+
# list all text content types that will have the charset default to UTF-8 when
|
|
63
|
+
# none is given
|
|
64
|
+
TEXT_CONTENT_TYPES = [
|
|
65
|
+
"text/css",
|
|
66
|
+
"text/csv",
|
|
67
|
+
"text/html",
|
|
68
|
+
"text/calendar",
|
|
69
|
+
"text/plain",
|
|
70
|
+
"text/javascript",
|
|
71
|
+
"application/json",
|
|
72
|
+
"application/ld+json",
|
|
73
|
+
"application/rtf",
|
|
74
|
+
"image/svg+xml",
|
|
75
|
+
"text/xml",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
# A list of all content types that are "safe" to be rendered inline in a browser.
|
|
79
|
+
INLINE_CONTENT_TYPES = [
|
|
80
|
+
"text/css",
|
|
81
|
+
"text/plain",
|
|
82
|
+
"text/csv",
|
|
83
|
+
"application/json",
|
|
84
|
+
"application/ld+json",
|
|
85
|
+
# We allow some media files deemed as safe, which comes from the matrix-react-sdk.
|
|
86
|
+
# https://github.com/matrix-org/matrix-react-sdk/blob/a70fcfd0bcf7f8c85986da18001ea11597989a7c/src/utils/blobs.ts#L51
|
|
87
|
+
# SVGs are *intentionally* omitted.
|
|
88
|
+
"image/jpeg",
|
|
89
|
+
"image/gif",
|
|
90
|
+
"image/png",
|
|
91
|
+
"image/apng",
|
|
92
|
+
"image/webp",
|
|
93
|
+
"image/avif",
|
|
94
|
+
"video/mp4",
|
|
95
|
+
"video/webm",
|
|
96
|
+
"video/ogg",
|
|
97
|
+
"video/quicktime",
|
|
98
|
+
"audio/mp4",
|
|
99
|
+
"audio/webm",
|
|
100
|
+
"audio/aac",
|
|
101
|
+
"audio/mpeg",
|
|
102
|
+
"audio/ogg",
|
|
103
|
+
"audio/wave",
|
|
104
|
+
"audio/wav",
|
|
105
|
+
"audio/x-wav",
|
|
106
|
+
"audio/x-pn-wav",
|
|
107
|
+
"audio/flac",
|
|
108
|
+
"audio/x-flac",
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
# Default timeout_ms for download and thumbnail requests
|
|
112
|
+
DEFAULT_MAX_TIMEOUT_MS = 20_000
|
|
113
|
+
|
|
114
|
+
# Maximum allowed timeout_ms for download and thumbnail requests
|
|
115
|
+
MAXIMUM_ALLOWED_MAX_TIMEOUT_MS = 60_000
|
|
116
|
+
|
|
117
|
+
# The ETag header value to use for immutable media. This can be anything.
|
|
118
|
+
_IMMUTABLE_ETAG = "1"
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def respond_404(request: SynapseRequest) -> None:
|
|
122
|
+
assert request.path is not None
|
|
123
|
+
respond_with_json(
|
|
124
|
+
request,
|
|
125
|
+
404,
|
|
126
|
+
cs_error("Not found '%s'" % (request.path.decode(),), code=Codes.NOT_FOUND),
|
|
127
|
+
send_cors=True,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
async def respond_with_file(
|
|
132
|
+
hs: "HomeServer",
|
|
133
|
+
request: SynapseRequest,
|
|
134
|
+
media_type: str,
|
|
135
|
+
file_path: str,
|
|
136
|
+
file_size: Optional[int] = None,
|
|
137
|
+
upload_name: Optional[str] = None,
|
|
138
|
+
) -> None:
|
|
139
|
+
logger.debug("Responding with %r", file_path)
|
|
140
|
+
|
|
141
|
+
if os.path.isfile(file_path):
|
|
142
|
+
if file_size is None:
|
|
143
|
+
stat = os.stat(file_path)
|
|
144
|
+
file_size = stat.st_size
|
|
145
|
+
|
|
146
|
+
add_file_headers(request, media_type, file_size, upload_name)
|
|
147
|
+
|
|
148
|
+
with open(file_path, "rb") as f:
|
|
149
|
+
await ThreadedFileSender(hs).beginFileTransfer(f, request)
|
|
150
|
+
|
|
151
|
+
finish_request(request)
|
|
152
|
+
else:
|
|
153
|
+
respond_404(request)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def add_file_headers(
|
|
157
|
+
request: Request,
|
|
158
|
+
media_type: str,
|
|
159
|
+
file_size: Optional[int],
|
|
160
|
+
upload_name: Optional[str],
|
|
161
|
+
) -> None:
|
|
162
|
+
"""Adds the correct response headers in preparation for responding with the
|
|
163
|
+
media.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
request
|
|
167
|
+
media_type: The media/content type.
|
|
168
|
+
file_size: Size in bytes of the media, if known.
|
|
169
|
+
upload_name: The name of the requested file, if any.
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
def _quote(x: str) -> str:
|
|
173
|
+
return urllib.parse.quote(x.encode("utf-8"))
|
|
174
|
+
|
|
175
|
+
# Default to a UTF-8 charset for text content types.
|
|
176
|
+
# ex, uses UTF-8 for 'text/css' but not 'text/css; charset=UTF-16'
|
|
177
|
+
if media_type.lower() in TEXT_CONTENT_TYPES:
|
|
178
|
+
content_type = media_type + "; charset=UTF-8"
|
|
179
|
+
else:
|
|
180
|
+
content_type = media_type
|
|
181
|
+
|
|
182
|
+
request.setHeader(b"Content-Type", content_type.encode("UTF-8"))
|
|
183
|
+
|
|
184
|
+
# A strict subset of content types is allowed to be inlined so that they may
|
|
185
|
+
# be viewed directly in a browser. Other file types are forced to be downloads.
|
|
186
|
+
#
|
|
187
|
+
# Only the type & subtype are important, parameters can be ignored.
|
|
188
|
+
if media_type.lower().split(";", 1)[0] in INLINE_CONTENT_TYPES:
|
|
189
|
+
disposition = "inline"
|
|
190
|
+
else:
|
|
191
|
+
disposition = "attachment"
|
|
192
|
+
|
|
193
|
+
if upload_name:
|
|
194
|
+
# RFC6266 section 4.1 [1] defines both `filename` and `filename*`.
|
|
195
|
+
#
|
|
196
|
+
# `filename` is defined to be a `value`, which is defined by RFC2616
|
|
197
|
+
# section 3.6 [2] to be a `token` or a `quoted-string`, where a `token`
|
|
198
|
+
# is (essentially) a single US-ASCII word, and a `quoted-string` is a
|
|
199
|
+
# US-ASCII string surrounded by double-quotes, using backslash as an
|
|
200
|
+
# escape character. Note that %-encoding is *not* permitted.
|
|
201
|
+
#
|
|
202
|
+
# `filename*` is defined to be an `ext-value`, which is defined in
|
|
203
|
+
# RFC5987 section 3.2.1 [3] to be `charset "'" [ language ] "'" value-chars`,
|
|
204
|
+
# where `value-chars` is essentially a %-encoded string in the given charset.
|
|
205
|
+
#
|
|
206
|
+
# [1]: https://tools.ietf.org/html/rfc6266#section-4.1
|
|
207
|
+
# [2]: https://tools.ietf.org/html/rfc2616#section-3.6
|
|
208
|
+
# [3]: https://tools.ietf.org/html/rfc5987#section-3.2.1
|
|
209
|
+
|
|
210
|
+
# We avoid the quoted-string version of `filename`, because (a) synapse didn't
|
|
211
|
+
# correctly interpret those as of 0.99.2 and (b) they are a bit of a pain and we
|
|
212
|
+
# may as well just do the filename* version.
|
|
213
|
+
if _can_encode_filename_as_token(upload_name):
|
|
214
|
+
disposition = "%s; filename=%s" % (
|
|
215
|
+
disposition,
|
|
216
|
+
upload_name,
|
|
217
|
+
)
|
|
218
|
+
else:
|
|
219
|
+
disposition = "%s; filename*=utf-8''%s" % (
|
|
220
|
+
disposition,
|
|
221
|
+
_quote(upload_name),
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
request.setHeader(b"Content-Disposition", disposition.encode("ascii"))
|
|
225
|
+
|
|
226
|
+
_add_cache_headers(request)
|
|
227
|
+
|
|
228
|
+
if file_size is not None:
|
|
229
|
+
request.setHeader(b"Content-Length", b"%d" % (file_size,))
|
|
230
|
+
|
|
231
|
+
# Tell web crawlers to not index, archive, or follow links in media. This
|
|
232
|
+
# should help to prevent things in the media repo from showing up in web
|
|
233
|
+
# search results.
|
|
234
|
+
request.setHeader(b"X-Robots-Tag", "noindex, nofollow, noarchive, noimageindex")
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _add_cache_headers(request: Request) -> None:
|
|
238
|
+
"""Adds the appropriate cache headers to the response"""
|
|
239
|
+
|
|
240
|
+
# Cache on the client for at least a day.
|
|
241
|
+
#
|
|
242
|
+
# We set this to "public,s-maxage=0,proxy-revalidate" to allow CDNs to cache
|
|
243
|
+
# the media, so long as they "revalidate" the media on every request. By
|
|
244
|
+
# revalidate, we mean send the request to Synapse with a `If-None-Match`
|
|
245
|
+
# header, to which Synapse can either respond with a 304 if the user is
|
|
246
|
+
# authenticated/authorized, or a 401/403 if they're not.
|
|
247
|
+
request.setHeader(
|
|
248
|
+
b"Cache-Control", b"public,max-age=86400,s-maxage=0,proxy-revalidate"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
# Set an ETag header to allow requesters to use it in requests to check if
|
|
252
|
+
# the cache is still valid. Since media is immutable (though may be
|
|
253
|
+
# deleted), we just set this to a constant.
|
|
254
|
+
request.setHeader(b"ETag", _IMMUTABLE_ETAG)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
# separators as defined in RFC2616. SP and HT are handled separately.
|
|
258
|
+
# see _can_encode_filename_as_token.
|
|
259
|
+
_FILENAME_SEPARATOR_CHARS = {
|
|
260
|
+
"(",
|
|
261
|
+
")",
|
|
262
|
+
"<",
|
|
263
|
+
">",
|
|
264
|
+
"@",
|
|
265
|
+
",",
|
|
266
|
+
";",
|
|
267
|
+
":",
|
|
268
|
+
"\\",
|
|
269
|
+
'"',
|
|
270
|
+
"/",
|
|
271
|
+
"[",
|
|
272
|
+
"]",
|
|
273
|
+
"?",
|
|
274
|
+
"=",
|
|
275
|
+
"{",
|
|
276
|
+
"}",
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _can_encode_filename_as_token(x: str) -> bool:
|
|
281
|
+
for c in x:
|
|
282
|
+
# from RFC2616:
|
|
283
|
+
#
|
|
284
|
+
# token = 1*<any CHAR except CTLs or separators>
|
|
285
|
+
#
|
|
286
|
+
# separators = "(" | ")" | "<" | ">" | "@"
|
|
287
|
+
# | "," | ";" | ":" | "\" | <">
|
|
288
|
+
# | "/" | "[" | "]" | "?" | "="
|
|
289
|
+
# | "{" | "}" | SP | HT
|
|
290
|
+
#
|
|
291
|
+
# CHAR = <any US-ASCII character (octets 0 - 127)>
|
|
292
|
+
#
|
|
293
|
+
# CTL = <any US-ASCII control character
|
|
294
|
+
# (octets 0 - 31) and DEL (127)>
|
|
295
|
+
#
|
|
296
|
+
if ord(c) >= 127 or ord(c) <= 32 or c in _FILENAME_SEPARATOR_CHARS:
|
|
297
|
+
return False
|
|
298
|
+
return True
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
async def respond_with_multipart_responder(
|
|
302
|
+
clock: Clock,
|
|
303
|
+
request: SynapseRequest,
|
|
304
|
+
responder: "Optional[Responder]",
|
|
305
|
+
media_type: str,
|
|
306
|
+
media_length: Optional[int],
|
|
307
|
+
upload_name: Optional[str],
|
|
308
|
+
) -> None:
|
|
309
|
+
"""
|
|
310
|
+
Responds to requests originating from the federation media `/download` endpoint by
|
|
311
|
+
streaming a multipart/mixed response
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
clock:
|
|
315
|
+
request: the federation request to respond to
|
|
316
|
+
responder: the responder which will send the response
|
|
317
|
+
media_info: metadata about the media item
|
|
318
|
+
"""
|
|
319
|
+
if not responder:
|
|
320
|
+
respond_404(request)
|
|
321
|
+
return
|
|
322
|
+
|
|
323
|
+
# If we have a responder we *must* use it as a context manager.
|
|
324
|
+
with responder:
|
|
325
|
+
if request._disconnected:
|
|
326
|
+
logger.warning(
|
|
327
|
+
"Not sending response to request %s, already disconnected.", request
|
|
328
|
+
)
|
|
329
|
+
return
|
|
330
|
+
|
|
331
|
+
if media_type.lower().split(";", 1)[0] in INLINE_CONTENT_TYPES:
|
|
332
|
+
disposition = "inline"
|
|
333
|
+
else:
|
|
334
|
+
disposition = "attachment"
|
|
335
|
+
|
|
336
|
+
def _quote(x: str) -> str:
|
|
337
|
+
return urllib.parse.quote(x.encode("utf-8"))
|
|
338
|
+
|
|
339
|
+
if upload_name:
|
|
340
|
+
if _can_encode_filename_as_token(upload_name):
|
|
341
|
+
disposition = "%s; filename=%s" % (
|
|
342
|
+
disposition,
|
|
343
|
+
upload_name,
|
|
344
|
+
)
|
|
345
|
+
else:
|
|
346
|
+
disposition = "%s; filename*=utf-8''%s" % (
|
|
347
|
+
disposition,
|
|
348
|
+
_quote(upload_name),
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
from synapse.media.media_storage import MultipartFileConsumer
|
|
352
|
+
|
|
353
|
+
_add_cache_headers(request)
|
|
354
|
+
|
|
355
|
+
# note that currently the json_object is just {}, this will change when linked media
|
|
356
|
+
# is implemented
|
|
357
|
+
multipart_consumer = MultipartFileConsumer(
|
|
358
|
+
clock,
|
|
359
|
+
request,
|
|
360
|
+
media_type,
|
|
361
|
+
{}, # Note: if we change this we need to change the returned ETag.
|
|
362
|
+
disposition,
|
|
363
|
+
media_length,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
logger.debug("Responding to media request with responder %s", responder)
|
|
367
|
+
if media_length is not None:
|
|
368
|
+
content_length = multipart_consumer.content_length()
|
|
369
|
+
assert content_length is not None
|
|
370
|
+
request.setHeader(b"Content-Length", b"%d" % (content_length,))
|
|
371
|
+
|
|
372
|
+
request.setHeader(
|
|
373
|
+
b"Content-Type",
|
|
374
|
+
b"multipart/mixed; boundary=%s" % multipart_consumer.boundary,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
try:
|
|
378
|
+
await responder.write_to_consumer(multipart_consumer)
|
|
379
|
+
except ConsumerRequestedStopError as e:
|
|
380
|
+
logger.debug("Failed to write to consumer: %s %s", type(e), e)
|
|
381
|
+
# Unregister the producer, if it has one, so Twisted doesn't complain
|
|
382
|
+
if request.producer:
|
|
383
|
+
request.unregisterProducer()
|
|
384
|
+
except Exception as e:
|
|
385
|
+
logger.warning("Failed to write to consumer: %s %s", type(e), e)
|
|
386
|
+
# Unregister the producer, if it has one, so Twisted doesn't complain
|
|
387
|
+
if request.producer:
|
|
388
|
+
request.unregisterProducer()
|
|
389
|
+
|
|
390
|
+
finish_request(request)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
async def respond_with_responder(
|
|
394
|
+
request: SynapseRequest,
|
|
395
|
+
responder: "Optional[Responder]",
|
|
396
|
+
media_type: str,
|
|
397
|
+
file_size: Optional[int],
|
|
398
|
+
upload_name: Optional[str] = None,
|
|
399
|
+
) -> None:
|
|
400
|
+
"""Responds to the request with given responder. If responder is None then
|
|
401
|
+
returns 404.
|
|
402
|
+
|
|
403
|
+
Args:
|
|
404
|
+
request
|
|
405
|
+
responder
|
|
406
|
+
media_type: The media/content type.
|
|
407
|
+
file_size: Size in bytes of the media. If not known it should be None
|
|
408
|
+
upload_name: The name of the requested file, if any.
|
|
409
|
+
"""
|
|
410
|
+
if not responder:
|
|
411
|
+
respond_404(request)
|
|
412
|
+
return
|
|
413
|
+
|
|
414
|
+
# If we have a responder we *must* use it as a context manager.
|
|
415
|
+
with responder:
|
|
416
|
+
if request._disconnected:
|
|
417
|
+
logger.warning(
|
|
418
|
+
"Not sending response to request %s, already disconnected.", request
|
|
419
|
+
)
|
|
420
|
+
return
|
|
421
|
+
|
|
422
|
+
logger.debug("Responding to media request with responder %s", responder)
|
|
423
|
+
add_file_headers(request, media_type, file_size, upload_name)
|
|
424
|
+
try:
|
|
425
|
+
await responder.write_to_consumer(request)
|
|
426
|
+
except ConsumerRequestedStopError as e:
|
|
427
|
+
logger.debug("Failed to write to consumer: %s %s", type(e), e)
|
|
428
|
+
# Unregister the producer, if it has one, so Twisted doesn't complain
|
|
429
|
+
if request.producer:
|
|
430
|
+
request.unregisterProducer()
|
|
431
|
+
except Exception as e:
|
|
432
|
+
logger.warning("Failed to write to consumer: %s %s", type(e), e)
|
|
433
|
+
# Unregister the producer, if it has one, so Twisted doesn't complain
|
|
434
|
+
if request.producer:
|
|
435
|
+
request.unregisterProducer()
|
|
436
|
+
|
|
437
|
+
finish_request(request)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def respond_with_304(request: SynapseRequest) -> None:
|
|
441
|
+
request.setResponseCode(304)
|
|
442
|
+
|
|
443
|
+
# could alternatively use request.notifyFinish() and flip a flag when
|
|
444
|
+
# the Deferred fires, but since the flag is RIGHT THERE it seems like
|
|
445
|
+
# a waste.
|
|
446
|
+
if request._disconnected:
|
|
447
|
+
logger.warning(
|
|
448
|
+
"Not sending response to request %s, already disconnected.", request
|
|
449
|
+
)
|
|
450
|
+
return None
|
|
451
|
+
|
|
452
|
+
_add_cache_headers(request)
|
|
453
|
+
|
|
454
|
+
request.finish()
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
def check_for_cached_entry_and_respond(request: SynapseRequest) -> bool:
|
|
458
|
+
"""Check if the request has a conditional header that allows us to return a
|
|
459
|
+
304 Not Modified response, and if it does, return a 304 response.
|
|
460
|
+
|
|
461
|
+
This handles clients and intermediary proxies caching media.
|
|
462
|
+
This method assumes that the user has already been
|
|
463
|
+
authorised to request the media.
|
|
464
|
+
|
|
465
|
+
Returns True if we have responded."""
|
|
466
|
+
|
|
467
|
+
# We've checked the user has access to the media, so we now check if it
|
|
468
|
+
# is a "conditional request" and we can just return a `304 Not Modified`
|
|
469
|
+
# response. Since media is immutable (though may be deleted), we just
|
|
470
|
+
# check this is the expected constant.
|
|
471
|
+
etag = request.getHeader("If-None-Match")
|
|
472
|
+
if etag == _IMMUTABLE_ETAG:
|
|
473
|
+
# Return a `304 Not modified`.
|
|
474
|
+
respond_with_304(request)
|
|
475
|
+
return True
|
|
476
|
+
|
|
477
|
+
return False
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
class Responder(ABC):
|
|
481
|
+
"""Represents a response that can be streamed to the requester.
|
|
482
|
+
|
|
483
|
+
Responder is a context manager which *must* be used, so that any resources
|
|
484
|
+
held can be cleaned up.
|
|
485
|
+
"""
|
|
486
|
+
|
|
487
|
+
@abstractmethod
|
|
488
|
+
def write_to_consumer(self, consumer: IConsumer) -> Awaitable:
|
|
489
|
+
"""Stream response into consumer
|
|
490
|
+
|
|
491
|
+
Args:
|
|
492
|
+
consumer: The consumer to stream into.
|
|
493
|
+
|
|
494
|
+
Returns:
|
|
495
|
+
Resolves once the response has finished being written
|
|
496
|
+
"""
|
|
497
|
+
raise NotImplementedError()
|
|
498
|
+
|
|
499
|
+
def __enter__(self) -> None: # noqa: B027
|
|
500
|
+
pass
|
|
501
|
+
|
|
502
|
+
def __exit__( # noqa: B027
|
|
503
|
+
self,
|
|
504
|
+
exc_type: Optional[type[BaseException]],
|
|
505
|
+
exc_val: Optional[BaseException],
|
|
506
|
+
exc_tb: Optional[TracebackType],
|
|
507
|
+
) -> None:
|
|
508
|
+
pass
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
|
512
|
+
class ThumbnailInfo:
|
|
513
|
+
"""Details about a generated thumbnail."""
|
|
514
|
+
|
|
515
|
+
width: int
|
|
516
|
+
height: int
|
|
517
|
+
method: str
|
|
518
|
+
# Content type of thumbnail, e.g. image/png
|
|
519
|
+
type: str
|
|
520
|
+
# The size of the media file, in bytes.
|
|
521
|
+
length: int
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
|
525
|
+
class FileInfo:
|
|
526
|
+
"""Details about a requested/uploaded file."""
|
|
527
|
+
|
|
528
|
+
# The server name where the media originated from, or None if local.
|
|
529
|
+
server_name: Optional[str]
|
|
530
|
+
# The local ID of the file. For local files this is the same as the media_id
|
|
531
|
+
file_id: str
|
|
532
|
+
# If the file is for the url preview cache
|
|
533
|
+
url_cache: bool = False
|
|
534
|
+
# Whether the file is a thumbnail or not.
|
|
535
|
+
thumbnail: Optional[ThumbnailInfo] = None
|
|
536
|
+
|
|
537
|
+
# The below properties exist to maintain compatibility with third-party modules.
|
|
538
|
+
@property
|
|
539
|
+
def thumbnail_width(self) -> Optional[int]:
|
|
540
|
+
if not self.thumbnail:
|
|
541
|
+
return None
|
|
542
|
+
return self.thumbnail.width
|
|
543
|
+
|
|
544
|
+
@property
|
|
545
|
+
def thumbnail_height(self) -> Optional[int]:
|
|
546
|
+
if not self.thumbnail:
|
|
547
|
+
return None
|
|
548
|
+
return self.thumbnail.height
|
|
549
|
+
|
|
550
|
+
@property
|
|
551
|
+
def thumbnail_method(self) -> Optional[str]:
|
|
552
|
+
if not self.thumbnail:
|
|
553
|
+
return None
|
|
554
|
+
return self.thumbnail.method
|
|
555
|
+
|
|
556
|
+
@property
|
|
557
|
+
def thumbnail_type(self) -> Optional[str]:
|
|
558
|
+
if not self.thumbnail:
|
|
559
|
+
return None
|
|
560
|
+
return self.thumbnail.type
|
|
561
|
+
|
|
562
|
+
@property
|
|
563
|
+
def thumbnail_length(self) -> Optional[int]:
|
|
564
|
+
if not self.thumbnail:
|
|
565
|
+
return None
|
|
566
|
+
return self.thumbnail.length
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
def get_filename_from_headers(headers: dict[bytes, list[bytes]]) -> Optional[str]:
|
|
570
|
+
"""
|
|
571
|
+
Get the filename of the downloaded file by inspecting the
|
|
572
|
+
Content-Disposition HTTP header.
|
|
573
|
+
|
|
574
|
+
Args:
|
|
575
|
+
headers: The HTTP request headers.
|
|
576
|
+
|
|
577
|
+
Returns:
|
|
578
|
+
The filename, or None.
|
|
579
|
+
"""
|
|
580
|
+
content_disposition = headers.get(b"Content-Disposition", [b""])
|
|
581
|
+
|
|
582
|
+
# No header, bail out.
|
|
583
|
+
if not content_disposition[0]:
|
|
584
|
+
return None
|
|
585
|
+
|
|
586
|
+
_, params = _parse_header(content_disposition[0])
|
|
587
|
+
|
|
588
|
+
upload_name = None
|
|
589
|
+
|
|
590
|
+
# First check if there is a valid UTF-8 filename
|
|
591
|
+
upload_name_utf8 = params.get(b"filename*", None)
|
|
592
|
+
if upload_name_utf8:
|
|
593
|
+
if upload_name_utf8.lower().startswith(b"utf-8''"):
|
|
594
|
+
upload_name_utf8 = upload_name_utf8[7:]
|
|
595
|
+
# We have a filename*= section. This MUST be ASCII, and any UTF-8
|
|
596
|
+
# bytes are %-quoted.
|
|
597
|
+
try:
|
|
598
|
+
# Once it is decoded, we can then unquote the %-encoded
|
|
599
|
+
# parts strictly into a unicode string.
|
|
600
|
+
upload_name = urllib.parse.unquote(
|
|
601
|
+
upload_name_utf8.decode("ascii"), errors="strict"
|
|
602
|
+
)
|
|
603
|
+
except UnicodeDecodeError:
|
|
604
|
+
# Incorrect UTF-8.
|
|
605
|
+
pass
|
|
606
|
+
|
|
607
|
+
# If there isn't check for an ascii name.
|
|
608
|
+
if not upload_name:
|
|
609
|
+
upload_name_ascii = params.get(b"filename", None)
|
|
610
|
+
if upload_name_ascii and is_ascii(upload_name_ascii):
|
|
611
|
+
upload_name = upload_name_ascii.decode("ascii")
|
|
612
|
+
|
|
613
|
+
# This may be None here, indicating we did not find a matching name.
|
|
614
|
+
return upload_name
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
def _parse_header(line: bytes) -> tuple[bytes, dict[bytes, bytes]]:
|
|
618
|
+
"""Parse a Content-type like header.
|
|
619
|
+
|
|
620
|
+
Cargo-culted from `cgi`, but works on bytes rather than strings.
|
|
621
|
+
|
|
622
|
+
Args:
|
|
623
|
+
line: header to be parsed
|
|
624
|
+
|
|
625
|
+
Returns:
|
|
626
|
+
The main content-type, followed by the parameter dictionary
|
|
627
|
+
"""
|
|
628
|
+
parts = _parseparam(b";" + line)
|
|
629
|
+
key = next(parts)
|
|
630
|
+
pdict = {}
|
|
631
|
+
for p in parts:
|
|
632
|
+
i = p.find(b"=")
|
|
633
|
+
if i >= 0:
|
|
634
|
+
name = p[:i].strip().lower()
|
|
635
|
+
value = p[i + 1 :].strip()
|
|
636
|
+
|
|
637
|
+
# strip double-quotes
|
|
638
|
+
if len(value) >= 2 and value[0:1] == value[-1:] == b'"':
|
|
639
|
+
value = value[1:-1]
|
|
640
|
+
value = value.replace(b"\\\\", b"\\").replace(b'\\"', b'"')
|
|
641
|
+
pdict[name] = value
|
|
642
|
+
|
|
643
|
+
return key, pdict
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
def _parseparam(s: bytes) -> Generator[bytes, None, None]:
|
|
647
|
+
"""Generator which splits the input on ;, respecting double-quoted sequences
|
|
648
|
+
|
|
649
|
+
Cargo-culted from `cgi`, but works on bytes rather than strings.
|
|
650
|
+
|
|
651
|
+
Args:
|
|
652
|
+
s: header to be parsed
|
|
653
|
+
|
|
654
|
+
Returns:
|
|
655
|
+
The split input
|
|
656
|
+
"""
|
|
657
|
+
while s[:1] == b";":
|
|
658
|
+
s = s[1:]
|
|
659
|
+
|
|
660
|
+
# look for the next ;
|
|
661
|
+
end = s.find(b";")
|
|
662
|
+
|
|
663
|
+
# if there is an odd number of " marks between here and the next ;, skip to the
|
|
664
|
+
# next ; instead
|
|
665
|
+
while end > 0 and (s.count(b'"', 0, end) - s.count(b'\\"', 0, end)) % 2:
|
|
666
|
+
end = s.find(b";", end + 1)
|
|
667
|
+
|
|
668
|
+
if end < 0:
|
|
669
|
+
end = len(s)
|
|
670
|
+
f = s[:end]
|
|
671
|
+
yield f.strip()
|
|
672
|
+
s = s[end:]
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
class ConsumerRequestedStopError(Exception):
|
|
676
|
+
"""A consumer asked us to stop producing"""
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
@implementer(interfaces.IPushProducer)
|
|
680
|
+
class ThreadedFileSender:
|
|
681
|
+
"""
|
|
682
|
+
A producer that sends the contents of a file to a consumer, reading from the
|
|
683
|
+
file on a thread.
|
|
684
|
+
|
|
685
|
+
This works by having a loop in a threadpool repeatedly reading from the
|
|
686
|
+
file, until the consumer pauses the producer. There is then a loop in the
|
|
687
|
+
main thread that waits until the consumer resumes the producer and then
|
|
688
|
+
starts reading in the threadpool again.
|
|
689
|
+
|
|
690
|
+
This is done to ensure that we're never waiting in the threadpool, as
|
|
691
|
+
otherwise its easy to starve it of threads.
|
|
692
|
+
"""
|
|
693
|
+
|
|
694
|
+
# How much data to read in one go.
|
|
695
|
+
CHUNK_SIZE = 2**14
|
|
696
|
+
|
|
697
|
+
# How long we wait for the consumer to be ready again before aborting the
|
|
698
|
+
# read.
|
|
699
|
+
TIMEOUT_SECONDS = 90.0
|
|
700
|
+
|
|
701
|
+
def __init__(self, hs: "HomeServer") -> None:
|
|
702
|
+
self.reactor = hs.get_reactor()
|
|
703
|
+
self.clock = hs.get_clock()
|
|
704
|
+
self.thread_pool = hs.get_media_sender_thread_pool()
|
|
705
|
+
|
|
706
|
+
self.file: Optional[BinaryIO] = None
|
|
707
|
+
self.deferred: "Deferred[None]" = Deferred()
|
|
708
|
+
self.consumer: Optional[interfaces.IConsumer] = None
|
|
709
|
+
|
|
710
|
+
# Signals if the thread should keep reading/sending data. Set means
|
|
711
|
+
# continue, clear means pause.
|
|
712
|
+
self.wakeup_event = DeferredEvent(self.clock)
|
|
713
|
+
|
|
714
|
+
# Signals if the thread should terminate, e.g. because the consumer has
|
|
715
|
+
# gone away.
|
|
716
|
+
self.stop_writing = False
|
|
717
|
+
|
|
718
|
+
def beginFileTransfer(
|
|
719
|
+
self, file: BinaryIO, consumer: interfaces.IConsumer
|
|
720
|
+
) -> "Deferred[None]":
|
|
721
|
+
"""
|
|
722
|
+
Begin transferring a file
|
|
723
|
+
"""
|
|
724
|
+
self.file = file
|
|
725
|
+
self.consumer = consumer
|
|
726
|
+
|
|
727
|
+
self.consumer.registerProducer(self, True)
|
|
728
|
+
|
|
729
|
+
# We set the wakeup signal as we should start producing immediately.
|
|
730
|
+
self.wakeup_event.set()
|
|
731
|
+
run_in_background(self.start_read_loop)
|
|
732
|
+
|
|
733
|
+
return make_deferred_yieldable(self.deferred)
|
|
734
|
+
|
|
735
|
+
def resumeProducing(self) -> None:
|
|
736
|
+
"""interfaces.IPushProducer"""
|
|
737
|
+
self.wakeup_event.set()
|
|
738
|
+
|
|
739
|
+
def pauseProducing(self) -> None:
|
|
740
|
+
"""interfaces.IPushProducer"""
|
|
741
|
+
self.wakeup_event.clear()
|
|
742
|
+
|
|
743
|
+
def stopProducing(self) -> None:
|
|
744
|
+
"""interfaces.IPushProducer"""
|
|
745
|
+
|
|
746
|
+
# Unregister the consumer so we don't try and interact with it again.
|
|
747
|
+
if self.consumer:
|
|
748
|
+
self.consumer.unregisterProducer()
|
|
749
|
+
|
|
750
|
+
self.consumer = None
|
|
751
|
+
|
|
752
|
+
# Terminate the loop.
|
|
753
|
+
self.stop_writing = True
|
|
754
|
+
self.wakeup_event.set()
|
|
755
|
+
|
|
756
|
+
if not self.deferred.called:
|
|
757
|
+
self.deferred.errback(
|
|
758
|
+
ConsumerRequestedStopError("Consumer asked us to stop producing")
|
|
759
|
+
)
|
|
760
|
+
|
|
761
|
+
async def start_read_loop(self) -> None:
|
|
762
|
+
"""This is the loop that drives reading/writing"""
|
|
763
|
+
try:
|
|
764
|
+
while not self.stop_writing:
|
|
765
|
+
# Start the loop in the threadpool to read data.
|
|
766
|
+
more_data = await defer_to_threadpool(
|
|
767
|
+
self.reactor, self.thread_pool, self._on_thread_read_loop
|
|
768
|
+
)
|
|
769
|
+
if not more_data:
|
|
770
|
+
# Reached EOF, we can just return.
|
|
771
|
+
return
|
|
772
|
+
|
|
773
|
+
if not self.wakeup_event.is_set():
|
|
774
|
+
ret = await self.wakeup_event.wait(self.TIMEOUT_SECONDS)
|
|
775
|
+
if not ret:
|
|
776
|
+
raise Exception("Timed out waiting to resume")
|
|
777
|
+
except Exception:
|
|
778
|
+
self._error(Failure())
|
|
779
|
+
finally:
|
|
780
|
+
self._finish()
|
|
781
|
+
|
|
782
|
+
def _on_thread_read_loop(self) -> bool:
|
|
783
|
+
"""This is the loop that happens on a thread.
|
|
784
|
+
|
|
785
|
+
Returns:
|
|
786
|
+
Whether there is more data to send.
|
|
787
|
+
"""
|
|
788
|
+
|
|
789
|
+
while not self.stop_writing and self.wakeup_event.is_set():
|
|
790
|
+
# The file should always have been set before we get here.
|
|
791
|
+
assert self.file is not None
|
|
792
|
+
|
|
793
|
+
chunk = self.file.read(self.CHUNK_SIZE)
|
|
794
|
+
if not chunk:
|
|
795
|
+
return False
|
|
796
|
+
|
|
797
|
+
self.reactor.callFromThread(self._write, chunk)
|
|
798
|
+
|
|
799
|
+
return True
|
|
800
|
+
|
|
801
|
+
def _write(self, chunk: bytes) -> None:
|
|
802
|
+
"""Called from the thread to write a chunk of data"""
|
|
803
|
+
if self.consumer:
|
|
804
|
+
self.consumer.write(chunk)
|
|
805
|
+
|
|
806
|
+
def _error(self, failure: Failure) -> None:
|
|
807
|
+
"""Called when there was a fatal error"""
|
|
808
|
+
if self.consumer:
|
|
809
|
+
self.consumer.unregisterProducer()
|
|
810
|
+
self.consumer = None
|
|
811
|
+
|
|
812
|
+
if not self.deferred.called:
|
|
813
|
+
self.deferred.errback(failure)
|
|
814
|
+
|
|
815
|
+
def _finish(self) -> None:
|
|
816
|
+
"""Called when we have finished writing (either on success or
|
|
817
|
+
failure)."""
|
|
818
|
+
if self.file:
|
|
819
|
+
self.file.close()
|
|
820
|
+
self.file = None
|
|
821
|
+
|
|
822
|
+
if self.consumer:
|
|
823
|
+
self.consumer.unregisterProducer()
|
|
824
|
+
self.consumer = None
|
|
825
|
+
|
|
826
|
+
if not self.deferred.called:
|
|
827
|
+
self.deferred.callback(None)
|