Compare commits
42 Commits
v0.3.1
...
code-dedupe
| Author | SHA1 | Date | |
|---|---|---|---|
| 00221db8fe | |||
| 65b3bc7c48 | |||
| 99d98efeb1 | |||
| 7b25ef2e6c | |||
| 1f8a7a707c | |||
| 86ec20e787 | |||
| 8c21388f01 | |||
| d657fa32e9 | |||
| 321e197d8c | |||
| 16a98b0683 | |||
| 9e1bbc1650 | |||
| 91ff6a36a4 | |||
| 56f1d8be1f | |||
| ed60f189cc | |||
| cabf4362be | |||
| 2472c7c47a | |||
| 136cb038cf | |||
| 8f89be0fbd | |||
| bbdced9c90 | |||
| a6f4dc2b74 | |||
| df203fa244 | |||
| c6e6eb0af3 | |||
| 29babebc4d | |||
| 2f3194840c | |||
| 0ebb323490 | |||
| f8e1255994 | |||
| b5c0c30a5e | |||
| ac4590952b | |||
| 67569cb9c8 | |||
| 11ec0dff4f | |||
| a198f0481a | |||
| 6266e0ab5e | |||
| 9ee1485960 | |||
| 05314ec46c | |||
| b66d2d44d0 | |||
| 3b2db9027a | |||
| 97e81885db | |||
| 706c1c993b | |||
| cb70d51e2b | |||
| bfb827a418 | |||
| e2fb588a8c | |||
| 43c4dfc5df |
+29
-16
@@ -14,10 +14,10 @@ on:
|
|||||||
- 'docs/**'
|
- 'docs/**'
|
||||||
- 'debian/**'
|
- 'debian/**'
|
||||||
- 'docker/**'
|
- 'docker/**'
|
||||||
- 'test_results/**'
|
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- dev
|
tags:
|
||||||
|
- '*'
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
@@ -48,6 +48,18 @@ jobs:
|
|||||||
- name: Sync repository
|
- name: Sync repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Tag comparison check
|
||||||
|
if: startsWith('refs/tags/v', github.ref)
|
||||||
|
run: |
|
||||||
|
# Tag mismatch with latest repo tag check to prevent potential downgrades
|
||||||
|
LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||||
|
|
||||||
|
if [ $LATEST_TAG != ${{ github.ref_name }} ]; then
|
||||||
|
echo '# WARNING: Attempting to run this workflow for a tag that is not the latest repo tag. Aborting.'
|
||||||
|
echo '# WARNING: Attempting to run this workflow for a tag that is not the latest repo tag. Aborting.' >> $GITHUB_STEP_SUMMARY
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: DeterminateSystems/nix-installer-action@main
|
uses: DeterminateSystems/nix-installer-action@main
|
||||||
|
|
||||||
@@ -138,7 +150,7 @@ jobs:
|
|||||||
name: Build
|
name: Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: tests
|
needs: tests
|
||||||
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'
|
if: startsWith('refs/tags/v', github.ref) || github.ref == 'refs/heads/main' || (github.event_name == 'pull_request' && github.event.pull_request.draft == false)
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
@@ -223,20 +235,21 @@ jobs:
|
|||||||
name: Docker publish
|
name: Docker publish
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') && github.event_name != 'pull_request'
|
if: startsWith('refs/tags/v', github.ref) || github.ref == 'refs/heads/main' || (github.event_name == 'pull_request' && github.event.pull_request.draft == false)
|
||||||
env:
|
env:
|
||||||
DOCKER_ARM64: docker.io/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}-arm64v8
|
DOCKER_ARM64: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||||
DOCKER_AMD64: docker.io/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}-amd64
|
DOCKER_AMD64: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||||
DOCKER_TAG: docker.io/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}
|
DOCKER_TAG: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}
|
||||||
DOCKER_BRANCH: docker.io/${{ github.repository }}:${{ (github.ref == 'refs/heads/main' && 'latest') || github.ref_name }}
|
DOCKER_BRANCH: docker.io/${{ github.repository }}:${{ (startsWith('refs/tags/v', github.ref) && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}
|
||||||
GHCR_ARM64: ghcr.io/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}-arm64v8
|
GHCR_ARM64: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||||
GHCR_AMD64: ghcr.io/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}-amd64
|
GHCR_AMD64: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||||
GHCR_TAG: ghcr.io/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}
|
GHCR_TAG: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}
|
||||||
GHCR_BRANCH: ghcr.io/${{ github.repository }}:${{ (github.ref == 'refs/heads/main' && 'latest') || github.ref_name }}
|
GHCR_BRANCH: ghcr.io/${{ github.repository }}:${{ (startsWith('refs/tags/v', github.ref) && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}
|
||||||
GLCR_ARM64: registry.gitlab.com/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}-arm64v8
|
GLCR_ARM64: registry.gitlab.com/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||||
GLCR_AMD64: registry.gitlab.com/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}-amd64
|
GLCR_AMD64: registry.gitlab.com/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||||
GLCR_TAG: registry.gitlab.com/${{ github.repository }}:${{ github.ref_name }}-${{ github.sha }}
|
GLCR_TAG: registry.gitlab.com/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}-${{ github.sha }}
|
||||||
GLCR_BRANCH: registry.gitlab.com/${{ github.repository }}:${{ (github.ref == 'refs/heads/main' && 'latest') || github.ref_name }}
|
GLCR_BRANCH: registry.gitlab.com/${{ github.repository }}:${{ (startsWith('refs/tags/v', github.ref) && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.head_ref)) || github.ref_name }}
|
||||||
|
|
||||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
|
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '00 12 * * *'
|
- cron: '00 12 * * *'
|
||||||
|
|
||||||
@@ -37,4 +39,4 @@ jobs:
|
|||||||
scan-type: fs
|
scan-type: fs
|
||||||
format: sarif
|
format: sarif
|
||||||
output: trivy-results.sarif
|
output: trivy-results.sarif
|
||||||
severity: CRITICAL,HIGH,MEDIUM,LOW
|
severity: CRITICAL,HIGH,MEDIUM,LOW
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# Local environment overrides
|
||||||
|
/.env
|
||||||
|
|
||||||
# CMake
|
# CMake
|
||||||
cmake-build-*/
|
cmake-build-*/
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
# Contributing guide
|
||||||
|
|
||||||
|
This page is for about contributing to conduwuit. The [development](docs/development.md) page may be of interest for you as well.
|
||||||
|
|
||||||
|
If you would like to work on an [issue][issues] that is not assigned, preferably ask in the Matrix room first at [#conduwuit:puppygock.gay][conduwuit-matrix], and comment on it.
|
||||||
|
|
||||||
|
### Linting and Formatting
|
||||||
|
|
||||||
|
It is mandatory all your changes satisfy the lints (clippy, rustc, rustdoc, etc) and your code is formatted via the **nightly** `cargo fmt`. A lot of the `rustfmt.toml` features depend on nightly toolchain. It would be ideal if they weren't nightly-exclusive features, but they currently still are. CI's rustfmt uses nightly.
|
||||||
|
|
||||||
|
If you need to allow a lint, please make sure it's either obvious as to why (e.g. clippy saying redundant clone but it's actually required) or it has a comment saying why. Do not write inefficient code for the sake of satisfying lints. If a lint is wrong and provides a more inefficient solution or suggestion, allow the lint and mention that in a comment.
|
||||||
|
|
||||||
|
### Running CI tests locally
|
||||||
|
|
||||||
|
conduwuit's CI for tests, linting, formatting, audit, etc use [`engage`][engage]. engage can be installed from nixpkgs or `cargo install engage`. conduwuit's Nix flake devshell has the nixpkgs engage with `direnv`. Use `engage --help` for more usage details.
|
||||||
|
|
||||||
|
To test, format, lint, etc that CI would do, install engage, allow the `.envrc` file using `direnv allow`, and run `engage`.
|
||||||
|
|
||||||
|
All of the tasks are defined at the [engage.toml][engage.toml] file. You can view all of them neatly by running `engage list`
|
||||||
|
|
||||||
|
If you would like to run only a specific engage task group, use `just`:
|
||||||
|
- `engage just <group>`
|
||||||
|
- Example: `engage just lints`
|
||||||
|
|
||||||
|
If you would like to run a specific engage task in a specific group, use `just <GROUP> [TASK]`: `engage just lints cargo-fmt`
|
||||||
|
|
||||||
|
The following binaries are used in [`engage.toml`][engage.toml]:
|
||||||
|
|
||||||
|
- [`engage`][engage]
|
||||||
|
- `nix`
|
||||||
|
- [`direnv`][direnv]
|
||||||
|
- `rustc`
|
||||||
|
- `cargo`
|
||||||
|
- `cargo-fmt`
|
||||||
|
- `rustdoc`
|
||||||
|
- `cargo-clippy`
|
||||||
|
- [`cargo-audit`][cargo-audit]
|
||||||
|
- [`cargo-deb`][cargo-deb]
|
||||||
|
- [`lychee`][lychee]
|
||||||
|
|
||||||
|
### Matrix tests
|
||||||
|
|
||||||
|
CI runs [Complement][complement], but currently does not fail if results from the checked-in results differ with the new results. If your changes are done to fix Matrix tests, note that in your pull request. If more Complement tests start failing from your changes, please review the logs (they are uploaded as artifacts) and determine if they're intended or not.
|
||||||
|
|
||||||
|
If you'd like to run Complement locally using Nix, see the [testing](docs/development/testing.md) page.
|
||||||
|
|
||||||
|
[Sytest][sytest] support will come soon.
|
||||||
|
|
||||||
|
### Writing documentation
|
||||||
|
|
||||||
|
conduwuit's website uses [`mdbook`][mdbook] and deployed via CI using GitHub Pages in the [`documentation.yml`][documentation.yml] workflow file with Nix's mdbook in the devshell. All documentation is in the `docs/` directory at the top level. The compiled mdbook website is also uploaded as an artifact.
|
||||||
|
|
||||||
|
To build the documentation using Nix, run: `bin/nix-build-and-cache just .#book`
|
||||||
|
|
||||||
|
### Inclusivity and Diversity
|
||||||
|
|
||||||
|
All **MUST** code and write with inclusivity and diversity in mind. See the [following page by Google on writing inclusive code and documentation](https://developers.google.com/style/inclusive-documentation).
|
||||||
|
|
||||||
|
This **EXPLICITLY** forbids usage of terms like "blacklist"/"whitelist" and "master"/"slave", [forbids gender-specific words and phrases](https://developers.google.com/style/pronouns#gender-neutral-pronouns), forbids ableist language like "sanity-check", "cripple", or "insane", and forbids culture-specific language (e.g. US-only holidays or cultures).
|
||||||
|
|
||||||
|
No exceptions are allowed. Dependencies that may use these terms are allowed but [do not replicate the name in your functions or variables](https://developers.google.com/style/inclusive-documentation#write-around).
|
||||||
|
|
||||||
|
In addition to language, write and code with the user experience in mind. This is software that intends to be used by everyone, so make it easy and comfortable for everyone to use. 🏳️⚧️
|
||||||
|
|
||||||
|
### Variable, comment, function, etc standards
|
||||||
|
|
||||||
|
Rust's default style and standards with regards to [function names, variable names, comments](https://rust-lang.github.io/api-guidelines/naming.html), etc applies here.
|
||||||
|
|
||||||
|
### Creating pull requests
|
||||||
|
|
||||||
|
Please try to keep contributions to the GitHub. While the mirrors of conduwuit allow for pull/merge requests, there is no guarantee I will see them in a timely manner.
|
||||||
|
|
||||||
|
If you open a pull request on one of the mirrors, it is your responsibility to inform me about its existence. In the future I may try to solve this with more repo bots in the conduwuit Matrix room. There is no mailing list or email-patch support on the sr.ht mirror, but if you'd like to email me a git patch you can do so at `strawberry@puppygock.gay`.
|
||||||
|
|
||||||
|
Direct all PRs/MRs to the `main` branch.
|
||||||
|
|
||||||
|
By sending a pull request or patch, you are agreeing that your changes are allowed to be licenced under the Apache-2.0 licence and all of your conduct is in line with the Contributor's Covenant.
|
||||||
|
|
||||||
|
[issues]: https://github.com/girlbossceo/conduwuit/issues
|
||||||
|
[conduwuit-matrix]: https://matrix.to/#/#conduwuit:puppygock.gay
|
||||||
|
[complement]: https://github.com/matrix-org/complement/
|
||||||
|
[engage.toml]: https://github.com/girlbossceo/conduwuit/blob/main/engage.toml
|
||||||
|
[engage]: https://charles.page.computer.surgery/engage/
|
||||||
|
[sytest]: https://github.com/matrix-org/sytest/
|
||||||
|
[cargo-deb]: https://github.com/kornelski/cargo-deb
|
||||||
|
[lychee]: https://github.com/lycheeverse/lychee
|
||||||
|
[cargo-audit]: https://github.com/RustSec/rustsec/tree/main/cargo-audit
|
||||||
|
[direnv]: https://direnv.net/
|
||||||
|
[mdbook]: https://rust-lang.github.io/mdBook/
|
||||||
|
[documentation.yml]: https://github.com/girlbossceo/conduwuit/blob/main/.github/workflows/documentation.yml
|
||||||
Generated
+84
-66
@@ -61,15 +61,15 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstyle"
|
name = "anstyle"
|
||||||
version = "1.0.6"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.82"
|
version = "1.0.83"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
|
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arc-swap"
|
name = "arc-swap"
|
||||||
@@ -161,9 +161,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.2.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
@@ -472,9 +472,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.96"
|
version = "1.0.97"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd"
|
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -568,7 +568,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conduit"
|
name = "conduit"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argon2",
|
"argon2",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -1090,9 +1090,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.14"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@@ -1357,16 +1357,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "html5ever"
|
name = "html5ever"
|
||||||
version = "0.26.0"
|
version = "0.27.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7"
|
checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"mac",
|
"mac",
|
||||||
"markup5ever",
|
"markup5ever",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 2.0.60",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1885,9 +1885,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markup5ever"
|
name = "markup5ever"
|
||||||
version = "0.11.0"
|
version = "0.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016"
|
checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"phf",
|
"phf",
|
||||||
@@ -1899,9 +1899,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markup5ever_rcdom"
|
name = "markup5ever_rcdom"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9521dd6750f8e80ee6c53d65e2e4656d7de37064f3a7a5d2d11d05df93839c2"
|
checksum = "edaa21ab3701bfee5099ade5f7e1f84553fd19228cf332f13cd6e964bf59be18"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"html5ever",
|
"html5ever",
|
||||||
"markup5ever",
|
"markup5ever",
|
||||||
@@ -2092,9 +2092,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-iter"
|
name = "num-iter"
|
||||||
version = "0.1.44"
|
version = "0.1.45"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
|
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
@@ -2115,9 +2115,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.18"
|
version = "0.2.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
@@ -2332,21 +2332,21 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf"
|
name = "phf"
|
||||||
version = "0.10.1"
|
version = "0.11.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
|
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_shared",
|
"phf_shared 0.11.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf_codegen"
|
name = "phf_codegen"
|
||||||
version = "0.10.0"
|
version = "0.11.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
|
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_generator",
|
"phf_generator 0.11.2",
|
||||||
"phf_shared",
|
"phf_shared 0.11.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2355,7 +2355,17 @@ version = "0.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
|
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_shared",
|
"phf_shared 0.10.0",
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared 0.11.2",
|
||||||
"rand",
|
"rand",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2368,6 +2378,15 @@ dependencies = [
|
|||||||
"siphasher",
|
"siphasher",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.5"
|
version = "1.1.5"
|
||||||
@@ -2698,7 +2717,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma"
|
name = "ruma"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assign",
|
"assign",
|
||||||
"js_int",
|
"js_int",
|
||||||
@@ -2718,7 +2737,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-appservice-api"
|
name = "ruma-appservice-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -2730,7 +2749,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-client-api"
|
name = "ruma-client-api"
|
||||||
version = "0.17.4"
|
version = "0.17.4"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"assign",
|
"assign",
|
||||||
@@ -2752,7 +2771,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-common"
|
name = "ruma-common"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
@@ -2782,7 +2801,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-events"
|
name = "ruma-events"
|
||||||
version = "0.27.11"
|
version = "0.27.11"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"indexmap 2.2.6",
|
"indexmap 2.2.6",
|
||||||
@@ -2804,7 +2823,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-federation-api"
|
name = "ruma-federation-api"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -2816,7 +2835,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers-validation"
|
name = "ruma-identifiers-validation"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -2825,7 +2844,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identity-service-api"
|
name = "ruma-identity-service-api"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -2835,7 +2854,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-macros"
|
name = "ruma-macros"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
@@ -2850,7 +2869,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-push-gateway-api"
|
name = "ruma-push-gateway-api"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -2862,7 +2881,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-signatures"
|
name = "ruma-signatures"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
@@ -2878,7 +2897,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-state-res"
|
name = "ruma-state-res"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#1c291e18efd0559c2dd76b27d555c86471cbb0fd"
|
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#e6e8462c050296c1ee4911f1c0e66112fb7c4986"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"js_int",
|
"js_int",
|
||||||
@@ -2906,7 +2925,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-librocksdb-sys"
|
name = "rust-librocksdb-sys"
|
||||||
version = "0.21.0+9.1.1"
|
version = "0.21.0+9.1.1"
|
||||||
source = "git+https://github.com/zaidoon1/rust-rocksdb?branch=master#c5cd6bd25152ef1f8a488761351da0c3d29ed93a"
|
source = "git+https://github.com/zaidoon1/rust-rocksdb?branch=master#567825463480b75f733b73f01c1bd05990aea5b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"bzip2-sys",
|
"bzip2-sys",
|
||||||
@@ -2923,7 +2942,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-rocksdb"
|
name = "rust-rocksdb"
|
||||||
version = "0.25.0"
|
version = "0.25.0"
|
||||||
source = "git+https://github.com/zaidoon1/rust-rocksdb?branch=master#c5cd6bd25152ef1f8a488761351da0c3d29ed93a"
|
source = "git+https://github.com/zaidoon1/rust-rocksdb?branch=master#567825463480b75f733b73f01c1bd05990aea5b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rust-librocksdb-sys",
|
"rust-librocksdb-sys",
|
||||||
@@ -3080,11 +3099,11 @@ checksum = "621e3680f3e07db4c9c2c3fb07c6223ab2fab2e54bd3c04c3ae037990f428c32"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.10.0"
|
version = "2.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
|
checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 2.5.0",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -3093,9 +3112,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework-sys"
|
name = "security-framework-sys"
|
||||||
version = "2.10.0"
|
version = "2.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
|
checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -3480,7 +3499,7 @@ dependencies = [
|
|||||||
"new_debug_unreachable",
|
"new_debug_unreachable",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"phf_shared",
|
"phf_shared 0.10.0",
|
||||||
"precomputed-hash",
|
"precomputed-hash",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@@ -3491,8 +3510,8 @@ version = "0.5.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
|
checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_generator",
|
"phf_generator 0.10.0",
|
||||||
"phf_shared",
|
"phf_shared 0.10.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
@@ -3772,16 +3791,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.10"
|
version = "0.7.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
|
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3826,7 +3844,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow 0.6.7",
|
"winnow 0.6.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4277,9 +4295,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpage"
|
name = "webpage"
|
||||||
version = "2.0.0"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fb86b12e58d490a99867f561ce8466ffa7b73e24d015a8e7f5bc111d4424ba2"
|
checksum = "70862efc041d46e6bbaa82bb9c34ae0596d090e86cbd14bd9e93b36ee6802eac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"html5ever",
|
"html5ever",
|
||||||
"markup5ever_rcdom",
|
"markup5ever_rcdom",
|
||||||
@@ -4520,9 +4538,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.6.7"
|
version = "0.6.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578"
|
checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@@ -4549,9 +4567,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xml5ever"
|
name = "xml5ever"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4034e1d05af98b51ad7214527730626f019682d797ba38b51689212118d8e650"
|
checksum = "7c376f76ed09df711203e20c3ef5ce556f0166fa03d39590016c0fd625437fad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"mac",
|
"mac",
|
||||||
@@ -4566,18 +4584,18 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.32"
|
version = "0.7.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
|
checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.7.32"
|
version = "0.7.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
checksum = "6f4b6c273f496d8fd4eaf18853e6b448760225dc030ff2c485a786859aea6393"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|||||||
+23
-19
@@ -10,11 +10,11 @@ authors = [
|
|||||||
homepage = "https://conduwuit.puppyirl.gay/"
|
homepage = "https://conduwuit.puppyirl.gay/"
|
||||||
repository = "https://github.com/girlbossceo/conduwuit"
|
repository = "https://github.com/girlbossceo/conduwuit"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See also `rust-toolchain.toml`
|
# See also `rust-toolchain.toml`
|
||||||
rust-version = "1.76.0"
|
rust-version = "1.77.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
console-subscriber = { version = "0.2", optional = true }
|
console-subscriber = { version = "0.2", optional = true }
|
||||||
@@ -362,44 +362,45 @@ default = [
|
|||||||
"brotli_compression",
|
"brotli_compression",
|
||||||
"zstd_compression",
|
"zstd_compression",
|
||||||
"release_max_log_level",
|
"release_max_log_level",
|
||||||
|
"io_uring",
|
||||||
]
|
]
|
||||||
backend_sqlite = ["sqlite"]
|
backend_sqlite = ["sqlite"]
|
||||||
backend_rocksdb = ["rocksdb"]
|
backend_rocksdb = ["rocksdb"]
|
||||||
rocksdb = ["rust-rocksdb"]
|
rocksdb = ["dep:rust-rocksdb"]
|
||||||
jemalloc = [
|
jemalloc = [
|
||||||
"tikv-jemalloc-sys",
|
"dep:tikv-jemalloc-sys",
|
||||||
"tikv-jemalloc-ctl",
|
"dep:tikv-jemalloc-ctl",
|
||||||
"tikv-jemallocator",
|
"dep:tikv-jemallocator",
|
||||||
"rust-rocksdb/jemalloc",
|
"rust-rocksdb/jemalloc",
|
||||||
]
|
]
|
||||||
jemalloc_prof = ["tikv-jemalloc-sys/profiling"]
|
jemalloc_prof = ["tikv-jemalloc-sys/profiling"]
|
||||||
sqlite = ["rusqlite", "parking_lot", "thread_local"]
|
sqlite = ["dep:rusqlite", "dep:parking_lot", "dep:thread_local"]
|
||||||
systemd = ["sd-notify"]
|
systemd = ["dep:sd-notify"]
|
||||||
sentry_telemetry = ["sentry", "sentry-tracing", "sentry-tower"]
|
sentry_telemetry = ["dep:sentry", "dep:sentry-tracing", "dep:sentry-tower"]
|
||||||
|
|
||||||
gzip_compression = ["tower-http/compression-gzip", "reqwest/gzip"]
|
gzip_compression = ["tower-http/compression-gzip", "reqwest/gzip"]
|
||||||
zstd_compression = ["tower-http/compression-zstd"]
|
zstd_compression = ["tower-http/compression-zstd"]
|
||||||
brotli_compression = ["tower-http/compression-br", "reqwest/brotli"]
|
brotli_compression = ["tower-http/compression-br", "reqwest/brotli"]
|
||||||
|
|
||||||
sha256_media = ["sha2"]
|
sha256_media = ["dep:sha2"]
|
||||||
io_uring = ["rust-rocksdb/io-uring"]
|
io_uring = ["rust-rocksdb/io-uring"]
|
||||||
axum_dual_protocol = ["axum-server-dual-protocol"]
|
axum_dual_protocol = ["dep:axum-server-dual-protocol"]
|
||||||
|
|
||||||
perf_measurements = [
|
perf_measurements = [
|
||||||
"opentelemetry",
|
"dep:opentelemetry",
|
||||||
"tracing-flame",
|
"dep:tracing-flame",
|
||||||
"tracing-opentelemetry",
|
"dep:tracing-opentelemetry",
|
||||||
"opentelemetry_sdk",
|
"dep:opentelemetry_sdk",
|
||||||
"opentelemetry-jaeger",
|
"dep:opentelemetry-jaeger",
|
||||||
]
|
]
|
||||||
|
|
||||||
# enable the tokio_console server
|
# enable the tokio_console server
|
||||||
# incompatible with release_max_log_level
|
# incompatible with release_max_log_level
|
||||||
tokio_console = ["console-subscriber", "tokio/tracing"]
|
tokio_console = ["dep:console-subscriber", "tokio/tracing"]
|
||||||
|
|
||||||
hot_reload = ["dep:hot-lib-reloader"]
|
hot_reload = ["dep:hot-lib-reloader"]
|
||||||
|
|
||||||
hardened_malloc = ["hardened_malloc-rs"]
|
hardened_malloc = ["dep:hardened_malloc-rs"]
|
||||||
|
|
||||||
# increases performance, reduces build times, and reduces binary size by not compiling or
|
# increases performance, reduces build times, and reduces binary size by not compiling or
|
||||||
# genreating code for log level filters that users will generally not use (debug and trace) only in release builds
|
# genreating code for log level filters that users will generally not use (debug and trace) only in release builds
|
||||||
@@ -459,9 +460,11 @@ systemd-units = { unit-name = "conduwuit" }
|
|||||||
|
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
#debug = 0
|
||||||
lto = 'off'
|
lto = 'off'
|
||||||
codegen-units = 512
|
codegen-units = 512
|
||||||
incremental = true
|
incremental = true
|
||||||
|
overflow-checks = true
|
||||||
#panic = "abort"
|
#panic = "abort"
|
||||||
|
|
||||||
# seems to speed up continuous debug compilations
|
# seems to speed up continuous debug compilations
|
||||||
@@ -622,6 +625,8 @@ manual_let_else = "warn"
|
|||||||
trivially_copy_pass_by_ref = "warn"
|
trivially_copy_pass_by_ref = "warn"
|
||||||
wildcard_imports = "warn"
|
wildcard_imports = "warn"
|
||||||
checked_conversions = "warn"
|
checked_conversions = "warn"
|
||||||
|
#integer_arithmetic = "warn"
|
||||||
|
#as_conversions = "warn"
|
||||||
|
|
||||||
# some sadness
|
# some sadness
|
||||||
missing_errors_doc = "allow"
|
missing_errors_doc = "allow"
|
||||||
@@ -642,7 +647,6 @@ map_err_ignore = "allow"
|
|||||||
missing_docs_in_private_items = "allow"
|
missing_docs_in_private_items = "allow"
|
||||||
multiple_inherent_impl = "allow"
|
multiple_inherent_impl = "allow"
|
||||||
error_impl_error = "allow"
|
error_impl_error = "allow"
|
||||||
as_conversions = "allow"
|
|
||||||
string_add = "allow"
|
string_add = "allow"
|
||||||
string_slice = "allow"
|
string_slice = "allow"
|
||||||
ref_patterns = "allow"
|
ref_patterns = "allow"
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
`main` / stable: [](https://github.com/girlbossceo/conduwuit/actions/workflows/ci.yml)
|
`main` / stable: [](https://github.com/girlbossceo/conduwuit/actions/workflows/ci.yml)
|
||||||
|
|
||||||
`dev`: [](https://github.com/girlbossceo/conduwuit/actions/workflows/ci.yml)
|
|
||||||
|
|
||||||
<!-- ANCHOR: catchphrase -->
|
<!-- ANCHOR: catchphrase -->
|
||||||
### a very cool, featureful fork of [Conduit](https://conduit.rs/)
|
### a very cool, featureful fork of [Conduit](https://conduit.rs/)
|
||||||
<!-- ANCHOR_END: catchphrase -->
|
<!-- ANCHOR_END: catchphrase -->
|
||||||
@@ -37,14 +35,6 @@ from time to time.
|
|||||||
<!-- ANCHOR_END: body -->
|
<!-- ANCHOR_END: body -->
|
||||||
|
|
||||||
<!-- ANCHOR: footer -->
|
<!-- ANCHOR: footer -->
|
||||||
#### How can I contribute?
|
|
||||||
|
|
||||||
1. Look for an issue you would like to work on and make sure it's not assigned
|
|
||||||
to other users
|
|
||||||
2. Ask someone to assign the issue to you (comment on the issue or chat in
|
|
||||||
[#conduwuit:puppygock.gay](https://matrix.to/#/#conduwuit:puppygock.gay))
|
|
||||||
3. Fork the repo and work on the issue.
|
|
||||||
4. Submit a PR (please keep contributions to the GitHub repo, main development is done here, not the GitLab repo which exists just as a mirror. If you are avoiding GitHub, feel free to join our Matrix chat to get your patch in.)
|
|
||||||
|
|
||||||
#### Contact
|
#### Contact
|
||||||
|
|
||||||
|
|||||||
+3
-6
@@ -20,12 +20,9 @@ OCI_IMAGE="complement-conduit:dev"
|
|||||||
toplevel="$(git rev-parse --show-toplevel)"
|
toplevel="$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
pushd "$toplevel" > /dev/null
|
pushd "$toplevel" > /dev/null
|
||||||
# uses nix-output-monitor (nom) if available
|
|
||||||
if command -v nom &> /dev/null; then
|
bin/nix-build-and-cache just .#complement
|
||||||
nom build .#complement
|
|
||||||
else
|
|
||||||
nix build -L .#complement
|
|
||||||
fi
|
|
||||||
docker load < result
|
docker load < result
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
|
|
||||||
|
|||||||
+47
-33
@@ -13,41 +13,55 @@ just() {
|
|||||||
nix build -L "$@"
|
nix build -L "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -z "$ATTIC_TOKEN" ]; then
|
if [ -z "$ATTIC_TOKEN" ]; then
|
||||||
# historical "conduit" store for compatibility purposes, same as conduwuit
|
|
||||||
nix run --inputs-from "$toplevel" attic -- \
|
|
||||||
login \
|
|
||||||
conduit \
|
|
||||||
"${ATTIC_ENDPOINT:-https://attic.kennel.juneis.dog/conduit}" \
|
|
||||||
"$ATTIC_TOKEN"
|
|
||||||
|
|
||||||
readarray -t outputs < <(nix path-info "$@")
|
|
||||||
readarray -t derivations < <(nix path-info "$@" --derivation)
|
|
||||||
|
|
||||||
# Push the target installable and its build dependencies
|
|
||||||
nix run --inputs-from "$toplevel" attic -- \
|
|
||||||
push \
|
|
||||||
conduit \
|
|
||||||
"${outputs[@]}" \
|
|
||||||
"${derivations[@]}"
|
|
||||||
|
|
||||||
# main "conduwuit" store
|
|
||||||
nix run --inputs-from "$toplevel" attic -- \
|
|
||||||
login \
|
|
||||||
conduwuit \
|
|
||||||
"${ATTIC_ENDPOINT:-https://attic.kennel.juneis.dog/conduwuit}" \
|
|
||||||
"$ATTIC_TOKEN"
|
|
||||||
|
|
||||||
# Push the target installable and its build dependencies
|
|
||||||
nix run --inputs-from "$toplevel" attic -- \
|
|
||||||
push \
|
|
||||||
conduwuit \
|
|
||||||
"${outputs[@]}" \
|
|
||||||
"${derivations[@]}"
|
|
||||||
else
|
|
||||||
echo "\$ATTIC_TOKEN is unset, skipping uploading to the binary cache"
|
echo "\$ATTIC_TOKEN is unset, skipping uploading to the binary cache"
|
||||||
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# historical "conduit" store for compatibility purposes, same as conduwuit
|
||||||
|
nix run --inputs-from "$toplevel" attic -- \
|
||||||
|
login \
|
||||||
|
conduit \
|
||||||
|
"${ATTIC_ENDPOINT:-https://attic.kennel.juneis.dog/conduit}" \
|
||||||
|
"$ATTIC_TOKEN"
|
||||||
|
|
||||||
|
# Find all output paths of the installables and their build dependencies
|
||||||
|
readarray -t derivations < <(nix path-info --derivation "$@")
|
||||||
|
cache=()
|
||||||
|
for derivation in "${derivations[@]}"; do
|
||||||
|
cache+=(
|
||||||
|
"$(nix-store --query --requisites --include-outputs "$derivation")"
|
||||||
|
)
|
||||||
|
done
|
||||||
|
|
||||||
|
# Upload them to Attic (conduit store)
|
||||||
|
#
|
||||||
|
# Use `xargs` and a here-string because something would probably explode if
|
||||||
|
# several thousand arguments got passed to a command at once. Hopefully no
|
||||||
|
# store paths include a newline in them.
|
||||||
|
(
|
||||||
|
IFS=$'\n'
|
||||||
|
nix shell --inputs-from "$toplevel" attic -c xargs \
|
||||||
|
attic push conduit <<< "${cache[*]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# main "conduwuit" store
|
||||||
|
nix run --inputs-from "$toplevel" attic -- \
|
||||||
|
login \
|
||||||
|
conduwuit \
|
||||||
|
"${ATTIC_ENDPOINT:-https://attic.kennel.juneis.dog/conduwuit}" \
|
||||||
|
"$ATTIC_TOKEN"
|
||||||
|
|
||||||
|
# Upload them to Attic (conduwuit store)
|
||||||
|
#
|
||||||
|
# Use `xargs` and a here-string because something would probably explode if
|
||||||
|
# several thousand arguments got passed to a command at once. Hopefully no
|
||||||
|
# store paths include a newline in them.
|
||||||
|
(
|
||||||
|
IFS=$'\n'
|
||||||
|
nix shell --inputs-from "$toplevel" attic -c xargs \
|
||||||
|
attic push conduwuit <<< "${cache[*]}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build and cache things needed for CI
|
# Build and cache things needed for CI
|
||||||
@@ -56,7 +70,7 @@ ci() {
|
|||||||
--inputs-from "$toplevel"
|
--inputs-from "$toplevel"
|
||||||
|
|
||||||
# Keep sorted
|
# Keep sorted
|
||||||
"$toplevel#devShells.x86_64-linux.default.inputDerivation"
|
"$toplevel#devShells.x86_64-linux.default"
|
||||||
attic#default
|
attic#default
|
||||||
nixpkgs#direnv
|
nixpkgs#direnv
|
||||||
nixpkgs#jq
|
nixpkgs#jq
|
||||||
|
|||||||
@@ -13,3 +13,4 @@
|
|||||||
- [Appservices](appservices.md)
|
- [Appservices](appservices.md)
|
||||||
- [Development](development.md)
|
- [Development](development.md)
|
||||||
- [Testing](development/testing.md)
|
- [Testing](development/testing.md)
|
||||||
|
- [Contributing](contributing.md)
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{{#include ../CONTRIBUTING.md}}
|
||||||
@@ -17,17 +17,12 @@ OCI images for conduwuit are available in the registries listed below.
|
|||||||
| GitHub Registry | [ghcr.io/girlbossceo/conduwuit:main][gh] | ![Image Size][shield-main] | Stable main branch. |
|
| GitHub Registry | [ghcr.io/girlbossceo/conduwuit:main][gh] | ![Image Size][shield-main] | Stable main branch. |
|
||||||
| GitLab Registry | [registry.gitlab.com/girlbossceo/conduwuit:main][gl] | ![Image Size][shield-main] | Stable main branch. |
|
| GitLab Registry | [registry.gitlab.com/girlbossceo/conduwuit:main][gl] | ![Image Size][shield-main] | Stable main branch. |
|
||||||
| Docker Hub | [docker.io/girlbossceo/conduwuit:main][dh] | ![Image Size][shield-main] | Stable main branch. |
|
| Docker Hub | [docker.io/girlbossceo/conduwuit:main][dh] | ![Image Size][shield-main] | Stable main branch. |
|
||||||
| GitHub Registry | [ghcr.io/girlbossceo/conduwuit:dev][gh] | ![Image Size][shield-dev] | Development version/branch. |
|
|
||||||
| GitLab Registry | [registry.gitlab.com/girlbossceo/conduwuit:dev][gl] | ![Image Size][shield-dev] | Development version/branch. |
|
|
||||||
| Docker Hub | [docker.io/girlbossceo/conduwuit:dev][dh] | ![Image Size][shield-dev] | Development version/branch. |
|
|
||||||
|
|
||||||
|
|
||||||
[dh]: https://hub.docker.com/repository/docker/girlbossceo/conduwuit
|
[dh]: https://hub.docker.com/repository/docker/girlbossceo/conduwuit
|
||||||
[gh]: https://github.com/girlbossceo/conduwuit/pkgs/container/conduwuit
|
[gh]: https://github.com/girlbossceo/conduwuit/pkgs/container/conduwuit
|
||||||
[gl]: https://gitlab.com/girlbossceo/conduwuit/container_registry/6351657
|
[gl]: https://gitlab.com/girlbossceo/conduwuit/container_registry/6351657
|
||||||
[shield-latest]: https://img.shields.io/docker/image-size/girlbossceo/conduwuit/latest
|
[shield-latest]: https://img.shields.io/docker/image-size/girlbossceo/conduwuit/latest
|
||||||
[shield-main]: https://img.shields.io/docker/image-size/girlbossceo/conduwuit/main
|
[shield-main]: https://img.shields.io/docker/image-size/girlbossceo/conduwuit/main
|
||||||
[shield-dev]: https://img.shields.io/docker/image-size/girlbossceo/conduwuit/dev
|
|
||||||
|
|
||||||
|
|
||||||
Use
|
Use
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,8 @@
|
|||||||
# Development
|
# Development
|
||||||
|
|
||||||
Information about developing the project. If you are only interested in using
|
Information about developing the project. If you are only interested in using
|
||||||
it, you can safely ignore this section.
|
it, you can safely ignore this section. If you plan on contributing, see the
|
||||||
|
[contributor's guide](contributing.md).
|
||||||
|
|
||||||
## Debugging with `tokio-console`
|
## Debugging with `tokio-console`
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#### What's different about your fork than upstream Conduit?
|
#### What's different about your fork than upstream Conduit?
|
||||||
|
|
||||||
See [differences.md](differences.md)
|
See the [differences](differences.md) page
|
||||||
|
|
||||||
#### How can I deploy my own?
|
#### How can I deploy my own?
|
||||||
|
|
||||||
@@ -14,4 +14,8 @@ See [differences.md](differences.md)
|
|||||||
|
|
||||||
If you want to connect an Appservice to Conduwuit, take a look at the [appservices documentation](appservices.md).
|
If you want to connect an Appservice to Conduwuit, take a look at the [appservices documentation](appservices.md).
|
||||||
|
|
||||||
|
#### How can I contribute?
|
||||||
|
|
||||||
|
See the [contributor's guide](contributing.md)
|
||||||
|
|
||||||
{{#include ../README.md:footer}}
|
{{#include ../README.md:footer}}
|
||||||
|
|||||||
+1
-1
@@ -131,7 +131,7 @@ cargo clippy \
|
|||||||
[[task]]
|
[[task]]
|
||||||
name = "lychee"
|
name = "lychee"
|
||||||
group = "lints"
|
group = "lints"
|
||||||
script = "lychee --offline docs"
|
script = "lychee --verbose --offline docs *.md"
|
||||||
|
|
||||||
[[task]]
|
[[task]]
|
||||||
name = "cargo"
|
name = "cargo"
|
||||||
|
|||||||
Generated
+5
-5
@@ -238,15 +238,15 @@
|
|||||||
"rocksdb": {
|
"rocksdb": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1713810944,
|
"lastModified": 1714770052,
|
||||||
"narHash": "sha256-/Xf0bzNJPclH9IP80QNaABfhj4IAR5LycYET18VFCXc=",
|
"narHash": "sha256-NCPYF2wYBsB9OHEkZSOYoPlxjC9BBMhJp8EM5M1o3Mc=",
|
||||||
"owner": "facebook",
|
"owner": "girlbossceo",
|
||||||
"repo": "rocksdb",
|
"repo": "rocksdb",
|
||||||
"rev": "6f7cabeac80a3a6150be2c8a8369fcecb107bf43",
|
"rev": "db6df0b185774778457dabfcbd822cb81760cade",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "facebook",
|
"owner": "girlbossceo",
|
||||||
"ref": "v9.1.1",
|
"ref": "v9.1.1",
|
||||||
"repo": "rocksdb",
|
"repo": "rocksdb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
flake-utils.url = "github:numtide/flake-utils?ref=main";
|
flake-utils.url = "github:numtide/flake-utils?ref=main";
|
||||||
nix-filter.url = "github:numtide/nix-filter?ref=main";
|
nix-filter.url = "github:numtide/nix-filter?ref=main";
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable";
|
||||||
rocksdb = { url = "github:facebook/rocksdb?ref=v9.1.1"; flake = false; };
|
# https://github.com/girlbossceo/rocksdb/commit/db6df0b185774778457dabfcbd822cb81760cade
|
||||||
|
rocksdb = { url = "github:girlbossceo/rocksdb?ref=v9.1.1"; flake = false; };
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs:
|
outputs = inputs:
|
||||||
@@ -21,7 +22,7 @@
|
|||||||
file = ./rust-toolchain.toml;
|
file = ./rust-toolchain.toml;
|
||||||
|
|
||||||
# See also `rust-toolchain.toml`
|
# See also `rust-toolchain.toml`
|
||||||
sha256 = "sha256-e4mlaJehWBymYxJGgnbuCObVlqMlQSilZ8FljG9zPHY=";
|
sha256 = "sha256-+syqAd2kX8KVa8/U2gz3blIQTTsYYt3U63xBWaGOSc8";
|
||||||
};
|
};
|
||||||
|
|
||||||
scope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: {
|
scope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: {
|
||||||
@@ -179,6 +180,10 @@
|
|||||||
# Useful for editing the book locally
|
# Useful for editing the book locally
|
||||||
mdbook
|
mdbook
|
||||||
])
|
])
|
||||||
|
++ (if !pkgsHost.stdenv.isDarwin then [
|
||||||
|
# Needed for building with io_uring
|
||||||
|
pkgsHost.liburing
|
||||||
|
] else [])
|
||||||
++
|
++
|
||||||
scopeHost.main.nativeBuildInputs;
|
scopeHost.main.nativeBuildInputs;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ buildDepsOnlyEnv =
|
|||||||
});
|
});
|
||||||
|
|
||||||
buildPackageEnv = {
|
buildPackageEnv = {
|
||||||
CONDUWUIT_VERSION_EXTRA = inputs.self.shortRev or inputs.self.dirtyShortRev;
|
CONDUWUIT_VERSION_EXTRA = inputs.self.shortRev or inputs.self.dirtyShortRev or "";
|
||||||
} // buildDepsOnlyEnv;
|
} // buildDepsOnlyEnv;
|
||||||
|
|
||||||
commonAttrs = {
|
commonAttrs = {
|
||||||
@@ -83,9 +83,15 @@ craneLib.buildPackage ( commonAttrs // {
|
|||||||
(features != [])
|
(features != [])
|
||||||
"--features " + (builtins.concatStringsSep "," features);
|
"--features " + (builtins.concatStringsSep "," features);
|
||||||
|
|
||||||
|
# This is redundant with CI
|
||||||
|
cargoTestCommand = "";
|
||||||
|
|
||||||
# This is redundant with CI
|
# This is redundant with CI
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
|
|
||||||
|
# https://crane.dev/faq/rebuilds-bindgen.html
|
||||||
|
NIX_OUTPATH_USED_AS_RANDOM_SEED = "aaaaaaaaaa";
|
||||||
|
|
||||||
env = buildPackageEnv;
|
env = buildPackageEnv;
|
||||||
|
|
||||||
passthru = {
|
passthru = {
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
# If you're having trouble making the relevant changes, bug a maintainer.
|
# If you're having trouble making the relevant changes, bug a maintainer.
|
||||||
|
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "1.76.0"
|
channel = "1.77.0"
|
||||||
components = [
|
components = [
|
||||||
# For rust-analyzer
|
# For rust-analyzer
|
||||||
"rust-src",
|
"rust-src",
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::fmt::Write as _;
|
||||||
|
|
||||||
use register::RegistrationKind;
|
use register::RegistrationKind;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::{
|
api::client::{
|
||||||
@@ -238,7 +240,7 @@ pub(crate) async fn register_route(body: Ruma<register::v3::Request>) -> Result<
|
|||||||
// If `new_user_displayname_suffix` is set, registration will push whatever
|
// If `new_user_displayname_suffix` is set, registration will push whatever
|
||||||
// content is set to the user's display name with a space before it
|
// content is set to the user's display name with a space before it
|
||||||
if !services().globals.new_user_displayname_suffix().is_empty() {
|
if !services().globals.new_user_displayname_suffix().is_empty() {
|
||||||
displayname.push_str(&(" ".to_owned() + services().globals.new_user_displayname_suffix()));
|
_ = write!(displayname, " {}", services().globals.config.new_user_displayname_suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
services()
|
services()
|
||||||
@@ -355,33 +357,7 @@ pub(crate) async fn register_route(body: Ruma<register::v3::Request>) -> Result<
|
|||||||
&& !services().globals.config.auto_join_rooms.is_empty()
|
&& !services().globals.config.auto_join_rooms.is_empty()
|
||||||
&& (services().globals.allow_guests_auto_join_rooms() || !is_guest)
|
&& (services().globals.allow_guests_auto_join_rooms() || !is_guest)
|
||||||
{
|
{
|
||||||
for room in &services().globals.config.auto_join_rooms {
|
auto_join_rooms(&user_id).await?;
|
||||||
if !services()
|
|
||||||
.rooms
|
|
||||||
.state_cache
|
|
||||||
.server_in_room(services().globals.server_name(), room)?
|
|
||||||
{
|
|
||||||
warn!("Skipping room {room} to automatically join as we have never joined before.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(room_id_server_name) = room.server_name() {
|
|
||||||
if let Err(e) = join_room_by_id_helper(
|
|
||||||
Some(&user_id),
|
|
||||||
room,
|
|
||||||
Some("Automatically joining this room upon registration".to_owned()),
|
|
||||||
&[room_id_server_name.to_owned(), services().globals.server_name().to_owned()],
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
// don't return this error so we don't fail registrations
|
|
||||||
error!("Failed to automatically join room {room} for user {user_id}: {e}");
|
|
||||||
} else {
|
|
||||||
info!("Automatically joined room {room} for user {user_id}");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(register::v3::Response {
|
Ok(register::v3::Response {
|
||||||
@@ -591,3 +567,40 @@ pub(crate) async fn request_3pid_management_token_via_msisdn_route(
|
|||||||
"Third party identifier is not allowed",
|
"Third party identifier is not allowed",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Auto joins all the specified users to the rooms listed in the
|
||||||
|
/// `auto_join_rooms` config option
|
||||||
|
///
|
||||||
|
/// TODO: can this be moved somewhere else instead of this file where routes are
|
||||||
|
/// typically defined?
|
||||||
|
pub(crate) async fn auto_join_rooms(user_id: &UserId) -> Result<()> {
|
||||||
|
for room in &services().globals.config.auto_join_rooms {
|
||||||
|
if !services()
|
||||||
|
.rooms
|
||||||
|
.state_cache
|
||||||
|
.server_in_room(&services().globals.config.server_name, room)?
|
||||||
|
{
|
||||||
|
warn!("Skipping room {room} to automatically join as we have never joined before.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(room_id_server_name) = room.server_name() {
|
||||||
|
if let Err(e) = join_room_by_id_helper(
|
||||||
|
Some(user_id),
|
||||||
|
room,
|
||||||
|
Some("Automatically joining this room upon registration".to_owned()),
|
||||||
|
&[room_id_server_name.to_owned(), services().globals.config.server_name.clone()],
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
// don't return this error so we don't fail registrations
|
||||||
|
error!("Failed to automatically join room {room} for user {user_id}: {e}");
|
||||||
|
} else {
|
||||||
|
info!("Automatically joined room {room} for user {user_id}");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -269,9 +269,7 @@ async fn alias_checks(room_alias: &OwnedRoomAliasId, appservice_info: &Option<Re
|
|||||||
if !info.aliases.is_match(room_alias.as_str()) {
|
if !info.aliases.is_match(room_alias.as_str()) {
|
||||||
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias is not in namespace."));
|
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias is not in namespace."));
|
||||||
}
|
}
|
||||||
}
|
} else if services().appservice.is_exclusive_alias(room_alias).await {
|
||||||
|
|
||||||
if services().appservice.is_exclusive_alias(room_alias).await {
|
|
||||||
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias reserved by appservice."));
|
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias reserved by appservice."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
use ruma::api::client::{
|
use ruma::{
|
||||||
backup::{
|
api::client::{
|
||||||
add_backup_keys, add_backup_keys_for_room, add_backup_keys_for_session, create_backup_version,
|
backup::{
|
||||||
delete_backup_keys, delete_backup_keys_for_room, delete_backup_keys_for_session, delete_backup_version,
|
add_backup_keys, add_backup_keys_for_room, add_backup_keys_for_session, create_backup_version,
|
||||||
get_backup_info, get_backup_keys, get_backup_keys_for_room, get_backup_keys_for_session,
|
delete_backup_keys, delete_backup_keys_for_room, delete_backup_keys_for_session, delete_backup_version,
|
||||||
get_latest_backup_info, update_backup_version,
|
get_backup_info, get_backup_keys, get_backup_keys_for_room, get_backup_keys_for_session,
|
||||||
|
get_latest_backup_info, update_backup_version,
|
||||||
|
},
|
||||||
|
error::ErrorKind,
|
||||||
},
|
},
|
||||||
error::ErrorKind,
|
UInt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{services, Error, Result, Ruma};
|
use crate::{services, Error, Result, Ruma};
|
||||||
@@ -56,7 +59,8 @@ pub(crate) async fn get_latest_backup_info_route(
|
|||||||
|
|
||||||
Ok(get_latest_backup_info::v3::Response {
|
Ok(get_latest_backup_info::v3::Response {
|
||||||
algorithm,
|
algorithm,
|
||||||
count: (services().key_backups.count_keys(sender_user, &version)? as u32).into(),
|
count: (UInt::try_from(services().key_backups.count_keys(sender_user, &version)?)
|
||||||
|
.expect("user backup keys count should not be that high")),
|
||||||
etag: services().key_backups.get_etag(sender_user, &version)?,
|
etag: services().key_backups.get_etag(sender_user, &version)?,
|
||||||
version,
|
version,
|
||||||
})
|
})
|
||||||
@@ -76,10 +80,12 @@ pub(crate) async fn get_backup_info_route(
|
|||||||
|
|
||||||
Ok(get_backup_info::v3::Response {
|
Ok(get_backup_info::v3::Response {
|
||||||
algorithm,
|
algorithm,
|
||||||
count: (services()
|
count: (UInt::try_from(
|
||||||
.key_backups
|
services()
|
||||||
.count_keys(sender_user, &body.version)? as u32)
|
.key_backups
|
||||||
.into(),
|
.count_keys(sender_user, &body.version)?,
|
||||||
|
)
|
||||||
|
.expect("user backup keys count should not be that high")),
|
||||||
etag: services()
|
etag: services()
|
||||||
.key_backups
|
.key_backups
|
||||||
.get_etag(sender_user, &body.version)?,
|
.get_etag(sender_user, &body.version)?,
|
||||||
@@ -139,10 +145,12 @@ pub(crate) async fn add_backup_keys_route(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(add_backup_keys::v3::Response {
|
Ok(add_backup_keys::v3::Response {
|
||||||
count: (services()
|
count: (UInt::try_from(
|
||||||
.key_backups
|
services()
|
||||||
.count_keys(sender_user, &body.version)? as u32)
|
.key_backups
|
||||||
.into(),
|
.count_keys(sender_user, &body.version)?,
|
||||||
|
)
|
||||||
|
.expect("user backup keys count should not be that high")),
|
||||||
etag: services()
|
etag: services()
|
||||||
.key_backups
|
.key_backups
|
||||||
.get_etag(sender_user, &body.version)?,
|
.get_etag(sender_user, &body.version)?,
|
||||||
@@ -181,10 +189,12 @@ pub(crate) async fn add_backup_keys_for_room_route(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(add_backup_keys_for_room::v3::Response {
|
Ok(add_backup_keys_for_room::v3::Response {
|
||||||
count: (services()
|
count: (UInt::try_from(
|
||||||
.key_backups
|
services()
|
||||||
.count_keys(sender_user, &body.version)? as u32)
|
.key_backups
|
||||||
.into(),
|
.count_keys(sender_user, &body.version)?,
|
||||||
|
)
|
||||||
|
.expect("user backup keys count should not be that high")),
|
||||||
etag: services()
|
etag: services()
|
||||||
.key_backups
|
.key_backups
|
||||||
.get_etag(sender_user, &body.version)?,
|
.get_etag(sender_user, &body.version)?,
|
||||||
@@ -221,10 +231,12 @@ pub(crate) async fn add_backup_keys_for_session_route(
|
|||||||
.add_key(sender_user, &body.version, &body.room_id, &body.session_id, &body.session_data)?;
|
.add_key(sender_user, &body.version, &body.room_id, &body.session_id, &body.session_data)?;
|
||||||
|
|
||||||
Ok(add_backup_keys_for_session::v3::Response {
|
Ok(add_backup_keys_for_session::v3::Response {
|
||||||
count: (services()
|
count: (UInt::try_from(
|
||||||
.key_backups
|
services()
|
||||||
.count_keys(sender_user, &body.version)? as u32)
|
.key_backups
|
||||||
.into(),
|
.count_keys(sender_user, &body.version)?,
|
||||||
|
)
|
||||||
|
.expect("user backup keys count should not be that high")),
|
||||||
etag: services()
|
etag: services()
|
||||||
.key_backups
|
.key_backups
|
||||||
.get_etag(sender_user, &body.version)?,
|
.get_etag(sender_user, &body.version)?,
|
||||||
@@ -294,10 +306,12 @@ pub(crate) async fn delete_backup_keys_route(
|
|||||||
.delete_all_keys(sender_user, &body.version)?;
|
.delete_all_keys(sender_user, &body.version)?;
|
||||||
|
|
||||||
Ok(delete_backup_keys::v3::Response {
|
Ok(delete_backup_keys::v3::Response {
|
||||||
count: (services()
|
count: (UInt::try_from(
|
||||||
.key_backups
|
services()
|
||||||
.count_keys(sender_user, &body.version)? as u32)
|
.key_backups
|
||||||
.into(),
|
.count_keys(sender_user, &body.version)?,
|
||||||
|
)
|
||||||
|
.expect("user backup keys count should not be that high")),
|
||||||
etag: services()
|
etag: services()
|
||||||
.key_backups
|
.key_backups
|
||||||
.get_etag(sender_user, &body.version)?,
|
.get_etag(sender_user, &body.version)?,
|
||||||
@@ -317,10 +331,12 @@ pub(crate) async fn delete_backup_keys_for_room_route(
|
|||||||
.delete_room_keys(sender_user, &body.version, &body.room_id)?;
|
.delete_room_keys(sender_user, &body.version, &body.room_id)?;
|
||||||
|
|
||||||
Ok(delete_backup_keys_for_room::v3::Response {
|
Ok(delete_backup_keys_for_room::v3::Response {
|
||||||
count: (services()
|
count: (UInt::try_from(
|
||||||
.key_backups
|
services()
|
||||||
.count_keys(sender_user, &body.version)? as u32)
|
.key_backups
|
||||||
.into(),
|
.count_keys(sender_user, &body.version)?,
|
||||||
|
)
|
||||||
|
.expect("user backup keys count should not be that high")),
|
||||||
etag: services()
|
etag: services()
|
||||||
.key_backups
|
.key_backups
|
||||||
.get_etag(sender_user, &body.version)?,
|
.get_etag(sender_user, &body.version)?,
|
||||||
@@ -340,10 +356,12 @@ pub(crate) async fn delete_backup_keys_for_session_route(
|
|||||||
.delete_room_key(sender_user, &body.version, &body.room_id, &body.session_id)?;
|
.delete_room_key(sender_user, &body.version, &body.room_id, &body.session_id)?;
|
||||||
|
|
||||||
Ok(delete_backup_keys_for_session::v3::Response {
|
Ok(delete_backup_keys_for_session::v3::Response {
|
||||||
count: (services()
|
count: (UInt::try_from(
|
||||||
.key_backups
|
services()
|
||||||
.count_keys(sender_user, &body.version)? as u32)
|
.key_backups
|
||||||
.into(),
|
.count_keys(sender_user, &body.version)?,
|
||||||
|
)
|
||||||
|
.expect("user backup keys count should not be that high")),
|
||||||
etag: services()
|
etag: services()
|
||||||
.key_backups
|
.key_backups
|
||||||
.get_etag(sender_user, &body.version)?,
|
.get_etag(sender_user, &body.version)?,
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ pub(crate) async fn get_context_route(body: Ruma<get_context::v3::Request>) -> R
|
|||||||
lazy_loaded.insert(base_event.sender.as_str().to_owned());
|
lazy_loaded.insert(base_event.sender.as_str().to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use limit with maximum 100
|
// Use limit or else 10, with maximum 100
|
||||||
let limit = u64::from(body.limit).min(100) as usize;
|
let limit = usize::try_from(body.limit).unwrap_or(10).min(100);
|
||||||
|
|
||||||
let base_event = base_event.to_room_event();
|
let base_event = base_event.to_room_event();
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use ruma::{
|
|||||||
},
|
},
|
||||||
StateEventType,
|
StateEventType,
|
||||||
},
|
},
|
||||||
ServerName, UInt,
|
uint, ServerName, UInt,
|
||||||
};
|
};
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
@@ -198,8 +198,9 @@ pub(crate) async fn get_public_rooms_filtered_helper(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use limit or else 10, with maximum 100
|
||||||
let limit = limit.map_or(10, u64::from);
|
let limit = limit.map_or(10, u64::from);
|
||||||
let mut num_since = 0_u64;
|
let mut num_since: u64 = 0;
|
||||||
|
|
||||||
if let Some(s) = &since {
|
if let Some(s) = &since {
|
||||||
let mut characters = s.chars();
|
let mut characters = s.chars();
|
||||||
@@ -363,12 +364,16 @@ pub(crate) async fn get_public_rooms_filtered_helper(
|
|||||||
|
|
||||||
all_rooms.sort_by(|l, r| r.num_joined_members.cmp(&l.num_joined_members));
|
all_rooms.sort_by(|l, r| r.num_joined_members.cmp(&l.num_joined_members));
|
||||||
|
|
||||||
let total_room_count_estimate = (all_rooms.len() as u32).into();
|
let total_room_count_estimate = UInt::try_from(all_rooms.len()).unwrap_or_else(|_| uint!(0));
|
||||||
|
|
||||||
let chunk: Vec<_> = all_rooms
|
let chunk: Vec<_> = all_rooms
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(num_since as usize)
|
.skip(
|
||||||
.take(limit as usize)
|
num_since
|
||||||
|
.try_into()
|
||||||
|
.expect("num_since should not be this high"),
|
||||||
|
)
|
||||||
|
.take(limit.try_into().expect("limit should not be this high"))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let prev_batch = if num_since == 0 {
|
let prev_batch = if num_since == 0 {
|
||||||
@@ -377,10 +382,15 @@ pub(crate) async fn get_public_rooms_filtered_helper(
|
|||||||
Some(format!("p{num_since}"))
|
Some(format!("p{num_since}"))
|
||||||
};
|
};
|
||||||
|
|
||||||
let next_batch = if chunk.len() < limit as usize {
|
let next_batch = if chunk.len() < limit.try_into().unwrap() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(format!("n{}", num_since + limit))
|
Some(format!(
|
||||||
|
"n{}",
|
||||||
|
num_since
|
||||||
|
.checked_add(limit)
|
||||||
|
.expect("num_since and limit should not be that large")
|
||||||
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(get_public_rooms_filtered::v3::Response {
|
Ok(get_public_rooms_filtered::v3::Response {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
cmp,
|
||||||
collections::{hash_map, BTreeMap, HashMap, HashSet},
|
collections::{hash_map, BTreeMap, HashMap, HashSet},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
@@ -338,7 +339,9 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
|
|||||||
hash_map::Entry::Vacant(e) => {
|
hash_map::Entry::Vacant(e) => {
|
||||||
e.insert((Instant::now(), 1));
|
e.insert((Instant::now(), 1));
|
||||||
},
|
},
|
||||||
hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1),
|
hash_map::Entry::Occupied(mut e) => {
|
||||||
|
*e.get_mut() = (Instant::now(), e.get().1.saturating_add(1));
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -353,10 +356,8 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
|
|||||||
.get(server)
|
.get(server)
|
||||||
{
|
{
|
||||||
// Exponential backoff
|
// Exponential backoff
|
||||||
let mut min_elapsed_duration = Duration::from_secs(5 * 60) * (*tries) * (*tries);
|
const MAX_DURATION: Duration = Duration::from_secs(60 * 60 * 24);
|
||||||
if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) {
|
let min_elapsed_duration = cmp::min(MAX_DURATION, Duration::from_secs(5 * 60) * (*tries) * (*tries));
|
||||||
min_elapsed_duration = Duration::from_secs(60 * 60 * 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
if time.elapsed() < min_elapsed_duration {
|
if time.elapsed() < min_elapsed_duration {
|
||||||
debug!("Backing off query from {:?}", server);
|
debug!("Backing off query from {:?}", server);
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ pub(crate) async fn create_content_route(
|
|||||||
mxc.clone(),
|
mxc.clone(),
|
||||||
body.filename
|
body.filename
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|filename| "inline; filename=".to_owned() + filename)
|
.map(|filename| format!("attachment; filename={filename}"))
|
||||||
.as_deref(),
|
.as_deref(),
|
||||||
body.content_type.as_deref(),
|
body.content_type.as_deref(),
|
||||||
&body.file,
|
&body.file,
|
||||||
@@ -173,15 +173,16 @@ pub(crate) async fn get_content_route(body: Ruma<get_content::v3::Request>) -> R
|
|||||||
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
||||||
|
|
||||||
if let Some(FileMeta {
|
if let Some(FileMeta {
|
||||||
content_disposition,
|
|
||||||
content_type,
|
content_type,
|
||||||
file,
|
file,
|
||||||
|
..
|
||||||
}) = services().media.get(mxc.clone()).await?
|
}) = services().media.get(mxc.clone()).await?
|
||||||
{
|
{
|
||||||
|
// TODO: safely sanitise filename to be included in the content-disposition
|
||||||
Ok(get_content::v3::Response {
|
Ok(get_content::v3::Response {
|
||||||
file,
|
file,
|
||||||
content_type,
|
content_type,
|
||||||
content_disposition,
|
content_disposition: Some("attachment".to_owned()),
|
||||||
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
||||||
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
|
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
|
||||||
})
|
})
|
||||||
@@ -243,7 +244,7 @@ pub(crate) async fn get_content_as_filename_route(
|
|||||||
Ok(get_content_as_filename::v3::Response {
|
Ok(get_content_as_filename::v3::Response {
|
||||||
file,
|
file,
|
||||||
content_type,
|
content_type,
|
||||||
content_disposition: Some(format!("inline; filename={}", body.filename)),
|
content_disposition: Some("attachment".to_owned()),
|
||||||
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
||||||
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
|
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
|
||||||
})
|
})
|
||||||
@@ -258,7 +259,7 @@ pub(crate) async fn get_content_as_filename_route(
|
|||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(remote_content_response) => Ok(get_content_as_filename::v3::Response {
|
Ok(remote_content_response) => Ok(get_content_as_filename::v3::Response {
|
||||||
content_disposition: Some(format!("inline: filename={}", body.filename)),
|
content_disposition: Some("attachment".to_owned()),
|
||||||
content_type: remote_content_response.content_type,
|
content_type: remote_content_response.content_type,
|
||||||
file: remote_content_response.file,
|
file: remote_content_response.file,
|
||||||
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
||||||
@@ -327,6 +328,7 @@ pub(crate) async fn get_content_thumbnail_route(
|
|||||||
content_type,
|
content_type,
|
||||||
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
||||||
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
|
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
|
||||||
|
content_disposition: Some("attachment".to_owned()),
|
||||||
})
|
})
|
||||||
} else if !server_is_ours(&body.server_name) && body.allow_remote {
|
} else if !server_is_ours(&body.server_name) && body.allow_remote {
|
||||||
if services()
|
if services()
|
||||||
@@ -371,7 +373,13 @@ pub(crate) async fn get_content_thumbnail_route(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(get_thumbnail_response)
|
Ok(get_content_thumbnail::v3::Response {
|
||||||
|
file: get_thumbnail_response.file,
|
||||||
|
content_type: get_thumbnail_response.content_type,
|
||||||
|
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
||||||
|
cache_control: Some(CACHE_CONTROL_IMMUTABLE.to_owned()),
|
||||||
|
content_disposition: Some("attachment".to_owned()),
|
||||||
|
})
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug_warn!("Fetching media `{}` failed: {:?}", mxc, e);
|
debug_warn!("Fetching media `{}` failed: {:?}", mxc, e);
|
||||||
@@ -434,13 +442,19 @@ async fn get_remote_content(
|
|||||||
.create(
|
.create(
|
||||||
None,
|
None,
|
||||||
mxc.to_owned(),
|
mxc.to_owned(),
|
||||||
content_response.content_disposition.as_deref(),
|
Some("attachment"),
|
||||||
content_response.content_type.as_deref(),
|
content_response.content_type.as_deref(),
|
||||||
&content_response.file,
|
&content_response.file,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(content_response)
|
Ok(get_content::v3::Response {
|
||||||
|
file: content_response.file,
|
||||||
|
content_type: content_response.content_type,
|
||||||
|
content_disposition: Some("attachment".to_owned()),
|
||||||
|
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.to_owned()),
|
||||||
|
cache_control: Some(CACHE_CONTROL_IMMUTABLE.to_owned()),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn download_image(client: &reqwest::Client, url: &str) -> Result<UrlPreviewData> {
|
async fn download_image(client: &reqwest::Client, url: &str) -> Result<UrlPreviewData> {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
cmp,
|
||||||
collections::{hash_map::Entry, BTreeMap, HashMap, HashSet},
|
collections::{hash_map::Entry, BTreeMap, HashMap, HashSet},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
@@ -1301,8 +1302,8 @@ async fn make_join_request(
|
|||||||
) -> Result<(federation::membership::prepare_join_event::v1::Response, OwnedServerName)> {
|
) -> Result<(federation::membership::prepare_join_event::v1::Response, OwnedServerName)> {
|
||||||
let mut make_join_response_and_server = Err(Error::BadServerResponse("No server available to assist in joining."));
|
let mut make_join_response_and_server = Err(Error::BadServerResponse("No server available to assist in joining."));
|
||||||
|
|
||||||
let mut make_join_counter = 0;
|
let mut make_join_counter: u16 = 0;
|
||||||
let mut incompatible_room_version_count = 0;
|
let mut incompatible_room_version_count: u8 = 0;
|
||||||
|
|
||||||
for remote_server in servers {
|
for remote_server in servers {
|
||||||
if server_is_ours(remote_server) {
|
if server_is_ours(remote_server) {
|
||||||
@@ -1322,7 +1323,7 @@ async fn make_join_request(
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
trace!("make_join response: {:?}", make_join_response);
|
trace!("make_join response: {:?}", make_join_response);
|
||||||
make_join_counter += 1;
|
make_join_counter = make_join_counter.saturating_add(1);
|
||||||
|
|
||||||
if let Err(ref e) = make_join_response {
|
if let Err(ref e) = make_join_response {
|
||||||
trace!("make_join ErrorKind string: {:?}", e.error_code().to_string());
|
trace!("make_join ErrorKind string: {:?}", e.error_code().to_string());
|
||||||
@@ -1336,7 +1337,7 @@ async fn make_join_request(
|
|||||||
.to_string()
|
.to_string()
|
||||||
.contains("M_UNSUPPORTED_ROOM_VERSION")
|
.contains("M_UNSUPPORTED_ROOM_VERSION")
|
||||||
{
|
{
|
||||||
incompatible_room_version_count += 1;
|
incompatible_room_version_count = incompatible_room_version_count.saturating_add(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if incompatible_room_version_count > 15 {
|
if incompatible_room_version_count > 15 {
|
||||||
@@ -1393,7 +1394,9 @@ async fn validate_and_add_event_id(
|
|||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
e.insert((Instant::now(), 1));
|
e.insert((Instant::now(), 1));
|
||||||
},
|
},
|
||||||
Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1),
|
Entry::Occupied(mut e) => {
|
||||||
|
*e.get_mut() = (Instant::now(), e.get().1.saturating_add(1));
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1405,10 +1408,8 @@ async fn validate_and_add_event_id(
|
|||||||
.get(&event_id)
|
.get(&event_id)
|
||||||
{
|
{
|
||||||
// Exponential backoff
|
// Exponential backoff
|
||||||
let mut min_elapsed_duration = Duration::from_secs(5 * 60) * (*tries) * (*tries);
|
const MAX_DURATION: Duration = Duration::from_secs(60 * 60 * 24);
|
||||||
if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) {
|
let min_elapsed_duration = cmp::min(MAX_DURATION, Duration::from_secs(5 * 60) * (*tries) * (*tries));
|
||||||
min_elapsed_duration = Duration::from_secs(60 * 60 * 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
if time.elapsed() < min_elapsed_duration {
|
if time.elapsed() < min_elapsed_duration {
|
||||||
debug!("Backing off from {}", event_id);
|
debug!("Backing off from {}", event_id);
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ pub(crate) async fn get_message_events_route(
|
|||||||
.lazy_load_confirm_delivery(sender_user, sender_device, &body.room_id, from)
|
.lazy_load_confirm_delivery(sender_user, sender_device, &body.room_id, from)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let limit = u64::from(body.limit).min(100) as usize;
|
let limit = usize::try_from(body.limit).unwrap_or(10).min(100);
|
||||||
|
|
||||||
let next_token;
|
let next_token;
|
||||||
|
|
||||||
@@ -159,8 +159,9 @@ pub(crate) async fn get_message_events_route(
|
|||||||
.timeline
|
.timeline
|
||||||
.pdus_after(sender_user, &body.room_id, from)?
|
.pdus_after(sender_user, &body.room_id, from)?
|
||||||
.filter_map(Result::ok) // Filter out buggy events
|
.filter_map(Result::ok) // Filter out buggy events
|
||||||
.filter(|(_, pdu)| contains_url_filter(pdu, &body.filter))
|
.filter(|(_, pdu)| { contains_url_filter(pdu, &body.filter) && visibility_filter(pdu, sender_user, &body.room_id)
|
||||||
.filter(|(_, pdu)| visibility_filter(pdu, sender_user, &body.room_id))
|
|
||||||
|
})
|
||||||
.take_while(|&(k, _)| Some(k) != to) // Stop at `to`
|
.take_while(|&(k, _)| Some(k) != to) // Stop at `to`
|
||||||
.take(limit)
|
.take(limit)
|
||||||
.collect();
|
.collect();
|
||||||
@@ -205,8 +206,7 @@ pub(crate) async fn get_message_events_route(
|
|||||||
.timeline
|
.timeline
|
||||||
.pdus_until(sender_user, &body.room_id, from)?
|
.pdus_until(sender_user, &body.room_id, from)?
|
||||||
.filter_map(Result::ok) // Filter out buggy events
|
.filter_map(Result::ok) // Filter out buggy events
|
||||||
.filter(|(_, pdu)| contains_url_filter(pdu, &body.filter))
|
.filter(|(_, pdu)| {contains_url_filter(pdu, &body.filter) && visibility_filter(pdu, sender_user, &body.room_id)})
|
||||||
.filter(|(_, pdu)| visibility_filter(pdu, sender_user, &body.room_id))
|
|
||||||
.take_while(|&(k, _)| Some(k) != to) // Stop at `to`
|
.take_while(|&(k, _)| Some(k) != to) // Stop at `to`
|
||||||
.take(limit)
|
.take(limit)
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@@ -49,9 +49,20 @@ pub(crate) async fn get_presence_route(body: Ruma<get_presence::v3::Request>) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(presence) = presence_event {
|
if let Some(presence) = presence_event {
|
||||||
|
let status_msg = if presence
|
||||||
|
.content
|
||||||
|
.status_msg
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(String::is_empty)
|
||||||
|
{
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
presence.content.status_msg
|
||||||
|
};
|
||||||
|
|
||||||
Ok(get_presence::v3::Response {
|
Ok(get_presence::v3::Response {
|
||||||
// TODO: Should ruma just use the presenceeventcontent type here?
|
// TODO: Should ruma just use the presenceeventcontent type here?
|
||||||
status_msg: presence.content.status_msg,
|
status_msg,
|
||||||
currently_active: presence.content.currently_active,
|
currently_active: presence.content.currently_active,
|
||||||
last_active_ago: presence
|
last_active_ago: presence
|
||||||
.content
|
.content
|
||||||
|
|||||||
@@ -801,7 +801,15 @@ pub(crate) async fn upgrade_room_route(body: Ruma<upgrade_room::v3::Request>) ->
|
|||||||
.map_err(|_| Error::bad_database("Invalid room event in database."))?;
|
.map_err(|_| Error::bad_database("Invalid room event in database."))?;
|
||||||
|
|
||||||
// Setting events_default and invite to the greater of 50 and users_default + 1
|
// Setting events_default and invite to the greater of 50 and users_default + 1
|
||||||
let new_level = max(int!(50), power_levels_event_content.users_default + int!(1));
|
let new_level = max(
|
||||||
|
int!(50),
|
||||||
|
power_levels_event_content
|
||||||
|
.users_default
|
||||||
|
.checked_add(int!(1))
|
||||||
|
.ok_or_else(|| {
|
||||||
|
Error::BadRequest(ErrorKind::BadJson, "users_default power levels event content is not valid")
|
||||||
|
})?,
|
||||||
|
);
|
||||||
power_levels_event_content.events_default = new_level;
|
power_levels_event_content.events_default = new_level;
|
||||||
power_levels_event_content.invite = new_level;
|
power_levels_event_content.invite = new_level;
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use ruma::{
|
|||||||
},
|
},
|
||||||
events::AnyStateEvent,
|
events::AnyStateEvent,
|
||||||
serde::Raw,
|
serde::Raw,
|
||||||
OwnedRoomId,
|
uint, OwnedRoomId,
|
||||||
};
|
};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
@@ -39,7 +39,12 @@ pub(crate) async fn search_events_route(body: Ruma<search_events::v3::Request>)
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Use limit or else 10, with maximum 100
|
// Use limit or else 10, with maximum 100
|
||||||
let limit = filter.limit.map_or(10, u64::from).min(100) as usize;
|
let limit: usize = filter
|
||||||
|
.limit
|
||||||
|
.unwrap_or_else(|| uint!(10))
|
||||||
|
.try_into()
|
||||||
|
.unwrap_or(10)
|
||||||
|
.min(100);
|
||||||
|
|
||||||
let mut room_states: BTreeMap<OwnedRoomId, Vec<Raw<AnyStateEvent>>> = BTreeMap::new();
|
let mut room_states: BTreeMap<OwnedRoomId, Vec<Raw<AnyStateEvent>>> = BTreeMap::new();
|
||||||
|
|
||||||
@@ -106,14 +111,16 @@ pub(crate) async fn search_events_route(body: Ruma<search_events::v3::Request>)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let skip = match body.next_batch.as_ref().map(|s| s.parse()) {
|
let skip: usize = match body.next_batch.as_ref().map(|s| s.parse()) {
|
||||||
Some(Ok(s)) => s,
|
Some(Ok(s)) => s,
|
||||||
Some(Err(_)) => return Err(Error::BadRequest(ErrorKind::InvalidParam, "Invalid next_batch token.")),
|
Some(Err(_)) => return Err(Error::BadRequest(ErrorKind::InvalidParam, "Invalid next_batch token.")),
|
||||||
None => 0, // Default to the start
|
None => 0, // Default to the start
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
for _ in 0..skip + limit {
|
let next_batch: usize = skip.saturating_add(limit);
|
||||||
|
|
||||||
|
for _ in 0..next_batch {
|
||||||
if let Some(s) = searches
|
if let Some(s) = searches
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|s| (s.peek().cloned(), s))
|
.map(|s| (s.peek().cloned(), s))
|
||||||
@@ -162,12 +169,12 @@ pub(crate) async fn search_events_route(body: Ruma<search_events::v3::Request>)
|
|||||||
let next_batch = if results.len() < limit {
|
let next_batch = if results.len() < limit {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((skip + limit).to_string())
|
Some(next_batch.to_string())
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(search_events::v3::Response::new(ResultCategories {
|
Ok(search_events::v3::Response::new(ResultCategories {
|
||||||
room_events: ResultRoomEvents {
|
room_events: ResultRoomEvents {
|
||||||
count: Some((results.len() as u32).into()),
|
count: Some(results.len().try_into().unwrap_or_else(|_| uint!(0))),
|
||||||
groups: BTreeMap::new(), // TODO
|
groups: BTreeMap::new(), // TODO
|
||||||
next_batch,
|
next_batch,
|
||||||
results,
|
results,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::{error::ErrorKind, space::get_hierarchy},
|
api::client::{error::ErrorKind, space::get_hierarchy},
|
||||||
UInt,
|
uint, UInt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{service::rooms::spaces::PagnationToken, services, Error, Result, Ruma};
|
use crate::{service::rooms::spaces::PagnationToken, services, Error, Result, Ruma};
|
||||||
@@ -14,10 +14,12 @@ use crate::{service::rooms::spaces::PagnationToken, services, Error, Result, Rum
|
|||||||
pub(crate) async fn get_hierarchy_route(body: Ruma<get_hierarchy::v1::Request>) -> Result<get_hierarchy::v1::Response> {
|
pub(crate) async fn get_hierarchy_route(body: Ruma<get_hierarchy::v1::Request>) -> Result<get_hierarchy::v1::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
let limit = body
|
let limit: usize = body
|
||||||
.limit
|
.limit
|
||||||
.unwrap_or_else(|| UInt::from(10_u32))
|
.unwrap_or_else(|| uint!(10))
|
||||||
.min(UInt::from(100_u32));
|
.try_into()
|
||||||
|
.unwrap_or(10)
|
||||||
|
.min(100);
|
||||||
|
|
||||||
let max_depth = body
|
let max_depth = body
|
||||||
.max_depth
|
.max_depth
|
||||||
@@ -45,9 +47,9 @@ pub(crate) async fn get_hierarchy_route(body: Ruma<get_hierarchy::v1::Request>)
|
|||||||
.get_client_hierarchy(
|
.get_client_hierarchy(
|
||||||
sender_user,
|
sender_user,
|
||||||
&body.room_id,
|
&body.room_id,
|
||||||
u64::from(limit) as usize,
|
limit,
|
||||||
key.map_or(0, |token| u64::from(token.skip) as usize),
|
key.map_or(0, |token| token.skip.try_into().unwrap_or(0)),
|
||||||
u64::from(max_depth) as usize,
|
max_depth.try_into().unwrap_or(3),
|
||||||
body.suggested_only,
|
body.suggested_only,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -539,7 +539,7 @@ async fn handle_left_room(
|
|||||||
|
|
||||||
left_state_ids.insert(leave_shortstatekey, left_event_id);
|
left_state_ids.insert(leave_shortstatekey, left_event_id);
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i: u8 = 0;
|
||||||
for (key, id) in left_state_ids {
|
for (key, id) in left_state_ids {
|
||||||
if full_state || since_state_ids.get(&key) != Some(&id) {
|
if full_state || since_state_ids.get(&key) != Some(&id) {
|
||||||
let (event_type, state_key) = services().rooms.short.get_statekey_from_short(key)?;
|
let (event_type, state_key) = services().rooms.short.get_statekey_from_short(key)?;
|
||||||
@@ -557,7 +557,7 @@ async fn handle_left_room(
|
|||||||
|
|
||||||
left_state_events.push(pdu.to_sync_state_event());
|
left_state_events.push(pdu.to_sync_state_event());
|
||||||
|
|
||||||
i += 1;
|
i = i.wrapping_add(1);
|
||||||
if i % 100 == 0 {
|
if i % 100 == 0 {
|
||||||
tokio::task::yield_now().await;
|
tokio::task::yield_now().await;
|
||||||
}
|
}
|
||||||
@@ -705,7 +705,7 @@ async fn load_joined_room(
|
|||||||
// Recalculate heroes (first 5 members)
|
// Recalculate heroes (first 5 members)
|
||||||
let mut heroes = Vec::new();
|
let mut heroes = Vec::new();
|
||||||
|
|
||||||
if joined_member_count + invited_member_count <= 5 {
|
if joined_member_count.saturating_add(invited_member_count) <= 5 {
|
||||||
// Go through all PDUs and for each member event, check if the user is still
|
// Go through all PDUs and for each member event, check if the user is still
|
||||||
// joined or invited until we have 5 or we reach the end
|
// joined or invited until we have 5 or we reach the end
|
||||||
|
|
||||||
@@ -784,7 +784,7 @@ async fn load_joined_room(
|
|||||||
let mut state_events = Vec::new();
|
let mut state_events = Vec::new();
|
||||||
let mut lazy_loaded = HashSet::new();
|
let mut lazy_loaded = HashSet::new();
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i: u8 = 0;
|
||||||
for (shortstatekey, id) in current_state_ids {
|
for (shortstatekey, id) in current_state_ids {
|
||||||
let (event_type, state_key) = services()
|
let (event_type, state_key) = services()
|
||||||
.rooms
|
.rooms
|
||||||
@@ -798,7 +798,7 @@ async fn load_joined_room(
|
|||||||
};
|
};
|
||||||
state_events.push(pdu);
|
state_events.push(pdu);
|
||||||
|
|
||||||
i += 1;
|
i = i.wrapping_add(1);
|
||||||
if i % 100 == 0 {
|
if i % 100 == 0 {
|
||||||
tokio::task::yield_now().await;
|
tokio::task::yield_now().await;
|
||||||
}
|
}
|
||||||
@@ -819,7 +819,7 @@ async fn load_joined_room(
|
|||||||
}
|
}
|
||||||
state_events.push(pdu);
|
state_events.push(pdu);
|
||||||
|
|
||||||
i += 1;
|
i = i.wrapping_add(1);
|
||||||
if i % 100 == 0 {
|
if i % 100 == 0 {
|
||||||
tokio::task::yield_now().await;
|
tokio::task::yield_now().await;
|
||||||
}
|
}
|
||||||
@@ -1416,10 +1416,14 @@ pub(crate) async fn sync_events_v4_route(
|
|||||||
.ranges
|
.ranges
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|mut r| {
|
.map(|mut r| {
|
||||||
r.0 =
|
r.0 = r.0.clamp(
|
||||||
r.0.clamp(uint!(0), UInt::from(all_joined_rooms.len() as u32 - 1));
|
uint!(0),
|
||||||
r.1 =
|
UInt::try_from(all_joined_rooms.len().saturating_sub(1)).unwrap_or(UInt::MAX),
|
||||||
r.1.clamp(r.0, UInt::from(all_joined_rooms.len() as u32 - 1));
|
);
|
||||||
|
r.1 = r.1.clamp(
|
||||||
|
r.0,
|
||||||
|
UInt::try_from(all_joined_rooms.len().saturating_sub(1)).unwrap_or(UInt::MAX),
|
||||||
|
);
|
||||||
let room_ids = all_joined_rooms[(u64::from(r.0) as usize)..=(u64::from(r.1) as usize)].to_vec();
|
let room_ids = all_joined_rooms[(u64::from(r.0) as usize)..=(u64::from(r.1) as usize)].to_vec();
|
||||||
new_known_rooms.extend(room_ids.iter().cloned());
|
new_known_rooms.extend(room_ids.iter().cloned());
|
||||||
for room_id in &room_ids {
|
for room_id in &room_ids {
|
||||||
@@ -1592,14 +1596,13 @@ pub(crate) async fn sync_events_v4_route(
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let name = match heroes.len().cmp(&(1_usize)) {
|
let name = match heroes.len().cmp(&(1_usize)) {
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
|
let firsts = heroes[1..]
|
||||||
|
.iter()
|
||||||
|
.map(|h| h.0.clone())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ");
|
||||||
let last = heroes[0].0.clone();
|
let last = heroes[0].0.clone();
|
||||||
Some(
|
Some(format!("{firsts} and {last}"))
|
||||||
heroes[1..]
|
|
||||||
.iter()
|
|
||||||
.map(|h| h.0.clone())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", ") + " and " + &last,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
Ordering::Equal => Some(heroes[0].0.clone()),
|
Ordering::Equal => Some(heroes[0].0.clone()),
|
||||||
Ordering::Less => None,
|
Ordering::Less => None,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use ruma::api::client::{error::ErrorKind, threads::get_threads};
|
use ruma::{
|
||||||
|
api::client::{error::ErrorKind, threads::get_threads},
|
||||||
|
uint,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{services, Error, Result, Ruma};
|
use crate::{services, Error, Result, Ruma};
|
||||||
|
|
||||||
@@ -9,7 +12,8 @@ pub(crate) async fn get_threads_route(body: Ruma<get_threads::v1::Request>) -> R
|
|||||||
// Use limit or else 10, with maximum 100
|
// Use limit or else 10, with maximum 100
|
||||||
let limit = body
|
let limit = body
|
||||||
.limit
|
.limit
|
||||||
.and_then(|l| l.try_into().ok())
|
.unwrap_or_else(|| uint!(10))
|
||||||
|
.try_into()
|
||||||
.unwrap_or(10)
|
.unwrap_or(10)
|
||||||
.min(100);
|
.min(100);
|
||||||
|
|
||||||
|
|||||||
@@ -22,14 +22,30 @@ pub(crate) async fn create_typing_event_route(
|
|||||||
|
|
||||||
if let Typing::Yes(duration) = body.state {
|
if let Typing::Yes(duration) = body.state {
|
||||||
let duration = utils::clamp(
|
let duration = utils::clamp(
|
||||||
duration.as_millis() as u64,
|
duration.as_millis().try_into().unwrap_or(u64::MAX),
|
||||||
services().globals.config.typing_client_timeout_min_s * 1000,
|
services()
|
||||||
services().globals.config.typing_client_timeout_max_s * 1000,
|
.globals
|
||||||
|
.config
|
||||||
|
.typing_client_timeout_min_s
|
||||||
|
.checked_mul(1000)
|
||||||
|
.unwrap(),
|
||||||
|
services()
|
||||||
|
.globals
|
||||||
|
.config
|
||||||
|
.typing_client_timeout_max_s
|
||||||
|
.checked_mul(1000)
|
||||||
|
.unwrap(),
|
||||||
);
|
);
|
||||||
services()
|
services()
|
||||||
.rooms
|
.rooms
|
||||||
.typing
|
.typing
|
||||||
.typing_add(sender_user, &body.room_id, utils::millis_since_unix_epoch() + duration)
|
.typing_add(
|
||||||
|
sender_user,
|
||||||
|
&body.room_id,
|
||||||
|
utils::millis_since_unix_epoch()
|
||||||
|
.checked_add(duration)
|
||||||
|
.expect("user typing timeout should not get this high"),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
services()
|
services()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use crate::{services, Result, Ruma};
|
|||||||
/// and don't share a room with the sender
|
/// and don't share a room with the sender
|
||||||
pub(crate) async fn search_users_route(body: Ruma<search_users::v3::Request>) -> Result<search_users::v3::Response> {
|
pub(crate) async fn search_users_route(body: Ruma<search_users::v3::Request>) -> Result<search_users::v3::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
let limit = u64::from(body.limit) as usize;
|
let limit = usize::try_from(body.limit).unwrap_or(10); // default limit is 10
|
||||||
|
|
||||||
let mut users = services().users.iter().filter_map(|user_id| {
|
let mut users = services().users.iter().filter_map(|user_id| {
|
||||||
// Filter out buggy users (they should not exist, but you never know...)
|
// Filter out buggy users (they should not exist, but you never know...)
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ pub(crate) async fn turn_server_route(
|
|||||||
|
|
||||||
let (username, password) = if !turn_secret.is_empty() {
|
let (username, password) = if !turn_secret.is_empty() {
|
||||||
let expiry = SecondsSinceUnixEpoch::from_system_time(
|
let expiry = SecondsSinceUnixEpoch::from_system_time(
|
||||||
SystemTime::now() + Duration::from_secs(services().globals.turn_ttl()),
|
SystemTime::now()
|
||||||
|
.checked_add(Duration::from_secs(services().globals.turn_ttl()))
|
||||||
|
.expect("TURN TTL should not get this high"),
|
||||||
)
|
)
|
||||||
.expect("time is valid");
|
.expect("time is valid");
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,9 @@ pub(crate) async fn get_server_keys_route() -> Result<impl IntoResponse> {
|
|||||||
old_verify_keys: BTreeMap::new(),
|
old_verify_keys: BTreeMap::new(),
|
||||||
signatures: BTreeMap::new(),
|
signatures: BTreeMap::new(),
|
||||||
valid_until_ts: MilliSecondsSinceUnixEpoch::from_system_time(
|
valid_until_ts: MilliSecondsSinceUnixEpoch::from_system_time(
|
||||||
SystemTime::now() + Duration::from_secs(86400 * 7),
|
SystemTime::now()
|
||||||
|
.checked_add(Duration::from_secs(86400 * 7))
|
||||||
|
.expect("valid_until_ts should not get this high"),
|
||||||
)
|
)
|
||||||
.expect("time is valid"),
|
.expect("time is valid"),
|
||||||
})
|
})
|
||||||
@@ -398,8 +400,13 @@ pub(crate) async fn send_transaction_message_route(
|
|||||||
.is_joined(&typing.user_id, &typing.room_id)?
|
.is_joined(&typing.user_id, &typing.room_id)?
|
||||||
{
|
{
|
||||||
if typing.typing {
|
if typing.typing {
|
||||||
let timeout = utils::millis_since_unix_epoch()
|
let timeout = utils::millis_since_unix_epoch().saturating_add(
|
||||||
+ services().globals.config.typing_federation_timeout_s * 1000;
|
services()
|
||||||
|
.globals
|
||||||
|
.config
|
||||||
|
.typing_federation_timeout_s
|
||||||
|
.saturating_mul(1000),
|
||||||
|
);
|
||||||
services()
|
services()
|
||||||
.rooms
|
.rooms
|
||||||
.typing
|
.typing
|
||||||
@@ -662,7 +669,7 @@ pub(crate) async fn get_missing_events_route(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if body.earliest_events.contains(&queued_events[i]) {
|
if body.earliest_events.contains(&queued_events[i]) {
|
||||||
i += 1;
|
i = i.saturating_add(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -671,7 +678,7 @@ pub(crate) async fn get_missing_events_route(
|
|||||||
&body.room_id,
|
&body.room_id,
|
||||||
&queued_events[i],
|
&queued_events[i],
|
||||||
)? {
|
)? {
|
||||||
i += 1;
|
i = i.saturating_add(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,7 +695,7 @@ pub(crate) async fn get_missing_events_route(
|
|||||||
);
|
);
|
||||||
events.push(PduEvent::convert_to_outgoing_federation_event(pdu));
|
events.push(PduEvent::convert_to_outgoing_federation_event(pdu));
|
||||||
}
|
}
|
||||||
i += 1;
|
i = i.saturating_add(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(get_missing_events::v1::Response {
|
Ok(get_missing_events::v1::Response {
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ impl service::account_data::Data for KeyValueDatabase {
|
|||||||
|
|
||||||
// Skip the data that's exactly at since, because we sent that last time
|
// Skip the data that's exactly at since, because we sent that last time
|
||||||
let mut first_possible = prefix.clone();
|
let mut first_possible = prefix.clone();
|
||||||
first_possible.extend_from_slice(&(since + 1).to_be_bytes());
|
first_possible.extend_from_slice(&(since.saturating_add(1)).to_be_bytes());
|
||||||
|
|
||||||
for r in self
|
for r in self
|
||||||
.roomuserdataid_accountdata
|
.roomuserdataid_accountdata
|
||||||
|
|||||||
@@ -158,18 +158,15 @@ impl service::globals::Data for KeyValueDatabase {
|
|||||||
let max_appservice_in_room_cache = self.appservice_in_room_cache.read().unwrap().capacity();
|
let max_appservice_in_room_cache = self.appservice_in_room_cache.read().unwrap().capacity();
|
||||||
let max_lasttimelinecount_cache = self.lasttimelinecount_cache.lock().unwrap().capacity();
|
let max_lasttimelinecount_cache = self.lasttimelinecount_cache.lock().unwrap().capacity();
|
||||||
|
|
||||||
let mut response = format!(
|
format!(
|
||||||
"\
|
"\
|
||||||
auth_chain_cache: {auth_chain_cache} / {max_auth_chain_cache}
|
auth_chain_cache: {auth_chain_cache} / {max_auth_chain_cache}
|
||||||
our_real_users_cache: {our_real_users_cache} / {max_our_real_users_cache}
|
our_real_users_cache: {our_real_users_cache} / {max_our_real_users_cache}
|
||||||
appservice_in_room_cache: {appservice_in_room_cache} / {max_appservice_in_room_cache}
|
appservice_in_room_cache: {appservice_in_room_cache} / {max_appservice_in_room_cache}
|
||||||
lasttimelinecount_cache: {lasttimelinecount_cache} / {max_lasttimelinecount_cache}\n\n"
|
lasttimelinecount_cache: {lasttimelinecount_cache} / {max_lasttimelinecount_cache}\n\n
|
||||||
);
|
{}",
|
||||||
if let Ok(db_stats) = self.db.memory_usage() {
|
self.db.memory_usage().unwrap_or_default()
|
||||||
response += &db_stats;
|
)
|
||||||
}
|
|
||||||
|
|
||||||
response
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_caches(&self, amount: u32) {
|
fn clear_caches(&self, amount: u32) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use ruma::{events::presence::PresenceEvent, presence::PresenceState, OwnedUserId, UInt, UserId};
|
use ruma::{events::presence::PresenceEvent, presence::PresenceState, OwnedUserId, UInt, UserId};
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::KeyValueDatabase,
|
database::KeyValueDatabase,
|
||||||
|
debug_info,
|
||||||
service::{self, presence::Presence},
|
service::{self, presence::Presence},
|
||||||
services,
|
services,
|
||||||
utils::{self, user_id_from_bytes},
|
utils::{self, user_id_from_bytes},
|
||||||
@@ -50,13 +50,21 @@ impl service::presence::Data for KeyValueDatabase {
|
|||||||
|
|
||||||
// tighten for state flicker?
|
// tighten for state flicker?
|
||||||
if !state_changed && last_active_ts <= last_last_active_ts {
|
if !state_changed && last_active_ts <= last_last_active_ts {
|
||||||
debug!(
|
debug_info!(
|
||||||
"presence spam {:?} last_active_ts:{:?} <= {:?}",
|
"presence spam {:?} last_active_ts:{:?} <= {:?}",
|
||||||
user_id, last_active_ts, last_last_active_ts
|
user_id,
|
||||||
|
last_active_ts,
|
||||||
|
last_last_active_ts
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let status_msg = if status_msg.as_ref().is_some_and(String::is_empty) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
status_msg
|
||||||
|
};
|
||||||
|
|
||||||
let presence = Presence::new(
|
let presence = Presence::new(
|
||||||
presence_state.to_owned(),
|
presence_state.to_owned(),
|
||||||
currently_active.unwrap_or(false),
|
currently_active.unwrap_or(false),
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ impl service::rooms::pdu_metadata::Data for KeyValueDatabase {
|
|||||||
let mut current = prefix.clone();
|
let mut current = prefix.clone();
|
||||||
|
|
||||||
let count_raw = match until {
|
let count_raw = match until {
|
||||||
PduCount::Normal(x) => x - 1,
|
PduCount::Normal(x) => x.saturating_sub(1),
|
||||||
PduCount::Backfilled(x) => {
|
PduCount::Backfilled(x) => {
|
||||||
current.extend_from_slice(&0_u64.to_be_bytes());
|
current.extend_from_slice(&0_u64.to_be_bytes());
|
||||||
u64::MAX - x - 1
|
u64::MAX.saturating_sub(x).saturating_sub(1)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
current.extend_from_slice(&count_raw.to_be_bytes());
|
current.extend_from_slice(&count_raw.to_be_bytes());
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl service::rooms::read_receipt::Data for KeyValueDatabase {
|
|||||||
let prefix2 = prefix.clone();
|
let prefix2 = prefix.clone();
|
||||||
|
|
||||||
let mut first_possible_edu = prefix.clone();
|
let mut first_possible_edu = prefix.clone();
|
||||||
first_possible_edu.extend_from_slice(&(since + 1).to_be_bytes()); // +1 so we don't send the event at since
|
first_possible_edu.extend_from_slice(&(since.saturating_add(1)).to_be_bytes()); // +1 so we don't send the event at since
|
||||||
|
|
||||||
Box::new(
|
Box::new(
|
||||||
self.readreceiptid_readreceipt
|
self.readreceiptid_readreceipt
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ impl service::rooms::state_accessor::Data for KeyValueDatabase {
|
|||||||
.expect("there is always one layer")
|
.expect("there is always one layer")
|
||||||
.1;
|
.1;
|
||||||
let mut result = HashMap::new();
|
let mut result = HashMap::new();
|
||||||
let mut i = 0;
|
let mut i: u8 = 0;
|
||||||
for compressed in full_state.iter() {
|
for compressed in full_state.iter() {
|
||||||
let parsed = services()
|
let parsed = services()
|
||||||
.rooms
|
.rooms
|
||||||
@@ -25,7 +25,7 @@ impl service::rooms::state_accessor::Data for KeyValueDatabase {
|
|||||||
.parse_compressed_state_event(compressed)?;
|
.parse_compressed_state_event(compressed)?;
|
||||||
result.insert(parsed.0, parsed.1);
|
result.insert(parsed.0, parsed.1);
|
||||||
|
|
||||||
i += 1;
|
i = i.wrapping_add(1);
|
||||||
if i % 100 == 0 {
|
if i % 100 == 0 {
|
||||||
tokio::task::yield_now().await;
|
tokio::task::yield_now().await;
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ impl service::rooms::state_accessor::Data for KeyValueDatabase {
|
|||||||
.1;
|
.1;
|
||||||
|
|
||||||
let mut result = HashMap::new();
|
let mut result = HashMap::new();
|
||||||
let mut i = 0;
|
let mut i: u8 = 0;
|
||||||
for compressed in full_state.iter() {
|
for compressed in full_state.iter() {
|
||||||
let (_, eventid) = services()
|
let (_, eventid) = services()
|
||||||
.rooms
|
.rooms
|
||||||
@@ -63,7 +63,7 @@ impl service::rooms::state_accessor::Data for KeyValueDatabase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 1;
|
i = i.wrapping_add(1);
|
||||||
if i % 100 == 0 {
|
if i % 100 == 0 {
|
||||||
tokio::task::yield_now().await;
|
tokio::task::yield_now().await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,11 +154,11 @@ impl service::rooms::state_cache::Data for KeyValueDatabase {
|
|||||||
if user_is_local(&joined) && !services().users.is_deactivated(&joined).unwrap_or(true) {
|
if user_is_local(&joined) && !services().users.is_deactivated(&joined).unwrap_or(true) {
|
||||||
real_users.insert(joined);
|
real_users.insert(joined);
|
||||||
}
|
}
|
||||||
joinedcount += 1;
|
joinedcount = joinedcount.saturating_add(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for _invited in self.room_members_invited(room_id).filter_map(Result::ok) {
|
for _invited in self.room_members_invited(room_id).filter_map(Result::ok) {
|
||||||
invitedcount += 1;
|
invitedcount = invitedcount.saturating_add(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.roomid_joinedcount
|
self.roomid_joinedcount
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ fn pdu_count(pdu_id: &[u8]) -> Result<PduCount> {
|
|||||||
utils::u64_from_bytes(&pdu_id[pdu_id.len() - 2 * size_of::<u64>()..pdu_id.len() - size_of::<u64>()]);
|
utils::u64_from_bytes(&pdu_id[pdu_id.len() - 2 * size_of::<u64>()..pdu_id.len() - size_of::<u64>()]);
|
||||||
|
|
||||||
if matches!(second_last_u64, Ok(0)) {
|
if matches!(second_last_u64, Ok(0)) {
|
||||||
Ok(PduCount::Backfilled(u64::MAX - last_u64))
|
Ok(PduCount::Backfilled(u64::MAX.saturating_sub(last_u64)))
|
||||||
} else {
|
} else {
|
||||||
Ok(PduCount::Normal(last_u64))
|
Ok(PduCount::Normal(last_u64))
|
||||||
}
|
}
|
||||||
@@ -275,22 +275,18 @@ fn count_to_id(room_id: &RoomId, count: PduCount, offset: u64, subtract: bool) -
|
|||||||
let count_raw = match count {
|
let count_raw = match count {
|
||||||
PduCount::Normal(x) => {
|
PduCount::Normal(x) => {
|
||||||
if subtract {
|
if subtract {
|
||||||
x - offset
|
x.saturating_sub(offset)
|
||||||
} else {
|
} else {
|
||||||
x + offset
|
x.saturating_add(offset)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PduCount::Backfilled(x) => {
|
PduCount::Backfilled(x) => {
|
||||||
pdu_id.extend_from_slice(&0_u64.to_be_bytes());
|
pdu_id.extend_from_slice(&0_u64.to_be_bytes());
|
||||||
let num = u64::MAX - x;
|
let num = u64::MAX.saturating_sub(x);
|
||||||
if subtract {
|
if subtract {
|
||||||
if num > 0 {
|
num.saturating_sub(offset)
|
||||||
num - offset
|
|
||||||
} else {
|
|
||||||
num
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
num + offset
|
num.saturating_add(offset)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ impl service::rooms::user::Data for KeyValueDatabase {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, &b)| b == 0xFF)
|
.find(|(_, &b)| b == 0xFF)
|
||||||
.ok_or_else(|| Error::bad_database("Invalid userroomid_joined in db."))?
|
.ok_or_else(|| Error::bad_database("Invalid userroomid_joined in db."))?
|
||||||
.0 + 1; // +1 because the room id starts AFTER the separator
|
.0
|
||||||
|
.saturating_add(1); // +1 because the room id starts AFTER the separator
|
||||||
|
|
||||||
let room_id = key[roomid_index..].to_vec();
|
let room_id = key[roomid_index..].to_vec();
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use ruma::{
|
|||||||
encryption::{CrossSigningKey, DeviceKeys, OneTimeKey},
|
encryption::{CrossSigningKey, DeviceKeys, OneTimeKey},
|
||||||
events::{AnyToDeviceEvent, StateEventType},
|
events::{AnyToDeviceEvent, StateEventType},
|
||||||
serde::Raw,
|
serde::Raw,
|
||||||
DeviceId, DeviceKeyAlgorithm, DeviceKeyId, MilliSecondsSinceUnixEpoch, OwnedDeviceId, OwnedDeviceKeyId,
|
uint, DeviceId, DeviceKeyAlgorithm, DeviceKeyId, MilliSecondsSinceUnixEpoch, OwnedDeviceId, OwnedDeviceKeyId,
|
||||||
OwnedMxcUri, OwnedUserId, UInt, UserId,
|
OwnedMxcUri, OwnedUserId, UInt, UserId,
|
||||||
};
|
};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
@@ -414,7 +414,7 @@ impl service::users::Data for KeyValueDatabase {
|
|||||||
.algorithm(),
|
.algorithm(),
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
*counts.entry(algorithm?).or_default() += UInt::from(1_u32);
|
*counts.entry(algorithm?).or_default() += uint!(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(counts)
|
Ok(counts)
|
||||||
@@ -561,7 +561,7 @@ impl service::users::Data for KeyValueDatabase {
|
|||||||
prefix.push(0xFF);
|
prefix.push(0xFF);
|
||||||
|
|
||||||
let mut start = prefix.clone();
|
let mut start = prefix.clone();
|
||||||
start.extend_from_slice(&(from + 1).to_be_bytes());
|
start.extend_from_slice(&(from.saturating_add(1)).to_be_bytes());
|
||||||
|
|
||||||
let to = to.unwrap_or(u64::MAX);
|
let to = to.unwrap_or(u64::MAX);
|
||||||
|
|
||||||
|
|||||||
@@ -173,13 +173,11 @@ pub(crate) async fn migrations(db: &KeyValueDatabase, config: &Config) -> Result
|
|||||||
let mut current_sstatehash: Option<u64> = None;
|
let mut current_sstatehash: Option<u64> = None;
|
||||||
let mut current_room = None;
|
let mut current_room = None;
|
||||||
let mut current_state = HashSet::new();
|
let mut current_state = HashSet::new();
|
||||||
let mut counter = 0;
|
|
||||||
|
|
||||||
let mut handle_state = |current_sstatehash: u64,
|
let handle_state = |current_sstatehash: u64,
|
||||||
current_room: &RoomId,
|
current_room: &RoomId,
|
||||||
current_state: HashSet<_>,
|
current_state: HashSet<_>,
|
||||||
last_roomstates: &mut HashMap<_, _>| {
|
last_roomstates: &mut HashMap<_, _>| {
|
||||||
counter += 1;
|
|
||||||
let last_roomsstatehash = last_roomstates.get(current_room);
|
let last_roomsstatehash = last_roomstates.get(current_room);
|
||||||
|
|
||||||
let states_parents = last_roomsstatehash.map_or_else(
|
let states_parents = last_roomsstatehash.map_or_else(
|
||||||
|
|||||||
+3
-13
@@ -340,6 +340,7 @@ impl KeyValueDatabase {
|
|||||||
|
|
||||||
roomid_inviteviaservers: builder.open_tree("roomid_inviteviaservers")?,
|
roomid_inviteviaservers: builder.open_tree("roomid_inviteviaservers")?,
|
||||||
|
|
||||||
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
auth_chain_cache: Mutex::new(LruCache::new(
|
auth_chain_cache: Mutex::new(LruCache::new(
|
||||||
(f64::from(config.auth_chain_cache_capacity) * config.conduit_cache_capacity_modifier) as usize,
|
(f64::from(config.auth_chain_cache_capacity) * config.conduit_cache_capacity_modifier) as usize,
|
||||||
)),
|
)),
|
||||||
@@ -401,19 +402,8 @@ impl KeyValueDatabase {
|
|||||||
let sqlite_exists = path.join("conduit.db").exists();
|
let sqlite_exists = path.join("conduit.db").exists();
|
||||||
let rocksdb_exists = path.join("IDENTITY").exists();
|
let rocksdb_exists = path.join("IDENTITY").exists();
|
||||||
|
|
||||||
let mut count = 0;
|
if sqlite_exists && rocksdb_exists {
|
||||||
|
return Err(Error::bad_config("Multiple databases at database_path detected."));
|
||||||
if sqlite_exists {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if rocksdb_exists {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if count > 1 {
|
|
||||||
warn!("Multiple databases at database_path detected");
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if sqlite_exists && config.database_backend != "sqlite" {
|
if sqlite_exists && config.database_backend != "sqlite" {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ impl KvTree for RocksDbEngineTree<'_> {
|
|||||||
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
|
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
|
||||||
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
||||||
readoptions.set_total_order_seek(true);
|
readoptions.set_total_order_seek(true);
|
||||||
|
readoptions.set_async_io(cfg!(feature = "io_uring"));
|
||||||
|
|
||||||
Ok(self.db.rocks.get_cf_opt(&self.cf(), key, &readoptions)?)
|
Ok(self.db.rocks.get_cf_opt(&self.cf(), key, &readoptions)?)
|
||||||
}
|
}
|
||||||
@@ -26,6 +27,7 @@ impl KvTree for RocksDbEngineTree<'_> {
|
|||||||
fn multi_get(&self, keys: &[&[u8]]) -> Result<Vec<Option<Vec<u8>>>> {
|
fn multi_get(&self, keys: &[&[u8]]) -> Result<Vec<Option<Vec<u8>>>> {
|
||||||
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
||||||
readoptions.set_total_order_seek(true);
|
readoptions.set_total_order_seek(true);
|
||||||
|
readoptions.set_async_io(cfg!(feature = "io_uring"));
|
||||||
|
|
||||||
// Optimization can be `true` if key vector is pre-sorted **by the column
|
// Optimization can be `true` if key vector is pre-sorted **by the column
|
||||||
// comparator**.
|
// comparator**.
|
||||||
@@ -113,6 +115,7 @@ impl KvTree for RocksDbEngineTree<'_> {
|
|||||||
fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a> {
|
fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a> {
|
||||||
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
||||||
readoptions.set_total_order_seek(true);
|
readoptions.set_total_order_seek(true);
|
||||||
|
readoptions.set_async_io(cfg!(feature = "io_uring"));
|
||||||
|
|
||||||
Box::new(
|
Box::new(
|
||||||
self.db
|
self.db
|
||||||
@@ -126,6 +129,7 @@ impl KvTree for RocksDbEngineTree<'_> {
|
|||||||
fn iter_from<'a>(&'a self, from: &[u8], backwards: bool) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a> {
|
fn iter_from<'a>(&'a self, from: &[u8], backwards: bool) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a> {
|
||||||
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
||||||
readoptions.set_total_order_seek(true);
|
readoptions.set_total_order_seek(true);
|
||||||
|
readoptions.set_async_io(cfg!(feature = "io_uring"));
|
||||||
|
|
||||||
Box::new(
|
Box::new(
|
||||||
self.db
|
self.db
|
||||||
@@ -150,6 +154,8 @@ impl KvTree for RocksDbEngineTree<'_> {
|
|||||||
fn increment(&self, key: &[u8]) -> Result<Vec<u8>> {
|
fn increment(&self, key: &[u8]) -> Result<Vec<u8>> {
|
||||||
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
||||||
readoptions.set_total_order_seek(true);
|
readoptions.set_total_order_seek(true);
|
||||||
|
readoptions.set_async_io(cfg!(feature = "io_uring"));
|
||||||
|
|
||||||
let writeoptions = rust_rocksdb::WriteOptions::default();
|
let writeoptions = rust_rocksdb::WriteOptions::default();
|
||||||
|
|
||||||
let old = self.db.rocks.get_cf_opt(&self.cf(), key, &readoptions)?;
|
let old = self.db.rocks.get_cf_opt(&self.cf(), key, &readoptions)?;
|
||||||
@@ -168,6 +174,8 @@ impl KvTree for RocksDbEngineTree<'_> {
|
|||||||
fn increment_batch(&self, iter: &mut dyn Iterator<Item = Vec<u8>>) -> Result<()> {
|
fn increment_batch(&self, iter: &mut dyn Iterator<Item = Vec<u8>>) -> Result<()> {
|
||||||
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
||||||
readoptions.set_total_order_seek(true);
|
readoptions.set_total_order_seek(true);
|
||||||
|
readoptions.set_async_io(cfg!(feature = "io_uring"));
|
||||||
|
|
||||||
let writeoptions = rust_rocksdb::WriteOptions::default();
|
let writeoptions = rust_rocksdb::WriteOptions::default();
|
||||||
|
|
||||||
let mut batch = WriteBatchWithTransaction::<false>::default();
|
let mut batch = WriteBatchWithTransaction::<false>::default();
|
||||||
@@ -190,6 +198,7 @@ impl KvTree for RocksDbEngineTree<'_> {
|
|||||||
fn scan_prefix<'a>(&'a self, prefix: Vec<u8>) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a> {
|
fn scan_prefix<'a>(&'a self, prefix: Vec<u8>) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a> {
|
||||||
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
let mut readoptions = rust_rocksdb::ReadOptions::default();
|
||||||
readoptions.set_total_order_seek(true);
|
readoptions.set_total_order_seek(true);
|
||||||
|
readoptions.set_async_io(cfg!(feature = "io_uring"));
|
||||||
|
|
||||||
Box::new(
|
Box::new(
|
||||||
self.db
|
self.db
|
||||||
|
|||||||
@@ -35,7 +35,11 @@ pub(crate) struct Engine {
|
|||||||
impl KeyValueDatabaseEngine for Arc<Engine> {
|
impl KeyValueDatabaseEngine for Arc<Engine> {
|
||||||
fn open(config: &Config) -> Result<Self> {
|
fn open(config: &Config) -> Result<Self> {
|
||||||
let cache_capacity_bytes = config.db_cache_capacity_mb * 1024.0 * 1024.0;
|
let cache_capacity_bytes = config.db_cache_capacity_mb * 1024.0 * 1024.0;
|
||||||
|
|
||||||
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
let row_cache_capacity_bytes = (cache_capacity_bytes * 0.50) as usize;
|
let row_cache_capacity_bytes = (cache_capacity_bytes * 0.50) as usize;
|
||||||
|
|
||||||
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
let col_cache_capacity_bytes = (cache_capacity_bytes * 0.50) as usize;
|
let col_cache_capacity_bytes = (cache_capacity_bytes * 0.50) as usize;
|
||||||
|
|
||||||
let mut col_cache = HashMap::new();
|
let mut col_cache = HashMap::new();
|
||||||
@@ -128,6 +132,7 @@ impl KeyValueDatabaseEngine for Arc<Engine> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
fn memory_usage(&self) -> Result<String> {
|
fn memory_usage(&self) -> Result<String> {
|
||||||
let mut res = String::new();
|
let mut res = String::new();
|
||||||
let stats = rust_rocksdb::perf::get_memory_usage_stats(Some(&[&self.rocks]), Some(&[&self.row_cache]))?;
|
let stats = rust_rocksdb::perf::get_memory_usage_stats(Some(&[&self.rocks]), Some(&[&self.row_cache]))?;
|
||||||
|
|||||||
@@ -145,7 +145,14 @@ pub(crate) fn cf_options(cfg: &Config, name: &str, mut opts: Options, cache: &mu
|
|||||||
cache_size(cfg, cfg.statekeyshort_cache_capacity, 1024),
|
cache_size(cfg, cfg.statekeyshort_cache_capacity, 1024),
|
||||||
),
|
),
|
||||||
|
|
||||||
"pduid_pdu" => set_table_with_new_cache(&mut opts, cfg, cache, name, cfg.pdu_cache_capacity as usize * 1536),
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
|
"pduid_pdu" => set_table_with_new_cache(
|
||||||
|
&mut opts,
|
||||||
|
cfg,
|
||||||
|
cache,
|
||||||
|
name,
|
||||||
|
(cfg.pdu_cache_capacity as usize).saturating_mul(1536),
|
||||||
|
),
|
||||||
|
|
||||||
"eventid_outlierpdu" => set_table_with_shared_cache(&mut opts, cfg, cache, name, "pduid_pdu"),
|
"eventid_outlierpdu" => set_table_with_shared_cache(&mut opts, cfg, cache, name, "pduid_pdu"),
|
||||||
|
|
||||||
@@ -309,7 +316,10 @@ fn set_table_with_shared_cache(
|
|||||||
fn cache_size(config: &Config, base_size: u32, entity_size: usize) -> usize {
|
fn cache_size(config: &Config, base_size: u32, entity_size: usize) -> usize {
|
||||||
let ents = f64::from(base_size) * config.conduit_cache_capacity_modifier;
|
let ents = f64::from(base_size) * config.conduit_cache_capacity_modifier;
|
||||||
|
|
||||||
ents as usize * entity_size
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
|
(ents as usize)
|
||||||
|
.checked_mul(entity_size)
|
||||||
|
.expect("cache capacity size is too large")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table_options(_config: &Config) -> BlockBasedOptions {
|
fn table_options(_config: &Config) -> BlockBasedOptions {
|
||||||
|
|||||||
+29
-15
@@ -21,7 +21,7 @@ thread_local! {
|
|||||||
|
|
||||||
struct PreparedStatementIterator<'a> {
|
struct PreparedStatementIterator<'a> {
|
||||||
iterator: Box<dyn Iterator<Item = TupleOfBytes> + 'a>,
|
iterator: Box<dyn Iterator<Item = TupleOfBytes> + 'a>,
|
||||||
_statement_ref: NonAliasingBox<rusqlite::Statement<'a>>,
|
_statement_ref: AliasableBox<rusqlite::Statement<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for PreparedStatementIterator<'_> {
|
impl Iterator for PreparedStatementIterator<'_> {
|
||||||
@@ -30,16 +30,25 @@ impl Iterator for PreparedStatementIterator<'_> {
|
|||||||
fn next(&mut self) -> Option<Self::Item> { self.iterator.next() }
|
fn next(&mut self) -> Option<Self::Item> { self.iterator.next() }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NonAliasingBox<T>(*mut T);
|
struct AliasableBox<T>(*mut T);
|
||||||
impl<T> Drop for NonAliasingBox<T> {
|
impl<T> Drop for AliasableBox<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// TODO: figure out why this is necessary, but also this is sqlite so dont think
|
// SAFETY: This is cursed and relies on non-local reasoning.
|
||||||
// i care that much. i tried checking commit history but couldn't find out why
|
//
|
||||||
// this was done.
|
// In order for this to be safe:
|
||||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
//
|
||||||
unsafe {
|
// * All aliased references to this value must have been dropped first, for
|
||||||
_ = Box::from_raw(self.0);
|
// example by coming after its referrers in struct fields, because struct
|
||||||
};
|
// fields are automatically dropped in order from top to bottom in the absence
|
||||||
|
// of an explicit Drop impl. Otherwise, the referrers may read into
|
||||||
|
// deallocated memory.
|
||||||
|
// * This type must not be copyable or cloneable. Otherwise, double-free can
|
||||||
|
// occur.
|
||||||
|
//
|
||||||
|
// These conditions are met, but again, note that changing safe code in
|
||||||
|
// this module can result in unsoundness if any of these constraints are
|
||||||
|
// violated.
|
||||||
|
unsafe { drop(Box::from_raw(self.0)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,8 +102,13 @@ impl KeyValueDatabaseEngine for Arc<Engine> {
|
|||||||
// 2. divide by permanent connections + permanent iter connections + write
|
// 2. divide by permanent connections + permanent iter connections + write
|
||||||
// connection
|
// connection
|
||||||
// 3. round down to nearest integer
|
// 3. round down to nearest integer
|
||||||
let cache_size_per_thread: u32 =
|
#[allow(
|
||||||
((config.db_cache_capacity_mb * 1024.0) / ((num_cpus::get().max(1) * 2) + 1) as f64) as u32;
|
clippy::as_conversions,
|
||||||
|
clippy::cast_possible_truncation,
|
||||||
|
clippy::cast_precision_loss,
|
||||||
|
clippy::cast_sign_loss
|
||||||
|
)]
|
||||||
|
let cache_size_per_thread = ((config.db_cache_capacity_mb * 1024.0) / ((num_cpus::get() as f64 * 2.0) + 1.0)) as u32;
|
||||||
|
|
||||||
let writer = Mutex::new(Engine::prepare_conn(&path, cache_size_per_thread)?);
|
let writer = Mutex::new(Engine::prepare_conn(&path, cache_size_per_thread)?);
|
||||||
|
|
||||||
@@ -161,7 +175,7 @@ impl SqliteTable {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let statement_ref = NonAliasingBox(statement);
|
let statement_ref = AliasableBox(statement);
|
||||||
|
|
||||||
//let name = self.name.clone();
|
//let name = self.name.clone();
|
||||||
|
|
||||||
@@ -250,7 +264,7 @@ impl KvTree for SqliteTable {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let statement_ref = NonAliasingBox(statement);
|
let statement_ref = AliasableBox(statement);
|
||||||
|
|
||||||
let iterator = Box::new(
|
let iterator = Box::new(
|
||||||
statement
|
statement
|
||||||
@@ -272,7 +286,7 @@ impl KvTree for SqliteTable {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let statement_ref = NonAliasingBox(statement);
|
let statement_ref = AliasableBox(statement);
|
||||||
|
|
||||||
let iterator = Box::new(
|
let iterator = Box::new(
|
||||||
statement
|
statement
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ impl Watchers {
|
|||||||
let mut watchers = self.watchers.write().unwrap();
|
let mut watchers = self.watchers.write().unwrap();
|
||||||
for prefix in triggered {
|
for prefix in triggered {
|
||||||
if let Some(tx) = watchers.remove(prefix) {
|
if let Some(tx) = watchers.remove(prefix) {
|
||||||
_ = tx.0.send(());
|
tx.0.send(()).expect("channel should still be open");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-1
@@ -131,9 +131,10 @@ fn request_result_log(method: &Method, uri: &Uri, result: &axum::response::Respo
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cors_layer(_server: &Server) -> CorsLayer {
|
fn cors_layer(_server: &Server) -> CorsLayer {
|
||||||
const METHODS: [Method; 6] = [
|
const METHODS: [Method; 7] = [
|
||||||
Method::GET,
|
Method::GET,
|
||||||
Method::HEAD,
|
Method::HEAD,
|
||||||
|
Method::PATCH,
|
||||||
Method::POST,
|
Method::POST,
|
||||||
Method::PUT,
|
Method::PUT,
|
||||||
Method::DELETE,
|
Method::DELETE,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::{service::admin::escape_html, services, Result};
|
|||||||
|
|
||||||
pub(crate) async fn register(body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
pub(crate) async fn register(body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
||||||
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
||||||
let appservice_config = body[1..body.len() - 1].join("\n");
|
let appservice_config = body[1..body.len().checked_sub(1).unwrap()].join("\n");
|
||||||
let parsed_config = serde_yaml::from_str::<Registration>(&appservice_config);
|
let parsed_config = serde_yaml::from_str::<Registration>(&appservice_config);
|
||||||
match parsed_config {
|
match parsed_config {
|
||||||
Ok(yaml) => match services().appservice.register_appservice(yaml).await {
|
Ok(yaml) => match services().appservice.register_appservice(yaml).await {
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ pub(crate) async fn get_remote_pdu_list(
|
|||||||
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
||||||
let list = body
|
let list = body
|
||||||
.clone()
|
.clone()
|
||||||
.drain(1..body.len() - 1)
|
.drain(1..body.len().checked_sub(1).unwrap())
|
||||||
.filter_map(|pdu| EventId::parse(pdu).ok())
|
.filter_map(|pdu| EventId::parse(pdu).ok())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@ pub(crate) async fn change_log_level(
|
|||||||
|
|
||||||
pub(crate) async fn sign_json(body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
pub(crate) async fn sign_json(body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
||||||
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
||||||
let string = body[1..body.len() - 1].join("\n");
|
let string = body[1..body.len().checked_sub(1).unwrap()].join("\n");
|
||||||
match serde_json::from_str(&string) {
|
match serde_json::from_str(&string) {
|
||||||
Ok(mut value) => {
|
Ok(mut value) => {
|
||||||
ruma::signatures::sign_json(
|
ruma::signatures::sign_json(
|
||||||
@@ -404,7 +404,7 @@ pub(crate) async fn sign_json(body: Vec<&str>) -> Result<RoomMessageEventContent
|
|||||||
|
|
||||||
pub(crate) async fn verify_json(body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
pub(crate) async fn verify_json(body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
||||||
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
||||||
let string = body[1..body.len() - 1].join("\n");
|
let string = body[1..body.len().checked_sub(1).unwrap()].join("\n");
|
||||||
match serde_json::from_str(&string) {
|
match serde_json::from_str(&string) {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
let pub_key_map = RwLock::new(BTreeMap::new());
|
let pub_key_map = RwLock::new(BTreeMap::new());
|
||||||
|
|||||||
@@ -139,14 +139,19 @@ pub(crate) async fn delete(
|
|||||||
|
|
||||||
pub(crate) async fn delete_list(body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
pub(crate) async fn delete_list(body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
||||||
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
||||||
let mxc_list = body.clone().drain(1..body.len() - 1).collect::<Vec<_>>();
|
let mxc_list = body
|
||||||
|
.clone()
|
||||||
|
.drain(1..body.len().checked_sub(1).unwrap())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut mxc_deletion_count = 0;
|
let mut mxc_deletion_count: usize = 0;
|
||||||
|
|
||||||
for mxc in mxc_list {
|
for mxc in mxc_list {
|
||||||
debug!("Deleting MXC {mxc} in bulk");
|
debug!("Deleting MXC {mxc} in bulk");
|
||||||
services().media.delete(mxc.to_owned()).await?;
|
services().media.delete(mxc.to_owned()).await?;
|
||||||
mxc_deletion_count += 1;
|
mxc_deletion_count = mxc_deletion_count
|
||||||
|
.checked_add(1)
|
||||||
|
.expect("mxc_deletion_count should not get this high");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ pub(crate) async fn list(_body: Vec<&str>, page: Option<usize>) -> Result<RoomMe
|
|||||||
|
|
||||||
let rooms = rooms
|
let rooms = rooms
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(page.saturating_sub(1) * PAGE_SIZE)
|
.skip(page.saturating_sub(1).saturating_mul(PAGE_SIZE))
|
||||||
.take(PAGE_SIZE)
|
.take(PAGE_SIZE)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub(crate) async fn process(command: RoomDirectoryCommand, _body: Vec<&str>) ->
|
|||||||
|
|
||||||
let rooms = rooms
|
let rooms = rooms
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(page.saturating_sub(1) * PAGE_SIZE)
|
.skip(page.saturating_sub(1).saturating_mul(PAGE_SIZE))
|
||||||
.take(PAGE_SIZE)
|
.take(PAGE_SIZE)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ pub(crate) async fn memory_usage(_body: Vec<&str>) -> Result<RoomMessageEventCon
|
|||||||
Ok(RoomMessageEventContent::text_plain(format!(
|
Ok(RoomMessageEventContent::text_plain(format!(
|
||||||
"Services:\n{response0}\n\nDatabase:\n{response1}\n{}",
|
"Services:\n{response0}\n\nDatabase:\n{response1}\n{}",
|
||||||
if !response2.is_empty() {
|
if !response2.is_empty() {
|
||||||
"Allocator:\n{response2}"
|
format!("Allocator:\n {response2}")
|
||||||
} else {
|
} else {
|
||||||
""
|
String::new()
|
||||||
}
|
}
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use std::{fmt::Write as _, sync::Arc};
|
use std::{fmt::Write as _, sync::Arc};
|
||||||
|
|
||||||
use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomId, UserId};
|
use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomId, UserId};
|
||||||
use tracing::{error, info, warn};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::client_server::{join_room_by_id_helper, leave_all_rooms, AUTO_GEN_PASSWORD_LENGTH},
|
api::client_server::{auto_join_rooms, leave_all_rooms, AUTO_GEN_PASSWORD_LENGTH},
|
||||||
service::admin::{escape_html, get_room_info},
|
service::admin::{escape_html, get_room_info},
|
||||||
services,
|
services,
|
||||||
utils::{self, user_id::user_is_local},
|
utils::{self, user_id::user_is_local},
|
||||||
@@ -15,7 +14,7 @@ pub(crate) async fn list(_body: Vec<&str>) -> Result<RoomMessageEventContent> {
|
|||||||
match services().users.list_local_users() {
|
match services().users.list_local_users() {
|
||||||
Ok(users) => {
|
Ok(users) => {
|
||||||
let mut msg = format!("Found {} local user account(s):\n", users.len());
|
let mut msg = format!("Found {} local user account(s):\n", users.len());
|
||||||
msg += &users.join("\n");
|
_ = write!(msg, "{}\n", users.join("\n"));
|
||||||
Ok(RoomMessageEventContent::text_plain(&msg))
|
Ok(RoomMessageEventContent::text_plain(&msg))
|
||||||
},
|
},
|
||||||
Err(e) => Ok(RoomMessageEventContent::text_plain(e.to_string())),
|
Err(e) => Ok(RoomMessageEventContent::text_plain(e.to_string())),
|
||||||
@@ -28,15 +27,17 @@ pub(crate) async fn create(
|
|||||||
let password = password.unwrap_or_else(|| utils::random_string(AUTO_GEN_PASSWORD_LENGTH));
|
let password = password.unwrap_or_else(|| utils::random_string(AUTO_GEN_PASSWORD_LENGTH));
|
||||||
|
|
||||||
// Validate user id
|
// Validate user id
|
||||||
let user_id =
|
let user_id = match UserId::parse_with_server_name(
|
||||||
match UserId::parse_with_server_name(username.as_str().to_lowercase(), services().globals.server_name()) {
|
username.as_str().to_lowercase(),
|
||||||
Ok(id) => id,
|
&services().globals.config.server_name,
|
||||||
Err(e) => {
|
) {
|
||||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
Ok(id) => id,
|
||||||
"The supplied username is not a valid username: {e}"
|
Err(e) => {
|
||||||
)))
|
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||||
},
|
"The supplied username is not a valid username: {e}"
|
||||||
};
|
)))
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
if !user_is_local(&user_id) {
|
if !user_is_local(&user_id) {
|
||||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||||
@@ -61,8 +62,13 @@ pub(crate) async fn create(
|
|||||||
|
|
||||||
// If `new_user_displayname_suffix` is set, registration will push whatever
|
// If `new_user_displayname_suffix` is set, registration will push whatever
|
||||||
// content is set to the user's display name with a space before it
|
// content is set to the user's display name with a space before it
|
||||||
if !services().globals.new_user_displayname_suffix().is_empty() {
|
if !services()
|
||||||
displayname.push_str(&(" ".to_owned() + services().globals.new_user_displayname_suffix()));
|
.globals
|
||||||
|
.config
|
||||||
|
.new_user_displayname_suffix
|
||||||
|
.is_empty()
|
||||||
|
{
|
||||||
|
_ = write!(displayname, " {}", services().globals.config.new_user_displayname_suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
services()
|
services()
|
||||||
@@ -86,36 +92,7 @@ pub(crate) async fn create(
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
if !services().globals.config.auto_join_rooms.is_empty() {
|
if !services().globals.config.auto_join_rooms.is_empty() {
|
||||||
for room in &services().globals.config.auto_join_rooms {
|
auto_join_rooms(&user_id).await?;
|
||||||
if !services()
|
|
||||||
.rooms
|
|
||||||
.state_cache
|
|
||||||
.server_in_room(services().globals.server_name(), room)?
|
|
||||||
{
|
|
||||||
warn!("Skipping room {room} to automatically join as we have never joined before.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(room_id_server_name) = room.server_name() {
|
|
||||||
match join_room_by_id_helper(
|
|
||||||
Some(&user_id),
|
|
||||||
room,
|
|
||||||
Some("Automatically joining this room upon registration".to_owned()),
|
|
||||||
&[room_id_server_name.to_owned(), services().globals.server_name().to_owned()],
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(_) => {
|
|
||||||
info!("Automatically joined room {room} for user {user_id}");
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
// don't return this error so we don't fail registrations
|
|
||||||
error!("Failed to automatically join room {room} for user {user_id}: {e}");
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we dont add a device since we're not the user, just the creator
|
// we dont add a device since we're not the user, just the creator
|
||||||
@@ -152,7 +129,7 @@ pub(crate) async fn deactivate(
|
|||||||
== UserId::parse_with_server_name("conduit", services().globals.server_name()).expect("conduit user exists")
|
== UserId::parse_with_server_name("conduit", services().globals.server_name()).expect("conduit user exists")
|
||||||
{
|
{
|
||||||
return Ok(RoomMessageEventContent::text_plain(
|
return Ok(RoomMessageEventContent::text_plain(
|
||||||
"Not allowed to deactivate the Conduit service account.",
|
"Not allowed to deactivate the conduwuit service account.",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +165,7 @@ pub(crate) async fn reset_password(_body: Vec<&str>, username: String) -> Result
|
|||||||
};
|
};
|
||||||
|
|
||||||
// check if user belongs to our server
|
// check if user belongs to our server
|
||||||
if user_id.server_name() != services().globals.server_name() {
|
if !user_is_local(&user_id) {
|
||||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||||
"User {user_id} does not belong to our server."
|
"User {user_id} does not belong to our server."
|
||||||
)));
|
)));
|
||||||
@@ -234,7 +211,7 @@ pub(crate) async fn deactivate_all(body: Vec<&str>, leave_rooms: bool, force: bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut deactivation_count = 0;
|
let mut deactivation_count: usize = 0;
|
||||||
let mut admins = Vec::new();
|
let mut admins = Vec::new();
|
||||||
|
|
||||||
if !force {
|
if !force {
|
||||||
@@ -253,7 +230,7 @@ pub(crate) async fn deactivate_all(body: Vec<&str>, leave_rooms: bool, force: bo
|
|||||||
|
|
||||||
for &user_id in &user_ids {
|
for &user_id in &user_ids {
|
||||||
// check if user belongs to our server and skips over non-local users
|
// check if user belongs to our server and skips over non-local users
|
||||||
if user_id.server_name() != services().globals.server_name() {
|
if !user_is_local(user_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +248,7 @@ pub(crate) async fn deactivate_all(body: Vec<&str>, leave_rooms: bool, force: bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if services().users.deactivate_account(user_id).is_ok() {
|
if services().users.deactivate_account(user_id).is_ok() {
|
||||||
deactivation_count += 1;
|
deactivation_count = deactivation_count.saturating_add(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +288,7 @@ pub(crate) async fn list_joined_rooms(_body: Vec<&str>, user_id: String) -> Resu
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if user_id.server_name() != services().globals.server_name() {
|
if !user_is_local(&user_id) {
|
||||||
return Ok(RoomMessageEventContent::text_plain("User does not belong to our server."));
|
return Ok(RoomMessageEventContent::text_plain("User does not belong to our server."));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +312,8 @@ pub(crate) async fn list_joined_rooms(_body: Vec<&str>, user_id: String) -> Resu
|
|||||||
rooms.reverse();
|
rooms.reverse();
|
||||||
|
|
||||||
let output_plain = format!(
|
let output_plain = format!(
|
||||||
"Rooms {user_id} Joined:\n{}",
|
"Rooms {user_id} Joined ({}):\n{}",
|
||||||
|
rooms.len(),
|
||||||
rooms
|
rooms
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(id, members, name)| format!("{id}\tMembers: {members}\tName: {name}"))
|
.map(|(id, members, name)| format!("{id}\tMembers: {members}\tName: {name}"))
|
||||||
@@ -343,8 +321,9 @@ pub(crate) async fn list_joined_rooms(_body: Vec<&str>, user_id: String) -> Resu
|
|||||||
.join("\n")
|
.join("\n")
|
||||||
);
|
);
|
||||||
let output_html = format!(
|
let output_html = format!(
|
||||||
"<table><caption>Rooms {user_id} \
|
"<table><caption>Rooms {user_id} Joined \
|
||||||
Joined</caption>\n<tr><th>id</th>\t<th>members</th>\t<th>name</th></tr>\n{}</table>",
|
({})</caption>\n<tr><th>id</th>\t<th>members</th>\t<th>name</th></tr>\n{}</table>",
|
||||||
|
rooms.len(),
|
||||||
rooms
|
rooms
|
||||||
.iter()
|
.iter()
|
||||||
.fold(String::new(), |mut output, (id, members, name)| {
|
.fold(String::new(), |mut output, (id, members, name)| {
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ impl Client {
|
|||||||
fn base(config: &Config) -> Result<reqwest::ClientBuilder> {
|
fn base(config: &Config) -> Result<reqwest::ClientBuilder> {
|
||||||
let version = conduwuit_version();
|
let version = conduwuit_version();
|
||||||
|
|
||||||
|
let user_agent = format!("Conduwuit/{version}");
|
||||||
|
|
||||||
let mut builder = reqwest::Client::builder()
|
let mut builder = reqwest::Client::builder()
|
||||||
.hickory_dns(true)
|
.hickory_dns(true)
|
||||||
.connect_timeout(Duration::from_secs(config.request_conn_timeout))
|
.connect_timeout(Duration::from_secs(config.request_conn_timeout))
|
||||||
@@ -96,7 +98,7 @@ impl Client {
|
|||||||
.timeout(Duration::from_secs(config.request_total_timeout))
|
.timeout(Duration::from_secs(config.request_total_timeout))
|
||||||
.pool_idle_timeout(Duration::from_secs(config.request_idle_timeout))
|
.pool_idle_timeout(Duration::from_secs(config.request_idle_timeout))
|
||||||
.pool_max_idle_per_host(config.request_idle_per_host.into())
|
.pool_max_idle_per_host(config.request_idle_per_host.into())
|
||||||
.user_agent("Conduwuit".to_owned() + "/" + &version)
|
.user_agent(user_agent)
|
||||||
.redirect(redirect::Policy::limited(6))
|
.redirect(redirect::Policy::limited(6))
|
||||||
.connection_verbose(true);
|
.connection_verbose(true);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ pub(crate) struct Hooked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Resolver {
|
impl Resolver {
|
||||||
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
pub(crate) fn new(config: &Config) -> Self {
|
pub(crate) fn new(config: &Config) -> Self {
|
||||||
let (sys_conf, mut opts) = hickory_resolver::system_conf::read_system_conf()
|
let (sys_conf, mut opts) = hickory_resolver::system_conf::read_system_conf()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use crate::{services, utils, Error, Result};
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct FileMeta {
|
pub(crate) struct FileMeta {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) content_disposition: Option<String>,
|
pub(crate) content_disposition: Option<String>,
|
||||||
pub(crate) content_type: Option<String>,
|
pub(crate) content_type: Option<String>,
|
||||||
pub(crate) file: Vec<u8>,
|
pub(crate) file: Vec<u8>,
|
||||||
@@ -187,7 +188,9 @@ impl Service {
|
|||||||
Ok(duration) => {
|
Ok(duration) => {
|
||||||
debug!("Parsed duration: {:?}", duration);
|
debug!("Parsed duration: {:?}", duration);
|
||||||
debug!("System time now: {:?}", SystemTime::now());
|
debug!("System time now: {:?}", SystemTime::now());
|
||||||
SystemTime::now() - duration
|
SystemTime::now().checked_sub(duration).ok_or_else(|| {
|
||||||
|
Error::bad_database("Duration specified is not valid against the current system time")
|
||||||
|
})?
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to parse user-specified time duration: {}", e);
|
error!("Failed to parse user-specified time duration: {}", e);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ pub(crate) struct Services<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Services<'_> {
|
impl Services<'_> {
|
||||||
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
pub(crate) fn build<
|
pub(crate) fn build<
|
||||||
D: appservice::Data
|
D: appservice::Data
|
||||||
+ pusher::Data
|
+ pusher::Data
|
||||||
|
|||||||
@@ -188,13 +188,14 @@ impl Service {
|
|||||||
|
|
||||||
let ctx = PushConditionRoomCtx {
|
let ctx = PushConditionRoomCtx {
|
||||||
room_id: room_id.to_owned(),
|
room_id: room_id.to_owned(),
|
||||||
member_count: UInt::from(
|
member_count: UInt::try_from(
|
||||||
services()
|
services()
|
||||||
.rooms
|
.rooms
|
||||||
.state_cache
|
.state_cache
|
||||||
.room_joined_count(room_id)?
|
.room_joined_count(room_id)?
|
||||||
.unwrap_or(1) as u32,
|
.unwrap_or(1),
|
||||||
),
|
)
|
||||||
|
.unwrap_or_else(|_| uint!(0)),
|
||||||
user_id: user.to_owned(),
|
user_id: user.to_owned(),
|
||||||
user_display_name: services()
|
user_display_name: services()
|
||||||
.users
|
.users
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ use std::{
|
|||||||
|
|
||||||
pub(crate) use data::Data;
|
pub(crate) use data::Data;
|
||||||
use ruma::{api::client::error::ErrorKind, EventId, RoomId};
|
use ruma::{api::client::error::ErrorKind, EventId, RoomId};
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, trace, warn};
|
||||||
|
|
||||||
use crate::{services, Error, Result};
|
use crate::{services, utils::debug_slice_truncated, Error, Result};
|
||||||
|
|
||||||
pub(crate) struct Service {
|
pub(crate) struct Service {
|
||||||
pub(crate) db: &'static dyn Data,
|
pub(crate) db: &'static dyn Data,
|
||||||
@@ -30,7 +30,7 @@ impl Service {
|
|||||||
.filter_map(move |sid| services().rooms.short.get_eventid_from_short(sid).ok()))
|
.filter_map(move |sid| services().rooms.short.get_eventid_from_short(sid).ok()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip(self), fields(starting_events = debug_slice_truncated(starting_events, 5)))]
|
||||||
pub(crate) async fn get_auth_chain(&self, room_id: &RoomId, starting_events: &[&EventId]) -> Result<Vec<u64>> {
|
pub(crate) async fn get_auth_chain(&self, room_id: &RoomId, starting_events: &[&EventId]) -> Result<Vec<u64>> {
|
||||||
const NUM_BUCKETS: usize = 50; //TODO: change possible w/o disrupting db?
|
const NUM_BUCKETS: usize = 50; //TODO: change possible w/o disrupting db?
|
||||||
const BUCKET: BTreeSet<(u64, &EventId)> = BTreeSet::new();
|
const BUCKET: BTreeSet<(u64, &EventId)> = BTreeSet::new();
|
||||||
@@ -68,6 +68,7 @@ impl Service {
|
|||||||
.auth_chain
|
.auth_chain
|
||||||
.get_cached_eventid_authchain(&chunk_key)?
|
.get_cached_eventid_authchain(&chunk_key)?
|
||||||
{
|
{
|
||||||
|
trace!("Found cache entry for whole chunk");
|
||||||
full_auth_chain.extend(cached.iter().copied());
|
full_auth_chain.extend(cached.iter().copied());
|
||||||
hits += 1;
|
hits += 1;
|
||||||
continue;
|
continue;
|
||||||
@@ -82,6 +83,7 @@ impl Service {
|
|||||||
.auth_chain
|
.auth_chain
|
||||||
.get_cached_eventid_authchain(&[sevent_id])?
|
.get_cached_eventid_authchain(&[sevent_id])?
|
||||||
{
|
{
|
||||||
|
trace!(?event_id, "Found cache entry for event");
|
||||||
chunk_cache.extend(cached.iter().copied());
|
chunk_cache.extend(cached.iter().copied());
|
||||||
hits2 += 1;
|
hits2 += 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -132,15 +134,18 @@ impl Service {
|
|||||||
Ok(full_auth_chain)
|
Ok(full_auth_chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self, event_id))]
|
#[tracing::instrument(skip(self, room_id))]
|
||||||
fn get_auth_chain_inner(&self, room_id: &RoomId, event_id: &EventId) -> Result<HashSet<u64>> {
|
fn get_auth_chain_inner(&self, room_id: &RoomId, event_id: &EventId) -> Result<HashSet<u64>> {
|
||||||
let mut todo = vec![Arc::from(event_id)];
|
let mut todo = vec![Arc::from(event_id)];
|
||||||
let mut found = HashSet::new();
|
let mut found = HashSet::new();
|
||||||
|
|
||||||
while let Some(event_id) = todo.pop() {
|
while let Some(event_id) = todo.pop() {
|
||||||
|
trace!(?event_id, "processing auth event");
|
||||||
|
|
||||||
match services().rooms.timeline.get_pdu(&event_id) {
|
match services().rooms.timeline.get_pdu(&event_id) {
|
||||||
Ok(Some(pdu)) => {
|
Ok(Some(pdu)) => {
|
||||||
if pdu.room_id != room_id {
|
if pdu.room_id != room_id {
|
||||||
|
error!(?event_id, ?pdu, "auth event for incorrect room_id");
|
||||||
return Err(Error::BadRequest(ErrorKind::forbidden(), "Evil event in db"));
|
return Err(Error::BadRequest(ErrorKind::forbidden(), "Evil event in db"));
|
||||||
}
|
}
|
||||||
for auth_event in &pdu.auth_events {
|
for auth_event in &pdu.auth_events {
|
||||||
@@ -150,6 +155,7 @@ impl Service {
|
|||||||
.get_or_create_shorteventid(auth_event)?;
|
.get_or_create_shorteventid(auth_event)?;
|
||||||
|
|
||||||
if found.insert(sauthevent) {
|
if found.insert(sauthevent) {
|
||||||
|
trace!(?event_id, ?auth_event, "adding auth event to processing queue");
|
||||||
todo.push(auth_event.clone());
|
todo.push(auth_event.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,6 +236,7 @@ impl Service {
|
|||||||
const MAX_DURATION: Duration = Duration::from_secs(60 * 60 * 24);
|
const MAX_DURATION: Duration = Duration::from_secs(60 * 60 * 24);
|
||||||
let min_duration = cmp::min(MAX_DURATION, Duration::from_secs(5 * 60) * (*tries) * (*tries));
|
let min_duration = cmp::min(MAX_DURATION, Duration::from_secs(5 * 60) * (*tries) * (*tries));
|
||||||
let duration = time.elapsed();
|
let duration = time.elapsed();
|
||||||
|
|
||||||
if duration < min_duration {
|
if duration < min_duration {
|
||||||
debug!(
|
debug!(
|
||||||
duration = ?duration,
|
duration = ?duration,
|
||||||
@@ -1003,7 +1004,7 @@ impl Service {
|
|||||||
hash_map::Entry::Vacant(e) => {
|
hash_map::Entry::Vacant(e) => {
|
||||||
e.insert((Instant::now(), 1));
|
e.insert((Instant::now(), 1));
|
||||||
},
|
},
|
||||||
hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1),
|
hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1.saturating_add(1)),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1034,10 +1035,9 @@ impl Service {
|
|||||||
.get(&*next_id)
|
.get(&*next_id)
|
||||||
{
|
{
|
||||||
// Exponential backoff
|
// Exponential backoff
|
||||||
let mut min_elapsed_duration = Duration::from_secs(5 * 60) * (*tries) * (*tries);
|
const MAX_DURATION: Duration = Duration::from_secs(60 * 60 * 24);
|
||||||
if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) {
|
let min_elapsed_duration =
|
||||||
min_elapsed_duration = Duration::from_secs(60 * 60 * 24);
|
cmp::min(MAX_DURATION, Duration::from_secs(5 * 60) * (*tries) * (*tries));
|
||||||
}
|
|
||||||
|
|
||||||
if time.elapsed() < min_elapsed_duration {
|
if time.elapsed() < min_elapsed_duration {
|
||||||
info!("Backing off from {}", next_id);
|
info!("Backing off from {}", next_id);
|
||||||
@@ -1143,10 +1143,9 @@ impl Service {
|
|||||||
.get(&**next_id)
|
.get(&**next_id)
|
||||||
{
|
{
|
||||||
// Exponential backoff
|
// Exponential backoff
|
||||||
let mut min_elapsed_duration = Duration::from_secs(5 * 60) * (*tries) * (*tries);
|
const MAX_DURATION: Duration = Duration::from_secs(60 * 60 * 24);
|
||||||
if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) {
|
let min_elapsed_duration =
|
||||||
min_elapsed_duration = Duration::from_secs(60 * 60 * 24);
|
cmp::min(MAX_DURATION, Duration::from_secs(5 * 60) * (*tries) * (*tries));
|
||||||
}
|
|
||||||
|
|
||||||
if time.elapsed() < min_elapsed_duration {
|
if time.elapsed() < min_elapsed_duration {
|
||||||
debug!("Backing off from {}", next_id);
|
debug!("Backing off from {}", next_id);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ pub(crate) use data::Data;
|
|||||||
use ruma::{
|
use ruma::{
|
||||||
api::{client::relations::get_relating_events, Direction},
|
api::{client::relations::get_relating_events, Direction},
|
||||||
events::{relation::RelationType, TimelineEventType},
|
events::{relation::RelationType, TimelineEventType},
|
||||||
EventId, RoomId, UInt, UserId,
|
uint, EventId, RoomId, UInt, UserId,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@@ -57,8 +57,9 @@ impl Service {
|
|||||||
|
|
||||||
// Use limit or else 10, with maximum 100
|
// Use limit or else 10, with maximum 100
|
||||||
let limit = limit
|
let limit = limit
|
||||||
.and_then(|u| u32::try_from(u).ok())
|
.unwrap_or_else(|| uint!(10))
|
||||||
.map_or(10_usize, |u| u as usize)
|
.try_into()
|
||||||
|
.unwrap_or(10)
|
||||||
.min(100);
|
.min(100);
|
||||||
|
|
||||||
let next_token;
|
let next_token;
|
||||||
|
|||||||
@@ -818,7 +818,7 @@ impl FedDest {
|
|||||||
fn into_uri_string(self) -> String {
|
fn into_uri_string(self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::Literal(addr) => addr.to_string(),
|
Self::Literal(addr) => addr.to_string(),
|
||||||
Self::Named(host, port) => host + &port,
|
Self::Named(host, port) => format!("{host}{port}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+53
-2
@@ -21,6 +21,7 @@ use crate::{services, Error, Result};
|
|||||||
|
|
||||||
pub(crate) fn clamp<T: Ord>(val: T, min: T, max: T) -> T { cmp::min(cmp::max(val, min), max) }
|
pub(crate) fn clamp<T: Ord>(val: T, min: T, max: T) -> T { cmp::min(cmp::max(val, min), max) }
|
||||||
|
|
||||||
|
#[allow(clippy::as_conversions)]
|
||||||
pub(crate) fn millis_since_unix_epoch() -> u64 {
|
pub(crate) fn millis_since_unix_epoch() -> u64 {
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
@@ -196,10 +197,60 @@ impl fmt::Display for HtmlEscape<'_> {
|
|||||||
/// git commit hashes.
|
/// git commit hashes.
|
||||||
pub(crate) fn conduwuit_version() -> String {
|
pub(crate) fn conduwuit_version() -> String {
|
||||||
match option_env!("CONDUWUIT_VERSION_EXTRA") {
|
match option_env!("CONDUWUIT_VERSION_EXTRA") {
|
||||||
Some(extra) => format!("{} ({})", env!("CARGO_PKG_VERSION"), extra),
|
Some(extra) => {
|
||||||
|
if extra.is_empty() {
|
||||||
|
env!("CARGO_PKG_VERSION").to_owned()
|
||||||
|
} else {
|
||||||
|
format!("{} ({})", env!("CARGO_PKG_VERSION"), extra)
|
||||||
|
}
|
||||||
|
},
|
||||||
None => match option_env!("CONDUIT_VERSION_EXTRA") {
|
None => match option_env!("CONDUIT_VERSION_EXTRA") {
|
||||||
Some(extra) => format!("{} ({})", env!("CARGO_PKG_VERSION"), extra),
|
Some(extra) => {
|
||||||
|
if extra.is_empty() {
|
||||||
|
env!("CARGO_PKG_VERSION").to_owned()
|
||||||
|
} else {
|
||||||
|
format!("{} ({})", env!("CARGO_PKG_VERSION"), extra)
|
||||||
|
}
|
||||||
|
},
|
||||||
None => env!("CARGO_PKG_VERSION").to_owned(),
|
None => env!("CARGO_PKG_VERSION").to_owned(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Debug-formats the given slice, but only up to the first `max_len` elements.
|
||||||
|
/// Any further elements are replaced by an ellipsis.
|
||||||
|
///
|
||||||
|
/// See also [`debug_slice_truncated()`],
|
||||||
|
pub(crate) struct TruncatedDebugSlice<'a, T> {
|
||||||
|
inner: &'a [T],
|
||||||
|
max_len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: fmt::Debug> fmt::Debug for TruncatedDebugSlice<'_, T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
if self.inner.len() <= self.max_len {
|
||||||
|
write!(f, "{:?}", self.inner)
|
||||||
|
} else {
|
||||||
|
f.debug_list()
|
||||||
|
.entries(&self.inner[..self.max_len])
|
||||||
|
.entry(&"...")
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See [`TruncatedDebugSlice`]. Useful for `#[instrument]`:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #[tracing::instrument(fields(
|
||||||
|
/// foos = debug_slice_truncated(foos, N)
|
||||||
|
/// ))]
|
||||||
|
/// ```
|
||||||
|
pub(crate) fn debug_slice_truncated<T: fmt::Debug>(
|
||||||
|
slice: &[T], max_len: usize,
|
||||||
|
) -> tracing::field::DebugValue<TruncatedDebugSlice<'_, T>> {
|
||||||
|
tracing::field::debug(TruncatedDebugSlice {
|
||||||
|
inner: slice,
|
||||||
|
max_len,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user