Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f57e2d734 | |||
| 04fc87ad07 | |||
| dc573f4562 | |||
| 74826dcb94 | |||
| b20c4e0539 | |||
| fb8a2846df | |||
| 04971d0430 | |||
| f098532b09 | |||
| 60927c1c72 | |||
| 03296412ab | |||
| 934ab6a4fe | |||
| 1378399f9d | |||
| 09680f653f | |||
| 39f19c483a | |||
| 39c0f4ea3d | |||
| 405167fc3f | |||
| b13ea4ff45 | |||
| 100fc5e0f7 | |||
| 96f9d64111 | |||
| 30ad5da5f1 | |||
| ce0ca96df4 | |||
| 4851ad26e2 | |||
| 328759a60f | |||
| 463fa4fd53 | |||
| db494e0d68 | |||
| 4788040458 | |||
| 06531993f6 | |||
| c29197b3f4 | |||
| 739eab46d5 | |||
| 923a98eb66 | |||
| 4430e4dee0 | |||
| d67f19a55d | |||
| b903b46d16 | |||
| 167559bb27 | |||
| 838e4b9d8d | |||
| 038b71fc9d | |||
| 720fbd09c2 | |||
| c42cb90dd3 | |||
| 5950355348 | |||
| f79bd2ac72 | |||
| 80ec0e31b1 | |||
| bda44b16b1 | |||
| e2280aa1a5 | |||
| bdf2de076a | |||
| 1797fec3c9 | |||
| 188fa5a073 | |||
| f0c63c539b | |||
| 649e9da1f8 | |||
| df28359a19 | |||
| 9370e93a8d | |||
| bdd5845490 | |||
| bacffd6174 | |||
| a1bfd7a018 | |||
| 7009f56a7a | |||
| 2c0bfac43e | |||
| fcb6c8a113 | |||
| 1ab77aeb91 |
+249
-11
@@ -27,6 +27,16 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
# sccache
|
||||||
|
SCCACHE_GHA_ENABLED: "true"
|
||||||
|
RUSTC_WRAPPER: "sccache"
|
||||||
|
SCCACHE_BUCKET: "sccache"
|
||||||
|
SCCACHE_S3_USE_SSL: ${{ vars.SCCACHE_S3_USE_SSL }}
|
||||||
|
SCCACHE_REGION: ${{ vars.SCCACHE_REGION }}
|
||||||
|
SCCACHE_ENDPOINT: ${{ vars.SCCACHE_ENDPOINT }}
|
||||||
|
SCCACHE_CACHE_MULTIARCH: ${{ vars.SCCACHE_CACHE_MULTIARCH }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
# Required to make some things output color
|
# Required to make some things output color
|
||||||
TERM: ansi
|
TERM: ansi
|
||||||
# Publishing to my nix binary cache
|
# Publishing to my nix binary cache
|
||||||
@@ -38,8 +48,11 @@ env:
|
|||||||
# Custom nix binary cache if fork is being used
|
# Custom nix binary cache if fork is being used
|
||||||
ATTIC_ENDPOINT: ${{ vars.ATTIC_ENDPOINT }}
|
ATTIC_ENDPOINT: ${{ vars.ATTIC_ENDPOINT }}
|
||||||
ATTIC_PUBLIC_KEY: ${{ vars.ATTIC_PUBLIC_KEY }}
|
ATTIC_PUBLIC_KEY: ${{ vars.ATTIC_PUBLIC_KEY }}
|
||||||
# Get error output from nix that we can actually use
|
# Get error output from nix that we can actually use, and use our binary caches for the earlier CI steps
|
||||||
NIX_CONFIG: show-trace = true
|
NIX_CONFIG: |
|
||||||
|
show-trace = true
|
||||||
|
extra-substituters = https://attic.kennel.juneis.dog/conduit https://attic.kennel.juneis.dog/conduwuit https://cache.lix.systems https://conduwuit.cachix.org
|
||||||
|
extra-trusted-public-keys = conduit:eEKoUwlQGDdYmAI/Q/0slVlegqh/QmAvQd7HBSm21Wk= conduwuit:BbycGUgTISsltcmH0qNjFR9dbrQNYgdIAcmViSGoVTE= cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o= conduwuit.cachix.org-1:MFRm6jcnfTf0jSAbmvLfhO3KBMt4px+1xaereWXp8Xg=
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
packages: write
|
packages: write
|
||||||
@@ -49,6 +62,8 @@ jobs:
|
|||||||
tests:
|
tests:
|
||||||
name: Test
|
name: Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CARGO_PROFILE: "test"
|
||||||
steps:
|
steps:
|
||||||
- name: Free Disk Space (Ubuntu)
|
- name: Free Disk Space (Ubuntu)
|
||||||
uses: jlumbroso/free-disk-space@main
|
uses: jlumbroso/free-disk-space@main
|
||||||
@@ -57,7 +72,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Tag comparison check
|
- name: Tag comparison check
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-rc') }}
|
||||||
run: |
|
run: |
|
||||||
# Tag mismatch with latest repo tag check to prevent potential downgrades
|
# Tag mismatch with latest repo tag check to prevent potential downgrades
|
||||||
LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
|
LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||||
@@ -115,15 +130,38 @@ jobs:
|
|||||||
- name: Prepare build environment
|
- name: Prepare build environment
|
||||||
run: |
|
run: |
|
||||||
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
||||||
nix profile install --impure --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
nix profile install --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||||
direnv allow
|
direnv allow
|
||||||
nix develop .#all-features --command true
|
nix develop .#all-features --command true
|
||||||
|
|
||||||
- name: Cache CI dependencies
|
- name: Cache CI dependencies
|
||||||
run: |
|
run: |
|
||||||
|
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||||
|
ATTEMPTS=3
|
||||||
|
SUCCESS=false
|
||||||
|
while (( ATTEMPTS-- > 0 ))
|
||||||
|
do
|
||||||
bin/nix-build-and-cache ci
|
bin/nix-build-and-cache ci
|
||||||
|
if [[ $? == 0 ]]; then
|
||||||
|
SUCCESS=true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $SUCCESS == "false" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# use sccache for Rust
|
||||||
|
- name: Run sccache-cache
|
||||||
|
uses: mozilla-actions/sccache-action@main
|
||||||
|
|
||||||
|
# use rust-cache
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
cache-all-crates: "true"
|
||||||
|
|
||||||
- name: Run CI tests
|
- name: Run CI tests
|
||||||
run: |
|
run: |
|
||||||
@@ -177,6 +215,10 @@ jobs:
|
|||||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
- name: Run cargo clean test artifacts
|
||||||
|
run: |
|
||||||
|
cargo clean --profile test
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build
|
name: Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -187,6 +229,9 @@ jobs:
|
|||||||
- target: aarch64-unknown-linux-musl
|
- target: aarch64-unknown-linux-musl
|
||||||
- target: x86_64-unknown-linux-musl
|
- target: x86_64-unknown-linux-musl
|
||||||
steps:
|
steps:
|
||||||
|
- name: Free Disk Space (Ubuntu)
|
||||||
|
uses: jlumbroso/free-disk-space@main
|
||||||
|
|
||||||
- name: Sync repository
|
- name: Sync repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -237,16 +282,42 @@ jobs:
|
|||||||
- name: Prepare build environment
|
- name: Prepare build environment
|
||||||
run: |
|
run: |
|
||||||
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
||||||
nix profile install --impure --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
nix profile install --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||||
direnv allow
|
direnv allow
|
||||||
nix develop .#all-features --command true
|
nix develop .#all-features --command true
|
||||||
|
|
||||||
|
# use sccache for Rust
|
||||||
|
- name: Run sccache-cache
|
||||||
|
uses: mozilla-actions/sccache-action@main
|
||||||
|
|
||||||
|
# use rust-cache
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
cache-all-crates: "true"
|
||||||
|
|
||||||
- name: Build static ${{ matrix.target }}
|
- name: Build static ${{ matrix.target }}
|
||||||
run: |
|
run: |
|
||||||
CARGO_DEB_TARGET_TUPLE=$(echo ${{ matrix.target }} | grep -o -E '^([^-]*-){3}[^-]*')
|
CARGO_DEB_TARGET_TUPLE=$(echo ${{ matrix.target }} | grep -o -E '^([^-]*-){3}[^-]*')
|
||||||
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||||
|
|
||||||
|
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||||
|
ATTEMPTS=3
|
||||||
|
SUCCESS=false
|
||||||
|
while (( ATTEMPTS-- > 0 ))
|
||||||
|
do
|
||||||
bin/nix-build-and-cache just .#static-${{ matrix.target }}-all-features
|
bin/nix-build-and-cache just .#static-${{ matrix.target }}-all-features
|
||||||
|
if [[ $? == 0 ]]; then
|
||||||
|
SUCCESS=true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $SUCCESS == "false" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -v -p target/release/
|
mkdir -v -p target/release/
|
||||||
mkdir -v -p target/$CARGO_DEB_TARGET_TUPLE/release/
|
mkdir -v -p target/$CARGO_DEB_TARGET_TUPLE/release/
|
||||||
cp -v -f result/bin/conduit target/release/conduwuit
|
cp -v -f result/bin/conduit target/release/conduwuit
|
||||||
@@ -256,6 +327,66 @@ jobs:
|
|||||||
mv -v target/release/conduwuit static-${{ matrix.target }}
|
mv -v target/release/conduwuit static-${{ matrix.target }}
|
||||||
mv -v target/release/${{ matrix.target }}.deb ${{ matrix.target }}.deb
|
mv -v target/release/${{ matrix.target }}.deb ${{ matrix.target }}.deb
|
||||||
|
|
||||||
|
# quick smoke test of the x86_64 static release binary
|
||||||
|
- name: Run x86_64 static release binary
|
||||||
|
run: |
|
||||||
|
# GH actions default runners are x86_64 only
|
||||||
|
if file result/bin/conduit | grep x86-64; then
|
||||||
|
result/bin/conduit --version
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build static debug ${{ matrix.target }}
|
||||||
|
run: |
|
||||||
|
CARGO_DEB_TARGET_TUPLE=$(echo ${{ matrix.target }} | grep -o -E '^([^-]*-){3}[^-]*')
|
||||||
|
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||||
|
|
||||||
|
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||||
|
ATTEMPTS=3
|
||||||
|
SUCCESS=false
|
||||||
|
while (( ATTEMPTS-- > 0 ))
|
||||||
|
do
|
||||||
|
bin/nix-build-and-cache just .#static-${{ matrix.target }}-all-features-debug
|
||||||
|
if [[ $? == 0 ]]; then
|
||||||
|
SUCCESS=true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $SUCCESS == "false" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# > warning: dev profile is not supported and will be a hard error in the future. cargo-deb is for making releases, and it doesn't make sense to use it with dev profiles.
|
||||||
|
# so we need to coerce cargo-deb into thinking this is a release binary
|
||||||
|
mkdir -v -p target/release/
|
||||||
|
mkdir -v -p target/$CARGO_DEB_TARGET_TUPLE/release/
|
||||||
|
cp -v -f result/bin/conduit target/release/conduwuit
|
||||||
|
cp -v -f result/bin/conduit target/$CARGO_DEB_TARGET_TUPLE/release/conduwuit
|
||||||
|
# -p conduit is the main crate name
|
||||||
|
direnv exec . cargo deb --verbose --no-build --no-strip -p conduit --target=$CARGO_DEB_TARGET_TUPLE --output target/release/${{ matrix.target }}-debug.deb
|
||||||
|
mv -v target/release/conduwuit static-${{ matrix.target }}-debug
|
||||||
|
mv -v target/release/${{ matrix.target }}-debug.deb ${{ matrix.target }}-debug.deb
|
||||||
|
|
||||||
|
# quick smoke test of the x86_64 static debug binary
|
||||||
|
- name: Run x86_64 static debug binary
|
||||||
|
run: |
|
||||||
|
# GH actions default runners are x86_64 only
|
||||||
|
if file result/bin/conduit | grep x86-64; then
|
||||||
|
result/bin/conduit --version
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check validity of produced deb package, invalid debs will error on these commands
|
||||||
|
- name: Validate produced deb package
|
||||||
|
run: |
|
||||||
|
# List contents
|
||||||
|
dpkg-deb --contents ${{ matrix.target }}.deb
|
||||||
|
dpkg-deb --contents ${{ matrix.target }}-debug.deb
|
||||||
|
# List info
|
||||||
|
dpkg-deb --info ${{ matrix.target }}.deb
|
||||||
|
dpkg-deb --info ${{ matrix.target }}-debug.deb
|
||||||
|
|
||||||
- name: Upload static-${{ matrix.target }}
|
- name: Upload static-${{ matrix.target }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@@ -271,11 +402,65 @@ jobs:
|
|||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
compression-level: 0
|
compression-level: 0
|
||||||
|
|
||||||
|
- name: Upload static-${{ matrix.target }}-debug
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: static-${{ matrix.target }}-debug
|
||||||
|
path: static-${{ matrix.target }}-debug
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Upload deb ${{ matrix.target }}-debug
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: deb-${{ matrix.target }}-debug
|
||||||
|
path: ${{ matrix.target }}-debug.deb
|
||||||
|
if-no-files-found: error
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
- name: Build OCI image ${{ matrix.target }}
|
- name: Build OCI image ${{ matrix.target }}
|
||||||
run: |
|
run: |
|
||||||
|
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||||
|
ATTEMPTS=3
|
||||||
|
SUCCESS=false
|
||||||
|
while (( ATTEMPTS-- > 0 ))
|
||||||
|
do
|
||||||
bin/nix-build-and-cache just .#oci-image-${{ matrix.target }}-all-features
|
bin/nix-build-and-cache just .#oci-image-${{ matrix.target }}-all-features
|
||||||
|
if [[ $? == 0 ]]; then
|
||||||
|
SUCCESS=true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $SUCCESS == "false" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
cp -v -f result oci-image-${{ matrix.target }}.tar.gz
|
cp -v -f result oci-image-${{ matrix.target }}.tar.gz
|
||||||
|
|
||||||
|
- name: Build debug OCI image ${{ matrix.target }}
|
||||||
|
run: |
|
||||||
|
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||||
|
ATTEMPTS=3
|
||||||
|
SUCCESS=false
|
||||||
|
while (( ATTEMPTS-- > 0 ))
|
||||||
|
do
|
||||||
|
bin/nix-build-and-cache just .#oci-image-${{ matrix.target }}-all-features-debug
|
||||||
|
if [[ $? == 0 ]]; then
|
||||||
|
SUCCESS=true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $SUCCESS == "false" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp -v -f result oci-image-${{ matrix.target }}-debug.tar.gz
|
||||||
|
|
||||||
- name: Upload OCI image ${{ matrix.target }}
|
- name: Upload OCI image ${{ matrix.target }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@@ -284,6 +469,14 @@ jobs:
|
|||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
compression-level: 0
|
compression-level: 0
|
||||||
|
|
||||||
|
- name: Upload OCI image ${{ matrix.target }}-debug
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: oci-image-${{ matrix.target }}-debug
|
||||||
|
path: oci-image-${{ matrix.target }}-debug.tar.gz
|
||||||
|
if-no-files-found: error
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
name: Docker publish
|
name: Docker publish
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -293,15 +486,15 @@ jobs:
|
|||||||
DOCKER_ARM64: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
DOCKER_ARM64: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||||
DOCKER_AMD64: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
DOCKER_AMD64: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||||
DOCKER_TAG: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
DOCKER_TAG: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
||||||
DOCKER_BRANCH: docker.io/${{ github.repository }}:${{ (startsWith(github.ref, 'refs/tags/v') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
DOCKER_BRANCH: docker.io/${{ github.repository }}:${{ (startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-rc') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||||
GHCR_ARM64: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
GHCR_ARM64: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||||
GHCR_AMD64: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
GHCR_AMD64: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||||
GHCR_TAG: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
GHCR_TAG: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
||||||
GHCR_BRANCH: ghcr.io/${{ github.repository }}:${{ (startsWith(github.ref, 'refs/tags/v') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
GHCR_BRANCH: ghcr.io/${{ github.repository }}:${{ (startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-rc') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||||
GLCR_ARM64: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
GLCR_ARM64: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||||
GLCR_AMD64: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
GLCR_AMD64: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||||
GLCR_TAG: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
GLCR_TAG: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
||||||
GLCR_BRANCH: registry.gitlab.com/conduwuit/conduwuit:${{ (startsWith(github.ref, 'refs/tags/v') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
GLCR_BRANCH: registry.gitlab.com/conduwuit/conduwuit:${{ (startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-rc') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||||
|
|
||||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
|
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
|
||||||
@@ -334,8 +527,10 @@ jobs:
|
|||||||
|
|
||||||
- name: Move OCI images into position
|
- name: Move OCI images into position
|
||||||
run: |
|
run: |
|
||||||
mv -v oci-image-x86_64-*/*.tar.gz oci-image-amd64.tar.gz
|
mv -v oci-image-x86_64-unknown-linux-musl/*.tar.gz oci-image-amd64.tar.gz
|
||||||
mv -v oci-image-aarch64-*/*.tar.gz oci-image-arm64v8.tar.gz
|
mv -v oci-image-aarch64-unknown-linux-musl/*.tar.gz oci-image-arm64v8.tar.gz
|
||||||
|
mv -v oci-image-x86_64-unknown-linux-musl-debug/*.tar.gz oci-image-amd64-debug.tar.gz
|
||||||
|
mv -v oci-image-aarch64-unknown-linux-musl-debug/*.tar.gz oci-image-arm64v8-debug.tar.gz
|
||||||
|
|
||||||
- name: Load and push amd64 image
|
- name: Load and push amd64 image
|
||||||
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||||
@@ -359,6 +554,28 @@ jobs:
|
|||||||
docker push ${{ env.GHCR_ARM64 }}
|
docker push ${{ env.GHCR_ARM64 }}
|
||||||
docker push ${{ env.GLCR_ARM64 }}
|
docker push ${{ env.GLCR_ARM64 }}
|
||||||
|
|
||||||
|
- name: Load and push amd64 debug image
|
||||||
|
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||||
|
run: |
|
||||||
|
docker load -i oci-image-amd64-debug.tar.gz
|
||||||
|
docker tag $(docker images -q conduit:main) ${{ env.DOCKER_AMD64 }}-debug
|
||||||
|
docker tag $(docker images -q conduit:main) ${{ env.GHCR_AMD64 }}-debug
|
||||||
|
docker tag $(docker images -q conduit:main) ${{ env.GLCR_AMD64 }}-debug
|
||||||
|
docker push ${{ env.DOCKER_AMD64 }}-debug
|
||||||
|
docker push ${{ env.GHCR_AMD64 }}-debug
|
||||||
|
docker push ${{ env.GLCR_AMD64 }}-debug
|
||||||
|
|
||||||
|
- name: Load and push arm64 debug image
|
||||||
|
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||||
|
run: |
|
||||||
|
docker load -i oci-image-arm64v8-debug.tar.gz
|
||||||
|
docker tag $(docker images -q conduit:main) ${{ env.DOCKER_ARM64 }}-debug
|
||||||
|
docker tag $(docker images -q conduit:main) ${{ env.GHCR_ARM64 }}-debug
|
||||||
|
docker tag $(docker images -q conduit:main) ${{ env.GLCR_ARM64 }}-debug
|
||||||
|
docker push ${{ env.DOCKER_ARM64 }}-debug
|
||||||
|
docker push ${{ env.GHCR_ARM64 }}-debug
|
||||||
|
docker push ${{ env.GLCR_ARM64 }}-debug
|
||||||
|
|
||||||
- name: Create Docker combined manifests
|
- name: Create Docker combined manifests
|
||||||
run: |
|
run: |
|
||||||
# Dockerhub Container Registry
|
# Dockerhub Container Registry
|
||||||
@@ -368,9 +585,21 @@ jobs:
|
|||||||
docker manifest create ${{ env.GHCR_TAG }} --amend ${{ env.GHCR_ARM64 }} --amend ${{ env.GHCR_AMD64 }}
|
docker manifest create ${{ env.GHCR_TAG }} --amend ${{ env.GHCR_ARM64 }} --amend ${{ env.GHCR_AMD64 }}
|
||||||
docker manifest create ${{ env.GHCR_BRANCH }} --amend ${{ env.GHCR_ARM64 }} --amend ${{ env.GHCR_AMD64 }}
|
docker manifest create ${{ env.GHCR_BRANCH }} --amend ${{ env.GHCR_ARM64 }} --amend ${{ env.GHCR_AMD64 }}
|
||||||
# GitLab Container Registry
|
# GitLab Container Registry
|
||||||
docker manifest create ${{ env.GLCR_TAG }} --amend ${{ env.GLCR_ARM64 }} --amend ${{ env.GCCR_AMD64 }}
|
docker manifest create ${{ env.GLCR_TAG }} --amend ${{ env.GLCR_ARM64 }} --amend ${{ env.GLCR_AMD64 }}
|
||||||
docker manifest create ${{ env.GLCR_BRANCH }} --amend ${{ env.GLCR_ARM64 }} --amend ${{ env.GLCR_AMD64 }}
|
docker manifest create ${{ env.GLCR_BRANCH }} --amend ${{ env.GLCR_ARM64 }} --amend ${{ env.GLCR_AMD64 }}
|
||||||
|
|
||||||
|
- name: Create Docker combined debug manifests
|
||||||
|
run: |
|
||||||
|
# Dockerhub Container Registry
|
||||||
|
docker manifest create ${{ env.DOCKER_TAG }}-debug --amend ${{ env.DOCKER_ARM64 }}-debug --amend ${{ env.DOCKER_AMD64 }}-debug
|
||||||
|
docker manifest create ${{ env.DOCKER_BRANCH }}-debug --amend ${{ env.DOCKER_ARM64 }}-debug --amend ${{ env.DOCKER_AMD64 }}-debug
|
||||||
|
# GitHub Container Registry
|
||||||
|
docker manifest create ${{ env.GHCR_TAG }}-debug --amend ${{ env.GHCR_ARM64 }}-debug --amend ${{ env.GHCR_AMD64 }}-debug
|
||||||
|
docker manifest create ${{ env.GHCR_BRANCH }}-debug --amend ${{ env.GHCR_ARM64 }}-debug --amend ${{ env.GHCR_AMD64 }}-debug
|
||||||
|
# GitLab Container Registry
|
||||||
|
docker manifest create ${{ env.GLCR_TAG }}-debug --amend ${{ env.GLCR_ARM64 }}-debug --amend ${{ env.GLCR_AMD64 }}-debug
|
||||||
|
docker manifest create ${{ env.GLCR_BRANCH }}-debug --amend ${{ env.GLCR_ARM64 }}-debug --amend ${{ env.GLCR_AMD64 }}-debug
|
||||||
|
|
||||||
- name: Push manifests to Docker registries
|
- name: Push manifests to Docker registries
|
||||||
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||||
run: |
|
run: |
|
||||||
@@ -380,6 +609,12 @@ jobs:
|
|||||||
docker manifest push ${{ env.GHCR_BRANCH }}
|
docker manifest push ${{ env.GHCR_BRANCH }}
|
||||||
docker manifest push ${{ env.GLCR_TAG }}
|
docker manifest push ${{ env.GLCR_TAG }}
|
||||||
docker manifest push ${{ env.GLCR_BRANCH }}
|
docker manifest push ${{ env.GLCR_BRANCH }}
|
||||||
|
docker manifest push ${{ env.DOCKER_TAG }}-debug
|
||||||
|
docker manifest push ${{ env.DOCKER_BRANCH }}-debug
|
||||||
|
docker manifest push ${{ env.GHCR_TAG }}-debug
|
||||||
|
docker manifest push ${{ env.GHCR_BRANCH }}-debug
|
||||||
|
docker manifest push ${{ env.GLCR_TAG }}-debug
|
||||||
|
docker manifest push ${{ env.GLCR_BRANCH }}-debug
|
||||||
|
|
||||||
- name: Add Image Links to Job Summary
|
- name: Add Image Links to Job Summary
|
||||||
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||||
@@ -387,3 +622,6 @@ jobs:
|
|||||||
echo "- \`docker pull ${{ env.DOCKER_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
echo "- \`docker pull ${{ env.DOCKER_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- \`docker pull ${{ env.GHCR_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
echo "- \`docker pull ${{ env.GHCR_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- \`docker pull ${{ env.GLCR_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
echo "- \`docker pull ${{ env.GLCR_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "- \`docker pull ${{ env.DOCKER_TAG }}-debug\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "- \`docker pull ${{ env.GHCR_TAG }}-debug\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "- \`docker pull ${{ env.GLCR_TAG }}-debug\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|||||||
@@ -21,8 +21,11 @@ env:
|
|||||||
# Custom nix binary cache if fork is being used
|
# Custom nix binary cache if fork is being used
|
||||||
ATTIC_ENDPOINT: ${{ vars.ATTIC_ENDPOINT }}
|
ATTIC_ENDPOINT: ${{ vars.ATTIC_ENDPOINT }}
|
||||||
ATTIC_PUBLIC_KEY: ${{ vars.ATTIC_PUBLIC_KEY }}
|
ATTIC_PUBLIC_KEY: ${{ vars.ATTIC_PUBLIC_KEY }}
|
||||||
# Get error output from nix that we can actually use
|
# Get error output from nix that we can actually use, and use our binary caches for the earlier CI steps
|
||||||
NIX_CONFIG: show-trace = true
|
NIX_CONFIG: |
|
||||||
|
show-trace = true
|
||||||
|
extra-substituters = https://attic.kennel.juneis.dog/conduit https://attic.kennel.juneis.dog/conduwuit https://cache.lix.systems https://conduwuit.cachix.org
|
||||||
|
extra-trusted-public-keys = conduit:eEKoUwlQGDdYmAI/Q/0slVlegqh/QmAvQd7HBSm21Wk= conduwuit:BbycGUgTISsltcmH0qNjFR9dbrQNYgdIAcmViSGoVTE= cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o= conduwuit.cachix.org-1:MFRm6jcnfTf0jSAbmvLfhO3KBMt4px+1xaereWXp8Xg=
|
||||||
|
|
||||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||||
@@ -44,6 +47,9 @@ jobs:
|
|||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Free Disk Space (Ubuntu)
|
||||||
|
uses: jlumbroso/free-disk-space@main
|
||||||
|
|
||||||
- name: Sync repository
|
- name: Sync repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -98,13 +104,29 @@ jobs:
|
|||||||
- name: Prepare build environment
|
- name: Prepare build environment
|
||||||
run: |
|
run: |
|
||||||
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
||||||
nix profile install --impure --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
nix profile install --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||||
direnv allow
|
direnv allow
|
||||||
nix develop --command true
|
nix develop --command true
|
||||||
|
|
||||||
- name: Cache CI dependencies
|
- name: Cache CI dependencies
|
||||||
run: |
|
run: |
|
||||||
|
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||||
|
ATTEMPTS=3
|
||||||
|
SUCCESS=false
|
||||||
|
while (( ATTEMPTS-- > 0 ))
|
||||||
|
do
|
||||||
bin/nix-build-and-cache ci
|
bin/nix-build-and-cache ci
|
||||||
|
if [[ $? == 0 ]]; then
|
||||||
|
SUCCESS=true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $SUCCESS == "false" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Run lychee and markdownlint
|
- name: Run lychee and markdownlint
|
||||||
run: |
|
run: |
|
||||||
@@ -113,8 +135,26 @@ jobs:
|
|||||||
|
|
||||||
- name: Build documentation (book)
|
- name: Build documentation (book)
|
||||||
run: |
|
run: |
|
||||||
./bin/nix-build-and-cache just .#book
|
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||||
|
ATTEMPTS=3
|
||||||
|
SUCCESS=false
|
||||||
|
while (( ATTEMPTS-- > 0 ))
|
||||||
|
do
|
||||||
|
bin/nix-build-and-cache just .#book
|
||||||
|
if [[ $? == 0 ]]; then
|
||||||
|
SUCCESS=true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $SUCCESS == "false" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
cp -r --dereference result public
|
cp -r --dereference result public
|
||||||
|
|
||||||
- name: Upload generated documentation (book) as normal artifact
|
- name: Upload generated documentation (book) as normal artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ The following binaries are used in [`engage.toml`][engage.toml]:
|
|||||||
- [`cargo-deb`][cargo-deb]
|
- [`cargo-deb`][cargo-deb]
|
||||||
- [`lychee`][lychee]
|
- [`lychee`][lychee]
|
||||||
- [`markdownlint-cli`][markdownlint-cli]
|
- [`markdownlint-cli`][markdownlint-cli]
|
||||||
|
- `dpkg`
|
||||||
|
|
||||||
### Matrix tests
|
### Matrix tests
|
||||||
|
|
||||||
|
|||||||
Generated
+122
-116
@@ -85,9 +85,9 @@ checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-compression"
|
name = "async-compression"
|
||||||
version = "0.4.11"
|
version = "0.4.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5"
|
checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli",
|
"brotli",
|
||||||
"flate2",
|
"flate2",
|
||||||
@@ -118,7 +118,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -129,7 +129,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -377,7 +377,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -474,13 +474,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.3"
|
version = "1.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18e2d530f35b40a84124146478cd16f34225306a8441998836466a2e2961c950"
|
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -562,7 +561,7 @@ dependencies = [
|
|||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -579,7 +578,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conduit"
|
name = "conduit"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"conduit_admin",
|
"conduit_admin",
|
||||||
@@ -608,7 +607,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conduit_admin"
|
name = "conduit_admin"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"conduit_api",
|
"conduit_api",
|
||||||
@@ -627,7 +626,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conduit_api"
|
name = "conduit_api"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum 0.7.5",
|
"axum 0.7.5",
|
||||||
"axum-client-ip",
|
"axum-client-ip",
|
||||||
@@ -661,7 +660,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conduit_core"
|
name = "conduit_core"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argon2",
|
"argon2",
|
||||||
"axum 0.7.5",
|
"axum 0.7.5",
|
||||||
@@ -703,7 +702,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conduit_database"
|
name = "conduit_database"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"conduit_core",
|
"conduit_core",
|
||||||
"const-str",
|
"const-str",
|
||||||
@@ -715,7 +714,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conduit_router"
|
name = "conduit_router"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum 0.7.5",
|
"axum 0.7.5",
|
||||||
"axum-client-ip",
|
"axum-client-ip",
|
||||||
@@ -746,7 +745,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "conduit_service"
|
name = "conduit_service"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
@@ -769,7 +768,6 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"ruma",
|
"ruma",
|
||||||
"ruma-identifiers-validation 0.9.5 (git+https://github.com/girlbossceo/ruwuma?rev=fd686e77950680462377c9105dfb4136dd49c7a0)",
|
|
||||||
"rustyline-async",
|
"rustyline-async",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -972,7 +970,7 @@ dependencies = [
|
|||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio 0.8.11",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-mio",
|
"signal-hook-mio",
|
||||||
@@ -1022,7 +1020,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1126,7 +1124,7 @@ dependencies = [
|
|||||||
"heck 0.4.1",
|
"heck 0.4.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1262,7 +1260,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1543,7 +1541,7 @@ dependencies = [
|
|||||||
"markup5ever",
|
"markup5ever",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1747,12 +1745,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.25.1"
|
version = "0.25.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11"
|
checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"byteorder",
|
"byteorder-lite",
|
||||||
"color_quant",
|
"color_quant",
|
||||||
"gif",
|
"gif",
|
||||||
"image-webp",
|
"image-webp",
|
||||||
@@ -1764,12 +1762,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image-webp"
|
name = "image-webp"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d"
|
checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder-lite",
|
"byteorder-lite",
|
||||||
"thiserror",
|
"quick-error 2.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1952,7 +1950,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1975,9 +1973,9 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
|
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
@@ -2033,9 +2031,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lz4-sys"
|
name = "lz4-sys"
|
||||||
version = "1.9.5"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3"
|
checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -2149,6 +2147,18 @@ dependencies = [
|
|||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "new_debug_unreachable"
|
name = "new_debug_unreachable"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
@@ -2461,7 +2471,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"proc-macro2-diagnostics",
|
"proc-macro2-diagnostics",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2554,7 +2564,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2642,7 +2652,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
"version_check",
|
"version_check",
|
||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
@@ -2667,7 +2677,7 @@ dependencies = [
|
|||||||
"itertools 0.12.1",
|
"itertools 0.12.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2703,6 +2713,12 @@ version = "1.2.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-error"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quinn"
|
name = "quinn"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
@@ -2739,14 +2755,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quinn-udp"
|
name = "quinn-udp"
|
||||||
version = "0.5.2"
|
version = "0.5.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46"
|
checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tracing",
|
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2791,9 +2806,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.2"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
|
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
@@ -2898,7 +2913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
|
checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hostname 0.3.1",
|
"hostname 0.3.1",
|
||||||
"quick-error",
|
"quick-error 1.2.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2919,7 +2934,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma"
|
name = "ruma"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assign",
|
"assign",
|
||||||
"js_int",
|
"js_int",
|
||||||
@@ -2929,6 +2944,7 @@ dependencies = [
|
|||||||
"ruma-common",
|
"ruma-common",
|
||||||
"ruma-events",
|
"ruma-events",
|
||||||
"ruma-federation-api",
|
"ruma-federation-api",
|
||||||
|
"ruma-identifiers-validation",
|
||||||
"ruma-identity-service-api",
|
"ruma-identity-service-api",
|
||||||
"ruma-push-gateway-api",
|
"ruma-push-gateway-api",
|
||||||
"ruma-server-util",
|
"ruma-server-util",
|
||||||
@@ -2940,7 +2956,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-appservice-api"
|
name = "ruma-appservice-api"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -2952,7 +2968,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-client-api"
|
name = "ruma-client-api"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"assign",
|
"assign",
|
||||||
@@ -2975,7 +2991,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-common"
|
name = "ruma-common"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
@@ -2988,7 +3004,7 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand",
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"ruma-identifiers-validation 0.9.5 (git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5)",
|
"ruma-identifiers-validation",
|
||||||
"ruma-macros",
|
"ruma-macros",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_html_form",
|
"serde_html_form",
|
||||||
@@ -3005,7 +3021,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-events"
|
name = "ruma-events"
|
||||||
version = "0.28.1"
|
version = "0.28.1"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"indexmap 2.2.6",
|
"indexmap 2.2.6",
|
||||||
@@ -3015,7 +3031,7 @@ dependencies = [
|
|||||||
"pulldown-cmark",
|
"pulldown-cmark",
|
||||||
"regex",
|
"regex",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
"ruma-identifiers-validation 0.9.5 (git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5)",
|
"ruma-identifiers-validation",
|
||||||
"ruma-macros",
|
"ruma-macros",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -3028,7 +3044,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-federation-api"
|
name = "ruma-federation-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -3040,16 +3056,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers-validation"
|
name = "ruma-identifiers-validation"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
|
||||||
"js_int",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ruma-identifiers-validation"
|
|
||||||
version = "0.9.5"
|
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=fd686e77950680462377c9105dfb4136dd49c7a0#fd686e77950680462377c9105dfb4136dd49c7a0"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -3058,7 +3065,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identity-service-api"
|
name = "ruma-identity-service-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -3068,22 +3075,22 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-macros"
|
name = "ruma-macros"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"ruma-identifiers-validation 0.9.5 (git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5)",
|
"ruma-identifiers-validation",
|
||||||
"serde",
|
"serde",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-push-gateway-api"
|
name = "ruma-push-gateway-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -3095,7 +3102,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-server-util"
|
name = "ruma-server-util"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"headers",
|
"headers",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
@@ -3108,7 +3115,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-signatures"
|
name = "ruma-signatures"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
@@ -3124,7 +3131,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-state-res"
|
name = "ruma-state-res"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.12.1",
|
"itertools 0.12.1",
|
||||||
"js_int",
|
"js_int",
|
||||||
@@ -3138,8 +3145,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-librocksdb-sys"
|
name = "rust-librocksdb-sys"
|
||||||
version = "0.23.1+9.3.1"
|
version = "0.24.0+9.4.0"
|
||||||
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=db1ba33c2b78ad228e2525e8902d059c24fc81a1#db1ba33c2b78ad228e2525e8902d059c24fc81a1"
|
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=4056a3b0f823013fec49f6d0b3e5698856e6476a#4056a3b0f823013fec49f6d0b3e5698856e6476a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"bzip2-sys",
|
"bzip2-sys",
|
||||||
@@ -3155,8 +3162,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-rocksdb"
|
name = "rust-rocksdb"
|
||||||
version = "0.27.1"
|
version = "0.28.0"
|
||||||
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=db1ba33c2b78ad228e2525e8902d059c24fc81a1#db1ba33c2b78ad228e2525e8902d059c24fc81a1"
|
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=4056a3b0f823013fec49f6d0b3e5698856e6476a#4056a3b0f823013fec49f6d0b3e5698856e6476a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rust-librocksdb-sys",
|
"rust-librocksdb-sys",
|
||||||
@@ -3212,7 +3219,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-webpki 0.102.5",
|
"rustls-webpki 0.102.6",
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@@ -3227,7 +3234,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-webpki 0.102.5",
|
"rustls-webpki 0.102.6",
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@@ -3273,9 +3280,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.102.5"
|
version = "0.102.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78"
|
checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
@@ -3352,9 +3359,9 @@ checksum = "4646d6f919800cd25c50edb49438a1381e2cd4833c027e75e8897981c50b8b5e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.11.0"
|
version = "2.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
|
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
@@ -3365,9 +3372,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework-sys"
|
name = "security-framework-sys"
|
||||||
version = "2.11.0"
|
version = "2.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
|
checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -3531,7 +3538,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3677,7 +3684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio 0.8.11",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3824,9 +3831,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.71"
|
version = "2.0.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -3884,22 +3891,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.62"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb"
|
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.62"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c"
|
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4013,21 +4020,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.38.0"
|
version = "1.39.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio 1.0.1",
|
||||||
"num_cpus",
|
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4042,13 +4048,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.3.0"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4122,14 +4128,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.8.14"
|
version = "0.8.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
|
checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_edit 0.22.15",
|
"toml_edit 0.22.16",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4154,15 +4160,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.15"
|
version = "0.22.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1"
|
checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap 2.2.6",
|
"indexmap 2.2.6",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow 0.6.13",
|
"winnow 0.6.15",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4250,7 +4256,7 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.40"
|
version = "0.1.40"
|
||||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@@ -4261,17 +4267,17 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.27"
|
version = "0.1.27"
|
||||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.32"
|
version = "0.1.32"
|
||||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"valuable",
|
"valuable",
|
||||||
@@ -4291,7 +4297,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-log"
|
name = "tracing-log"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@@ -4319,7 +4325,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-subscriber"
|
name = "tracing-subscriber"
|
||||||
version = "0.3.18"
|
version = "0.3.18"
|
||||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"matchers",
|
"matchers",
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
@@ -4535,7 +4541,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4569,7 +4575,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.72",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
@@ -4840,9 +4846,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.6.13"
|
version = "0.6.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
|
checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@@ -4926,9 +4932,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zune-jpeg"
|
name = "zune-jpeg"
|
||||||
version = "0.4.11"
|
version = "0.4.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448"
|
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zune-core",
|
"zune-core",
|
||||||
]
|
]
|
||||||
|
|||||||
+42
-29
@@ -14,13 +14,13 @@ categories = ["network-programming"]
|
|||||||
description = "a very cool fork of Conduit, a Matrix homeserver written in Rust"
|
description = "a very cool fork of Conduit, a Matrix homeserver written in Rust"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
homepage = "https://conduwuit.puppyirl.gay/"
|
homepage = "https://conduwuit.puppyirl.gay/"
|
||||||
keywords = ["chat", "matrix", "server"]
|
keywords = ["chat", "matrix", "server", "uwu"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
# See also `rust-toolchain.toml`
|
# See also `rust-toolchain.toml`
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/girlbossceo/conduwuit"
|
repository = "https://github.com/girlbossceo/conduwuit"
|
||||||
rust-version = "1.77.0"
|
rust-version = "1.80.0"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
|
|
||||||
[workspace.metadata.crane]
|
[workspace.metadata.crane]
|
||||||
name = "conduit"
|
name = "conduit"
|
||||||
@@ -188,7 +188,7 @@ version = "0.3.30"
|
|||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[workspace.dependencies.tokio]
|
[workspace.dependencies.tokio]
|
||||||
version = "1.38.0"
|
version = "1.39.1"
|
||||||
features = [
|
features = [
|
||||||
"fs",
|
"fs",
|
||||||
"net",
|
"net",
|
||||||
@@ -204,7 +204,7 @@ features = [
|
|||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
||||||
[workspace.dependencies.libloading]
|
[workspace.dependencies.libloading]
|
||||||
version = "0.8.3"
|
version = "0.8.5"
|
||||||
|
|
||||||
# Validating urls in config, was already a transitive dependency
|
# Validating urls in config, was already a transitive dependency
|
||||||
[workspace.dependencies.url]
|
[workspace.dependencies.url]
|
||||||
@@ -218,7 +218,7 @@ features = ["alloc", "std"]
|
|||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[workspace.dependencies.hyper]
|
[workspace.dependencies.hyper]
|
||||||
version = "1.4.0"
|
version = "1.4.1"
|
||||||
features = [
|
features = [
|
||||||
"server",
|
"server",
|
||||||
"http1",
|
"http1",
|
||||||
@@ -251,7 +251,7 @@ default-features = false
|
|||||||
|
|
||||||
# Used for conduit::Error type
|
# Used for conduit::Error type
|
||||||
[workspace.dependencies.thiserror]
|
[workspace.dependencies.thiserror]
|
||||||
version = "1.0.62"
|
version = "1.0.63"
|
||||||
|
|
||||||
# Used when hashing the state
|
# Used when hashing the state
|
||||||
[workspace.dependencies.ring]
|
[workspace.dependencies.ring]
|
||||||
@@ -280,7 +280,7 @@ version = "0.1.2"
|
|||||||
[workspace.dependencies.ruma]
|
[workspace.dependencies.ruma]
|
||||||
git = "https://github.com/girlbossceo/ruwuma"
|
git = "https://github.com/girlbossceo/ruwuma"
|
||||||
#branch = "conduwuit-changes"
|
#branch = "conduwuit-changes"
|
||||||
rev = "c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
rev = "c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||||
features = [
|
features = [
|
||||||
"compat",
|
"compat",
|
||||||
"rand",
|
"rand",
|
||||||
@@ -293,6 +293,7 @@ features = [
|
|||||||
"server-util",
|
"server-util",
|
||||||
"unstable-exhaustive-types",
|
"unstable-exhaustive-types",
|
||||||
"ring-compat",
|
"ring-compat",
|
||||||
|
"identifiers-validation",
|
||||||
"unstable-unspecified",
|
"unstable-unspecified",
|
||||||
"unstable-msc2448",
|
"unstable-msc2448",
|
||||||
"unstable-msc2666",
|
"unstable-msc2666",
|
||||||
@@ -307,10 +308,6 @@ features = [
|
|||||||
"unstable-extensible-events",
|
"unstable-extensible-events",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies.ruma-identifiers-validation]
|
|
||||||
git = "https://github.com/girlbossceo/ruwuma"
|
|
||||||
rev = "fd686e77950680462377c9105dfb4136dd49c7a0"
|
|
||||||
|
|
||||||
[workspace.dependencies.rust-rocksdb]
|
[workspace.dependencies.rust-rocksdb]
|
||||||
path = "deps/rust-rocksdb"
|
path = "deps/rust-rocksdb"
|
||||||
package = "rust-rocksdb-uwu"
|
package = "rust-rocksdb-uwu"
|
||||||
@@ -372,16 +369,17 @@ version = "0.34.0"
|
|||||||
version = "0.34.0"
|
version = "0.34.0"
|
||||||
|
|
||||||
# jemalloc usage
|
# jemalloc usage
|
||||||
|
# locked to 0.5.4 due to static binary linking breakage
|
||||||
[workspace.dependencies.tikv-jemalloc-sys]
|
[workspace.dependencies.tikv-jemalloc-sys]
|
||||||
version = "0.5.4"
|
version = "=0.6.0"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["stats", "unprefixed_malloc_on_supported_platforms"]
|
features = ["stats", "unprefixed_malloc_on_supported_platforms"]
|
||||||
[workspace.dependencies.tikv-jemallocator]
|
[workspace.dependencies.tikv-jemallocator]
|
||||||
version = "0.5.4"
|
version = "=0.5.4"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["stats", "unprefixed_malloc_on_supported_platforms"]
|
features = ["stats", "unprefixed_malloc_on_supported_platforms"]
|
||||||
[workspace.dependencies.tikv-jemalloc-ctl]
|
[workspace.dependencies.tikv-jemalloc-ctl]
|
||||||
version = "0.5.4"
|
version = "=0.5.4"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["use_std"]
|
features = ["use_std"]
|
||||||
|
|
||||||
@@ -405,8 +403,8 @@ features = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies.rustyline-async]
|
[workspace.dependencies.rustyline-async]
|
||||||
git = "https://github.com/girlbossceo/rustyline-async"
|
version = "0.4.2"
|
||||||
rev = "de26100b0db03e419a3d8e1dd26895d170d1fe50"
|
default-features = false
|
||||||
|
|
||||||
[workspace.dependencies.termimad]
|
[workspace.dependencies.termimad]
|
||||||
version = "0.29.4"
|
version = "0.29.4"
|
||||||
@@ -425,16 +423,16 @@ version = "0.1"
|
|||||||
# https://github.com/girlbossceo/tracing/commit/b348dca742af641c47bc390261f60711c2af573c
|
# https://github.com/girlbossceo/tracing/commit/b348dca742af641c47bc390261f60711c2af573c
|
||||||
[patch.crates-io.tracing-subscriber]
|
[patch.crates-io.tracing-subscriber]
|
||||||
git = "https://github.com/girlbossceo/tracing"
|
git = "https://github.com/girlbossceo/tracing"
|
||||||
rev = "b348dca742af641c47bc390261f60711c2af573c"
|
rev = "4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
[patch.crates-io.tracing]
|
[patch.crates-io.tracing]
|
||||||
git = "https://github.com/girlbossceo/tracing"
|
git = "https://github.com/girlbossceo/tracing"
|
||||||
rev = "b348dca742af641c47bc390261f60711c2af573c"
|
rev = "4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
[patch.crates-io.tracing-core]
|
[patch.crates-io.tracing-core]
|
||||||
git = "https://github.com/girlbossceo/tracing"
|
git = "https://github.com/girlbossceo/tracing"
|
||||||
rev = "b348dca742af641c47bc390261f60711c2af573c"
|
rev = "4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
[patch.crates-io.tracing-log]
|
[patch.crates-io.tracing-log]
|
||||||
git = "https://github.com/girlbossceo/tracing"
|
git = "https://github.com/girlbossceo/tracing"
|
||||||
rev = "b348dca742af641c47bc390261f60711c2af573c"
|
rev = "4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||||
|
|
||||||
# fixes hyper graceful shutdowns [https://github.com/programatik29/axum-server/issues/114]
|
# fixes hyper graceful shutdowns [https://github.com/programatik29/axum-server/issues/114]
|
||||||
# https://github.com/girlbossceo/axum-server/commit/8e3368d899079818934e61cc9c839abcbbcada8a
|
# https://github.com/girlbossceo/axum-server/commit/8e3368d899079818934e61cc9c839abcbbcada8a
|
||||||
@@ -442,6 +440,12 @@ rev = "b348dca742af641c47bc390261f60711c2af573c"
|
|||||||
git = "https://github.com/girlbossceo/axum-server"
|
git = "https://github.com/girlbossceo/axum-server"
|
||||||
rev = "8e3368d899079818934e61cc9c839abcbbcada8a"
|
rev = "8e3368d899079818934e61cc9c839abcbbcada8a"
|
||||||
|
|
||||||
|
# adds a tab completion callback: https://github.com/girlbossceo/rustyline-async/commit/de26100b0db03e419a3d8e1dd26895d170d1fe50
|
||||||
|
# adds event for CTRL+\: https://github.com/girlbossceo/rustyline-async/commit/67d8c49aeac03a5ef4e818f663eaa94dd7bf339b
|
||||||
|
[patch.crates-io.rustyline-async]
|
||||||
|
git = "https://github.com/girlbossceo/rustyline-async"
|
||||||
|
rev = "de26100b0db03e419a3d8e1dd26895d170d1fe50"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Our crates
|
# Our crates
|
||||||
#
|
#
|
||||||
@@ -653,7 +657,16 @@ opt-level = 'z'
|
|||||||
# '-Clink-arg=-Wl,-z,nodelete',
|
# '-Clink-arg=-Wl,-z,nodelete',
|
||||||
#]
|
#]
|
||||||
|
|
||||||
|
# primarily used for CI
|
||||||
[profile.test]
|
[profile.test]
|
||||||
|
inherits = "dev"
|
||||||
|
codegen-units = 16
|
||||||
|
incremental = false
|
||||||
|
|
||||||
|
[profile.test.package.'*']
|
||||||
|
inherits = "dev"
|
||||||
|
debug = 0
|
||||||
|
codegen-units = 16
|
||||||
incremental = false
|
incremental = false
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -715,19 +728,19 @@ variant_size_differences = "allow"
|
|||||||
[workspace.lints.clippy]
|
[workspace.lints.clippy]
|
||||||
|
|
||||||
###################
|
###################
|
||||||
cargo = "warn"
|
cargo = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
## some sadness
|
## some sadness
|
||||||
multiple_crate_versions = { level = "allow", priority = 1 }
|
multiple_crate_versions = { level = "allow", priority = 1 }
|
||||||
|
|
||||||
###################
|
###################
|
||||||
complexity = "warn"
|
complexity = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
###################
|
###################
|
||||||
correctness = "warn"
|
correctness = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
###################
|
###################
|
||||||
nursery = "warn"
|
nursery = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
## some sadness
|
## some sadness
|
||||||
missing_const_for_fn = { level = "allow", priority = 1 } # TODO
|
missing_const_for_fn = { level = "allow", priority = 1 } # TODO
|
||||||
@@ -737,7 +750,7 @@ significant_drop_in_scrutinee = { level = "allow", priority = 1 } # TODO
|
|||||||
significant_drop_tightening = { level = "allow", priority = 1 } # TODO
|
significant_drop_tightening = { level = "allow", priority = 1 } # TODO
|
||||||
|
|
||||||
###################
|
###################
|
||||||
pedantic = "warn"
|
pedantic = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
## some sadness
|
## some sadness
|
||||||
doc_markdown = { level = "allow", priority = 1 }
|
doc_markdown = { level = "allow", priority = 1 }
|
||||||
@@ -756,7 +769,7 @@ unnecessary_wraps = { level = "allow", priority = 1 }
|
|||||||
unused_async = { level = "allow", priority = 1 }
|
unused_async = { level = "allow", priority = 1 }
|
||||||
|
|
||||||
###################
|
###################
|
||||||
perf = "warn"
|
perf = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
###################
|
###################
|
||||||
#restriction = "warn"
|
#restriction = "warn"
|
||||||
@@ -806,14 +819,14 @@ unseparated_literal_suffix = "warn"
|
|||||||
verbose_file_reads = "warn"
|
verbose_file_reads = "warn"
|
||||||
|
|
||||||
###################
|
###################
|
||||||
style = "warn"
|
style = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
## some sadness
|
## some sadness
|
||||||
# trivial assertions are quite alright
|
# trivial assertions are quite alright
|
||||||
assertions_on_constants = { level = "allow", priority = 1 }
|
assertions_on_constants = { level = "allow", priority = 1 }
|
||||||
|
|
||||||
###################
|
###################
|
||||||
suspicious = "warn"
|
suspicious = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
## some sadness
|
## some sadness
|
||||||
let_underscore_future = { level = "allow", priority = 1 }
|
let_underscore_future = { level = "allow", priority = 1 }
|
||||||
|
|||||||
@@ -52,9 +52,10 @@
|
|||||||
|
|
||||||
# Performance monitoring/tracing sample rate for Sentry.io
|
# Performance monitoring/tracing sample rate for Sentry.io
|
||||||
#
|
#
|
||||||
# Note that too high values may impact performance, and can be disabled by setting it to 0.0
|
# Note that too high values may impact performance, and can be disabled by setting it to 0.0 (0%)
|
||||||
|
# This value is read as a percentage to Sentry, represented as a decimal
|
||||||
#
|
#
|
||||||
# Defaults to 0.15
|
# Defaults to 15% of traces (0.15)
|
||||||
#sentry_traces_sample_rate = 0.15
|
#sentry_traces_sample_rate = 0.15
|
||||||
|
|
||||||
# Whether to attach a stacktrace to Sentry reports.
|
# Whether to attach a stacktrace to Sentry reports.
|
||||||
@@ -401,7 +402,7 @@ allow_profile_lookup_federation_requests = true
|
|||||||
# setting this to false may reduce startup time.
|
# setting this to false may reduce startup time.
|
||||||
#
|
#
|
||||||
# Enabled by default.
|
# Enabled by default.
|
||||||
#media_statup_check = true
|
#media_startup_check = true
|
||||||
|
|
||||||
# OpenID token expiration/TTL in seconds
|
# OpenID token expiration/TTL in seconds
|
||||||
#
|
#
|
||||||
@@ -421,8 +422,11 @@ allow_profile_lookup_federation_requests = true
|
|||||||
|
|
||||||
# Set this to any float value to multiply conduwuit's in-memory LRU caches with.
|
# Set this to any float value to multiply conduwuit's in-memory LRU caches with.
|
||||||
# May be useful if you have significant memory to spare to increase performance.
|
# May be useful if you have significant memory to spare to increase performance.
|
||||||
|
#
|
||||||
|
# This was previously called `conduit_cache_capacity_modifier`
|
||||||
|
#
|
||||||
# Defaults to 1.0.
|
# Defaults to 1.0.
|
||||||
#conduit_cache_capacity_modifier = 1.0
|
#cache_capacity_modifier = 1.0
|
||||||
|
|
||||||
# Set this to any float value in megabytes for conduwuit to tell the database engine that this much memory is available for database-related caches.
|
# Set this to any float value in megabytes for conduwuit to tell the database engine that this much memory is available for database-related caches.
|
||||||
# May be useful if you have significant memory to spare to increase performance.
|
# May be useful if you have significant memory to spare to increase performance.
|
||||||
|
|||||||
Vendored
+1
-1
@@ -27,7 +27,7 @@ malloc-usable-size = ["rust-rocksdb/malloc-usable-size"]
|
|||||||
|
|
||||||
[dependencies.rust-rocksdb]
|
[dependencies.rust-rocksdb]
|
||||||
git = "https://github.com/zaidoon1/rust-rocksdb"
|
git = "https://github.com/zaidoon1/rust-rocksdb"
|
||||||
rev = "db1ba33c2b78ad228e2525e8902d059c24fc81a1"
|
rev = "4056a3b0f823013fec49f6d0b3e5698856e6476a"
|
||||||
#branch = "master"
|
#branch = "master"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Otherwise, follow standard Rust project build guides (installing git and cloning
|
|||||||
While conduwuit can run as any user it is better to use dedicated users for different services. This also allows
|
While conduwuit can run as any user it is better to use dedicated users for different services. This also allows
|
||||||
you to make sure that the file permissions are correctly set up.
|
you to make sure that the file permissions are correctly set up.
|
||||||
|
|
||||||
In Debian or RHEL, you can use this command to create a conduwuit user:
|
In Debian or Fedora/RHEL, you can use this command to create a conduwuit user:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo adduser --system conduwuit --group --disabled-login --no-create-home
|
sudo adduser --system conduwuit --group --disabled-login --no-create-home
|
||||||
@@ -53,13 +53,11 @@ RocksDB is the only supported database backend.
|
|||||||
|
|
||||||
## Setting the correct file permissions
|
## Setting the correct file permissions
|
||||||
|
|
||||||
If you are using a dedicated user for conduwuit, you will need to allow it to read the config. To do that you can run this command on
|
If you are using a dedicated user for conduwuit, you will need to allow it to read the config. To do that you can run this:
|
||||||
|
|
||||||
Debian or RHEL:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo chown -R root:root /etc/conduwuit
|
sudo chown -R root:root /etc/conduwuit
|
||||||
sudo chmod 755 /etc/conduwuit
|
sudo chmod -R 755 /etc/conduwuit
|
||||||
```
|
```
|
||||||
|
|
||||||
If you use the default database path you also need to run this:
|
If you use the default database path you also need to run this:
|
||||||
|
|||||||
+22
-3
@@ -60,6 +60,11 @@ name = "markdownlint"
|
|||||||
group = "versions"
|
group = "versions"
|
||||||
script = "markdownlint --version"
|
script = "markdownlint --version"
|
||||||
|
|
||||||
|
[[task]]
|
||||||
|
name = "dpkg"
|
||||||
|
group = "versions"
|
||||||
|
script = "dpkg --version"
|
||||||
|
|
||||||
[[task]]
|
[[task]]
|
||||||
name = "cargo-audit"
|
name = "cargo-audit"
|
||||||
group = "security"
|
group = "security"
|
||||||
@@ -68,7 +73,9 @@ script = "cargo audit -D warnings -D unmaintained -D unsound -D yanked"
|
|||||||
[[task]]
|
[[task]]
|
||||||
name = "cargo-fmt"
|
name = "cargo-fmt"
|
||||||
group = "lints"
|
group = "lints"
|
||||||
script = "cargo fmt --check -- --color=always"
|
script = """
|
||||||
|
cargo fmt --check -- --color=always
|
||||||
|
"""
|
||||||
|
|
||||||
[[task]]
|
[[task]]
|
||||||
name = "cargo-doc"
|
name = "cargo-doc"
|
||||||
@@ -79,6 +86,7 @@ env DIRENV_DEVSHELL=all-features \
|
|||||||
direnv exec . \
|
direnv exec . \
|
||||||
cargo doc \
|
cargo doc \
|
||||||
--workspace \
|
--workspace \
|
||||||
|
--profile test \
|
||||||
--all-features \
|
--all-features \
|
||||||
--no-deps \
|
--no-deps \
|
||||||
--document-private-items \
|
--document-private-items \
|
||||||
@@ -91,6 +99,7 @@ group = "lints"
|
|||||||
script = """
|
script = """
|
||||||
cargo clippy \
|
cargo clippy \
|
||||||
--workspace \
|
--workspace \
|
||||||
|
--profile test \
|
||||||
--all-targets \
|
--all-targets \
|
||||||
--color=always \
|
--color=always \
|
||||||
-- \
|
-- \
|
||||||
@@ -105,6 +114,7 @@ env DIRENV_DEVSHELL=all-features \
|
|||||||
direnv exec . \
|
direnv exec . \
|
||||||
cargo clippy \
|
cargo clippy \
|
||||||
--workspace \
|
--workspace \
|
||||||
|
--profile test \
|
||||||
--all-targets \
|
--all-targets \
|
||||||
--all-features \
|
--all-features \
|
||||||
--color=always \
|
--color=always \
|
||||||
@@ -118,6 +128,7 @@ group = "lints"
|
|||||||
script = """
|
script = """
|
||||||
cargo clippy \
|
cargo clippy \
|
||||||
--workspace \
|
--workspace \
|
||||||
|
--profile test \
|
||||||
--features jemalloc \
|
--features jemalloc \
|
||||||
--all-targets \
|
--all-targets \
|
||||||
--color=always \
|
--color=always \
|
||||||
@@ -156,6 +167,7 @@ env DIRENV_DEVSHELL=all-features \
|
|||||||
direnv exec . \
|
direnv exec . \
|
||||||
cargo test \
|
cargo test \
|
||||||
--workspace \
|
--workspace \
|
||||||
|
--profile test \
|
||||||
--all-targets \
|
--all-targets \
|
||||||
--all-features \
|
--all-features \
|
||||||
--color=always \
|
--color=always \
|
||||||
@@ -169,6 +181,7 @@ group = "tests"
|
|||||||
script = """
|
script = """
|
||||||
cargo test \
|
cargo test \
|
||||||
--workspace \
|
--workspace \
|
||||||
|
--profile test \
|
||||||
--all-targets \
|
--all-targets \
|
||||||
--color=always \
|
--color=always \
|
||||||
-- \
|
-- \
|
||||||
@@ -184,6 +197,12 @@ cargo test \
|
|||||||
name = "nix-default"
|
name = "nix-default"
|
||||||
group = "tests"
|
group = "tests"
|
||||||
script = """
|
script = """
|
||||||
bin/nix-build-and-cache just .#default
|
env DIRENV_DEVSHELL=dynamic \
|
||||||
nix run -L .#default -- --help
|
CARGO_PROFILE="test" \
|
||||||
|
direnv exec . \
|
||||||
|
bin/nix-build-and-cache just .#default-test
|
||||||
|
env DIRENV_DEVSHELL=dynamic \
|
||||||
|
CARGO_PROFILE="test" \
|
||||||
|
direnv exec . \
|
||||||
|
nix run -L .#default-test -- --help && nix run -L .#default-test -- --version
|
||||||
"""
|
"""
|
||||||
|
|||||||
Generated
+25
-25
@@ -9,11 +9,11 @@
|
|||||||
"nixpkgs-stable": "nixpkgs-stable"
|
"nixpkgs-stable": "nixpkgs-stable"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1717279440,
|
"lastModified": 1720542474,
|
||||||
"narHash": "sha256-kH04ReTjxOpQumgWnqy40vvQLSnLGxWP6RF3nq5Esrk=",
|
"narHash": "sha256-aKjJ/4l2I9+wNGTaOGRsuS3M1+IoTibqgEMPDikXm04=",
|
||||||
"owner": "zhaofengli",
|
"owner": "zhaofengli",
|
||||||
"repo": "attic",
|
"repo": "attic",
|
||||||
"rev": "717cc95983cdc357bc347d70be20ced21f935843",
|
"rev": "6139576a3ce6bb992e0f6c3022528ec233e45f00",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -81,11 +81,11 @@
|
|||||||
"complement": {
|
"complement": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1719903368,
|
"lastModified": 1720637557,
|
||||||
"narHash": "sha256-PPzgxM4Bir+Zh9FUV/v+RBxEYeJxYVmi/BYo3uqt268=",
|
"narHash": "sha256-oZz6nCmFmdJZpC+K1iOG2KkzTI6rlAmndxANPDVU7X0=",
|
||||||
"owner": "matrix-org",
|
"owner": "matrix-org",
|
||||||
"repo": "complement",
|
"repo": "complement",
|
||||||
"rev": "bc97f1ddc1cd7485faf80c8935ee2641f3e1b57c",
|
"rev": "0d14432e010482ea9e13a6f7c47c1533c0c9d62f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -123,11 +123,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1720226507,
|
"lastModified": 1720546058,
|
||||||
"narHash": "sha256-yHVvNsgrpyNTXZBEokL8uyB2J6gB1wEx0KOJzoeZi1A=",
|
"narHash": "sha256-iU2yVaPIZm5vMGdlT0+57vdB/aPq/V5oZFBRwYw+HBM=",
|
||||||
"owner": "ipetkov",
|
"owner": "ipetkov",
|
||||||
"repo": "crane",
|
"repo": "crane",
|
||||||
"rev": "0aed560c5c0a61c9385bddff471a13036203e11c",
|
"rev": "2d83156f23c43598cf44e152c33a59d3892f8b29",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -209,11 +209,11 @@
|
|||||||
"rust-analyzer-src": "rust-analyzer-src"
|
"rust-analyzer-src": "rust-analyzer-src"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1720420198,
|
"lastModified": 1720852044,
|
||||||
"narHash": "sha256-OIuDb6pHDyGpo7YMFyuRzMLcHm7mRvlYOz0Ht7ps2sU=",
|
"narHash": "sha256-3NBYz8VuXuKU+8ONd9NFafCNjPEGHIZQ2Mdoam1a4mY=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "fenix",
|
"repo": "fenix",
|
||||||
"rev": "abc0549e3560189462a7d394cc9d50af4608d103",
|
"rev": "5087b12a595ee73131a944d922f24d81dae05725",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -381,11 +381,11 @@
|
|||||||
"liburing": {
|
"liburing": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1719025212,
|
"lastModified": 1720798442,
|
||||||
"narHash": "sha256-kD0yhjNStqC6uFqC1AxBwUpc/HlSFtiKrV+gwDyroDc=",
|
"narHash": "sha256-gtPppAoksMLW4GuruQ36nf4EAqIA1Bs6V9Xcx8dBxrQ=",
|
||||||
"owner": "axboe",
|
"owner": "axboe",
|
||||||
"repo": "liburing",
|
"repo": "liburing",
|
||||||
"rev": "7b3245583069bd481190c9da18f22e9fc8c3a805",
|
"rev": "1d674f83b7d0f07553ac44d99a401b05853d9dbe",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -606,11 +606,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_4": {
|
"nixpkgs_4": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1720418205,
|
"lastModified": 1720768451,
|
||||||
"narHash": "sha256-cPJoFPXU44GlhWg4pUk9oUPqurPlCFZ11ZQPk21GTPU=",
|
"narHash": "sha256-EYekUHJE2gxeo2pM/zM9Wlqw1Uw2XTJXOSAO79ksc4Y=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "655a58a72a6601292512670343087c2d75d859c1",
|
"rev": "7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -673,16 +673,16 @@
|
|||||||
"rocksdb": {
|
"rocksdb": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1719949653,
|
"lastModified": 1720900786,
|
||||||
"narHash": "sha256-DYx7XHH2GEh17GukKhXs6laM6l+eugCmRkF0adpi9wk=",
|
"narHash": "sha256-Vta9Um/RRuWwZ46BjXftV06iWLm/j/9MX39emXUvSAY=",
|
||||||
"owner": "girlbossceo",
|
"owner": "girlbossceo",
|
||||||
"repo": "rocksdb",
|
"repo": "rocksdb",
|
||||||
"rev": "a935c0273e1ba44eacf88ce3685a9b9831486155",
|
"rev": "911f4243e69c2e320a7a209bf1f5f3ff5f825495",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "girlbossceo",
|
"owner": "girlbossceo",
|
||||||
"ref": "v9.3.1",
|
"ref": "v9.4.0",
|
||||||
"repo": "rocksdb",
|
"repo": "rocksdb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -705,11 +705,11 @@
|
|||||||
"rust-analyzer-src": {
|
"rust-analyzer-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1720344064,
|
"lastModified": 1720717809,
|
||||||
"narHash": "sha256-STmaV9Zu74QtkGGrbr9uMhskwagfCjJqOAYapXabiuk=",
|
"narHash": "sha256-6I+fm+nTLF/iaj7ffiFGlSY7POmubwUaPA/Wq0Bm53M=",
|
||||||
"owner": "rust-lang",
|
"owner": "rust-lang",
|
||||||
"repo": "rust-analyzer",
|
"repo": "rust-analyzer",
|
||||||
"rev": "a5b21ea0aa644dffd7cf958b43f11f221d53404e",
|
"rev": "ffbc5ad993d5cd2f3b8bcf9a511165470944ab91",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -9,8 +9,7 @@
|
|||||||
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";
|
||||||
# https://github.com/girlbossceo/rocksdb/commit/db6df0b185774778457dabfcbd822cb81760cade
|
rocksdb = { url = "github:girlbossceo/rocksdb?ref=v9.4.0"; flake = false; };
|
||||||
rocksdb = { url = "github:girlbossceo/rocksdb?ref=v9.3.1"; flake = false; };
|
|
||||||
liburing = { url = "github:axboe/liburing?ref=master"; flake = false; };
|
liburing = { url = "github:axboe/liburing?ref=master"; flake = false; };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,7 +24,7 @@
|
|||||||
file = ./rust-toolchain.toml;
|
file = ./rust-toolchain.toml;
|
||||||
|
|
||||||
# See also `rust-toolchain.toml`
|
# See also `rust-toolchain.toml`
|
||||||
sha256 = "sha256-+syqAd2kX8KVa8/U2gz3blIQTTsYYt3U63xBWaGOSc8";
|
sha256 = "sha256-6eN/GKzjVSjEhGO9FhWObkRFaE1Jf+uqMSdQnb8lcB4=";
|
||||||
};
|
};
|
||||||
|
|
||||||
mkScope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: {
|
mkScope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: {
|
||||||
@@ -45,10 +44,34 @@
|
|||||||
# we have this already at https://github.com/girlbossceo/rocksdb/commit/a935c0273e1ba44eacf88ce3685a9b9831486155
|
# we have this already at https://github.com/girlbossceo/rocksdb/commit/a935c0273e1ba44eacf88ce3685a9b9831486155
|
||||||
# unsetting this so i don't have to revert it and make this nix exclusive
|
# unsetting this so i don't have to revert it and make this nix exclusive
|
||||||
patches = [];
|
patches = [];
|
||||||
# no real reason to have snappy, no one uses this
|
|
||||||
cmakeFlags = pkgs.lib.subtractLists
|
cmakeFlags = pkgs.lib.subtractLists
|
||||||
[ "-DWITH_SNAPPY=1" ]
|
[
|
||||||
old.cmakeFlags;
|
# no real reason to have snappy, no one uses this
|
||||||
|
"-DWITH_SNAPPY=1"
|
||||||
|
# we dont need to use ldb or sst_dump (core_tools)
|
||||||
|
"-DWITH_CORE_TOOLS=1"
|
||||||
|
# we dont need to build rocksdb tests
|
||||||
|
"-DWITH_TESTS=1"
|
||||||
|
# we use rust-rocksdb via C interface and dont need C++ RTTI
|
||||||
|
"-DUSE_RTTI=1"
|
||||||
|
]
|
||||||
|
old.cmakeFlags
|
||||||
|
++ [
|
||||||
|
# we dont need to use ldb or sst_dump (core_tools)
|
||||||
|
"-DWITH_CORE_TOOLS=0"
|
||||||
|
# we dont need trace tools
|
||||||
|
"-DWITH_TRACE_TOOLS=0"
|
||||||
|
# we dont need to build rocksdb tests
|
||||||
|
"-DWITH_TESTS=0"
|
||||||
|
# we use rust-rocksdb via C interface and dont need C++ RTTI
|
||||||
|
"-DUSE_RTTI=0"
|
||||||
|
];
|
||||||
|
|
||||||
|
# outputs has "tools" which we dont need or use
|
||||||
|
outputs = [ "out" ];
|
||||||
|
|
||||||
|
# preInstall hooks has stuff for messing with ldb/sst_dump which we dont need or use
|
||||||
|
preInstall = "";
|
||||||
});
|
});
|
||||||
# TODO: remove once https://github.com/NixOS/nixpkgs/pull/314945 is available
|
# TODO: remove once https://github.com/NixOS/nixpkgs/pull/314945 is available
|
||||||
liburing = pkgs.liburing.overrideAttrs (old: {
|
liburing = pkgs.liburing.overrideAttrs (old: {
|
||||||
@@ -96,6 +119,9 @@
|
|||||||
# Needed for producing Debian packages
|
# Needed for producing Debian packages
|
||||||
cargo-deb
|
cargo-deb
|
||||||
|
|
||||||
|
# Needed for CI to check validity of produced Debian packages (dpkg-deb)
|
||||||
|
dpkg
|
||||||
|
|
||||||
# Needed for Complement
|
# Needed for Complement
|
||||||
go
|
go
|
||||||
|
|
||||||
@@ -110,6 +136,8 @@
|
|||||||
|
|
||||||
# Useful for editing the book locally
|
# Useful for editing the book locally
|
||||||
mdbook
|
mdbook
|
||||||
|
|
||||||
|
sccache
|
||||||
])
|
])
|
||||||
++ scope.main.buildInputs
|
++ scope.main.buildInputs
|
||||||
++ scope.main.propagatedBuildInputs
|
++ scope.main.propagatedBuildInputs
|
||||||
@@ -121,10 +149,35 @@
|
|||||||
{
|
{
|
||||||
packages = {
|
packages = {
|
||||||
default = scopeHost.main;
|
default = scopeHost.main;
|
||||||
|
default-debug = scopeHost.main.override {
|
||||||
|
profile = "dev";
|
||||||
|
# debug build users expect full logs
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
};
|
||||||
|
default-test = scopeHost.main.override {
|
||||||
|
profile = "test";
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
};
|
||||||
all-features = scopeHost.main.override {
|
all-features = scopeHost.main.override {
|
||||||
all_features = true;
|
all_features = true;
|
||||||
|
disable_features = [
|
||||||
# this is non-functional on nix for some reason
|
# this is non-functional on nix for some reason
|
||||||
disable_features = ["hardened_malloc"];
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
all-features-debug = scopeHost.main.override {
|
||||||
|
profile = "dev";
|
||||||
|
all_features = true;
|
||||||
|
# debug build users expect full logs
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
disable_features = [
|
||||||
|
# this is non-functional on nix for some reason
|
||||||
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
hmalloc = scopeHost.main.override { features = ["hardened_malloc"]; };
|
hmalloc = scopeHost.main.override { features = ["hardened_malloc"]; };
|
||||||
|
|
||||||
@@ -132,8 +185,26 @@
|
|||||||
oci-image-all-features = scopeHost.oci-image.override {
|
oci-image-all-features = scopeHost.oci-image.override {
|
||||||
main = scopeHost.main.override {
|
main = scopeHost.main.override {
|
||||||
all_features = true;
|
all_features = true;
|
||||||
|
disable_features = [
|
||||||
# this is non-functional on nix for some reason
|
# this is non-functional on nix for some reason
|
||||||
disable_features = ["hardened_malloc"];
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
oci-image-all-features-debug = scopeHost.oci-image.override {
|
||||||
|
main = scopeHost.main.override {
|
||||||
|
profile = "dev";
|
||||||
|
all_features = true;
|
||||||
|
# debug build users expect full logs
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
disable_features = [
|
||||||
|
# this is non-functional on nix for some reason
|
||||||
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
oci-image-hmalloc = scopeHost.oci-image.override {
|
oci-image-hmalloc = scopeHost.oci-image.override {
|
||||||
@@ -170,13 +241,54 @@
|
|||||||
value = scopeCrossStatic.main;
|
value = scopeCrossStatic.main;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# An output for a statically-linked unstripped debug ("dev") binary
|
||||||
|
{
|
||||||
|
name = "${binaryName}-debug";
|
||||||
|
value = scopeCrossStatic.main.override {
|
||||||
|
profile = "dev";
|
||||||
|
# debug build users expect full logs
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
# An output for a statically-linked unstripped debug binary with the
|
||||||
|
# "test" profile (for CI usage only)
|
||||||
|
{
|
||||||
|
name = "${binaryName}-test";
|
||||||
|
value = scopeCrossStatic.main.override {
|
||||||
|
profile = "test";
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
# An output for a statically-linked binary with `--all-features`
|
# An output for a statically-linked binary with `--all-features`
|
||||||
{
|
{
|
||||||
name = "${binaryName}-all-features";
|
name = "${binaryName}-all-features";
|
||||||
value = scopeCrossStatic.main.override {
|
value = scopeCrossStatic.main.override {
|
||||||
all_features = true;
|
all_features = true;
|
||||||
|
disable_features = [
|
||||||
# this is non-functional on nix for some reason
|
# this is non-functional on nix for some reason
|
||||||
disable_features = ["hardened_malloc"];
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
# An output for a statically-linked unstripped debug ("dev") binary with `--all-features`
|
||||||
|
{
|
||||||
|
name = "${binaryName}-all-features-debug";
|
||||||
|
value = scopeCrossStatic.main.override {
|
||||||
|
profile = "dev";
|
||||||
|
all_features = true;
|
||||||
|
# debug build users expect full logs
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
disable_features = [
|
||||||
|
# this is non-functional on nix for some reason
|
||||||
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,14 +306,49 @@
|
|||||||
value = scopeCrossStatic.oci-image;
|
value = scopeCrossStatic.oci-image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# An output for an OCI image based on that unstripped debug ("dev") binary
|
||||||
|
{
|
||||||
|
name = "oci-image-${crossSystem}-debug";
|
||||||
|
value = scopeCrossStatic.oci-image.override {
|
||||||
|
main = scopeCrossStatic.main.override {
|
||||||
|
profile = "dev";
|
||||||
|
# debug build users expect full logs
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
# An output for an OCI image based on that binary with `--all-features`
|
# An output for an OCI image based on that binary with `--all-features`
|
||||||
{
|
{
|
||||||
name = "oci-image-${crossSystem}-all-features";
|
name = "oci-image-${crossSystem}-all-features";
|
||||||
value = scopeCrossStatic.oci-image.override {
|
value = scopeCrossStatic.oci-image.override {
|
||||||
main = scopeCrossStatic.main.override {
|
main = scopeCrossStatic.main.override {
|
||||||
all_features = true;
|
all_features = true;
|
||||||
|
disable_features = [
|
||||||
# this is non-functional on nix for some reason
|
# this is non-functional on nix for some reason
|
||||||
disable_features = ["hardened_malloc"];
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
# An output for an OCI image based on that unstripped debug ("dev") binary with `--all-features`
|
||||||
|
{
|
||||||
|
name = "oci-image-${crossSystem}-all-features-debug";
|
||||||
|
value = scopeCrossStatic.oci-image.override {
|
||||||
|
main = scopeCrossStatic.main.override {
|
||||||
|
profile = "dev";
|
||||||
|
all_features = true;
|
||||||
|
# debug build users expect full logs
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
disable_features = [
|
||||||
|
# this is non-functional on nix for some reason
|
||||||
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -229,8 +376,12 @@
|
|||||||
(scopeHostStatic.overrideScope (final: prev: {
|
(scopeHostStatic.overrideScope (final: prev: {
|
||||||
main = prev.main.override {
|
main = prev.main.override {
|
||||||
all_features = true;
|
all_features = true;
|
||||||
|
disable_features = [
|
||||||
# this is non-functional on nix for some reason
|
# this is non-functional on nix for some reason
|
||||||
disable_features = ["hardened_malloc"];
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
devShells.no-features = mkDevShell
|
devShells.no-features = mkDevShell
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true
|
|||||||
ip_range_denylist = []
|
ip_range_denylist = []
|
||||||
url_preview_domain_contains_allowlist = ["*"]
|
url_preview_domain_contains_allowlist = ["*"]
|
||||||
media_compat_file_link = false
|
media_compat_file_link = false
|
||||||
media_statup_check = false
|
media_startup_check = false
|
||||||
rocksdb_direct_io = false
|
rocksdb_direct_io = false
|
||||||
|
|
||||||
[global.tls]
|
[global.tls]
|
||||||
|
|||||||
@@ -14,8 +14,15 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
main' = main.override {
|
main' = main.override {
|
||||||
profile = "dev";
|
profile = "test";
|
||||||
features = ["axum_dual_protocol"];
|
all_features = true;
|
||||||
|
disable_release_max_log_level = true;
|
||||||
|
disable_features = [
|
||||||
|
# this is non-functional on nix for some reason
|
||||||
|
"hardened_malloc"
|
||||||
|
# dont include experimental features
|
||||||
|
"experimental"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
start = writeShellScriptBin "start" ''
|
start = writeShellScriptBin "start" ''
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ lib.optionalAttrs stdenv.hostPlatform.isStatic {
|
|||||||
lib.concatStringsSep
|
lib.concatStringsSep
|
||||||
" "
|
" "
|
||||||
([]
|
([]
|
||||||
|
++ lib.optionals
|
||||||
|
stdenv.targetPlatform.isx86_64
|
||||||
|
[ "-C" "target-cpu=x86-64-v2" ]
|
||||||
|
++ lib.optionals
|
||||||
|
stdenv.targetPlatform.isAarch64
|
||||||
|
[ "-C" "target-cpu=cortex-a55" ] # cortex-a55 == ARMv8.2-a
|
||||||
# This disables PIE for static builds, which isn't great in terms
|
# This disables PIE for static builds, which isn't great in terms
|
||||||
# of security. Unfortunately, my hand is forced because nixpkgs'
|
# of security. Unfortunately, my hand is forced because nixpkgs'
|
||||||
# `libstdc++.a` is built without `-fPIE`, which precludes us from
|
# `libstdc++.a` is built without `-fPIE`, which precludes us from
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ rust-jemalloc-sys' = (rust-jemalloc-sys.override {
|
|||||||
unprefixed = true;
|
unprefixed = true;
|
||||||
}).overrideAttrs (old: {
|
}).overrideAttrs (old: {
|
||||||
configureFlags = old.configureFlags ++
|
configureFlags = old.configureFlags ++
|
||||||
|
# we dont need docs
|
||||||
|
[ "--disable-doc" ] ++
|
||||||
|
# we dont need cxx/C++ integration
|
||||||
|
[ "--disable-cxx" ] ++
|
||||||
# tikv-jemalloc-sys/profiling feature
|
# tikv-jemalloc-sys/profiling feature
|
||||||
lib.optional (featureEnabled "jemalloc_prof") "--enable-prof";
|
lib.optional (featureEnabled "jemalloc_prof") "--enable-prof";
|
||||||
});
|
});
|
||||||
@@ -71,10 +75,29 @@ buildDepsOnlyEnv =
|
|||||||
# which breaks Darwin entirely
|
# which breaks Darwin entirely
|
||||||
enableLiburing = enableLiburing;
|
enableLiburing = enableLiburing;
|
||||||
}).overrideAttrs (old: {
|
}).overrideAttrs (old: {
|
||||||
# TODO: static rocksdb fails to build on darwin
|
# TODO: static rocksdb fails to build on darwin, also see <https://github.com/NixOS/nixpkgs/issues/320448>
|
||||||
# build log at <https://girlboss.ceo/~strawberry/pb/JjGH>
|
# build log at <https://girlboss.ceo/~strawberry/pb/JjGH>
|
||||||
meta.broken = stdenv.hostPlatform.isStatic && stdenv.isDarwin;
|
meta.broken = stdenv.hostPlatform.isStatic && stdenv.isDarwin;
|
||||||
|
|
||||||
enableLiburing = enableLiburing;
|
enableLiburing = enableLiburing;
|
||||||
|
|
||||||
|
sse42Support = stdenv.targetPlatform.isx86_64;
|
||||||
|
|
||||||
|
cmakeFlags = if stdenv.targetPlatform.isx86_64
|
||||||
|
then lib.subtractLists [ "-DPORTABLE=1" ] old.cmakeFlags
|
||||||
|
++ lib.optionals stdenv.targetPlatform.isx86_64 [
|
||||||
|
"-DPORTABLE=x86-64-v2"
|
||||||
|
"-DUSE_SSE=1"
|
||||||
|
"-DHAVE_SSE=1"
|
||||||
|
"-DHAVE_SSE42=1"
|
||||||
|
]
|
||||||
|
else if stdenv.targetPlatform.isAarch64
|
||||||
|
then lib.subtractLists [ "-DPORTABLE=1" ] old.cmakeFlags
|
||||||
|
++ lib.optionals stdenv.targetPlatform.isAarch64 [
|
||||||
|
# cortex-a55 == ARMv8.2-a
|
||||||
|
"-DPORTABLE=armv8.2-a"
|
||||||
|
]
|
||||||
|
else old.cmakeFlags;
|
||||||
});
|
});
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@@ -101,7 +124,11 @@ buildPackageEnv = {
|
|||||||
# Only needed in static stdenv because these are transitive dependencies of rocksdb
|
# Only needed in static stdenv because these are transitive dependencies of rocksdb
|
||||||
CARGO_BUILD_RUSTFLAGS = buildDepsOnlyEnv.CARGO_BUILD_RUSTFLAGS
|
CARGO_BUILD_RUSTFLAGS = buildDepsOnlyEnv.CARGO_BUILD_RUSTFLAGS
|
||||||
+ lib.optionalString (enableLiburing && stdenv.hostPlatform.isStatic)
|
+ lib.optionalString (enableLiburing && stdenv.hostPlatform.isStatic)
|
||||||
" -L${lib.getLib liburing}/lib -luring";
|
" -L${lib.getLib liburing}/lib -luring"
|
||||||
|
+ lib.optionalString stdenv.targetPlatform.isx86_64
|
||||||
|
" -Ctarget-cpu=x86-64-v2"
|
||||||
|
+ lib.optionalString stdenv.targetPlatform.isAarch64
|
||||||
|
" -Ctarget-cpu=cortex-a55"; # cortex-a55 == ARMv8.2-a
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -126,6 +153,8 @@ commonAttrs = {
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dontStrip = profile == "dev" || profile == "test";
|
||||||
|
|
||||||
buildInputs = lib.optional (featureEnabled "jemalloc") rust-jemalloc-sys';
|
buildInputs = lib.optional (featureEnabled "jemalloc") rust-jemalloc-sys';
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|||||||
+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.77.0"
|
channel = "1.80.0"
|
||||||
components = [
|
components = [
|
||||||
# For rust-analyzer
|
# For rust-analyzer
|
||||||
"rust-src",
|
"rust-src",
|
||||||
|
|||||||
@@ -64,6 +64,6 @@ async fn view_room_topic(_body: Vec<&str>, room_id: Box<RoomId>) -> Result<RoomM
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(RoomMessageEventContent::notice_markdown(format!(
|
Ok(RoomMessageEventContent::notice_markdown(format!(
|
||||||
"Room topic:\n\n```{room_topic}\n```"
|
"Room topic:\n```\n{room_topic}\n```"
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ pub(super) async fn create(
|
|||||||
return Ok(RoomMessageEventContent::text_plain(format!("Userid {user_id} already exists")));
|
return Ok(RoomMessageEventContent::text_plain(format!("Userid {user_id} already exists")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if user_id.is_historical() {
|
||||||
|
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||||
|
"User ID {user_id} does not conform to new Matrix identifier spec"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
// Create user
|
// Create user
|
||||||
|
|||||||
@@ -117,7 +117,12 @@ pub(crate) async fn set_room_visibility_route(
|
|||||||
return Err(Error::BadRequest(ErrorKind::NotFound, "Room not found"));
|
return Err(Error::BadRequest(ErrorKind::NotFound, "Room not found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
user_can_publish_room(sender_user, &body.room_id)?;
|
if !user_can_publish_room(sender_user, &body.room_id)? {
|
||||||
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::forbidden(),
|
||||||
|
"User is not allowed to publish this room",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
match &body.visibility {
|
match &body.visibility {
|
||||||
room::Visibility::Public => {
|
room::Visibility::Public => {
|
||||||
@@ -377,8 +382,8 @@ fn user_can_publish_room(user_id: &UserId, room_id: &RoomId) -> Result<bool> {
|
|||||||
Ok(event.sender == user_id)
|
Ok(event.sender == user_id)
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::BadRequest(
|
return Err(Error::BadRequest(
|
||||||
ErrorKind::Unauthorized,
|
ErrorKind::forbidden(),
|
||||||
"You are not allowed to publish this room to the room directory",
|
"User is not allowed to publish this room",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,12 +200,13 @@ pub(crate) async fn get_content_route(
|
|||||||
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,
|
||||||
content_type,
|
content_type,
|
||||||
file,
|
|
||||||
content_disposition,
|
content_disposition,
|
||||||
}) = services().media.get(&mxc).await?
|
}) = services().media.get(&mxc).await?
|
||||||
{
|
{
|
||||||
let content_disposition = Some(make_content_disposition(&content_type, content_disposition, None));
|
let content_disposition = Some(make_content_disposition(&content_type, content_disposition, None));
|
||||||
|
let file = content.expect("content");
|
||||||
|
|
||||||
Ok(get_content::v3::Response {
|
Ok(get_content::v3::Response {
|
||||||
file,
|
file,
|
||||||
@@ -282,8 +283,8 @@ pub(crate) async fn get_content_as_filename_route(
|
|||||||
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,
|
||||||
content_type,
|
content_type,
|
||||||
file,
|
|
||||||
content_disposition,
|
content_disposition,
|
||||||
}) = services().media.get(&mxc).await?
|
}) = services().media.get(&mxc).await?
|
||||||
{
|
{
|
||||||
@@ -293,6 +294,7 @@ pub(crate) async fn get_content_as_filename_route(
|
|||||||
Some(body.filename.clone()),
|
Some(body.filename.clone()),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let file = content.expect("content");
|
||||||
Ok(get_content_as_filename::v3::Response {
|
Ok(get_content_as_filename::v3::Response {
|
||||||
file,
|
file,
|
||||||
content_type,
|
content_type,
|
||||||
@@ -371,8 +373,8 @@ pub(crate) async fn get_content_thumbnail_route(
|
|||||||
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,
|
||||||
content_type,
|
content_type,
|
||||||
file,
|
|
||||||
content_disposition,
|
content_disposition,
|
||||||
}) = services()
|
}) = services()
|
||||||
.media
|
.media
|
||||||
@@ -388,6 +390,7 @@ pub(crate) async fn get_content_thumbnail_route(
|
|||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
let content_disposition = Some(make_content_disposition(&content_type, content_disposition, None));
|
let content_disposition = Some(make_content_disposition(&content_type, content_disposition, None));
|
||||||
|
let file = content.expect("content");
|
||||||
|
|
||||||
Ok(get_content_thumbnail::v3::Response {
|
Ok(get_content_thumbnail::v3::Response {
|
||||||
file,
|
file,
|
||||||
|
|||||||
@@ -16,6 +16,14 @@ pub(crate) async fn set_presence_route(body: Ruma<set_presence::v3::Request>) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
|
if sender_user != &body.user_id && body.appservice_info.is_none() {
|
||||||
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::InvalidParam,
|
||||||
|
"Not allowed to set presence of other users",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
services()
|
services()
|
||||||
.presence
|
.presence
|
||||||
.set_presence(sender_user, &body.presence, None, None, body.status_msg.clone())?;
|
.set_presence(sender_user, &body.presence, None, None, body.status_msg.clone())?;
|
||||||
|
|||||||
+5
-5
@@ -1,15 +1,15 @@
|
|||||||
pub mod client;
|
pub mod client;
|
||||||
mod router;
|
pub mod router;
|
||||||
pub mod routes;
|
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|
||||||
extern crate conduit_core as conduit;
|
extern crate conduit_core as conduit;
|
||||||
extern crate conduit_service as service;
|
extern crate conduit_service as service;
|
||||||
|
|
||||||
pub(crate) use conduit::{debug_info, debug_warn, utils, Error, Result};
|
pub(crate) use conduit::{debug_info, debug_warn, pdu::PduEvent, utils, Error, Result};
|
||||||
pub(crate) use service::{pdu::PduEvent, services, user_is_local};
|
pub(crate) use service::{services, user_is_local};
|
||||||
|
|
||||||
pub(crate) use self::router::{Ruma, RumaResponse};
|
pub use crate::router::State;
|
||||||
|
pub(crate) use crate::router::{Ruma, RumaResponse};
|
||||||
|
|
||||||
conduit::mod_ctor! {}
|
conduit::mod_ctor! {}
|
||||||
conduit::mod_dtor! {}
|
conduit::mod_dtor! {}
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
|
mod args;
|
||||||
|
mod auth;
|
||||||
|
mod handler;
|
||||||
|
mod request;
|
||||||
|
mod response;
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
routing::{any, get, post},
|
routing::{any, get, post},
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use conduit::{err, Error, Server};
|
use conduit::{err, Server};
|
||||||
use http::Uri;
|
use http::Uri;
|
||||||
use ruma::api::client::error::ErrorKind;
|
|
||||||
|
|
||||||
use crate::{client, router::RouterExt, server};
|
use self::handler::RouterExt;
|
||||||
|
pub(super) use self::{args::Args as Ruma, response::RumaResponse};
|
||||||
|
use crate::{client, server};
|
||||||
|
|
||||||
pub fn build(router: Router, server: &Server) -> Router {
|
pub type State = &'static service::Services;
|
||||||
|
|
||||||
|
pub fn build(router: Router<State>, server: &Server) -> Router<State> {
|
||||||
let config = &server.config;
|
let config = &server.config;
|
||||||
let router = router
|
let router = router
|
||||||
.ruma_route(client::get_supported_versions_route)
|
.ruma_route(client::get_supported_versions_route)
|
||||||
@@ -233,7 +242,7 @@ pub fn build(router: Router, server: &Server) -> Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn initial_sync(_uri: Uri) -> impl IntoResponse {
|
async fn initial_sync(_uri: Uri) -> impl IntoResponse {
|
||||||
Error::BadRequest(ErrorKind::GuestAccessForbidden, "Guest access not implemented")
|
err!(Request(GuestAccessForbidden("Guest access not implemented")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn federation_disabled() -> impl IntoResponse { err!(Config("allow_federation", "Federation is disabled.")) }
|
async fn federation_disabled() -> impl IntoResponse { err!(Config("allow_federation", "Federation is disabled.")) }
|
||||||
@@ -1,24 +1,15 @@
|
|||||||
mod auth;
|
|
||||||
mod handler;
|
|
||||||
mod request;
|
|
||||||
mod response;
|
|
||||||
|
|
||||||
use std::{mem, ops::Deref};
|
use std::{mem, ops::Deref};
|
||||||
|
|
||||||
use axum::{async_trait, body::Body, extract::FromRequest};
|
use axum::{async_trait, body::Body, extract::FromRequest};
|
||||||
use bytes::{BufMut, BytesMut};
|
use bytes::{BufMut, BytesMut};
|
||||||
use conduit::{debug, debug_warn, trace, warn};
|
use conduit::{debug, err, trace, Error, Result};
|
||||||
use ruma::{
|
use ruma::{api::IncomingRequest, CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId};
|
||||||
api::{client::error::ErrorKind, IncomingRequest},
|
|
||||||
CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId,
|
|
||||||
};
|
|
||||||
|
|
||||||
use self::{auth::Auth, request::Request};
|
use super::{auth, auth::Auth, request, request::Request};
|
||||||
pub(super) use self::{handler::RouterExt, response::RumaResponse};
|
use crate::{service::appservice::RegistrationInfo, services};
|
||||||
use crate::{service::appservice::RegistrationInfo, services, Error, Result};
|
|
||||||
|
|
||||||
/// Extractor for Ruma request structs
|
/// Extractor for Ruma request structs
|
||||||
pub(crate) struct Ruma<T> {
|
pub(crate) struct Args<T> {
|
||||||
/// Request struct body
|
/// Request struct body
|
||||||
pub(crate) body: T,
|
pub(crate) body: T,
|
||||||
|
|
||||||
@@ -44,7 +35,7 @@ pub(crate) struct Ruma<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T, S> FromRequest<S, Body> for Ruma<T>
|
impl<T, S> FromRequest<S, Body> for Args<T>
|
||||||
where
|
where
|
||||||
T: IncomingRequest,
|
T: IncomingRequest,
|
||||||
{
|
{
|
||||||
@@ -65,7 +56,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Deref for Ruma<T> {
|
impl<T> Deref for Args<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target { &self.body }
|
fn deref(&self) -> &Self::Target { &self.body }
|
||||||
@@ -109,21 +100,14 @@ where
|
|||||||
let mut http_request = hyper::Request::builder()
|
let mut http_request = hyper::Request::builder()
|
||||||
.uri(request.parts.uri.clone())
|
.uri(request.parts.uri.clone())
|
||||||
.method(request.parts.method.clone());
|
.method(request.parts.method.clone());
|
||||||
*http_request.headers_mut().unwrap() = request.parts.headers.clone();
|
*http_request.headers_mut().expect("mutable http headers") = request.parts.headers.clone();
|
||||||
let http_request = http_request.body(body).unwrap();
|
let http_request = http_request.body(body).expect("http request body");
|
||||||
debug!(
|
|
||||||
"{:?} {:?} {:?}",
|
|
||||||
http_request.method(),
|
|
||||||
http_request.uri(),
|
|
||||||
http_request.headers()
|
|
||||||
);
|
|
||||||
|
|
||||||
trace!("{:?} {:?} {:?}", http_request.method(), http_request.uri(), json_body);
|
let headers = http_request.headers();
|
||||||
let body = T::try_from_http_request(http_request, &request.path).map_err(|e| {
|
let method = http_request.method();
|
||||||
warn!("try_from_http_request failed: {e:?}",);
|
let uri = http_request.uri();
|
||||||
debug_warn!("JSON body: {:?}", json_body);
|
debug!("{method:?} {uri:?} {headers:?}");
|
||||||
Error::BadRequest(ErrorKind::BadJson, "Failed to deserialize request.")
|
trace!("{method:?} {uri:?} {json_body:?}");
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(body)
|
T::try_from_http_request(http_request, &request.path).map_err(|e| err!(Request(BadJson(debug_warn!("{e}")))))
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ use conduit::Result;
|
|||||||
use http::Method;
|
use http::Method;
|
||||||
use ruma::api::IncomingRequest;
|
use ruma::api::IncomingRequest;
|
||||||
|
|
||||||
use super::{Ruma, RumaResponse};
|
use super::{Ruma, RumaResponse, State};
|
||||||
|
|
||||||
pub(in super::super) trait RouterExt {
|
pub(in super::super) trait RouterExt {
|
||||||
fn ruma_route<H, T>(self, handler: H) -> Self
|
fn ruma_route<H, T>(self, handler: H) -> Self
|
||||||
@@ -18,7 +18,7 @@ pub(in super::super) trait RouterExt {
|
|||||||
H: RumaHandler<T>;
|
H: RumaHandler<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RouterExt for Router {
|
impl RouterExt for Router<State> {
|
||||||
fn ruma_route<H, T>(self, handler: H) -> Self
|
fn ruma_route<H, T>(self, handler: H) -> Self
|
||||||
where
|
where
|
||||||
H: RumaHandler<T>,
|
H: RumaHandler<T>,
|
||||||
@@ -28,9 +28,9 @@ impl RouterExt for Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(in super::super) trait RumaHandler<T> {
|
pub(in super::super) trait RumaHandler<T> {
|
||||||
fn add_routes(&self, router: Router) -> Router;
|
fn add_routes(&self, router: Router<State>) -> Router<State>;
|
||||||
|
|
||||||
fn add_route(&self, router: Router, path: &str) -> Router;
|
fn add_route(&self, router: Router<State>, path: &str) -> Router<State>;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! ruma_handler {
|
macro_rules! ruma_handler {
|
||||||
@@ -41,17 +41,17 @@ macro_rules! ruma_handler {
|
|||||||
Req: IncomingRequest + Send + 'static,
|
Req: IncomingRequest + Send + 'static,
|
||||||
Ret: IntoResponse,
|
Ret: IntoResponse,
|
||||||
Fut: Future<Output = Result<Req::OutgoingResponse, Ret>> + Send,
|
Fut: Future<Output = Result<Req::OutgoingResponse, Ret>> + Send,
|
||||||
Fun: FnOnce($($tx,)* Ruma<Req>) -> Fut + Clone + Send + Sync + 'static,
|
Fun: FnOnce($($tx,)* Ruma<Req>,) -> Fut + Clone + Send + Sync + 'static,
|
||||||
$( $tx: FromRequestParts<()> + Send + 'static, )*
|
$( $tx: FromRequestParts<State> + Send + 'static, )*
|
||||||
{
|
{
|
||||||
fn add_routes(&self, router: Router) -> Router {
|
fn add_routes(&self, router: Router<State>) -> Router<State> {
|
||||||
Req::METADATA
|
Req::METADATA
|
||||||
.history
|
.history
|
||||||
.all_paths()
|
.all_paths()
|
||||||
.fold(router, |router, path| self.add_route(router, path))
|
.fold(router, |router, path| self.add_route(router, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_route(&self, router: Router, path: &str) -> Router {
|
fn add_route(&self, router: Router<State>, path: &str) -> Router<State> {
|
||||||
let handle = self.clone();
|
let handle = self.clone();
|
||||||
let method = method_to_filter(&Req::METADATA.method);
|
let method = method_to_filter(&Req::METADATA.method);
|
||||||
let action = |$($tx,)* req| async { handle($($tx,)* req).await.map(RumaResponse) };
|
let action = |$($tx,)* req| async { handle($($tx,)* req).await.map(RumaResponse) };
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ use std::str;
|
|||||||
|
|
||||||
use axum::{extract::Path, RequestExt, RequestPartsExt};
|
use axum::{extract::Path, RequestExt, RequestPartsExt};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use conduit::err;
|
||||||
use http::request::Parts;
|
use http::request::Parts;
|
||||||
use ruma::api::client::error::ErrorKind;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{services, Error, Result};
|
use crate::{services, Result};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub(super) struct QueryParams {
|
pub(super) struct QueryParams {
|
||||||
@@ -26,14 +26,15 @@ pub(super) async fn from(request: hyper::Request<axum::body::Body>) -> Result<Re
|
|||||||
let (mut parts, body) = limited.into_parts();
|
let (mut parts, body) = limited.into_parts();
|
||||||
|
|
||||||
let path: Path<Vec<String>> = parts.extract().await?;
|
let path: Path<Vec<String>> = parts.extract().await?;
|
||||||
let query = serde_html_form::from_str(parts.uri.query().unwrap_or_default())
|
let query = parts.uri.query().unwrap_or_default();
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::Unknown, "Failed to read query parameters"))?;
|
let query =
|
||||||
|
serde_html_form::from_str(query).map_err(|e| err!(Request(Unknown("Failed to read query parameters: {e}"))))?;
|
||||||
|
|
||||||
let max_body_size = services().globals.config.max_request_size;
|
let max_body_size = services().globals.config.max_request_size;
|
||||||
|
|
||||||
let body = axum::body::to_bytes(body, max_body_size)
|
let body = axum::body::to_bytes(body, max_body_size)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::TooLarge, "Request body too large"))?;
|
.map_err(|e| err!(Request(TooLarge("Request body too large: {e}"))))?;
|
||||||
|
|
||||||
Ok(Request {
|
Ok(Request {
|
||||||
path,
|
path,
|
||||||
|
|||||||
+59
-59
@@ -1,7 +1,8 @@
|
|||||||
use std::{collections::BTreeMap, net::IpAddr, time::Instant};
|
use std::{collections::BTreeMap, net::IpAddr, time::Instant};
|
||||||
|
|
||||||
|
use axum::extract::State;
|
||||||
use axum_client_ip::InsecureClientIp;
|
use axum_client_ip::InsecureClientIp;
|
||||||
use conduit::debug_warn;
|
use conduit::{debug, debug_warn, err, trace, warn, Err};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::{
|
api::{
|
||||||
client::error::ErrorKind,
|
client::error::ErrorKind,
|
||||||
@@ -18,11 +19,10 @@ use ruma::{
|
|||||||
OwnedEventId, ServerName,
|
OwnedEventId, ServerName,
|
||||||
};
|
};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tracing::{debug, error, trace, warn};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
service::rooms::event_handler::parse_incoming_pdu,
|
service::rooms::event_handler::parse_incoming_pdu,
|
||||||
services,
|
services::Services,
|
||||||
utils::{self},
|
utils::{self},
|
||||||
Error, Result, Ruma,
|
Error, Result, Ruma,
|
||||||
};
|
};
|
||||||
@@ -34,29 +34,23 @@ type ResolvedMap = BTreeMap<OwnedEventId, Result<(), Error>>;
|
|||||||
/// Push EDUs and PDUs to this server.
|
/// Push EDUs and PDUs to this server.
|
||||||
#[tracing::instrument(skip_all, fields(%client), name = "send")]
|
#[tracing::instrument(skip_all, fields(%client), name = "send")]
|
||||||
pub(crate) async fn send_transaction_message_route(
|
pub(crate) async fn send_transaction_message_route(
|
||||||
InsecureClientIp(client): InsecureClientIp, body: Ruma<send_transaction_message::v1::Request>,
|
State(services): State<&Services>, InsecureClientIp(client): InsecureClientIp,
|
||||||
|
body: Ruma<send_transaction_message::v1::Request>,
|
||||||
) -> Result<send_transaction_message::v1::Response> {
|
) -> Result<send_transaction_message::v1::Response> {
|
||||||
let origin = body.origin.as_ref().expect("server is authenticated");
|
let origin = body.origin.as_ref().expect("server is authenticated");
|
||||||
|
|
||||||
if *origin != body.body.origin {
|
if *origin != body.body.origin {
|
||||||
return Err(Error::BadRequest(
|
return Err!(Request(Forbidden(
|
||||||
ErrorKind::forbidden(),
|
"Not allowed to send transactions on behalf of other servers"
|
||||||
"Not allowed to send transactions on behalf of other servers",
|
)));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if body.pdus.len() > 50_usize {
|
if body.pdus.len() > 50_usize {
|
||||||
return Err(Error::BadRequest(
|
return Err!(Request(Forbidden("Not allowed to send more than 50 PDUs in one transaction")));
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Not allowed to send more than 50 PDUs in one transaction",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if body.edus.len() > 100_usize {
|
if body.edus.len() > 100_usize {
|
||||||
return Err(Error::BadRequest(
|
return Err!(Request(Forbidden("Not allowed to send more than 100 EDUs in one transaction")));
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Not allowed to send more than 100 EDUs in one transaction",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let txn_start_time = Instant::now();
|
let txn_start_time = Instant::now();
|
||||||
@@ -69,8 +63,8 @@ pub(crate) async fn send_transaction_message_route(
|
|||||||
"Starting txn",
|
"Starting txn",
|
||||||
);
|
);
|
||||||
|
|
||||||
let resolved_map = handle_pdus(&client, &body, origin, &txn_start_time).await?;
|
let resolved_map = handle_pdus(services, &client, &body, origin, &txn_start_time).await?;
|
||||||
handle_edus(&client, &body, origin).await?;
|
handle_edus(services, &client, &body, origin).await?;
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
pdus = ?body.pdus.len(),
|
pdus = ?body.pdus.len(),
|
||||||
@@ -90,7 +84,8 @@ pub(crate) async fn send_transaction_message_route(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_pdus(
|
async fn handle_pdus(
|
||||||
_client: &IpAddr, body: &Ruma<send_transaction_message::v1::Request>, origin: &ServerName, txn_start_time: &Instant,
|
services: &Services, _client: &IpAddr, body: &Ruma<send_transaction_message::v1::Request>, origin: &ServerName,
|
||||||
|
txn_start_time: &Instant,
|
||||||
) -> Result<ResolvedMap> {
|
) -> Result<ResolvedMap> {
|
||||||
let mut parsed_pdus = Vec::with_capacity(body.pdus.len());
|
let mut parsed_pdus = Vec::with_capacity(body.pdus.len());
|
||||||
for pdu in &body.pdus {
|
for pdu in &body.pdus {
|
||||||
@@ -110,7 +105,7 @@ async fn handle_pdus(
|
|||||||
// corresponding signing keys
|
// corresponding signing keys
|
||||||
let pub_key_map = RwLock::new(BTreeMap::new());
|
let pub_key_map = RwLock::new(BTreeMap::new());
|
||||||
if !parsed_pdus.is_empty() {
|
if !parsed_pdus.is_empty() {
|
||||||
services()
|
services
|
||||||
.rooms
|
.rooms
|
||||||
.event_handler
|
.event_handler
|
||||||
.fetch_required_signing_keys(parsed_pdus.iter().map(|(_event_id, event, _room_id)| event), &pub_key_map)
|
.fetch_required_signing_keys(parsed_pdus.iter().map(|(_event_id, event, _room_id)| event), &pub_key_map)
|
||||||
@@ -126,7 +121,7 @@ async fn handle_pdus(
|
|||||||
let mut resolved_map = BTreeMap::new();
|
let mut resolved_map = BTreeMap::new();
|
||||||
for (event_id, value, room_id) in parsed_pdus {
|
for (event_id, value, room_id) in parsed_pdus {
|
||||||
let pdu_start_time = Instant::now();
|
let pdu_start_time = Instant::now();
|
||||||
let mutex_lock = services()
|
let mutex_lock = services
|
||||||
.rooms
|
.rooms
|
||||||
.event_handler
|
.event_handler
|
||||||
.mutex_federation
|
.mutex_federation
|
||||||
@@ -134,7 +129,7 @@ async fn handle_pdus(
|
|||||||
.await;
|
.await;
|
||||||
resolved_map.insert(
|
resolved_map.insert(
|
||||||
event_id.clone(),
|
event_id.clone(),
|
||||||
services()
|
services
|
||||||
.rooms
|
.rooms
|
||||||
.event_handler
|
.event_handler
|
||||||
.handle_incoming_pdu(origin, &room_id, &event_id, value, true, &pub_key_map)
|
.handle_incoming_pdu(origin, &room_id, &event_id, value, true, &pub_key_map)
|
||||||
@@ -162,7 +157,7 @@ async fn handle_pdus(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_edus(
|
async fn handle_edus(
|
||||||
client: &IpAddr, body: &Ruma<send_transaction_message::v1::Request>, origin: &ServerName,
|
services: &Services, client: &IpAddr, body: &Ruma<send_transaction_message::v1::Request>, origin: &ServerName,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for edu in body
|
for edu in body
|
||||||
.edus
|
.edus
|
||||||
@@ -170,12 +165,12 @@ async fn handle_edus(
|
|||||||
.filter_map(|edu| serde_json::from_str::<Edu>(edu.json().get()).ok())
|
.filter_map(|edu| serde_json::from_str::<Edu>(edu.json().get()).ok())
|
||||||
{
|
{
|
||||||
match edu {
|
match edu {
|
||||||
Edu::Presence(presence) => handle_edu_presence(client, origin, presence).await?,
|
Edu::Presence(presence) => handle_edu_presence(services, client, origin, presence).await?,
|
||||||
Edu::Receipt(receipt) => handle_edu_receipt(client, origin, receipt).await?,
|
Edu::Receipt(receipt) => handle_edu_receipt(services, client, origin, receipt).await?,
|
||||||
Edu::Typing(typing) => handle_edu_typing(client, origin, typing).await?,
|
Edu::Typing(typing) => handle_edu_typing(services, client, origin, typing).await?,
|
||||||
Edu::DeviceListUpdate(content) => handle_edu_device_list_update(client, origin, content).await?,
|
Edu::DeviceListUpdate(content) => handle_edu_device_list_update(services, client, origin, content).await?,
|
||||||
Edu::DirectToDevice(content) => handle_edu_direct_to_device(client, origin, content).await?,
|
Edu::DirectToDevice(content) => handle_edu_direct_to_device(services, client, origin, content).await?,
|
||||||
Edu::SigningKeyUpdate(content) => handle_edu_signing_key_update(client, origin, content).await?,
|
Edu::SigningKeyUpdate(content) => handle_edu_signing_key_update(services, client, origin, content).await?,
|
||||||
Edu::_Custom(ref _custom) => {
|
Edu::_Custom(ref _custom) => {
|
||||||
debug_warn!(?body.edus, "received custom/unknown EDU");
|
debug_warn!(?body.edus, "received custom/unknown EDU");
|
||||||
},
|
},
|
||||||
@@ -185,8 +180,10 @@ async fn handle_edus(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_edu_presence(_client: &IpAddr, origin: &ServerName, presence: PresenceContent) -> Result<()> {
|
async fn handle_edu_presence(
|
||||||
if !services().globals.allow_incoming_presence() {
|
services: &Services, _client: &IpAddr, origin: &ServerName, presence: PresenceContent,
|
||||||
|
) -> Result<()> {
|
||||||
|
if !services.globals.allow_incoming_presence() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +196,7 @@ async fn handle_edu_presence(_client: &IpAddr, origin: &ServerName, presence: Pr
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
services().presence.set_presence(
|
services.presence.set_presence(
|
||||||
&update.user_id,
|
&update.user_id,
|
||||||
&update.presence,
|
&update.presence,
|
||||||
Some(update.currently_active),
|
Some(update.currently_active),
|
||||||
@@ -211,13 +208,15 @@ async fn handle_edu_presence(_client: &IpAddr, origin: &ServerName, presence: Pr
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_edu_receipt(_client: &IpAddr, origin: &ServerName, receipt: ReceiptContent) -> Result<()> {
|
async fn handle_edu_receipt(
|
||||||
if !services().globals.allow_incoming_read_receipts() {
|
services: &Services, _client: &IpAddr, origin: &ServerName, receipt: ReceiptContent,
|
||||||
|
) -> Result<()> {
|
||||||
|
if !services.globals.allow_incoming_read_receipts() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (room_id, room_updates) in receipt.receipts {
|
for (room_id, room_updates) in receipt.receipts {
|
||||||
if services()
|
if services
|
||||||
.rooms
|
.rooms
|
||||||
.event_handler
|
.event_handler
|
||||||
.acl_check(origin, &room_id)
|
.acl_check(origin, &room_id)
|
||||||
@@ -239,7 +238,7 @@ async fn handle_edu_receipt(_client: &IpAddr, origin: &ServerName, receipt: Rece
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if services()
|
if services
|
||||||
.rooms
|
.rooms
|
||||||
.state_cache
|
.state_cache
|
||||||
.room_members(&room_id)
|
.room_members(&room_id)
|
||||||
@@ -255,7 +254,7 @@ async fn handle_edu_receipt(_client: &IpAddr, origin: &ServerName, receipt: Rece
|
|||||||
room_id: room_id.clone(),
|
room_id: room_id.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
services()
|
services
|
||||||
.rooms
|
.rooms
|
||||||
.read_receipt
|
.read_receipt
|
||||||
.readreceipt_update(&user_id, &room_id, &event)?;
|
.readreceipt_update(&user_id, &room_id, &event)?;
|
||||||
@@ -273,8 +272,10 @@ async fn handle_edu_receipt(_client: &IpAddr, origin: &ServerName, receipt: Rece
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_edu_typing(_client: &IpAddr, origin: &ServerName, typing: TypingContent) -> Result<()> {
|
async fn handle_edu_typing(
|
||||||
if !services().globals.config.allow_incoming_typing {
|
services: &Services, _client: &IpAddr, origin: &ServerName, typing: TypingContent,
|
||||||
|
) -> Result<()> {
|
||||||
|
if !services.globals.config.allow_incoming_typing {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +287,7 @@ async fn handle_edu_typing(_client: &IpAddr, origin: &ServerName, typing: Typing
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if services()
|
if services
|
||||||
.rooms
|
.rooms
|
||||||
.event_handler
|
.event_handler
|
||||||
.acl_check(typing.user_id.server_name(), &typing.room_id)
|
.acl_check(typing.user_id.server_name(), &typing.room_id)
|
||||||
@@ -299,26 +300,26 @@ async fn handle_edu_typing(_client: &IpAddr, origin: &ServerName, typing: Typing
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if services()
|
if services
|
||||||
.rooms
|
.rooms
|
||||||
.state_cache
|
.state_cache
|
||||||
.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().saturating_add(
|
let timeout = utils::millis_since_unix_epoch().saturating_add(
|
||||||
services()
|
services
|
||||||
.globals
|
.globals
|
||||||
.config
|
.config
|
||||||
.typing_federation_timeout_s
|
.typing_federation_timeout_s
|
||||||
.saturating_mul(1000),
|
.saturating_mul(1000),
|
||||||
);
|
);
|
||||||
services()
|
services
|
||||||
.rooms
|
.rooms
|
||||||
.typing
|
.typing
|
||||||
.typing_add(&typing.user_id, &typing.room_id, timeout)
|
.typing_add(&typing.user_id, &typing.room_id, timeout)
|
||||||
.await?;
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
services()
|
services
|
||||||
.rooms
|
.rooms
|
||||||
.typing
|
.typing
|
||||||
.typing_remove(&typing.user_id, &typing.room_id)
|
.typing_remove(&typing.user_id, &typing.room_id)
|
||||||
@@ -336,7 +337,7 @@ async fn handle_edu_typing(_client: &IpAddr, origin: &ServerName, typing: Typing
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_edu_device_list_update(
|
async fn handle_edu_device_list_update(
|
||||||
_client: &IpAddr, origin: &ServerName, content: DeviceListUpdateContent,
|
services: &Services, _client: &IpAddr, origin: &ServerName, content: DeviceListUpdateContent,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let DeviceListUpdateContent {
|
let DeviceListUpdateContent {
|
||||||
user_id,
|
user_id,
|
||||||
@@ -351,13 +352,13 @@ async fn handle_edu_device_list_update(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
services().users.mark_device_key_update(&user_id)?;
|
services.users.mark_device_key_update(&user_id)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_edu_direct_to_device(
|
async fn handle_edu_direct_to_device(
|
||||||
_client: &IpAddr, origin: &ServerName, content: DirectDeviceContent,
|
services: &Services, _client: &IpAddr, origin: &ServerName, content: DirectDeviceContent,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let DirectDeviceContent {
|
let DirectDeviceContent {
|
||||||
sender,
|
sender,
|
||||||
@@ -375,7 +376,7 @@ async fn handle_edu_direct_to_device(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if this is a new transaction id
|
// Check if this is a new transaction id
|
||||||
if services()
|
if services
|
||||||
.transaction_ids
|
.transaction_ids
|
||||||
.existing_txnid(&sender, None, &message_id)?
|
.existing_txnid(&sender, None, &message_id)?
|
||||||
.is_some()
|
.is_some()
|
||||||
@@ -387,28 +388,27 @@ async fn handle_edu_direct_to_device(
|
|||||||
for (target_device_id_maybe, event) in map {
|
for (target_device_id_maybe, event) in map {
|
||||||
match target_device_id_maybe {
|
match target_device_id_maybe {
|
||||||
DeviceIdOrAllDevices::DeviceId(target_device_id) => {
|
DeviceIdOrAllDevices::DeviceId(target_device_id) => {
|
||||||
services().users.add_to_device_event(
|
services.users.add_to_device_event(
|
||||||
&sender,
|
&sender,
|
||||||
target_user_id,
|
target_user_id,
|
||||||
target_device_id,
|
target_device_id,
|
||||||
&ev_type.to_string(),
|
&ev_type.to_string(),
|
||||||
event.deserialize_as().map_err(|e| {
|
event
|
||||||
error!("To-Device event is invalid: {event:?} {e}");
|
.deserialize_as()
|
||||||
Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid")
|
.map_err(|e| err!(Request(InvalidParam(error!("To-Device event is invalid: {e}")))))?,
|
||||||
})?,
|
|
||||||
)?;
|
)?;
|
||||||
},
|
},
|
||||||
|
|
||||||
DeviceIdOrAllDevices::AllDevices => {
|
DeviceIdOrAllDevices::AllDevices => {
|
||||||
for target_device_id in services().users.all_device_ids(target_user_id) {
|
for target_device_id in services.users.all_device_ids(target_user_id) {
|
||||||
services().users.add_to_device_event(
|
services.users.add_to_device_event(
|
||||||
&sender,
|
&sender,
|
||||||
target_user_id,
|
target_user_id,
|
||||||
&target_device_id?,
|
&target_device_id?,
|
||||||
&ev_type.to_string(),
|
&ev_type.to_string(),
|
||||||
event
|
event
|
||||||
.deserialize_as()
|
.deserialize_as()
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid"))?,
|
.map_err(|e| err!(Request(InvalidParam("Event is invalid: {e}"))))?,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -417,7 +417,7 @@ async fn handle_edu_direct_to_device(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save transaction id with empty data
|
// Save transaction id with empty data
|
||||||
services()
|
services
|
||||||
.transaction_ids
|
.transaction_ids
|
||||||
.add_txnid(&sender, None, &message_id, &[])?;
|
.add_txnid(&sender, None, &message_id, &[])?;
|
||||||
|
|
||||||
@@ -425,7 +425,7 @@ async fn handle_edu_direct_to_device(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_edu_signing_key_update(
|
async fn handle_edu_signing_key_update(
|
||||||
_client: &IpAddr, origin: &ServerName, content: SigningKeyUpdateContent,
|
services: &Services, _client: &IpAddr, origin: &ServerName, content: SigningKeyUpdateContent,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let SigningKeyUpdateContent {
|
let SigningKeyUpdateContent {
|
||||||
user_id,
|
user_id,
|
||||||
@@ -442,7 +442,7 @@ async fn handle_edu_signing_key_update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(master_key) = master_key {
|
if let Some(master_key) = master_key {
|
||||||
services()
|
services
|
||||||
.users
|
.users
|
||||||
.add_cross_signing_keys(&user_id, &master_key, &self_signing_key, &None, true)?;
|
.add_cross_signing_keys(&user_id, &master_key, &self_signing_key, &None, true)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ pub struct Config {
|
|||||||
|
|
||||||
#[serde(default = "default_pdu_cache_capacity")]
|
#[serde(default = "default_pdu_cache_capacity")]
|
||||||
pub pdu_cache_capacity: u32,
|
pub pdu_cache_capacity: u32,
|
||||||
#[serde(default = "default_conduit_cache_capacity_modifier")]
|
#[serde(default = "default_cache_capacity_modifier", alias = "conduit_cache_capacity_modifier")]
|
||||||
pub conduit_cache_capacity_modifier: f64,
|
pub cache_capacity_modifier: f64,
|
||||||
#[serde(default = "default_auth_chain_cache_capacity")]
|
#[serde(default = "default_auth_chain_cache_capacity")]
|
||||||
pub auth_chain_cache_capacity: u32,
|
pub auth_chain_cache_capacity: u32,
|
||||||
#[serde(default = "default_shorteventid_cache_capacity")]
|
#[serde(default = "default_shorteventid_cache_capacity")]
|
||||||
@@ -391,8 +391,9 @@ struct ListeningAddr {
|
|||||||
addrs: Either<IpAddr, Vec<IpAddr>>,
|
addrs: Either<IpAddr, Vec<IpAddr>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEPRECATED_KEYS: &[&str] = &[
|
const DEPRECATED_KEYS: &[&str; 9] = &[
|
||||||
"cache_capacity",
|
"cache_capacity",
|
||||||
|
"conduit_cache_capacity_modifier",
|
||||||
"max_concurrent_requests",
|
"max_concurrent_requests",
|
||||||
"well_known_client",
|
"well_known_client",
|
||||||
"well_known_server",
|
"well_known_server",
|
||||||
@@ -484,7 +485,7 @@ impl fmt::Display for Config {
|
|||||||
);
|
);
|
||||||
line("Database backups to keep", &self.database_backups_to_keep.to_string());
|
line("Database backups to keep", &self.database_backups_to_keep.to_string());
|
||||||
line("Database cache capacity (MB)", &self.db_cache_capacity_mb.to_string());
|
line("Database cache capacity (MB)", &self.db_cache_capacity_mb.to_string());
|
||||||
line("Cache capacity modifier", &self.conduit_cache_capacity_modifier.to_string());
|
line("Cache capacity modifier", &self.cache_capacity_modifier.to_string());
|
||||||
line("PDU cache capacity", &self.pdu_cache_capacity.to_string());
|
line("PDU cache capacity", &self.pdu_cache_capacity.to_string());
|
||||||
line("Auth chain cache capacity", &self.auth_chain_cache_capacity.to_string());
|
line("Auth chain cache capacity", &self.auth_chain_cache_capacity.to_string());
|
||||||
line("Short eventid cache capacity", &self.shorteventid_cache_capacity.to_string());
|
line("Short eventid cache capacity", &self.shorteventid_cache_capacity.to_string());
|
||||||
@@ -847,7 +848,7 @@ fn default_db_cache_capacity_mb() -> f64 { 256.0 }
|
|||||||
|
|
||||||
fn default_pdu_cache_capacity() -> u32 { 150_000 }
|
fn default_pdu_cache_capacity() -> u32 { 150_000 }
|
||||||
|
|
||||||
fn default_conduit_cache_capacity_modifier() -> f64 { 1.0 }
|
fn default_cache_capacity_modifier() -> f64 { 1.0 }
|
||||||
|
|
||||||
fn default_auth_chain_cache_capacity() -> u32 { 100_000 }
|
fn default_auth_chain_cache_capacity() -> u32 { 100_000 }
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
//! Err(Database(error!("problem with db: {msg}")))` logs the error at the
|
//! Err(Database(error!("problem with db: {msg}")))` logs the error at the
|
||||||
//! callsite and then returns the error with the same string. Caller has the
|
//! callsite and then returns the error with the same string. Caller has the
|
||||||
//! option of replacing `error!` with `debug_error!`.
|
//! option of replacing `error!` with `debug_error!`.
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! Err {
|
macro_rules! Err {
|
||||||
($($args:tt)*) => {
|
($($args:tt)*) => {
|
||||||
@@ -49,14 +50,16 @@ macro_rules! err {
|
|||||||
$crate::$level!($($args),*);
|
$crate::$level!($($args),*);
|
||||||
$crate::error::Error::Request(
|
$crate::error::Error::Request(
|
||||||
::ruma::api::client::error::ErrorKind::forbidden(),
|
::ruma::api::client::error::ErrorKind::forbidden(),
|
||||||
$crate::format_maybe!($($args),*)
|
$crate::format_maybe!($($args),*),
|
||||||
|
::http::StatusCode::BAD_REQUEST
|
||||||
)
|
)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
(Request(Forbidden($($args:expr),*))) => {
|
(Request(Forbidden($($args:expr),*))) => {
|
||||||
$crate::error::Error::Request(
|
$crate::error::Error::Request(
|
||||||
::ruma::api::client::error::ErrorKind::forbidden(),
|
::ruma::api::client::error::ErrorKind::forbidden(),
|
||||||
$crate::format_maybe!($($args),*)
|
$crate::format_maybe!($($args),*),
|
||||||
|
::http::StatusCode::BAD_REQUEST
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,14 +67,16 @@ macro_rules! err {
|
|||||||
$crate::$level!($($args),*);
|
$crate::$level!($($args),*);
|
||||||
$crate::error::Error::Request(
|
$crate::error::Error::Request(
|
||||||
::ruma::api::client::error::ErrorKind::$variant,
|
::ruma::api::client::error::ErrorKind::$variant,
|
||||||
$crate::format_maybe!($($args),*)
|
$crate::format_maybe!($($args),*),
|
||||||
|
::http::StatusCode::BAD_REQUEST
|
||||||
)
|
)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
(Request($variant:ident($($args:expr),*))) => {
|
(Request($variant:ident($($args:expr),*))) => {
|
||||||
$crate::error::Error::Request(
|
$crate::error::Error::Request(
|
||||||
::ruma::api::client::error::ErrorKind::$variant,
|
::ruma::api::client::error::ErrorKind::$variant,
|
||||||
$crate::format_maybe!($($args),*)
|
$crate::format_maybe!($($args),*),
|
||||||
|
::http::StatusCode::BAD_REQUEST
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ pub enum Error {
|
|||||||
#[error("{0}: {1}")]
|
#[error("{0}: {1}")]
|
||||||
BadRequest(ruma::api::client::error::ErrorKind, &'static str), //TODO: remove
|
BadRequest(ruma::api::client::error::ErrorKind, &'static str), //TODO: remove
|
||||||
#[error("{0}: {1}")]
|
#[error("{0}: {1}")]
|
||||||
Request(ruma::api::client::error::ErrorKind, Cow<'static, str>),
|
Request(ruma::api::client::error::ErrorKind, Cow<'static, str>, http::StatusCode),
|
||||||
#[error("from {0}: {1}")]
|
#[error("from {0}: {1}")]
|
||||||
Redaction(ruma::OwnedServerName, ruma::canonical_json::RedactionError),
|
Redaction(ruma::OwnedServerName, ruma::canonical_json::RedactionError),
|
||||||
#[error("Remote server {0} responded with: {1}")]
|
#[error("Remote server {0} responded with: {1}")]
|
||||||
@@ -78,7 +78,7 @@ pub enum Error {
|
|||||||
|
|
||||||
// conduwuit
|
// conduwuit
|
||||||
#[error("Arithmetic operation failed: {0}")]
|
#[error("Arithmetic operation failed: {0}")]
|
||||||
Arithmetic(&'static str),
|
Arithmetic(Cow<'static, str>),
|
||||||
#[error("There was a problem with the '{0}' directive in your configuration: {1}")]
|
#[error("There was a problem with the '{0}' directive in your configuration: {1}")]
|
||||||
Config(&'static str, Cow<'static, str>),
|
Config(&'static str, Cow<'static, str>),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
@@ -120,7 +120,7 @@ impl Error {
|
|||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Federation(_, error) => response::ruma_error_kind(error).clone(),
|
Self::Federation(_, error) => response::ruma_error_kind(error).clone(),
|
||||||
Self::BadRequest(kind, _) | Self::Request(kind, _) => kind.clone(),
|
Self::BadRequest(kind, ..) | Self::Request(kind, ..) => kind.clone(),
|
||||||
_ => Unknown,
|
_ => Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,8 @@ impl Error {
|
|||||||
pub fn status_code(&self) -> http::StatusCode {
|
pub fn status_code(&self) -> http::StatusCode {
|
||||||
match self {
|
match self {
|
||||||
Self::Federation(_, ref error) | Self::RumaError(ref error) => error.status_code,
|
Self::Federation(_, ref error) | Self::RumaError(ref error) => error.status_code,
|
||||||
Self::BadRequest(ref kind, _) | Self::Request(ref kind, _) => response::bad_request_code(kind),
|
Self::Request(ref kind, _, code) => response::status_code(kind, *code),
|
||||||
|
Self::BadRequest(ref kind, ..) => response::bad_request_code(kind),
|
||||||
Self::Conflict(_) => http::StatusCode::CONFLICT,
|
Self::Conflict(_) => http::StatusCode::CONFLICT,
|
||||||
_ => http::StatusCode::INTERNAL_SERVER_ERROR,
|
_ => http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-16
@@ -1,7 +1,13 @@
|
|||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
use http_body_util::Full;
|
use http_body_util::Full;
|
||||||
use ruma::api::{client::uiaa::UiaaResponse, OutgoingResponse};
|
use ruma::api::{
|
||||||
|
client::{
|
||||||
|
error::{ErrorBody, ErrorKind},
|
||||||
|
uiaa::UiaaResponse,
|
||||||
|
},
|
||||||
|
OutgoingResponse,
|
||||||
|
};
|
||||||
|
|
||||||
use super::Error;
|
use super::Error;
|
||||||
use crate::error;
|
use crate::error;
|
||||||
@@ -25,7 +31,7 @@ impl From<Error> for UiaaResponse {
|
|||||||
return Self::AuthResponse(uiaainfo);
|
return Self::AuthResponse(uiaainfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = ruma::api::client::error::ErrorBody::Standard {
|
let body = ErrorBody::Standard {
|
||||||
kind: error.kind(),
|
kind: error.kind(),
|
||||||
message: error.message(),
|
message: error.message(),
|
||||||
};
|
};
|
||||||
@@ -37,10 +43,33 @@ impl From<Error> for UiaaResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn bad_request_code(kind: &ruma::api::client::error::ErrorKind) -> StatusCode {
|
pub(super) fn status_code(kind: &ErrorKind, hint: StatusCode) -> StatusCode {
|
||||||
use ruma::api::client::error::ErrorKind::*;
|
if hint == StatusCode::BAD_REQUEST {
|
||||||
|
bad_request_code(kind)
|
||||||
|
} else {
|
||||||
|
hint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn bad_request_code(kind: &ErrorKind) -> StatusCode {
|
||||||
|
use ErrorKind::*;
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
|
// 429
|
||||||
|
LimitExceeded {
|
||||||
|
..
|
||||||
|
} => StatusCode::TOO_MANY_REQUESTS,
|
||||||
|
|
||||||
|
// 413
|
||||||
|
TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
|
||||||
|
|
||||||
|
// 405
|
||||||
|
Unrecognized => StatusCode::METHOD_NOT_ALLOWED,
|
||||||
|
|
||||||
|
// 404
|
||||||
|
NotFound => StatusCode::NOT_FOUND,
|
||||||
|
|
||||||
|
// 403
|
||||||
GuestAccessForbidden
|
GuestAccessForbidden
|
||||||
| ThreepidAuthFailed
|
| ThreepidAuthFailed
|
||||||
| UserDeactivated
|
| UserDeactivated
|
||||||
@@ -52,26 +81,20 @@ pub(super) fn bad_request_code(kind: &ruma::api::client::error::ErrorKind) -> St
|
|||||||
..
|
..
|
||||||
} => StatusCode::FORBIDDEN,
|
} => StatusCode::FORBIDDEN,
|
||||||
|
|
||||||
|
// 401
|
||||||
UnknownToken {
|
UnknownToken {
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| MissingToken
|
| MissingToken
|
||||||
| Unauthorized => StatusCode::UNAUTHORIZED,
|
| Unauthorized => StatusCode::UNAUTHORIZED,
|
||||||
|
|
||||||
LimitExceeded {
|
// 400
|
||||||
..
|
|
||||||
} => StatusCode::TOO_MANY_REQUESTS,
|
|
||||||
|
|
||||||
TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
|
|
||||||
|
|
||||||
NotFound | Unrecognized => StatusCode::NOT_FOUND,
|
|
||||||
|
|
||||||
_ => StatusCode::BAD_REQUEST,
|
_ => StatusCode::BAD_REQUEST,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn ruma_error_message(error: &ruma::api::client::error::Error) -> String {
|
pub(super) fn ruma_error_message(error: &ruma::api::client::error::Error) -> String {
|
||||||
if let ruma::api::client::error::ErrorBody::Standard {
|
if let ErrorBody::Standard {
|
||||||
message,
|
message,
|
||||||
..
|
..
|
||||||
} = &error.body
|
} = &error.body
|
||||||
@@ -82,7 +105,6 @@ pub(super) fn ruma_error_message(error: &ruma::api::client::error::Error) -> Str
|
|||||||
format!("{error}")
|
format!("{error}")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn ruma_error_kind(e: &ruma::api::client::error::Error) -> &ruma::api::client::error::ErrorKind {
|
pub(super) fn ruma_error_kind(e: &ruma::api::client::error::Error) -> &ErrorKind {
|
||||||
e.error_kind()
|
e.error_kind().unwrap_or(&ErrorKind::Unknown)
|
||||||
.unwrap_or(&ruma::api::client::error::ErrorKind::Unknown)
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -116,7 +116,12 @@ impl PduEvent {
|
|||||||
.map_or_else(|| Ok(BTreeMap::new()), |u| serde_json::from_str(u.get()))
|
.map_or_else(|| Ok(BTreeMap::new()), |u| serde_json::from_str(u.get()))
|
||||||
.map_err(|_| Error::bad_database("Invalid unsigned in pdu event"))?;
|
.map_err(|_| Error::bad_database("Invalid unsigned in pdu event"))?;
|
||||||
|
|
||||||
unsigned.insert("age".to_owned(), to_raw_value(&1).unwrap());
|
// deliberately allowing for the possibility of negative age
|
||||||
|
let now: i128 = MilliSecondsSinceUnixEpoch::now().get().into();
|
||||||
|
let then: i128 = self.origin_server_ts.into();
|
||||||
|
let this_age: i128 = now.saturating_sub(then);
|
||||||
|
|
||||||
|
unsigned.insert("age".to_owned(), to_raw_value(&this_age).unwrap());
|
||||||
self.unsigned = Some(to_raw_value(&unsigned).expect("unsigned is valid"));
|
self.unsigned = Some(to_raw_value(&unsigned).expect("unsigned is valid"));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ use std::{cmp, time::Duration};
|
|||||||
|
|
||||||
pub use checked_ops::checked_ops;
|
pub use checked_ops::checked_ops;
|
||||||
|
|
||||||
use crate::{Error, Result};
|
use crate::{Err, Error, Result};
|
||||||
|
|
||||||
/// Checked arithmetic expression. Returns a Result<R, Error::Arithmetic>
|
/// Checked arithmetic expression. Returns a Result<R, Error::Arithmetic>
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! checked {
|
macro_rules! checked {
|
||||||
($($input:tt)*) => {
|
($($input:tt)*) => {
|
||||||
$crate::utils::math::checked_ops!($($input)*)
|
$crate::utils::math::checked_ops!($($input)*)
|
||||||
.ok_or_else(|| $crate::Error::Arithmetic("operation overflowed or result invalid"))
|
.ok_or_else(|| $crate::err!(Arithmetic("operation overflowed or result invalid")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ macro_rules! validated {
|
|||||||
($($input:tt)*) => {
|
($($input:tt)*) => {
|
||||||
//#[allow(clippy::arithmetic_side_effects)] {
|
//#[allow(clippy::arithmetic_side_effects)] {
|
||||||
//Some($($input)*)
|
//Some($($input)*)
|
||||||
// .ok_or_else(|| $crate::Error::Arithmetic("this error should never been seen"))
|
// .ok_or_else(|| $crate::err!(Arithmetic("this error should never been seen")))
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//NOTE: remove me when stmt_expr_attributes is stable
|
//NOTE: remove me when stmt_expr_attributes is stable
|
||||||
@@ -57,7 +57,7 @@ pub fn continue_exponential_backoff(min: Duration, max: Duration, elapsed: Durat
|
|||||||
#[allow(clippy::as_conversions)]
|
#[allow(clippy::as_conversions)]
|
||||||
pub fn usize_from_f64(val: f64) -> Result<usize, Error> {
|
pub fn usize_from_f64(val: f64) -> Result<usize, Error> {
|
||||||
if val < 0.0 {
|
if val < 0.0 {
|
||||||
return Err(Error::Arithmetic("Converting negative float to unsigned integer"));
|
return Err!(Arithmetic("Converting negative float to unsigned integer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//SAFETY: <https://doc.rust-lang.org/std/primitive.f64.html#method.to_int_unchecked>
|
//SAFETY: <https://doc.rust-lang.org/std/primitive.f64.html#method.to_int_unchecked>
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ 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.cache_capacity_modifier;
|
||||||
|
|
||||||
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
(ents as usize)
|
(ents as usize)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use axum::{
|
|||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use axum_client_ip::SecureClientIpSource;
|
use axum_client_ip::SecureClientIpSource;
|
||||||
use conduit::{Result, Server};
|
use conduit::{error, Result, Server};
|
||||||
use http::{
|
use http::{
|
||||||
header::{self, HeaderName},
|
header::{self, HeaderName},
|
||||||
HeaderValue, Method, StatusCode,
|
HeaderValue, Method, StatusCode,
|
||||||
@@ -149,7 +149,7 @@ fn cors_layer(_server: &Server) -> CorsLayer {
|
|||||||
fn body_limit_layer(server: &Server) -> DefaultBodyLimit { DefaultBodyLimit::max(server.config.max_request_size) }
|
fn body_limit_layer(server: &Server) -> DefaultBodyLimit { DefaultBodyLimit::max(server.config.max_request_size) }
|
||||||
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all, name = "panic")]
|
||||||
fn catch_panic(err: Box<dyn Any + Send + 'static>) -> http::Response<http_body_util::Full<bytes::Bytes>> {
|
fn catch_panic(err: Box<dyn Any + Send + 'static>) -> http::Response<http_body_util::Full<bytes::Bytes>> {
|
||||||
conduit_service::services()
|
conduit_service::services()
|
||||||
.server
|
.server
|
||||||
@@ -165,17 +165,17 @@ fn catch_panic(err: Box<dyn Any + Send + 'static>) -> http::Response<http_body_u
|
|||||||
"Unknown internal server error occurred.".to_owned()
|
"Unknown internal server error occurred.".to_owned()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
error!("{details:#}");
|
||||||
let body = serde_json::json!({
|
let body = serde_json::json!({
|
||||||
"errcode": "M_UNKNOWN",
|
"errcode": "M_UNKNOWN",
|
||||||
"error": "M_UNKNOWN: Internal server error occurred",
|
"error": "M_UNKNOWN: Internal server error occurred",
|
||||||
"details": details,
|
"details": details,
|
||||||
})
|
});
|
||||||
.to_string();
|
|
||||||
|
|
||||||
http::Response::builder()
|
http::Response::builder()
|
||||||
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
.header(header::CONTENT_TYPE, "application/json")
|
.header(header::CONTENT_TYPE, "application/json")
|
||||||
.body(http_body_util::Full::from(body))
|
.body(http_body_util::Full::from(body.to_string()))
|
||||||
.expect("Failed to create response for our panic catcher?")
|
.expect("Failed to create response for our panic catcher?")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-23
@@ -4,9 +4,8 @@ use axum::{
|
|||||||
extract::State,
|
extract::State,
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
};
|
};
|
||||||
use conduit::{debug, debug_error, debug_warn, defer, error, trace, Error, Result, Server};
|
use conduit::{debug, debug_error, debug_warn, defer, err, error, trace, Result, Server};
|
||||||
use http::{Method, StatusCode, Uri};
|
use http::{Method, StatusCode, Uri};
|
||||||
use ruma::api::client::error::{Error as RumaError, ErrorBody, ErrorKind};
|
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, level = "debug")]
|
#[tracing::instrument(skip_all, level = "debug")]
|
||||||
pub(crate) async fn spawn(
|
pub(crate) async fn spawn(
|
||||||
@@ -58,33 +57,13 @@ pub(crate) async fn handle(
|
|||||||
trace!(active, finished, "leave");
|
trace!(active, finished, "leave");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
let method = req.method().clone();
|
|
||||||
let uri = req.uri().clone();
|
let uri = req.uri().clone();
|
||||||
|
let method = req.method().clone();
|
||||||
let result = next.run(req).await;
|
let result = next.run(req).await;
|
||||||
handle_result(&method, &uri, result)
|
handle_result(&method, &uri, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_result(method: &Method, uri: &Uri, result: Response) -> Result<Response, StatusCode> {
|
fn handle_result(method: &Method, uri: &Uri, result: Response) -> Result<Response, StatusCode> {
|
||||||
handle_result_log(method, uri, &result);
|
|
||||||
match result.status() {
|
|
||||||
StatusCode::METHOD_NOT_ALLOWED => handle_result_405(method, uri, &result),
|
|
||||||
_ => Ok(result),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_result_405(_method: &Method, _uri: &Uri, result: &Response) -> Result<Response, StatusCode> {
|
|
||||||
let error = Error::RumaError(RumaError {
|
|
||||||
status_code: result.status(),
|
|
||||||
body: ErrorBody::Standard {
|
|
||||||
kind: ErrorKind::Unrecognized,
|
|
||||||
message: "M_UNRECOGNIZED: Method not allowed for endpoint".to_owned(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(error.into_response())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_result_log(method: &Method, uri: &Uri, result: &Response) {
|
|
||||||
let status = result.status();
|
let status = result.status();
|
||||||
let reason = status.canonical_reason().unwrap_or("Unknown Reason");
|
let reason = status.canonical_reason().unwrap_or("Unknown Reason");
|
||||||
let code = status.as_u16();
|
let code = status.as_u16();
|
||||||
@@ -97,4 +76,10 @@ fn handle_result_log(method: &Method, uri: &Uri, result: &Response) {
|
|||||||
} else {
|
} else {
|
||||||
trace!(method = ?method, uri = ?uri, "{code} {reason}");
|
trace!(method = ?method, uri = ?uri, "{code} {reason}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if status == StatusCode::METHOD_NOT_ALLOWED {
|
||||||
|
return Ok(err!(Request(Unrecognized("Method Not Allowed"))).into_response());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,24 +2,23 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use axum::{response::IntoResponse, routing::get, Router};
|
use axum::{response::IntoResponse, routing::get, Router};
|
||||||
use conduit::{Error, Server};
|
use conduit::{Error, Server};
|
||||||
use conduit_service as service;
|
use http::{StatusCode, Uri};
|
||||||
use http::Uri;
|
|
||||||
use ruma::api::client::error::ErrorKind;
|
use ruma::api::client::error::ErrorKind;
|
||||||
|
|
||||||
extern crate conduit_api as api;
|
extern crate conduit_api as api;
|
||||||
|
extern crate conduit_service as service;
|
||||||
|
|
||||||
pub(crate) fn build(server: &Arc<Server>) -> Router {
|
pub(crate) fn build(server: &Arc<Server>) -> Router {
|
||||||
let state = service::services();
|
let router = Router::<api::State>::new();
|
||||||
let router = Router::new()
|
|
||||||
|
api::router::build(router, server)
|
||||||
.route("/", get(it_works))
|
.route("/", get(it_works))
|
||||||
.fallback(not_found)
|
.fallback(not_found)
|
||||||
.with_state(state);
|
.with_state(service::services())
|
||||||
|
|
||||||
api::routes::build(router, server)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn not_found(_uri: Uri) -> impl IntoResponse {
|
async fn not_found(_uri: Uri) -> impl IntoResponse {
|
||||||
Error::BadRequest(ErrorKind::Unrecognized, "Unrecognized request")
|
Error::Request(ErrorKind::Unrecognized, "Not Found".into(), StatusCode::NOT_FOUND)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn it_works() -> &'static str { "hewwo from conduwuit woof!" }
|
async fn it_works() -> &'static str { "hewwo from conduwuit woof!" }
|
||||||
|
|||||||
@@ -127,8 +127,8 @@ async fn fini(server: &Arc<Server>, listener: UnixListener, mut tasks: JoinSet<(
|
|||||||
debug!("Waiting for requests to finish...");
|
debug!("Waiting for requests to finish...");
|
||||||
while server.metrics.requests_spawn_active.load(Ordering::Relaxed) > 0 {
|
while server.metrics.requests_spawn_active.load(Ordering::Relaxed) > 0 {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = tasks.join_next() => {}
|
task = tasks.join_next() => if task.is_none() { break; },
|
||||||
() = sleep(FINI_POLL_INTERVAL) => {}
|
() = sleep(FINI_POLL_INTERVAL) => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ lru-cache.workspace = true
|
|||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
regex.workspace = true
|
regex.workspace = true
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
ruma-identifiers-validation.workspace = true
|
|
||||||
ruma.workspace = true
|
ruma.workspace = true
|
||||||
rustyline-async.workspace = true
|
rustyline-async.workspace = true
|
||||||
rustyline-async.optional = true
|
rustyline-async.optional = true
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use conduit::{debug, error, Error, Result};
|
use conduit::{debug, error, error::default_log, Error, Result};
|
||||||
pub use create::create_admin_room;
|
pub use create::create_admin_room;
|
||||||
pub use grant::make_user_admin;
|
pub use grant::make_user_admin;
|
||||||
use loole::{Receiver, Sender};
|
use loole::{Receiver, Sender};
|
||||||
@@ -239,9 +239,9 @@ async fn respond_to_room(content: RoomMessageEventContent, room_id: &RoomId, use
|
|||||||
.build_and_append_pdu(response_pdu, user_id, room_id, &state_lock)
|
.build_and_append_pdu(response_pdu, user_id, room_id, &state_lock)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
if let Err(e) = handle_response_error(e, room_id, user_id, &state_lock).await {
|
handle_response_error(e, room_id, user_id, &state_lock)
|
||||||
error!("{e}");
|
.await
|
||||||
}
|
.unwrap_or_else(default_log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ pub struct Service {
|
|||||||
pub stable_room_versions: Vec<RoomVersionId>,
|
pub stable_room_versions: Vec<RoomVersionId>,
|
||||||
pub unstable_room_versions: Vec<RoomVersionId>,
|
pub unstable_room_versions: Vec<RoomVersionId>,
|
||||||
pub bad_event_ratelimiter: Arc<RwLock<HashMap<OwnedEventId, RateLimitState>>>,
|
pub bad_event_ratelimiter: Arc<RwLock<HashMap<OwnedEventId, RateLimitState>>>,
|
||||||
pub bad_signature_ratelimiter: Arc<RwLock<HashMap<Vec<String>, RateLimitState>>>,
|
|
||||||
pub bad_query_ratelimiter: Arc<RwLock<HashMap<OwnedServerName, RateLimitState>>>,
|
pub bad_query_ratelimiter: Arc<RwLock<HashMap<OwnedServerName, RateLimitState>>>,
|
||||||
pub stateres_mutex: Arc<Mutex<()>>,
|
pub stateres_mutex: Arc<Mutex<()>>,
|
||||||
pub server_user: OwnedUserId,
|
pub server_user: OwnedUserId,
|
||||||
@@ -101,7 +100,6 @@ impl crate::Service for Service {
|
|||||||
stable_room_versions,
|
stable_room_versions,
|
||||||
unstable_room_versions,
|
unstable_room_versions,
|
||||||
bad_event_ratelimiter: Arc::new(RwLock::new(HashMap::new())),
|
bad_event_ratelimiter: Arc::new(RwLock::new(HashMap::new())),
|
||||||
bad_signature_ratelimiter: Arc::new(RwLock::new(HashMap::new())),
|
|
||||||
bad_query_ratelimiter: Arc::new(RwLock::new(HashMap::new())),
|
bad_query_ratelimiter: Arc::new(RwLock::new(HashMap::new())),
|
||||||
stateres_mutex: Arc::new(Mutex::new(())),
|
stateres_mutex: Arc::new(Mutex::new(())),
|
||||||
admin_alias: RoomAliasId::parse(format!("#admins:{}", &config.server_name))
|
admin_alias: RoomAliasId::parse(format!("#admins:{}", &config.server_name))
|
||||||
@@ -144,13 +142,6 @@ impl crate::Service for Service {
|
|||||||
.len();
|
.len();
|
||||||
writeln!(out, "bad_query_ratelimiter: {bad_query_ratelimiter}")?;
|
writeln!(out, "bad_query_ratelimiter: {bad_query_ratelimiter}")?;
|
||||||
|
|
||||||
let bad_signature_ratelimiter = self
|
|
||||||
.bad_signature_ratelimiter
|
|
||||||
.read()
|
|
||||||
.expect("locked for reading")
|
|
||||||
.len();
|
|
||||||
writeln!(out, "bad_signature_ratelimiter: {bad_signature_ratelimiter}")?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,11 +157,6 @@ impl crate::Service for Service {
|
|||||||
.write()
|
.write()
|
||||||
.expect("locked for writing")
|
.expect("locked for writing")
|
||||||
.clear();
|
.clear();
|
||||||
|
|
||||||
self.bad_signature_ratelimiter
|
|
||||||
.write()
|
|
||||||
.expect("locked for writing")
|
|
||||||
.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
|
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
|
||||||
|
|||||||
@@ -12,6 +12,13 @@ pub(crate) struct Data {
|
|||||||
url_previews: Arc<Map>,
|
url_previews: Arc<Map>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(super) struct Metadata {
|
||||||
|
pub(super) content_disposition: Option<String>,
|
||||||
|
pub(super) content_type: Option<String>,
|
||||||
|
pub(super) key: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Data {
|
impl Data {
|
||||||
pub(super) fn new(db: &Arc<Database>) -> Self {
|
pub(super) fn new(db: &Arc<Database>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -104,9 +111,7 @@ impl Data {
|
|||||||
Ok(keys)
|
Ok(keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn search_file_metadata(
|
pub(super) fn search_file_metadata(&self, mxc: &str, width: u32, height: u32) -> Result<Metadata> {
|
||||||
&self, mxc: &str, width: u32, height: u32,
|
|
||||||
) -> Result<(Option<String>, Option<String>, Vec<u8>)> {
|
|
||||||
let mut prefix = mxc.as_bytes().to_vec();
|
let mut prefix = mxc.as_bytes().to_vec();
|
||||||
prefix.push(0xFF);
|
prefix.push(0xFF);
|
||||||
prefix.extend_from_slice(&width.to_be_bytes());
|
prefix.extend_from_slice(&width.to_be_bytes());
|
||||||
@@ -141,7 +146,12 @@ impl Data {
|
|||||||
.map_err(|_| Error::bad_database("Content Disposition in mediaid_file is invalid unicode."))?,
|
.map_err(|_| Error::bad_database("Content Disposition in mediaid_file is invalid unicode."))?,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
Ok((content_disposition, content_type, key))
|
|
||||||
|
Ok(Metadata {
|
||||||
|
content_disposition,
|
||||||
|
content_type,
|
||||||
|
key,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets all the media keys in our database (this includes all the metadata
|
/// Gets all the media keys in our database (this includes all the metadata
|
||||||
|
|||||||
+33
-183
@@ -1,13 +1,13 @@
|
|||||||
mod data;
|
mod data;
|
||||||
mod tests;
|
mod tests;
|
||||||
|
mod thumbnail;
|
||||||
|
|
||||||
use std::{collections::HashMap, io::Cursor, num::Saturating as Sat, path::PathBuf, sync::Arc, time::SystemTime};
|
use std::{collections::HashMap, path::PathBuf, sync::Arc, time::SystemTime};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use conduit::{checked, debug, debug_error, error, utils, Error, Result, Server};
|
use conduit::{debug, debug_error, err, error, utils, Err, Result, Server};
|
||||||
use data::Data;
|
use data::{Data, Metadata};
|
||||||
use image::imageops::FilterType;
|
|
||||||
use ruma::{OwnedMxcUri, OwnedUserId};
|
use ruma::{OwnedMxcUri, OwnedUserId};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
@@ -20,10 +20,9 @@ use crate::services;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FileMeta {
|
pub struct FileMeta {
|
||||||
#[allow(dead_code)]
|
pub content: Option<Vec<u8>>,
|
||||||
pub content_disposition: Option<String>,
|
|
||||||
pub content_type: Option<String>,
|
pub content_type: Option<String>,
|
||||||
pub file: Vec<u8>,
|
pub content_disposition: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Default)]
|
#[derive(Serialize, Default)]
|
||||||
@@ -101,47 +100,30 @@ impl Service {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
error!("Failed to find any media keys for MXC \"{mxc}\" in our database (MXC does not exist)");
|
Err!(Database(error!(
|
||||||
Err(Error::bad_database(
|
"Failed to find any media keys for MXC {mxc:?} in our database."
|
||||||
"Failed to find any media keys for the provided MXC in our database (MXC does not exist)",
|
)))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Uploads or replaces a file thumbnail.
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
pub async fn upload_thumbnail(
|
|
||||||
&self, sender_user: Option<OwnedUserId>, mxc: &str, content_disposition: Option<&str>,
|
|
||||||
content_type: Option<&str>, width: u32, height: u32, file: &[u8],
|
|
||||||
) -> Result<()> {
|
|
||||||
let key = if let Some(user) = sender_user {
|
|
||||||
self.db
|
|
||||||
.create_file_metadata(Some(user.as_str()), mxc, width, height, content_disposition, content_type)?
|
|
||||||
} else {
|
|
||||||
self.db
|
|
||||||
.create_file_metadata(None, mxc, width, height, content_disposition, content_type)?
|
|
||||||
};
|
|
||||||
|
|
||||||
//TODO: Dangling metadata in database if creation fails
|
|
||||||
let mut f = self.create_media_file(&key).await?;
|
|
||||||
f.write_all(file).await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Downloads a file.
|
/// Downloads a file.
|
||||||
pub async fn get(&self, mxc: &str) -> Result<Option<FileMeta>> {
|
pub async fn get(&self, mxc: &str) -> Result<Option<FileMeta>> {
|
||||||
if let Ok((content_disposition, content_type, key)) = self.db.search_file_metadata(mxc, 0, 0) {
|
if let Ok(Metadata {
|
||||||
let mut file = Vec::new();
|
content_disposition,
|
||||||
|
content_type,
|
||||||
|
key,
|
||||||
|
}) = self.db.search_file_metadata(mxc, 0, 0)
|
||||||
|
{
|
||||||
|
let mut content = Vec::new();
|
||||||
let path = self.get_media_file(&key);
|
let path = self.get_media_file(&key);
|
||||||
BufReader::new(fs::File::open(path).await?)
|
BufReader::new(fs::File::open(path).await?)
|
||||||
.read_to_end(&mut file)
|
.read_to_end(&mut content)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(Some(FileMeta {
|
Ok(Some(FileMeta {
|
||||||
content_disposition,
|
content: Some(content),
|
||||||
content_type,
|
content_type,
|
||||||
file,
|
content_disposition,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -154,23 +136,16 @@ impl Service {
|
|||||||
let all_keys = self.db.get_all_media_keys();
|
let all_keys = self.db.get_all_media_keys();
|
||||||
|
|
||||||
let user_duration: SystemTime = match cyborgtime::parse_duration(&time) {
|
let user_duration: SystemTime = match cyborgtime::parse_duration(&time) {
|
||||||
Ok(duration) => {
|
Err(e) => return Err!(Database(error!("Failed to parse specified time duration: {e}"))),
|
||||||
debug!("Parsed duration: {:?}", duration);
|
Ok(duration) => SystemTime::now()
|
||||||
debug!("System time now: {:?}", SystemTime::now());
|
.checked_sub(duration)
|
||||||
SystemTime::now().checked_sub(duration).ok_or_else(|| {
|
.ok_or(err!(Arithmetic("Duration {duration:?} is too large")))?,
|
||||||
Error::bad_database("Duration specified is not valid against the current system time")
|
|
||||||
})?
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
error!("Failed to parse user-specified time duration: {}", e);
|
|
||||||
return Err(Error::bad_database("Failed to parse user-specified time duration."));
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut remote_mxcs: Vec<String> = vec![];
|
let mut remote_mxcs: Vec<String> = vec![];
|
||||||
|
|
||||||
for key in all_keys {
|
for key in all_keys {
|
||||||
debug!("Full MXC key from database: {:?}", key);
|
debug!("Full MXC key from database: {key:?}");
|
||||||
|
|
||||||
// we need to get the MXC URL from the first part of the key (the first 0xff /
|
// we need to get the MXC URL from the first part of the key (the first 0xff /
|
||||||
// 255 push). this is all necessary because of conduit using magic keys for
|
// 255 push). this is all necessary because of conduit using magic keys for
|
||||||
@@ -179,24 +154,19 @@ impl Service {
|
|||||||
let mxc = parts
|
let mxc = parts
|
||||||
.next()
|
.next()
|
||||||
.map(|bytes| {
|
.map(|bytes| {
|
||||||
utils::string_from_bytes(bytes).map_err(|e| {
|
utils::string_from_bytes(bytes)
|
||||||
error!("Failed to parse MXC unicode bytes from our database: {}", e);
|
.map_err(|e| err!(Database(error!("Failed to parse MXC unicode bytes from our database: {e}"))))
|
||||||
Error::bad_database("Failed to parse MXC unicode bytes from our database")
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
let Some(mxc_s) = mxc else {
|
let Some(mxc_s) = mxc else {
|
||||||
return Err(Error::bad_database(
|
return Err!(Database("Parsed MXC URL unicode bytes from database but still is None"));
|
||||||
"Parsed MXC URL unicode bytes from database but still is None",
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Parsed MXC key to URL: {}", mxc_s);
|
debug!("Parsed MXC key to URL: {mxc_s}");
|
||||||
|
|
||||||
let mxc = OwnedMxcUri::from(mxc_s);
|
let mxc = OwnedMxcUri::from(mxc_s);
|
||||||
if mxc.server_name() == Ok(services().globals.server_name()) {
|
if mxc.server_name() == Ok(services().globals.server_name()) {
|
||||||
debug!("Ignoring local media MXC: {}", mxc);
|
debug!("Ignoring local media MXC: {mxc}");
|
||||||
// ignore our own MXC URLs as this would be local media.
|
// ignore our own MXC URLs as this would be local media.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -215,14 +185,14 @@ impl Service {
|
|||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if force {
|
if force {
|
||||||
error!("Could not delete MXC path {:?}: {:?}. Skipping...", path, err);
|
error!("Could not delete MXC path {path:?}: {err:?}. Skipping...");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Err(err.into());
|
return Err(err.into());
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
debug!("File created at: {:?}", file_created_at);
|
|
||||||
|
|
||||||
|
debug!("File created at: {file_created_at:?}");
|
||||||
if file_created_at <= user_duration {
|
if file_created_at <= user_duration {
|
||||||
debug!("File is within user duration, pushing to list of file paths and keys to delete.");
|
debug!("File is within user duration, pushing to list of file paths and keys to delete.");
|
||||||
remote_mxcs.push(mxc.to_string());
|
remote_mxcs.push(mxc.to_string());
|
||||||
@@ -232,15 +202,12 @@ impl Service {
|
|||||||
debug!(
|
debug!(
|
||||||
"Finished going through all our media in database for eligible keys to delete, checking if these are empty"
|
"Finished going through all our media in database for eligible keys to delete, checking if these are empty"
|
||||||
);
|
);
|
||||||
|
|
||||||
if remote_mxcs.is_empty() {
|
if remote_mxcs.is_empty() {
|
||||||
return Err(Error::bad_database("Did not found any eligible MXCs to delete."));
|
return Err!(Database("Did not found any eligible MXCs to delete."));
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Deleting media now in the past \"{:?}\".", user_duration);
|
debug!("Deleting media now in the past {user_duration:?}.");
|
||||||
|
|
||||||
let mut deletion_count: usize = 0;
|
let mut deletion_count: usize = 0;
|
||||||
|
|
||||||
for mxc in remote_mxcs {
|
for mxc in remote_mxcs {
|
||||||
debug!("Deleting MXC {mxc} from database and filesystem");
|
debug!("Deleting MXC {mxc} from database and filesystem");
|
||||||
self.delete(&mxc).await?;
|
self.delete(&mxc).await?;
|
||||||
@@ -250,123 +217,6 @@ impl Service {
|
|||||||
Ok(deletion_count)
|
Ok(deletion_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns width, height of the thumbnail and whether it should be cropped.
|
|
||||||
/// Returns None when the server should send the original file.
|
|
||||||
pub fn thumbnail_properties(&self, width: u32, height: u32) -> Option<(u32, u32, bool)> {
|
|
||||||
match (width, height) {
|
|
||||||
(0..=32, 0..=32) => Some((32, 32, true)),
|
|
||||||
(0..=96, 0..=96) => Some((96, 96, true)),
|
|
||||||
(0..=320, 0..=240) => Some((320, 240, false)),
|
|
||||||
(0..=640, 0..=480) => Some((640, 480, false)),
|
|
||||||
(0..=800, 0..=600) => Some((800, 600, false)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Downloads a file's thumbnail.
|
|
||||||
///
|
|
||||||
/// Here's an example on how it works:
|
|
||||||
///
|
|
||||||
/// - Client requests an image with width=567, height=567
|
|
||||||
/// - Server rounds that up to (800, 600), so it doesn't have to save too
|
|
||||||
/// many thumbnails
|
|
||||||
/// - Server rounds that up again to (958, 600) to fix the aspect ratio
|
|
||||||
/// (only for width,height>96)
|
|
||||||
/// - Server creates the thumbnail and sends it to the user
|
|
||||||
///
|
|
||||||
/// For width,height <= 96 the server uses another thumbnailing algorithm
|
|
||||||
/// which crops the image afterwards.
|
|
||||||
pub async fn get_thumbnail(&self, mxc: &str, width: u32, height: u32) -> Result<Option<FileMeta>> {
|
|
||||||
let (width, height, crop) = self
|
|
||||||
.thumbnail_properties(width, height)
|
|
||||||
.unwrap_or((0, 0, false)); // 0, 0 because that's the original file
|
|
||||||
|
|
||||||
if let Ok((content_disposition, content_type, key)) = self.db.search_file_metadata(mxc, width, height) {
|
|
||||||
// Using saved thumbnail
|
|
||||||
let mut file = Vec::new();
|
|
||||||
let path = self.get_media_file(&key);
|
|
||||||
fs::File::open(path).await?.read_to_end(&mut file).await?;
|
|
||||||
|
|
||||||
Ok(Some(FileMeta {
|
|
||||||
content_disposition,
|
|
||||||
content_type,
|
|
||||||
file: file.clone(),
|
|
||||||
}))
|
|
||||||
} else if let Ok((content_disposition, content_type, key)) = self.db.search_file_metadata(mxc, 0, 0) {
|
|
||||||
// Generate a thumbnail
|
|
||||||
let mut file = Vec::new();
|
|
||||||
let path = self.get_media_file(&key);
|
|
||||||
fs::File::open(path).await?.read_to_end(&mut file).await?;
|
|
||||||
|
|
||||||
if let Ok(image) = image::load_from_memory(&file) {
|
|
||||||
let original_width = image.width();
|
|
||||||
let original_height = image.height();
|
|
||||||
if width > original_width || height > original_height {
|
|
||||||
return Ok(Some(FileMeta {
|
|
||||||
content_disposition,
|
|
||||||
content_type,
|
|
||||||
file: file.clone(),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let thumbnail = if crop {
|
|
||||||
image.resize_to_fill(width, height, FilterType::CatmullRom)
|
|
||||||
} else {
|
|
||||||
let (exact_width, exact_height) = {
|
|
||||||
let ratio = Sat(original_width) * Sat(height);
|
|
||||||
let nratio = Sat(width) * Sat(original_height);
|
|
||||||
|
|
||||||
let use_width = nratio <= ratio;
|
|
||||||
let intermediate = if use_width {
|
|
||||||
Sat(original_height) * Sat(checked!(width / original_width)?)
|
|
||||||
} else {
|
|
||||||
Sat(original_width) * Sat(checked!(height / original_height)?)
|
|
||||||
};
|
|
||||||
|
|
||||||
if use_width {
|
|
||||||
(width, intermediate.0)
|
|
||||||
} else {
|
|
||||||
(intermediate.0, height)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
image.thumbnail_exact(exact_width, exact_height)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut thumbnail_bytes = Vec::new();
|
|
||||||
thumbnail.write_to(&mut Cursor::new(&mut thumbnail_bytes), image::ImageFormat::Png)?;
|
|
||||||
|
|
||||||
// Save thumbnail in database so we don't have to generate it again next time
|
|
||||||
let thumbnail_key = self.db.create_file_metadata(
|
|
||||||
None,
|
|
||||||
mxc,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
content_disposition.as_deref(),
|
|
||||||
content_type.as_deref(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let mut f = self.create_media_file(&thumbnail_key).await?;
|
|
||||||
f.write_all(&thumbnail_bytes).await?;
|
|
||||||
|
|
||||||
Ok(Some(FileMeta {
|
|
||||||
content_disposition,
|
|
||||||
content_type,
|
|
||||||
file: thumbnail_bytes.clone(),
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
// Couldn't parse file to generate thumbnail, send original
|
|
||||||
Ok(Some(FileMeta {
|
|
||||||
content_disposition,
|
|
||||||
content_type,
|
|
||||||
file: file.clone(),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_url_preview(&self, url: &str) -> Option<UrlPreviewData> { self.db.get_url_preview(url) }
|
pub async fn get_url_preview(&self, url: &str) -> Option<UrlPreviewData> { self.db.get_url_preview(url) }
|
||||||
|
|
||||||
/// TODO: use this?
|
/// TODO: use this?
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
use std::{cmp, io::Cursor, num::Saturating as Sat};
|
||||||
|
|
||||||
|
use conduit::{checked, Result};
|
||||||
|
use image::{imageops::FilterType, DynamicImage};
|
||||||
|
use ruma::OwnedUserId;
|
||||||
|
use tokio::{
|
||||||
|
fs,
|
||||||
|
io::{AsyncReadExt, AsyncWriteExt},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{data::Metadata, FileMeta};
|
||||||
|
|
||||||
|
impl super::Service {
|
||||||
|
/// Uploads or replaces a file thumbnail.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub async fn upload_thumbnail(
|
||||||
|
&self, sender_user: Option<OwnedUserId>, mxc: &str, content_disposition: Option<&str>,
|
||||||
|
content_type: Option<&str>, width: u32, height: u32, file: &[u8],
|
||||||
|
) -> Result<()> {
|
||||||
|
let key = if let Some(user) = sender_user {
|
||||||
|
self.db
|
||||||
|
.create_file_metadata(Some(user.as_str()), mxc, width, height, content_disposition, content_type)?
|
||||||
|
} else {
|
||||||
|
self.db
|
||||||
|
.create_file_metadata(None, mxc, width, height, content_disposition, content_type)?
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO: Dangling metadata in database if creation fails
|
||||||
|
let mut f = self.create_media_file(&key).await?;
|
||||||
|
f.write_all(file).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Downloads a file's thumbnail.
|
||||||
|
///
|
||||||
|
/// Here's an example on how it works:
|
||||||
|
///
|
||||||
|
/// - Client requests an image with width=567, height=567
|
||||||
|
/// - Server rounds that up to (800, 600), so it doesn't have to save too
|
||||||
|
/// many thumbnails
|
||||||
|
/// - Server rounds that up again to (958, 600) to fix the aspect ratio
|
||||||
|
/// (only for width,height>96)
|
||||||
|
/// - Server creates the thumbnail and sends it to the user
|
||||||
|
///
|
||||||
|
/// For width,height <= 96 the server uses another thumbnailing algorithm
|
||||||
|
/// which crops the image afterwards.
|
||||||
|
#[tracing::instrument(skip(self), name = "thumbnail", level = "debug")]
|
||||||
|
pub async fn get_thumbnail(&self, mxc: &str, width: u32, height: u32) -> Result<Option<FileMeta>> {
|
||||||
|
// 0, 0 because that's the original file
|
||||||
|
let (width, height, crop) = thumbnail_properties(width, height).unwrap_or((0, 0, false));
|
||||||
|
|
||||||
|
if let Ok(metadata) = self.db.search_file_metadata(mxc, width, height) {
|
||||||
|
self.get_thumbnail_saved(metadata).await
|
||||||
|
} else if let Ok(metadata) = self.db.search_file_metadata(mxc, 0, 0) {
|
||||||
|
self.get_thumbnail_generate(mxc, width, height, crop, metadata)
|
||||||
|
.await
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Using saved thumbnail
|
||||||
|
#[tracing::instrument(skip(self), name = "saved", level = "debug")]
|
||||||
|
async fn get_thumbnail_saved(&self, data: Metadata) -> Result<Option<FileMeta>> {
|
||||||
|
let mut content = Vec::new();
|
||||||
|
let path = self.get_media_file(&data.key);
|
||||||
|
fs::File::open(path)
|
||||||
|
.await?
|
||||||
|
.read_to_end(&mut content)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Some(into_filemeta(data, content)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate a thumbnail
|
||||||
|
#[tracing::instrument(skip(self), name = "generate", level = "debug")]
|
||||||
|
async fn get_thumbnail_generate(
|
||||||
|
&self, mxc: &str, width: u32, height: u32, crop: bool, data: Metadata,
|
||||||
|
) -> Result<Option<FileMeta>> {
|
||||||
|
let mut content = Vec::new();
|
||||||
|
let path = self.get_media_file(&data.key);
|
||||||
|
fs::File::open(path)
|
||||||
|
.await?
|
||||||
|
.read_to_end(&mut content)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let Ok(image) = image::load_from_memory(&content) else {
|
||||||
|
// Couldn't parse file to generate thumbnail, send original
|
||||||
|
return Ok(Some(into_filemeta(data, content)));
|
||||||
|
};
|
||||||
|
|
||||||
|
if width > image.width() || height > image.height() {
|
||||||
|
return Ok(Some(into_filemeta(data, content)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut thumbnail_bytes = Vec::new();
|
||||||
|
let thumbnail = thumbnail_generate(&image, width, height, crop)?;
|
||||||
|
thumbnail.write_to(&mut Cursor::new(&mut thumbnail_bytes), image::ImageFormat::Png)?;
|
||||||
|
|
||||||
|
// Save thumbnail in database so we don't have to generate it again next time
|
||||||
|
let thumbnail_key = self.db.create_file_metadata(
|
||||||
|
None,
|
||||||
|
mxc,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
data.content_disposition.as_deref(),
|
||||||
|
data.content_type.as_deref(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut f = self.create_media_file(&thumbnail_key).await?;
|
||||||
|
f.write_all(&thumbnail_bytes).await?;
|
||||||
|
|
||||||
|
Ok(Some(into_filemeta(data, thumbnail_bytes)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn thumbnail_generate(image: &DynamicImage, width: u32, height: u32, crop: bool) -> Result<DynamicImage> {
|
||||||
|
let thumbnail = if crop {
|
||||||
|
image.resize_to_fill(width, height, FilterType::CatmullRom)
|
||||||
|
} else {
|
||||||
|
let (exact_width, exact_height) = thumbnail_dimension(image, width, height)?;
|
||||||
|
image.thumbnail_exact(exact_width, exact_height)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(thumbnail)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn thumbnail_dimension(image: &DynamicImage, width: u32, height: u32) -> Result<(u32, u32)> {
|
||||||
|
let image_width = image.width();
|
||||||
|
let image_height = image.height();
|
||||||
|
|
||||||
|
let width = cmp::min(width, image_width);
|
||||||
|
let height = cmp::min(height, image_height);
|
||||||
|
|
||||||
|
let use_width = Sat(width) * Sat(image_height) < Sat(height) * Sat(image_width);
|
||||||
|
|
||||||
|
let x = if use_width {
|
||||||
|
let dividend = (Sat(height) * Sat(image_width)).0;
|
||||||
|
checked!(dividend / image_height)?
|
||||||
|
} else {
|
||||||
|
width
|
||||||
|
};
|
||||||
|
|
||||||
|
let y = if !use_width {
|
||||||
|
let dividend = (Sat(width) * Sat(image_height)).0;
|
||||||
|
checked!(dividend / image_width)?
|
||||||
|
} else {
|
||||||
|
height
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((x, y))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns width, height of the thumbnail and whether it should be cropped.
|
||||||
|
/// Returns None when the server should send the original file.
|
||||||
|
fn thumbnail_properties(width: u32, height: u32) -> Option<(u32, u32, bool)> {
|
||||||
|
match (width, height) {
|
||||||
|
(0..=32, 0..=32) => Some((32, 32, true)),
|
||||||
|
(0..=96, 0..=96) => Some((96, 96, true)),
|
||||||
|
(0..=320, 0..=240) => Some((320, 240, false)),
|
||||||
|
(0..=640, 0..=480) => Some((640, 480, false)),
|
||||||
|
(0..=800, 0..=600) => Some((800, 600, false)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_filemeta(data: Metadata, content: Vec<u8>) -> FileMeta {
|
||||||
|
FileMeta {
|
||||||
|
content: Some(content),
|
||||||
|
content_type: data.content_type,
|
||||||
|
content_disposition: data.content_disposition,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ impl Data {
|
|||||||
pub(super) fn new(server: &Arc<Server>, db: &Arc<Database>) -> Self {
|
pub(super) fn new(server: &Arc<Server>, db: &Arc<Database>) -> Self {
|
||||||
let config = &server.config;
|
let config = &server.config;
|
||||||
let cache_size = f64::from(config.auth_chain_cache_capacity);
|
let cache_size = f64::from(config.auth_chain_cache_capacity);
|
||||||
let cache_size = usize_from_f64(cache_size * config.conduit_cache_capacity_modifier).expect("valid cache size");
|
let cache_size = usize_from_f64(cache_size * config.cache_capacity_modifier).expect("valid cache size");
|
||||||
Self {
|
Self {
|
||||||
shorteventid_authchain: db["shorteventid_authchain"].clone(),
|
shorteventid_authchain: db["shorteventid_authchain"].clone(),
|
||||||
auth_chain_cache: Mutex::new(LruCache::new(cache_size)),
|
auth_chain_cache: Mutex::new(LruCache::new(cache_size)),
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ impl crate::Service for Service {
|
|||||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||||
let config = &args.server.config;
|
let config = &args.server.config;
|
||||||
let cache_size = f64::from(config.roomid_spacehierarchy_cache_capacity);
|
let cache_size = f64::from(config.roomid_spacehierarchy_cache_capacity);
|
||||||
let cache_size = cache_size * config.conduit_cache_capacity_modifier;
|
let cache_size = cache_size * config.cache_capacity_modifier;
|
||||||
Ok(Arc::new(Self {
|
Ok(Arc::new(Self {
|
||||||
roomid_spacehierarchy_cache: Mutex::new(LruCache::new(usize_from_f64(cache_size)?)),
|
roomid_spacehierarchy_cache: Mutex::new(LruCache::new(usize_from_f64(cache_size)?)),
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ impl crate::Service for Service {
|
|||||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||||
let config = &args.server.config;
|
let config = &args.server.config;
|
||||||
let server_visibility_cache_capacity =
|
let server_visibility_cache_capacity =
|
||||||
f64::from(config.server_visibility_cache_capacity) * config.conduit_cache_capacity_modifier;
|
f64::from(config.server_visibility_cache_capacity) * config.cache_capacity_modifier;
|
||||||
let user_visibility_cache_capacity =
|
let user_visibility_cache_capacity =
|
||||||
f64::from(config.user_visibility_cache_capacity) * config.conduit_cache_capacity_modifier;
|
f64::from(config.user_visibility_cache_capacity) * config.cache_capacity_modifier;
|
||||||
|
|
||||||
Ok(Arc::new(Self {
|
Ok(Arc::new(Self {
|
||||||
db: Data::new(args.db),
|
db: Data::new(args.db),
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ pub struct Service {
|
|||||||
impl crate::Service for Service {
|
impl crate::Service for Service {
|
||||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||||
let config = &args.server.config;
|
let config = &args.server.config;
|
||||||
let cache_capacity = f64::from(config.stateinfo_cache_capacity) * config.conduit_cache_capacity_modifier;
|
let cache_capacity = f64::from(config.stateinfo_cache_capacity) * config.cache_capacity_modifier;
|
||||||
Ok(Arc::new(Self {
|
Ok(Arc::new(Self {
|
||||||
db: Data::new(args.db),
|
db: Data::new(args.db),
|
||||||
stateinfo_cache: StdMutex::new(LruCache::new(usize_from_f64(cache_capacity)?)),
|
stateinfo_cache: StdMutex::new(LruCache::new(usize_from_f64(cache_capacity)?)),
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ async fn request_well_known(dest: &str) -> Result<Option<String>> {
|
|||||||
.as_str()
|
.as_str()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
if ruma_identifiers_validation::server_name::validate(m_server).is_err() {
|
if ruma::identifiers_validation::server_name::validate(m_server).is_err() {
|
||||||
debug_error!("response content missing or invalid");
|
debug_error!("response content missing or invalid");
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
@@ -443,7 +443,9 @@ impl crate::globals::resolver::Resolver {
|
|||||||
impl CachedDest {
|
impl CachedDest {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn valid(&self) -> bool { self.expire > SystemTime::now() }
|
pub fn valid(&self) -> bool { true }
|
||||||
|
|
||||||
|
//pub fn valid(&self) -> bool { self.expire > SystemTime::now() }
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn default_expire() -> SystemTime { rand::timepoint_secs(60 * 60 * 18..60 * 60 * 36) }
|
pub(crate) fn default_expire() -> SystemTime { rand::timepoint_secs(60 * 60 * 18..60 * 60 * 36) }
|
||||||
@@ -452,7 +454,9 @@ impl CachedDest {
|
|||||||
impl CachedOverride {
|
impl CachedOverride {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn valid(&self) -> bool { self.expire > SystemTime::now() }
|
pub fn valid(&self) -> bool { true }
|
||||||
|
|
||||||
|
//pub fn valid(&self) -> bool { self.expire > SystemTime::now() }
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn default_expire() -> SystemTime { rand::timepoint_secs(60 * 60 * 6..60 * 60 * 12) }
|
pub(crate) fn default_expire() -> SystemTime { rand::timepoint_secs(60 * 60 * 6..60 * 60 * 12) }
|
||||||
|
|||||||
+42
-57
@@ -1,6 +1,6 @@
|
|||||||
use std::{collections::BTreeMap, mem::size_of, sync::Arc};
|
use std::{collections::BTreeMap, mem::size_of, sync::Arc};
|
||||||
|
|
||||||
use conduit::{debug_info, utils, warn, Error, Result};
|
use conduit::{debug_info, err, utils, warn, Err, Error, Result};
|
||||||
use database::{Database, Map};
|
use database::{Database, Map};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::{device::Device, error::ErrorKind, filter::FilterDefinition},
|
api::client::{device::Device, error::ErrorKind, filter::FilterDefinition},
|
||||||
@@ -87,19 +87,19 @@ impl Data {
|
|||||||
let mut parts = bytes.split(|&b| b == 0xFF);
|
let mut parts = bytes.split(|&b| b == 0xFF);
|
||||||
let user_bytes = parts
|
let user_bytes = parts
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("User ID in token_userdeviceid is invalid."))?;
|
.ok_or_else(|| err!(Database("User ID in token_userdeviceid is invalid.")))?;
|
||||||
let device_bytes = parts
|
let device_bytes = parts
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("Device ID in token_userdeviceid is invalid."))?;
|
.ok_or_else(|| err!(Database("Device ID in token_userdeviceid is invalid.")))?;
|
||||||
|
|
||||||
Ok(Some((
|
Ok(Some((
|
||||||
UserId::parse(
|
UserId::parse(
|
||||||
utils::string_from_bytes(user_bytes)
|
utils::string_from_bytes(user_bytes)
|
||||||
.map_err(|_| Error::bad_database("User ID in token_userdeviceid is invalid unicode."))?,
|
.map_err(|e| err!(Database("User ID in token_userdeviceid is invalid unicode. {e}")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("User ID in token_userdeviceid is invalid."))?,
|
.map_err(|e| err!(Database("User ID in token_userdeviceid is invalid. {e}")))?,
|
||||||
utils::string_from_bytes(device_bytes)
|
utils::string_from_bytes(device_bytes)
|
||||||
.map_err(|_| Error::bad_database("Device ID in token_userdeviceid is invalid."))?,
|
.map_err(|e| err!(Database("Device ID in token_userdeviceid is invalid. {e}")))?,
|
||||||
)))
|
)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -109,9 +109,9 @@ impl Data {
|
|||||||
Box::new(self.userid_password.iter().map(|(bytes, _)| {
|
Box::new(self.userid_password.iter().map(|(bytes, _)| {
|
||||||
UserId::parse(
|
UserId::parse(
|
||||||
utils::string_from_bytes(&bytes)
|
utils::string_from_bytes(&bytes)
|
||||||
.map_err(|_| Error::bad_database("User ID in userid_password is invalid unicode."))?,
|
.map_err(|e| err!(Database("User ID in userid_password is invalid unicode. {e}")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("User ID in userid_password is invalid."))
|
.map_err(|e| err!(Database("User ID in userid_password is invalid. {e}")))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ impl Data {
|
|||||||
.map_or(Ok(None), |bytes| {
|
.map_or(Ok(None), |bytes| {
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
utils::string_from_bytes(&bytes)
|
utils::string_from_bytes(&bytes)
|
||||||
.map_err(|_| Error::bad_database("Displayname in db is invalid."))?,
|
.map_err(|e| err!(Database("Displayname in db is invalid. {e}")))?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -188,10 +188,8 @@ impl Data {
|
|||||||
self.userid_avatarurl
|
self.userid_avatarurl
|
||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
.map(|bytes| {
|
.map(|bytes| {
|
||||||
let s_bytes = utils::string_from_bytes(&bytes).map_err(|e| {
|
let s_bytes = utils::string_from_bytes(&bytes)
|
||||||
warn!("Avatar URL in db is invalid: {}", e);
|
.map_err(|e| err!(Database(warn!("Avatar URL in db is invalid: {e}"))))?;
|
||||||
Error::bad_database("Avatar URL in db is invalid.")
|
|
||||||
})?;
|
|
||||||
let mxc_uri: OwnedMxcUri = s_bytes.into();
|
let mxc_uri: OwnedMxcUri = s_bytes.into();
|
||||||
Ok(mxc_uri)
|
Ok(mxc_uri)
|
||||||
})
|
})
|
||||||
@@ -215,10 +213,7 @@ impl Data {
|
|||||||
self.userid_blurhash
|
self.userid_blurhash
|
||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
.map(|bytes| {
|
.map(|bytes| {
|
||||||
let s = utils::string_from_bytes(&bytes)
|
utils::string_from_bytes(&bytes).map_err(|e| err!(Database("Avatar URL in db is invalid. {e}")))
|
||||||
.map_err(|_| Error::bad_database("Avatar URL in db is invalid."))?;
|
|
||||||
|
|
||||||
Ok(s)
|
|
||||||
})
|
})
|
||||||
.transpose()
|
.transpose()
|
||||||
}
|
}
|
||||||
@@ -314,9 +309,9 @@ impl Data {
|
|||||||
bytes
|
bytes
|
||||||
.rsplit(|&b| b == 0xFF)
|
.rsplit(|&b| b == 0xFF)
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("UserDevice ID in db is invalid."))?,
|
.ok_or_else(|| err!(Database("UserDevice ID in db is invalid.")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("Device ID in userdeviceid_metadata is invalid."))?
|
.map_err(|e| err!(Database("Device ID in userdeviceid_metadata is invalid. {e}")))?
|
||||||
.into())
|
.into())
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -330,13 +325,9 @@ impl Data {
|
|||||||
|
|
||||||
// should not be None, but we shouldn't assert either lol...
|
// should not be None, but we shouldn't assert either lol...
|
||||||
if self.userdeviceid_metadata.get(&userdeviceid)?.is_none() {
|
if self.userdeviceid_metadata.get(&userdeviceid)?.is_none() {
|
||||||
warn!(
|
return Err!(Database(error!(
|
||||||
"Called set_token for a non-existent user \"{}\" and/or device ID \"{}\" with no metadata in database",
|
"User {user_id:?} does not exist or device ID {device_id:?} has no metadata."
|
||||||
user_id, device_id
|
)));
|
||||||
);
|
|
||||||
return Err(Error::bad_database(
|
|
||||||
"User does not exist or device ID has no metadata in database.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove old token
|
// Remove old token
|
||||||
@@ -366,14 +357,9 @@ impl Data {
|
|||||||
// Only existing devices should be able to call this, but we shouldn't assert
|
// Only existing devices should be able to call this, but we shouldn't assert
|
||||||
// either...
|
// either...
|
||||||
if self.userdeviceid_metadata.get(&key)?.is_none() {
|
if self.userdeviceid_metadata.get(&key)?.is_none() {
|
||||||
warn!(
|
return Err!(Database(error!(
|
||||||
"Called add_one_time_key for a non-existent user \"{}\" and/or device ID \"{}\" with no metadata in \
|
"User {user_id:?} does not exist or device ID {device_id:?} has no metadata."
|
||||||
database",
|
)));
|
||||||
user_id, device_id
|
|
||||||
);
|
|
||||||
return Err(Error::bad_database(
|
|
||||||
"User does not exist or device ID has no metadata in database.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
key.push(0xFF);
|
key.push(0xFF);
|
||||||
@@ -401,7 +387,7 @@ impl Data {
|
|||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
.map_or(Ok(0), |bytes| {
|
.map_or(Ok(0), |bytes| {
|
||||||
utils::u64_from_bytes(&bytes)
|
utils::u64_from_bytes(&bytes)
|
||||||
.map_err(|_| Error::bad_database("Count in roomid_lastroomactiveupdate is invalid."))
|
.map_err(|e| err!(Database("Count in roomid_lastroomactiveupdate is invalid. {e}")))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,11 +415,10 @@ impl Data {
|
|||||||
serde_json::from_slice(
|
serde_json::from_slice(
|
||||||
key.rsplit(|&b| b == 0xFF)
|
key.rsplit(|&b| b == 0xFF)
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("OneTimeKeyId in db is invalid."))?,
|
.ok_or_else(|| err!(Database("OneTimeKeyId in db is invalid.")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("OneTimeKeyId in db is invalid."))?,
|
.map_err(|e| err!(Database("OneTimeKeyId in db is invalid. {e}")))?,
|
||||||
serde_json::from_slice(&value)
|
serde_json::from_slice(&value).map_err(|e| err!(Database("OneTimeKeys in db are invalid. {e}")))?,
|
||||||
.map_err(|_| Error::bad_database("OneTimeKeys in db are invalid."))?,
|
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.transpose()
|
.transpose()
|
||||||
@@ -457,9 +442,9 @@ impl Data {
|
|||||||
bytes
|
bytes
|
||||||
.rsplit(|&b| b == 0xFF)
|
.rsplit(|&b| b == 0xFF)
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("OneTimeKey ID in db is invalid."))?,
|
.ok_or_else(|| err!(Database("OneTimeKey ID in db is invalid.")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("DeviceKeyId in db is invalid."))?
|
.map_err(|e| err!(Database("DeviceKeyId in db is invalid. {e}")))?
|
||||||
.algorithm(),
|
.algorithm(),
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
@@ -581,19 +566,19 @@ impl Data {
|
|||||||
.get(&key)?
|
.get(&key)?
|
||||||
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Tried to sign nonexistent key."))?,
|
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Tried to sign nonexistent key."))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("key in keyid_key is invalid."))?;
|
.map_err(|e| err!(Database("key in keyid_key is invalid. {e}")))?;
|
||||||
|
|
||||||
let signatures = cross_signing_key
|
let signatures = cross_signing_key
|
||||||
.get_mut("signatures")
|
.get_mut("signatures")
|
||||||
.ok_or_else(|| Error::bad_database("key in keyid_key has no signatures field."))?
|
.ok_or_else(|| err!(Database("key in keyid_key has no signatures field.")))?
|
||||||
.as_object_mut()
|
.as_object_mut()
|
||||||
.ok_or_else(|| Error::bad_database("key in keyid_key has invalid signatures field."))?
|
.ok_or_else(|| err!(Database("key in keyid_key has invalid signatures field.")))?
|
||||||
.entry(sender_id.to_string())
|
.entry(sender_id.to_string())
|
||||||
.or_insert_with(|| serde_json::Map::new().into());
|
.or_insert_with(|| serde_json::Map::new().into());
|
||||||
|
|
||||||
signatures
|
signatures
|
||||||
.as_object_mut()
|
.as_object_mut()
|
||||||
.ok_or_else(|| Error::bad_database("signatures in keyid_key for a user is invalid."))?
|
.ok_or_else(|| err!(Database("signatures in keyid_key for a user is invalid.")))?
|
||||||
.insert(signature.0, signature.1.into());
|
.insert(signature.0, signature.1.into());
|
||||||
|
|
||||||
self.keyid_key.insert(
|
self.keyid_key.insert(
|
||||||
@@ -640,7 +625,7 @@ impl Data {
|
|||||||
Error::bad_database("User ID in devicekeychangeid_userid is invalid unicode.")
|
Error::bad_database("User ID in devicekeychangeid_userid is invalid unicode.")
|
||||||
})?,
|
})?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("User ID in devicekeychangeid_userid is invalid."))
|
.map_err(|e| err!(Database("User ID in devicekeychangeid_userid is invalid. {e}")))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -685,7 +670,7 @@ impl Data {
|
|||||||
|
|
||||||
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
serde_json::from_slice(&bytes).map_err(|_| Error::bad_database("DeviceKeys in db are invalid."))?,
|
serde_json::from_slice(&bytes).map_err(|e| err!(Database("DeviceKeys in db are invalid. {e}")))?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -719,7 +704,7 @@ impl Data {
|
|||||||
) -> Result<Option<Raw<CrossSigningKey>>> {
|
) -> Result<Option<Raw<CrossSigningKey>>> {
|
||||||
self.keyid_key.get(key)?.map_or(Ok(None), |bytes| {
|
self.keyid_key.get(key)?.map_or(Ok(None), |bytes| {
|
||||||
let mut cross_signing_key = serde_json::from_slice::<serde_json::Value>(&bytes)
|
let mut cross_signing_key = serde_json::from_slice::<serde_json::Value>(&bytes)
|
||||||
.map_err(|_| Error::bad_database("CrossSigningKey in db is invalid."))?;
|
.map_err(|e| err!(Database("CrossSigningKey in db is invalid. {e}")))?;
|
||||||
clean_signatures(&mut cross_signing_key, sender_user, user_id, allowed_signatures)?;
|
clean_signatures(&mut cross_signing_key, sender_user, user_id, allowed_signatures)?;
|
||||||
|
|
||||||
Ok(Some(Raw::from_json(
|
Ok(Some(Raw::from_json(
|
||||||
@@ -751,7 +736,7 @@ impl Data {
|
|||||||
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
serde_json::from_slice(&bytes)
|
serde_json::from_slice(&bytes)
|
||||||
.map_err(|_| Error::bad_database("CrossSigningKey in db is invalid."))?,
|
.map_err(|e| err!(Database("CrossSigningKey in db is invalid. {e}")))?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -792,7 +777,7 @@ impl Data {
|
|||||||
for (_, value) in self.todeviceid_events.scan_prefix(prefix) {
|
for (_, value) in self.todeviceid_events.scan_prefix(prefix) {
|
||||||
events.push(
|
events.push(
|
||||||
serde_json::from_slice(&value)
|
serde_json::from_slice(&value)
|
||||||
.map_err(|_| Error::bad_database("Event in todeviceid_events is invalid."))?,
|
.map_err(|e| err!(Database("Event in todeviceid_events is invalid. {e}")))?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -816,7 +801,7 @@ impl Data {
|
|||||||
Ok::<_, Error>((
|
Ok::<_, Error>((
|
||||||
key.clone(),
|
key.clone(),
|
||||||
utils::u64_from_bytes(&key[key.len().saturating_sub(size_of::<u64>())..key.len()])
|
utils::u64_from_bytes(&key[key.len().saturating_sub(size_of::<u64>())..key.len()])
|
||||||
.map_err(|_| Error::bad_database("ToDeviceId has invalid count bytes."))?,
|
.map_err(|e| err!(Database("ToDeviceId has invalid count bytes. {e}")))?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
@@ -877,7 +862,7 @@ impl Data {
|
|||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
.map_or(Ok(None), |bytes| {
|
.map_or(Ok(None), |bytes| {
|
||||||
utils::u64_from_bytes(&bytes)
|
utils::u64_from_bytes(&bytes)
|
||||||
.map_err(|_| Error::bad_database("Invalid devicelistversion in db."))
|
.map_err(|e| err!(Database("Invalid devicelistversion in db. {e}")))
|
||||||
.map(Some)
|
.map(Some)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -893,7 +878,7 @@ impl Data {
|
|||||||
.scan_prefix(key)
|
.scan_prefix(key)
|
||||||
.map(|(_, bytes)| {
|
.map(|(_, bytes)| {
|
||||||
serde_json::from_slice::<Device>(&bytes)
|
serde_json::from_slice::<Device>(&bytes)
|
||||||
.map_err(|_| Error::bad_database("Device in userdeviceid_metadata is invalid."))
|
.map_err(|e| err!(Database("Device in userdeviceid_metadata is invalid. {e}")))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -920,7 +905,7 @@ impl Data {
|
|||||||
let raw = self.userfilterid_filter.get(&key)?;
|
let raw = self.userfilterid_filter.get(&key)?;
|
||||||
|
|
||||||
if let Some(raw) = raw {
|
if let Some(raw) = raw {
|
||||||
serde_json::from_slice(&raw).map_err(|_| Error::bad_database("Invalid filter event in db."))
|
serde_json::from_slice(&raw).map_err(|e| err!(Database("Invalid filter event in db. {e}")))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
@@ -954,7 +939,7 @@ impl Data {
|
|||||||
let expires_at = u64::from_be_bytes(
|
let expires_at = u64::from_be_bytes(
|
||||||
expires_at_bytes
|
expires_at_bytes
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| Error::bad_database("expires_at in openid_userid is invalid u64."))?,
|
.map_err(|e| err!(Database("expires_at in openid_userid is invalid u64. {e}")))?,
|
||||||
);
|
);
|
||||||
|
|
||||||
if expires_at < utils::millis_since_unix_epoch() {
|
if expires_at < utils::millis_since_unix_epoch() {
|
||||||
@@ -966,9 +951,9 @@ impl Data {
|
|||||||
|
|
||||||
UserId::parse(
|
UserId::parse(
|
||||||
utils::string_from_bytes(user_bytes)
|
utils::string_from_bytes(user_bytes)
|
||||||
.map_err(|_| Error::bad_database("User ID in openid_userid is invalid unicode."))?,
|
.map_err(|e| err!(Database("User ID in openid_userid is invalid unicode. {e}")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("User ID in openid_userid is invalid."))
|
.map_err(|e| err!(Database("User ID in openid_userid is invalid. {e}")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user