Remove polylith/API mode (#2967)

This removes most of the code used for polylith/API mode.

This removes the `/api` internal endpoints entirely. 

Binary size change roughly 5%: 
```
51437560 Feb 13 10:15 dendrite-monolith-server # old
48759008 Feb 13 10:15 dendrite-monolith-server # new
```
This commit is contained in:
Till 2023-02-14 12:47:47 +01:00 committed by GitHub
parent cc59879faa
commit 11d9b9db0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
106 changed files with 374 additions and 5850 deletions

View file

@ -17,7 +17,6 @@ see: https://www.matrix.org/security-disclosure-policy/
### Background information
<!-- Please include versions of all software when known e.g database versions, docker versions, client versions -->
- **Dendrite version or git SHA**:
- **Monolith or Polylith?**:
- **SQLite3 or Postgres?**:
- **Running in Docker?**:
- **`go version`**:

View file

@ -25,7 +25,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: "stable"
cache: true
- name: Install Node
@ -62,14 +62,14 @@ jobs:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: "stable"
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
# run go test with different go versions
test:
timeout-minutes: 10
name: Unit tests (Go ${{ matrix.go }})
name: Unit tests
runs-on: ubuntu-latest
# Service containers to run with `container-job`
services:
@ -91,25 +91,21 @@ jobs:
--health-interval 10s
--health-timeout 5s
--health-retries 5
strategy:
fail-fast: false
matrix:
go: ["1.19"]
steps:
- uses: actions/checkout@v3
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
go-version: "stable"
- uses: actions/cache@v3
# manually set up caches, as they otherwise clash with different steps using setup-go with cache=true
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go${{ matrix.go }}-unit-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go-stable-unit-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go${{ matrix.go }}-unit-
${{ runner.os }}-go-stable-unit-
- name: Set up gotestfmt
uses: gotesttools/gotestfmt-action@v2
with:
@ -130,7 +126,6 @@ jobs:
strategy:
fail-fast: false
matrix:
go: ["1.18", "1.19", "1.20.0"]
goos: ["linux"]
goarch: ["amd64", "386"]
steps:
@ -138,15 +133,15 @@ jobs:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
go-version: "stable"
- uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go${{ matrix.go }}${{ matrix.goos }}-${{ matrix.goarch }}-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go-stable-${{ matrix.goos }}-${{ matrix.goarch }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
key: ${{ runner.os }}-go${{ matrix.go }}${{ matrix.goos }}-${{ matrix.goarch }}-
key: ${{ runner.os }}-go-stable-${{ matrix.goos }}-${{ matrix.goarch }}-
- name: Install dependencies x86
if: ${{ matrix.goarch == '386' }}
run: sudo apt update && sudo apt-get install -y gcc-multilib
@ -164,23 +159,22 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: ["1.18", "1.19", "1.20.0"]
goos: ["windows"]
goarch: ["amd64"]
steps:
- uses: actions/checkout@v3
- name: Setup Go ${{ matrix.go }}
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
go-version: "stable"
- uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go${{ matrix.go }}${{ matrix.goos }}-${{ matrix.goarch }}-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go-stable-${{ matrix.goos }}-${{ matrix.goarch }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
key: ${{ runner.os }}-go${{ matrix.go }}${{ matrix.goos }}-${{ matrix.goarch }}-
key: ${{ runner.os }}-go-stable-${{ matrix.goos }}-${{ matrix.goarch }}-
- name: Install dependencies
run: sudo apt update && sudo apt install -y gcc-mingw-w64-x86-64 # install required gcc
- env:
@ -206,7 +200,7 @@ jobs:
integration:
timeout-minutes: 20
needs: initial-tests-done
name: Integration tests (Go ${{ matrix.go }})
name: Integration tests
runs-on: ubuntu-latest
# Service containers to run with `container-job`
services:
@ -228,16 +222,12 @@ jobs:
--health-interval 10s
--health-timeout 5s
--health-retries 5
strategy:
fail-fast: false
matrix:
go: ["1.19"]
steps:
- uses: actions/checkout@v3
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
go-version: "stable"
- name: Set up gotestfmt
uses: gotesttools/gotestfmt-action@v2
with:
@ -248,9 +238,9 @@ jobs:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go${{ matrix.go }}-test-race-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go-stable-test-race-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go${{ matrix.go }}-test-race-
${{ runner.os }}-go-stable-test-race-
- run: go test -race -json -v -coverpkg=./... -coverprofile=cover.out $(go list ./... | grep -v /cmd/dendrite*) 2>&1 | gotestfmt
env:
POSTGRES_HOST: localhost
@ -261,6 +251,7 @@ jobs:
uses: codecov/codecov-action@v3
with:
flags: unittests
fail_ci_if_error: true
# run database upgrade tests
upgrade_test:
@ -273,7 +264,7 @@ jobs:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: "1.18"
go-version: "stable"
cache: true
- name: Build upgrade-tests
run: go build ./cmd/dendrite-upgrade-tests
@ -293,7 +284,7 @@ jobs:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: "1.18"
go-version: "stable"
cache: true
- name: Build upgrade-tests
run: go build ./cmd/dendrite-upgrade-tests
@ -317,19 +308,9 @@ jobs:
- label: SQLite Cgo
cgo: 1
- label: SQLite native, full HTTP APIs
api: full-http
- label: SQLite Cgo, full HTTP APIs
api: full-http
cgo: 1
- label: PostgreSQL
postgres: postgres
- label: PostgreSQL, full HTTP APIs
postgres: postgres
api: full-http
container:
image: matrixdotorg/sytest-dendrite
volumes:
@ -338,7 +319,6 @@ jobs:
- /root/.cache/go-mod:/gopath/pkg/mod
env:
POSTGRES: ${{ matrix.postgres && 1}}
API: ${{ matrix.api && 1 }}
SYTEST_BRANCH: ${{ github.head_ref }}
CGO_ENABLED: ${{ matrix.cgo && 1 }}
steps:
@ -390,22 +370,9 @@ jobs:
- label: SQLite Cgo
cgo: 1
- label: SQLite native, full HTTP APIs
api: full-http
cgo: 0
- label: SQLite Cgo, full HTTP APIs
api: full-http
cgo: 1
- label: PostgreSQL
postgres: Postgres
cgo: 0
- label: PostgreSQL, full HTTP APIs
postgres: Postgres
api: full-http
cgo: 0
steps:
# Env vars are set file a file given by $GITHUB_PATH. We need both Go 1.17 and GOPATH on env to run Complement.
# See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path
@ -447,7 +414,7 @@ jobs:
(wget -O - "https://github.com/matrix-org/complement/archive/$BRANCH_NAME.tar.gz" | tar -xz --strip-components=1 -C complement) && break
done
# Build initial Dendrite image
- run: docker build --build-arg=CGO=${{ matrix.cgo }} -t complement-dendrite:${{ matrix.postgres }}${{ matrix.api }}${{ matrix.cgo }} -f build/scripts/Complement${{ matrix.postgres }}.Dockerfile .
- run: docker build --build-arg=CGO=${{ matrix.cgo }} -t complement-dendrite:${{ matrix.postgres }}${{ matrix.cgo }} -f build/scripts/Complement${{ matrix.postgres }}.Dockerfile .
working-directory: dendrite
env:
DOCKER_BUILDKIT: 1
@ -459,8 +426,7 @@ jobs:
shell: bash
name: Run Complement Tests
env:
COMPLEMENT_BASE_IMAGE: complement-dendrite:${{ matrix.postgres }}${{ matrix.api }}${{ matrix.cgo }}
COMPLEMENT_DENDRITE_API: ${{ matrix.api && 1 }}
COMPLEMENT_BASE_IMAGE: complement-dendrite:${{ matrix.postgres }}${{ matrix.cgo }}
COMPLEMENT_SHARE_ENV_PREFIX: COMPLEMENT_DENDRITE_
working-directory: complement

View file

@ -61,7 +61,6 @@ jobs:
cache-to: type=gha,mode=max
context: .
build-args: FLAGS=-X github.com/matrix-org/dendrite/internal.branch=${{ env.BRANCH }} -X github.com/matrix-org/dendrite/internal.build=${{ env.BUILD }}
target: monolith
platforms: ${{ env.PLATFORMS }}
push: true
tags: |
@ -77,7 +76,6 @@ jobs:
cache-to: type=gha,mode=max
context: .
build-args: FLAGS=-X github.com/matrix-org/dendrite/internal.branch=${{ env.BRANCH }} -X github.com/matrix-org/dendrite/internal.build=${{ env.BUILD }}
target: monolith
platforms: ${{ env.PLATFORMS }}
push: true
tags: |
@ -98,86 +96,6 @@ jobs:
with:
sarif_file: "trivy-results.sarif"
polylith:
name: Polylith image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
security-events: write # To upload Trivy sarif files
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Get release tag & build flags
if: github.event_name == 'release' # Only for GitHub releases
run: |
echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
echo "BUILD=$(git rev-parse --short HEAD || \"\")" >> $GITHUB_ENV
BRANCH=$(git symbolic-ref --short HEAD | tr -d \/)
[ ${BRANCH} == "main" ] && BRANCH=""
echo "BRANCH=${BRANCH}" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ env.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to GitHub Containers
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build main polylith image
if: github.ref_name == 'main'
id: docker_build_polylith
uses: docker/build-push-action@v3
with:
cache-from: type=gha
cache-to: type=gha,mode=max
context: .
build-args: FLAGS=-X github.com/matrix-org/dendrite/internal.branch=${{ env.BRANCH }} -X github.com/matrix-org/dendrite/internal.build=${{ env.BUILD }}
target: polylith
platforms: ${{ env.PLATFORMS }}
push: true
tags: |
${{ env.DOCKER_NAMESPACE }}/dendrite-polylith:${{ github.ref_name }}
ghcr.io/${{ env.GHCR_NAMESPACE }}/dendrite-polylith:${{ github.ref_name }}
- name: Build release polylith image
if: github.event_name == 'release' # Only for GitHub releases
id: docker_build_polylith_release
uses: docker/build-push-action@v3
with:
cache-from: type=gha
cache-to: type=gha,mode=max
context: .
build-args: FLAGS=-X github.com/matrix-org/dendrite/internal.branch=${{ env.BRANCH }} -X github.com/matrix-org/dendrite/internal.build=${{ env.BUILD }}
target: polylith
platforms: ${{ env.PLATFORMS }}
push: true
tags: |
${{ env.DOCKER_NAMESPACE }}/dendrite-polylith:latest
${{ env.DOCKER_NAMESPACE }}/dendrite-polylith:${{ env.RELEASE_VERSION }}
ghcr.io/${{ env.GHCR_NAMESPACE }}/dendrite-polylith:latest
ghcr.io/${{ env.GHCR_NAMESPACE }}/dendrite-polylith:${{ env.RELEASE_VERSION }}
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ghcr.io/${{ env.GHCR_NAMESPACE }}/dendrite-polylith:${{ github.ref_name }}
format: "sarif"
output: "trivy-results.sarif"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: "trivy-results.sarif"
demo-pinecone:
name: Pinecone demo image
runs-on: ubuntu-latest

View file

@ -24,19 +24,8 @@ jobs:
- label: SQLite Cgo
cgo: 1
- label: SQLite native, full HTTP APIs
api: full-http
- label: SQLite Cgo, full HTTP APIs
api: full-http
cgo: 1
- label: PostgreSQL
postgres: postgres
- label: PostgreSQL, full HTTP APIs
postgres: postgres
api: full-http
container:
image: matrixdotorg/sytest-dendrite:latest
volumes:
@ -45,7 +34,6 @@ jobs:
- /root/.cache/go-mod:/gopath/pkg/mod
env:
POSTGRES: ${{ matrix.postgres && 1}}
API: ${{ matrix.api && 1 }}
SYTEST_BRANCH: ${{ github.head_ref }}
RACE_DETECTION: 1
COVER: 1
@ -93,7 +81,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: '>=1.19.0'
go-version: 'stable'
cache: true
- name: Download all artifacts
uses: actions/download-artifact@v3
@ -125,22 +113,9 @@ jobs:
- label: SQLite Cgo
cgo: 1
- label: SQLite native, full HTTP APIs
api: full-http
cgo: 0
- label: SQLite Cgo, full HTTP APIs
api: full-http
cgo: 1
- label: PostgreSQL
postgres: Postgres
cgo: 0
- label: PostgreSQL, full HTTP APIs
postgres: Postgres
api: full-http
cgo: 0
steps:
# Env vars are set file a file given by $GITHUB_PATH. We need both Go 1.17 and GOPATH on env to run Complement.
# See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path
@ -182,7 +157,7 @@ jobs:
(wget -O - "https://github.com/matrix-org/complement/archive/$BRANCH_NAME.tar.gz" | tar -xz --strip-components=1 -C complement) && break
done
# Build initial Dendrite image
- run: docker build --build-arg=CGO=${{ matrix.cgo }} -t complement-dendrite:${{ matrix.postgres }}${{ matrix.api }}${{ matrix.cgo }} -f build/scripts/Complement${{ matrix.postgres }}.Dockerfile .
- run: docker build --build-arg=CGO=${{ matrix.cgo }} -t complement-dendrite:${{ matrix.postgres }}${{ matrix.cgo }} -f build/scripts/Complement${{ matrix.postgres }}.Dockerfile .
working-directory: dendrite
env:
DOCKER_BUILDKIT: 1
@ -203,8 +178,7 @@ jobs:
shell: bash
name: Run Complement Tests
env:
COMPLEMENT_BASE_IMAGE: complement-dendrite:${{ matrix.postgres }}${{ matrix.api }}${{ matrix.cgo }}
COMPLEMENT_DENDRITE_API: ${{ matrix.api && 1 }}
COMPLEMENT_BASE_IMAGE: complement-dendrite:${{ matrix.postgres }}${{ matrix.cgo }}
COMPLEMENT_SHARE_ENV_PREFIX: COMPLEMENT_DENDRITE_
COMPLEMENT_DENDRITE_COVER: 1
COMPLEMENT_POST_TEST_SCRIPT: /tmp/posttest.sh
@ -229,7 +203,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: '>=1.19.0'
go-version: 'stable'
cache: true
- name: Download all artifacts
uses: actions/download-artifact@v3

View file

@ -3,7 +3,7 @@
#
# base installs required dependencies and runs go mod download to cache dependencies
#
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.19-alpine AS base
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.20-alpine AS base
RUN apk --update --no-cache add bash build-base curl
#
@ -23,44 +23,27 @@ RUN --mount=target=. \
CGO_ENABLED=$([ "$TARGETARCH" = "$USERARCH" ] && echo "1" || echo "0") \
go build -v -ldflags="${FLAGS}" -trimpath -o /out/ ./cmd/...
#
# The dendrite base image
# Builds the Dendrite image containing all required binaries
#
FROM alpine:latest AS dendrite-base
FROM alpine:latest
RUN apk --update --no-cache add curl
LABEL org.opencontainers.image.title="Dendrite"
LABEL org.opencontainers.image.description="Next-generation Matrix homeserver written in Go"
LABEL org.opencontainers.image.source="https://github.com/matrix-org/dendrite"
LABEL org.opencontainers.image.licenses="Apache-2.0"
LABEL org.opencontainers.image.documentation="https://matrix-org.github.io/dendrite/"
LABEL org.opencontainers.image.vendor="The Matrix.org Foundation C.I.C."
#
# Builds the polylith image and only contains the polylith binary
#
FROM dendrite-base AS polylith
LABEL org.opencontainers.image.title="Dendrite (Polylith)"
COPY --from=build /out/dendrite-polylith-multi /usr/bin/
VOLUME /etc/dendrite
WORKDIR /etc/dendrite
ENTRYPOINT ["/usr/bin/dendrite-polylith-multi"]
#
# Builds the monolith image and contains all required binaries
#
FROM dendrite-base AS monolith
LABEL org.opencontainers.image.title="Dendrite (Monolith)"
COPY --from=build /out/create-account /usr/bin/create-account
COPY --from=build /out/generate-config /usr/bin/generate-config
COPY --from=build /out/generate-keys /usr/bin/generate-keys
COPY --from=build /out/dendrite-monolith-server /usr/bin/dendrite-monolith-server
COPY --from=build /out/dendrite /usr/bin/dendrite
VOLUME /etc/dendrite
WORKDIR /etc/dendrite
ENTRYPOINT ["/usr/bin/dendrite-monolith-server"]
ENTRYPOINT ["/usr/bin/dendrite"]
EXPOSE 8008 8448

View file

@ -24,7 +24,6 @@ This does not mean:
- Dendrite is ready for massive homeserver deployments. There is no sharding of microservices (although it is possible to run them on separate machines) and there is no high-availability/clustering support.
Currently, we expect Dendrite to function well for small (10s/100s of users) homeserver deployments as well as P2P Matrix nodes in-browser or on mobile devices.
In the future, we will be able to scale up to gigantic servers (equivalent to `matrix.org`) via polylith mode.
If you have further questions, please take a look at [our FAQ](docs/FAQ.md) or join us in:

View file

@ -21,14 +21,12 @@ import (
"sync"
"time"
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
"github.com/matrix-org/gomatrixserverlib"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/appservice/consumers"
"github.com/matrix-org/dendrite/appservice/inthttp"
"github.com/matrix-org/dendrite/appservice/query"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup/base"
@ -36,11 +34,6 @@ import (
userapi "github.com/matrix-org/dendrite/userapi/api"
)
// AddInternalRoutes registers HTTP handlers for internal API calls
func AddInternalRoutes(router *mux.Router, queryAPI appserviceAPI.AppServiceInternalAPI, enableMetrics bool) {
inthttp.AddRoutes(queryAPI, router, enableMetrics)
}
// NewInternalAPI returns a concerete implementation of the internal API. Callers
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI(

View file

@ -10,12 +10,8 @@ import (
"strings"
"testing"
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/appservice/inthttp"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/test"
@ -132,24 +128,8 @@ func TestAppserviceInternalAPI(t *testing.T) {
usrAPI := userapi.NewInternalAPI(base, &base.Cfg.UserAPI, nil, nil, rsAPI, nil)
asAPI := appservice.NewInternalAPI(base, usrAPI, rsAPI)
// Finally execute the tests
t.Run("HTTP API", func(t *testing.T) {
router := mux.NewRouter().PathPrefix(httputil.InternalPathPrefix).Subrouter()
appservice.AddInternalRoutes(router, asAPI, base.EnableMetrics)
apiURL, cancel := test.ListenAndServe(t, router, false)
defer cancel()
asHTTPApi, err := inthttp.NewAppserviceClient(apiURL, &http.Client{})
if err != nil {
t.Fatalf("failed to create HTTP client: %s", err)
}
runCases(t, asHTTPApi)
})
t.Run("Monolith", func(t *testing.T) {
runCases(t, asAPI)
})
})
}
func testUserIDExists(t *testing.T, asAPI api.AppServiceInternalAPI, userID string, wantExists bool) {

View file

@ -1,84 +0,0 @@
package inthttp
import (
"context"
"errors"
"net/http"
"github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/internal/httputil"
)
// HTTP paths for the internal HTTP APIs
const (
AppServiceRoomAliasExistsPath = "/appservice/RoomAliasExists"
AppServiceUserIDExistsPath = "/appservice/UserIDExists"
AppServiceLocationsPath = "/appservice/locations"
AppServiceUserPath = "/appservice/users"
AppServiceProtocolsPath = "/appservice/protocols"
)
// httpAppServiceQueryAPI contains the URL to an appservice query API and a
// reference to a httpClient used to reach it
type httpAppServiceQueryAPI struct {
appserviceURL string
httpClient *http.Client
}
// NewAppserviceClient creates a AppServiceQueryAPI implemented by talking
// to a HTTP POST API.
// If httpClient is nil an error is returned
func NewAppserviceClient(
appserviceURL string,
httpClient *http.Client,
) (api.AppServiceInternalAPI, error) {
if httpClient == nil {
return nil, errors.New("NewRoomserverAliasAPIHTTP: httpClient is <nil>")
}
return &httpAppServiceQueryAPI{appserviceURL, httpClient}, nil
}
// RoomAliasExists implements AppServiceQueryAPI
func (h *httpAppServiceQueryAPI) RoomAliasExists(
ctx context.Context,
request *api.RoomAliasExistsRequest,
response *api.RoomAliasExistsResponse,
) error {
return httputil.CallInternalRPCAPI(
"RoomAliasExists", h.appserviceURL+AppServiceRoomAliasExistsPath,
h.httpClient, ctx, request, response,
)
}
// UserIDExists implements AppServiceQueryAPI
func (h *httpAppServiceQueryAPI) UserIDExists(
ctx context.Context,
request *api.UserIDExistsRequest,
response *api.UserIDExistsResponse,
) error {
return httputil.CallInternalRPCAPI(
"UserIDExists", h.appserviceURL+AppServiceUserIDExistsPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpAppServiceQueryAPI) Locations(ctx context.Context, request *api.LocationRequest, response *api.LocationResponse) error {
return httputil.CallInternalRPCAPI(
"ASLocation", h.appserviceURL+AppServiceLocationsPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpAppServiceQueryAPI) User(ctx context.Context, request *api.UserRequest, response *api.UserResponse) error {
return httputil.CallInternalRPCAPI(
"ASUser", h.appserviceURL+AppServiceUserPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpAppServiceQueryAPI) Protocols(ctx context.Context, request *api.ProtocolRequest, response *api.ProtocolResponse) error {
return httputil.CallInternalRPCAPI(
"ASProtocols", h.appserviceURL+AppServiceProtocolsPath,
h.httpClient, ctx, request, response,
)
}

View file

@ -1,36 +0,0 @@
package inthttp
import (
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/internal/httputil"
)
// AddRoutes adds the AppServiceQueryAPI handlers to the http.ServeMux.
func AddRoutes(a api.AppServiceInternalAPI, internalAPIMux *mux.Router, enableMetrics bool) {
internalAPIMux.Handle(
AppServiceRoomAliasExistsPath,
httputil.MakeInternalRPCAPI("AppserviceRoomAliasExists", enableMetrics, a.RoomAliasExists),
)
internalAPIMux.Handle(
AppServiceUserIDExistsPath,
httputil.MakeInternalRPCAPI("AppserviceUserIDExists", enableMetrics, a.UserIDExists),
)
internalAPIMux.Handle(
AppServiceProtocolsPath,
httputil.MakeInternalRPCAPI("AppserviceProtocols", enableMetrics, a.Protocols),
)
internalAPIMux.Handle(
AppServiceLocationsPath,
httputil.MakeInternalRPCAPI("AppserviceLocations", enableMetrics, a.Locations),
)
internalAPIMux.Handle(
AppServiceUserPath,
httputil.MakeInternalRPCAPI("AppserviceUser", enableMetrics, a.User),
)
}

View file

@ -177,7 +177,7 @@ func startup() {
if err := cfg.Derive(); err != nil {
logrus.Fatalf("Failed to derive values from config: %s", err)
}
base := base.NewBaseDendrite(cfg, "Monolith")
base := base.NewBaseDendrite(cfg)
defer base.Close() // nolint: errcheck
rsAPI := roomserver.NewInternalAPI(base)
@ -215,7 +215,6 @@ func startup() {
monolith.AddAllPublicRoutes(base)
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
httpRouter.PathPrefix(httputil.InternalPathPrefix).Handler(base.InternalAPIMux)
httpRouter.PathPrefix(httputil.PublicClientPathPrefix).Handler(base.PublicClientAPIMux)
httpRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(base.PublicMediaAPIMux)

View file

@ -5,7 +5,6 @@ These are Docker images for Dendrite!
They can be found on Docker Hub:
- [matrixdotorg/dendrite-monolith](https://hub.docker.com/r/matrixdotorg/dendrite-monolith) for monolith deployments
- [matrixdotorg/dendrite-polylith](https://hub.docker.com/r/matrixdotorg/dendrite-polylith) for polylith deployments
## Dockerfiles
@ -15,7 +14,6 @@ repository, run:
```
docker build . --target monolith -t matrixdotorg/dendrite-monolith
docker build . --target polylith -t matrixdotorg/dendrite-monolith
docker build . --target demo-pinecone -t matrixdotorg/dendrite-demo-pinecone
docker build . --target demo-yggdrasil -t matrixdotorg/dendrite-demo-yggdrasil
```
@ -25,7 +23,6 @@ docker build . --target demo-yggdrasil -t matrixdotorg/dendrite-demo-yggdrasil
There are two sample `docker-compose` files:
- `docker-compose.monolith.yml` which runs a monolith Dendrite deployment
- `docker-compose.polylith.yml` which runs a polylith Dendrite deployment
## Configuration
@ -51,7 +48,7 @@ docker run --rm --entrypoint="" \
The key files will now exist in your current working directory, and can be mounted into place.
## Starting Dendrite as a monolith deployment
## Starting Dendrite
Create your config based on the [`dendrite-sample.monolith.yaml`](https://github.com/matrix-org/dendrite/blob/main/dendrite-sample.monolith.yaml) sample configuration file.
@ -61,16 +58,6 @@ Then start the deployment:
docker-compose -f docker-compose.monolith.yml up
```
## Starting Dendrite as a polylith deployment
Create your config based on the [`dendrite-sample.polylith.yaml`](https://github.com/matrix-org/dendrite/blob/main/dendrite-sample.polylith.yaml) sample configuration file.
Then start the deployment:
```
docker-compose -f docker-compose.polylith.yml up
```
## Building the images
The `build/docker/images-build.sh` script will build the base image, followed by

View file

@ -1,143 +0,0 @@
version: "3.4"
services:
postgres:
hostname: postgres
image: postgres:14
restart: always
volumes:
- ./postgres/create_db.sh:/docker-entrypoint-initdb.d/20-create_db.sh
# To persist your PostgreSQL databases outside of the Docker image,
# to prevent data loss, modify the following ./path_to path:
- ./path_to/postgresql:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: itsasecret
POSTGRES_USER: dendrite
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dendrite"]
interval: 5s
timeout: 5s
retries: 5
networks:
- internal
jetstream:
hostname: jetstream
image: nats:latest
command: |
--jetstream
--store_dir /var/lib/nats
--cluster_name Dendrite
volumes:
# To persist your NATS JetStream streams outside of the Docker image,
# prevent data loss, modify the following ./path_to path:
- ./path_to/nats:/var/lib/nats
networks:
- internal
client_api:
hostname: client_api
image: matrixdotorg/dendrite-polylith:latest
command: clientapi
volumes:
- ./config:/etc/dendrite
depends_on:
- jetstream
- postgres
networks:
- internal
restart: unless-stopped
media_api:
hostname: media_api
image: matrixdotorg/dendrite-polylith:latest
command: mediaapi
volumes:
- ./config:/etc/dendrite
- ./media:/var/dendrite/media
networks:
- internal
restart: unless-stopped
sync_api:
hostname: sync_api
image: matrixdotorg/dendrite-polylith:latest
command: syncapi
volumes:
- ./config:/etc/dendrite
depends_on:
- jetstream
- postgres
networks:
- internal
restart: unless-stopped
room_server:
hostname: room_server
image: matrixdotorg/dendrite-polylith:latest
command: roomserver
volumes:
- ./config:/etc/dendrite
depends_on:
- jetstream
- postgres
networks:
- internal
restart: unless-stopped
federation_api:
hostname: federation_api
image: matrixdotorg/dendrite-polylith:latest
command: federationapi
volumes:
- ./config:/etc/dendrite
depends_on:
- jetstream
- postgres
networks:
- internal
restart: unless-stopped
key_server:
hostname: key_server
image: matrixdotorg/dendrite-polylith:latest
command: keyserver
volumes:
- ./config:/etc/dendrite
depends_on:
- jetstream
- postgres
networks:
- internal
restart: unless-stopped
user_api:
hostname: user_api
image: matrixdotorg/dendrite-polylith:latest
command: userapi
volumes:
- ./config:/etc/dendrite
depends_on:
- jetstream
- postgres
networks:
- internal
restart: unless-stopped
appservice_api:
hostname: appservice_api
image: matrixdotorg/dendrite-polylith:latest
command: appservice
volumes:
- ./config:/etc/dendrite
networks:
- internal
depends_on:
- jetstream
- postgres
- room_server
- user_api
restart: unless-stopped
networks:
internal:
attachable: true

View file

@ -7,6 +7,5 @@ TAG=${1:-latest}
echo "Building tag '${TAG}'"
docker build . --target monolith -t matrixdotorg/dendrite-monolith:${TAG}
docker build . --target polylith -t matrixdotorg/dendrite-monolith:${TAG}
docker build . --target demo-pinecone -t matrixdotorg/dendrite-demo-pinecone:${TAG}
docker build . --target demo-yggdrasil -t matrixdotorg/dendrite-demo-yggdrasil:${TAG}

View file

@ -5,4 +5,3 @@ TAG=${1:-latest}
echo "Pulling tag '${TAG}'"
docker pull matrixdotorg/dendrite-monolith:${TAG}
docker pull matrixdotorg/dendrite-polylith:${TAG}

View file

@ -5,4 +5,3 @@ TAG=${1:-latest}
echo "Pushing tag '${TAG}'"
docker push matrixdotorg/dendrite-monolith:${TAG}
docker push matrixdotorg/dendrite-polylith:${TAG}

View file

@ -128,7 +128,7 @@ func (m *DendriteMonolith) Start() {
cfg := &config.Dendrite{}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
cfg.Global.ServerName = gomatrixserverlib.ServerName(hex.EncodeToString(pk))
cfg.Global.PrivateKey = sk
@ -149,7 +149,7 @@ func (m *DendriteMonolith) Start() {
panic(err)
}
base := base.NewBaseDendrite(cfg, "Monolith")
base := base.NewBaseDendrite(cfg)
base.ConfigureAdminEndpoints()
m.processContext = base.ProcessContext
defer base.Close() // nolint: errcheck
@ -194,7 +194,6 @@ func (m *DendriteMonolith) Start() {
monolith.AddAllPublicRoutes(base)
httpRouter := mux.NewRouter()
httpRouter.PathPrefix(httputil.InternalPathPrefix).Handler(base.InternalAPIMux)
httpRouter.PathPrefix(httputil.PublicClientPathPrefix).Handler(base.PublicClientAPIMux)
httpRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(base.PublicMediaAPIMux)
httpRouter.PathPrefix(httputil.DendriteAdminPathPrefix).Handler(base.DendriteAdminMux)

View file

@ -16,8 +16,8 @@ RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=${CGO} go build -o /dendrite ./cmd/generate-config && \
CGO_ENABLED=${CGO} go build -o /dendrite ./cmd/generate-keys && \
CGO_ENABLED=${CGO} go build -o /dendrite ./cmd/dendrite-monolith-server && \
CGO_ENABLED=${CGO} go test -c -cover -covermode=atomic -o /dendrite/dendrite-monolith-server-cover -coverpkg "github.com/matrix-org/..." ./cmd/dendrite-monolith-server && \
CGO_ENABLED=${CGO} go build -o /dendrite/dendrite ./cmd/dendrite && \
CGO_ENABLED=${CGO} go test -c -cover -covermode=atomic -o /dendrite/dendrite-cover -coverpkg "github.com/matrix-org/..." ./cmd/dendrite && \
cp build/scripts/complement-cmd.sh /complement-cmd.sh
WORKDIR /dendrite

View file

@ -19,13 +19,13 @@ WORKDIR /runtime
# This script compiles Dendrite for us.
RUN echo '\
#!/bin/bash -eux \n\
if test -f "/runtime/dendrite-monolith-server" && test -f "/runtime/dendrite-monolith-server-cover"; then \n\
if test -f "/runtime/dendrite" && test -f "/runtime/dendrite-cover"; then \n\
echo "Skipping compilation; binaries exist" \n\
exit 0 \n\
fi \n\
cd /dendrite \n\
go build -v -o /runtime /dendrite/cmd/dendrite-monolith-server \n\
go test -c -cover -covermode=atomic -o /runtime/dendrite-monolith-server-cover -coverpkg "github.com/matrix-org/..." /dendrite/cmd/dendrite-monolith-server \n\
go build -v -o /runtime /dendrite/cmd/dendrite \n\
go test -c -cover -covermode=atomic -o /runtime/dendrite-cover -coverpkg "github.com/matrix-org/..." /dendrite/cmd/dendrite \n\
' > compile.sh && chmod +x compile.sh
# This script runs Dendrite for us. Must be run in the /runtime directory.
@ -35,8 +35,8 @@ RUN echo '\
./generate-keys -keysize 1024 --server $SERVER_NAME --tls-cert server.crt --tls-key server.key --tls-authority-cert /complement/ca/ca.crt --tls-authority-key /complement/ca/ca.key \n\
./generate-config -server $SERVER_NAME --ci > dendrite.yaml \n\
cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates \n\
[ ${COVER} -eq 1 ] && exec ./dendrite-monolith-server-cover --test.coverprofile=integrationcover.log --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml \n\
exec ./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml \n\
[ ${COVER} -eq 1 ] && exec ./dendrite-cover --test.coverprofile=integrationcover.log --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml \n\
exec ./dendrite --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml \n\
' > run.sh && chmod +x run.sh

View file

@ -34,8 +34,8 @@ RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=${CGO} go build -o /dendrite ./cmd/generate-config && \
CGO_ENABLED=${CGO} go build -o /dendrite ./cmd/generate-keys && \
CGO_ENABLED=${CGO} go build -o /dendrite ./cmd/dendrite-monolith-server && \
CGO_ENABLED=${CGO} go test -c -cover -covermode=atomic -o /dendrite/dendrite-monolith-server-cover -coverpkg "github.com/matrix-org/..." ./cmd/dendrite-monolith-server && \
CGO_ENABLED=${CGO} go build -o /dendrite/dendrite ./cmd/dendrite && \
CGO_ENABLED=${CGO} go test -c -cover -covermode=atomic -o /dendrite/dendrite-cover -coverpkg "github.com/matrix-org/..." ./cmd/dendrite && \
cp build/scripts/complement-cmd.sh /complement-cmd.sh
WORKDIR /dendrite

View file

@ -4,19 +4,17 @@
if [[ "${COVER}" -eq 1 ]]; then
echo "Running with coverage"
exec /dendrite/dendrite-monolith-server-cover \
exec /dendrite/dendrite-cover \
--really-enable-open-registration \
--tls-cert server.crt \
--tls-key server.key \
--config dendrite.yaml \
-api=${API:-0} \
--test.coverprofile=complementcover.log
else
echo "Not running with coverage"
exec /dendrite/dendrite-monolith-server \
exec /dendrite/dendrite \
--really-enable-open-registration \
--tls-cert server.crt \
--tls-key server.key \
--config dendrite.yaml \
-api=${API:-0}
--config dendrite.yaml
fi

View file

@ -22,7 +22,7 @@ func Test_AuthFallback(t *testing.T) {
for _, wantErr := range []bool{false, true} {
t.Run(fmt.Sprintf("useHCaptcha(%v) - recaptchaEnabled(%v) - wantErr(%v)", useHCaptcha, recaptchaEnabled, wantErr), func(t *testing.T) {
// Set the defaults for each test
base.Cfg.ClientAPI.Defaults(config.DefaultOpts{Generate: true, Monolithic: true})
base.Cfg.ClientAPI.Defaults(config.DefaultOpts{Generate: true, SingleDatabase: true})
base.Cfg.ClientAPI.RecaptchaEnabled = recaptchaEnabled
base.Cfg.ClientAPI.RecaptchaPublicKey = "pub"
base.Cfg.ClientAPI.RecaptchaPrivateKey = "priv"
@ -33,7 +33,7 @@ func Test_AuthFallback(t *testing.T) {
base.Cfg.ClientAPI.RecaptchaSitekeyClass = "h-captcha"
}
cfgErrs := &config.ConfigErrors{}
base.Cfg.ClientAPI.Verify(cfgErrs, true)
base.Cfg.ClientAPI.Verify(cfgErrs)
if len(*cfgErrs) > 0 {
t.Fatalf("(hCaptcha=%v) unexpected config errors: %s", useHCaptcha, cfgErrs.Error())
}

View file

@ -18,7 +18,6 @@ import (
"net/http"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal/httputil"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/util"
@ -45,15 +44,6 @@ func LeaveRoomByID(
JSON: jsonerror.LeaveServerNoticeError(),
}
}
switch e := err.(type) {
case httputil.InternalAPIError:
if e.Message == jsonerror.LeaveServerNoticeError().Error() {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.LeaveServerNoticeError(),
}
}
}
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.Unknown(err.Error()),

View file

@ -31,8 +31,6 @@ import (
"time"
"github.com/matrix-org/dendrite/internal"
internalHTTPUtil "github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/tidwall/gjson"
"github.com/matrix-org/dendrite/internal/eventutil"
@ -861,16 +859,6 @@ func completeRegistration(
JSON: jsonerror.UserInUse("Desired user ID is already taken."),
}
}
switch e := err.(type) {
case internalHTTPUtil.InternalAPIError:
conflictErr := &userapi.ErrorConflict{Message: sqlutil.ErrUserExists.Error()}
if e.Message == conflictErr.Error() {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.UserInUse("Desired user ID is already taken."),
}
}
}
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: jsonerror.Unknown("failed to create account: " + err.Error()),

View file

@ -202,7 +202,7 @@ func TestValidationOfApplicationServices(t *testing.T) {
fakeConfig := &config.Dendrite{}
fakeConfig.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
fakeConfig.Global.ServerName = "localhost"
fakeConfig.ClientAPI.Derived.ApplicationServices = []config.ApplicationService{fakeApplicationService}

View file

@ -81,7 +81,7 @@ func GenerateDefaultConfig(sk ed25519.PrivateKey, storageDir string, cacheDir st
cfg := config.Dendrite{}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
cfg.Global.PrivateKey = sk
cfg.Global.JetStream.StoragePath = config.Path(fmt.Sprintf("%s/", filepath.Join(cacheDir, dbPrefix)))
@ -121,9 +121,9 @@ func (p *P2PMonolith) SetupPinecone(sk ed25519.PrivateKey) {
func (p *P2PMonolith) SetupDendrite(cfg *config.Dendrite, port int, enableRelaying bool, enableMetrics bool, enableWebsockets bool) {
if enableMetrics {
p.BaseDendrite = base.NewBaseDendrite(cfg, "Monolith")
p.BaseDendrite = base.NewBaseDendrite(cfg)
} else {
p.BaseDendrite = base.NewBaseDendrite(cfg, "Monolith", base.DisableMetrics)
p.BaseDendrite = base.NewBaseDendrite(cfg, base.DisableMetrics)
}
p.port = port
p.BaseDendrite.ConfigureAdminEndpoints()
@ -236,7 +236,6 @@ func (p *P2PMonolith) Addr() string {
func (p *P2PMonolith) setupHttpServers(userProvider *users.PineconeUserProvider, enableWebsockets bool) {
p.httpMux = mux.NewRouter().SkipClean(true).UseEncodedPath()
p.httpMux.PathPrefix(httputil.InternalPathPrefix).Handler(p.BaseDendrite.InternalAPIMux)
p.httpMux.PathPrefix(httputil.PublicClientPathPrefix).Handler(p.BaseDendrite.PublicClientAPIMux)
p.httpMux.PathPrefix(httputil.PublicMediaPathPrefix).Handler(p.BaseDendrite.PublicMediaAPIMux)
p.httpMux.PathPrefix(httputil.DendriteAdminPathPrefix).Handler(p.BaseDendrite.DendriteAdminMux)

View file

@ -118,7 +118,7 @@ func main() {
} else {
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
cfg.Global.PrivateKey = sk
cfg.Global.JetStream.StoragePath = config.Path(filepath.Join(*instanceDir, *instanceName))
@ -143,7 +143,7 @@ func main() {
cfg.Global.ServerName = gomatrixserverlib.ServerName(hex.EncodeToString(pk))
cfg.Global.KeyID = gomatrixserverlib.KeyID(signing.KeyID)
base := base.NewBaseDendrite(cfg, "Monolith")
base := base.NewBaseDendrite(cfg)
base.ConfigureAdminEndpoints()
defer base.Close() // nolint: errcheck
@ -157,13 +157,11 @@ func main() {
serverKeyAPI := &signing.YggdrasilKeys{}
keyRing := serverKeyAPI.KeyRing()
rsComponent := roomserver.NewInternalAPI(
rsAPI := roomserver.NewInternalAPI(
base,
)
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, federation, rsComponent)
rsAPI := rsComponent
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, federation, rsAPI)
userAPI := userapi.NewInternalAPI(base, &cfg.UserAPI, nil, keyAPI, rsAPI, base.PushGatewayHTTPClient())
keyAPI.SetUserAPI(userAPI)
@ -174,7 +172,7 @@ func main() {
base, federation, rsAPI, base.Caches, keyRing, true,
)
rsComponent.SetFederationAPI(fsAPI, keyRing)
rsAPI.SetFederationAPI(fsAPI, keyRing)
monolith := setup.Monolith{
Config: base.Cfg,
@ -197,7 +195,6 @@ func main() {
}
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
httpRouter.PathPrefix(httputil.InternalPathPrefix).Handler(base.InternalAPIMux)
httpRouter.PathPrefix(httputil.PublicClientPathPrefix).Handler(base.PublicClientAPIMux)
httpRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(base.PublicMediaAPIMux)
httpRouter.PathPrefix(httputil.DendriteAdminPathPrefix).Handler(base.DendriteAdminMux)

View file

@ -1,178 +0,0 @@
// Copyright 2017 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"flag"
"os"
"github.com/sirupsen/logrus"
"github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/federationapi"
"github.com/matrix-org/dendrite/keyserver"
"github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/setup/mscs"
"github.com/matrix-org/dendrite/userapi"
uapi "github.com/matrix-org/dendrite/userapi/api"
)
var (
httpBindAddr = flag.String("http-bind-address", ":8008", "The HTTP listening port for the server")
httpsBindAddr = flag.String("https-bind-address", ":8448", "The HTTPS listening port for the server")
apiBindAddr = flag.String("api-bind-address", "localhost:18008", "The HTTP listening port for the internal HTTP APIs (if -api is enabled)")
certFile = flag.String("tls-cert", "", "The PEM formatted X509 certificate to use for TLS")
keyFile = flag.String("tls-key", "", "The PEM private key to use for TLS")
enableHTTPAPIs = flag.Bool("api", false, "Use HTTP APIs instead of short-circuiting (warning: exposes API endpoints!)")
traceInternal = os.Getenv("DENDRITE_TRACE_INTERNAL") == "1"
)
func main() {
cfg := setup.ParseFlags(true)
httpAddr := config.HTTPAddress("http://" + *httpBindAddr)
httpsAddr := config.HTTPAddress("https://" + *httpsBindAddr)
httpAPIAddr := httpAddr
options := []basepkg.BaseDendriteOptions{}
if *enableHTTPAPIs {
logrus.Warnf("DANGER! The -api option is enabled, exposing internal APIs on %q!", *apiBindAddr)
httpAPIAddr = config.HTTPAddress("http://" + *apiBindAddr)
// If the HTTP APIs are enabled then we need to update the Listen
// statements in the configuration so that we know where to find
// the API endpoints. They'll listen on the same port as the monolith
// itself.
cfg.AppServiceAPI.InternalAPI.Connect = httpAPIAddr
cfg.ClientAPI.InternalAPI.Connect = httpAPIAddr
cfg.FederationAPI.InternalAPI.Connect = httpAPIAddr
cfg.KeyServer.InternalAPI.Connect = httpAPIAddr
cfg.MediaAPI.InternalAPI.Connect = httpAPIAddr
cfg.RoomServer.InternalAPI.Connect = httpAPIAddr
cfg.SyncAPI.InternalAPI.Connect = httpAPIAddr
cfg.UserAPI.InternalAPI.Connect = httpAPIAddr
options = append(options, basepkg.UseHTTPAPIs)
}
base := basepkg.NewBaseDendrite(cfg, "Monolith", options...)
defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient()
rsImpl := roomserver.NewInternalAPI(base)
// call functions directly on the impl unless running in HTTP mode
rsAPI := rsImpl
if base.UseHTTPAPIs {
roomserver.AddInternalRoutes(base.InternalAPIMux, rsImpl, base.EnableMetrics)
rsAPI = base.RoomserverHTTPClient()
}
if traceInternal {
rsAPI = &api.RoomserverInternalAPITrace{
Impl: rsAPI,
}
}
fsAPI := federationapi.NewInternalAPI(
base, federation, rsAPI, base.Caches, nil, false,
)
fsImplAPI := fsAPI
if base.UseHTTPAPIs {
federationapi.AddInternalRoutes(base.InternalAPIMux, fsAPI, base.EnableMetrics)
fsAPI = base.FederationAPIHTTPClient()
}
keyRing := fsAPI.KeyRing()
keyImpl := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI, rsAPI)
keyAPI := keyImpl
if base.UseHTTPAPIs {
keyserver.AddInternalRoutes(base.InternalAPIMux, keyAPI, base.EnableMetrics)
keyAPI = base.KeyServerHTTPClient()
}
pgClient := base.PushGatewayHTTPClient()
userImpl := userapi.NewInternalAPI(base, &cfg.UserAPI, cfg.Derived.ApplicationServices, keyAPI, rsAPI, pgClient)
userAPI := userImpl
if base.UseHTTPAPIs {
userapi.AddInternalRoutes(base.InternalAPIMux, userAPI, base.EnableMetrics)
userAPI = base.UserAPIClient()
}
if traceInternal {
userAPI = &uapi.UserInternalAPITrace{
Impl: userAPI,
}
}
// TODO: This should use userAPI, not userImpl, but the appservice setup races with
// the listeners and panics at startup if it tries to create appservice accounts
// before the listeners are up.
asAPI := appservice.NewInternalAPI(base, userImpl, rsAPI)
if base.UseHTTPAPIs {
appservice.AddInternalRoutes(base.InternalAPIMux, asAPI, base.EnableMetrics)
asAPI = base.AppserviceHTTPClient()
}
// The underlying roomserver implementation needs to be able to call the fedsender.
// This is different to rsAPI which can be the http client which doesn't need this
// dependency. Other components also need updating after their dependencies are up.
rsImpl.SetFederationAPI(fsAPI, keyRing)
rsImpl.SetAppserviceAPI(asAPI)
rsImpl.SetUserAPI(userAPI)
keyImpl.SetUserAPI(userAPI)
monolith := setup.Monolith{
Config: base.Cfg,
Client: base.CreateClient(),
FedClient: federation,
KeyRing: keyRing,
AppserviceAPI: asAPI,
// always use the concrete impl here even in -http mode because adding public routes
// must be done on the concrete impl not an HTTP client else fedapi will call itself
FederationAPI: fsImplAPI,
RoomserverAPI: rsAPI,
UserAPI: userAPI,
KeyAPI: keyAPI,
}
monolith.AddAllPublicRoutes(base)
if len(base.Cfg.MSCs.MSCs) > 0 {
if err := mscs.Enable(base, &monolith); err != nil {
logrus.WithError(err).Fatalf("Failed to enable MSCs")
}
}
// Expose the matrix APIs directly rather than putting them under a /api path.
go func() {
base.SetupAndServeHTTP(
httpAPIAddr, // internal API
httpAddr, // external API
nil, nil, // TLS settings
)
}()
// Handle HTTPS if certificate and key are provided
if *certFile != "" && *keyFile != "" {
go func() {
base.SetupAndServeHTTP(
basepkg.NoListener, // internal API
httpsAddr, // external API
certFile, keyFile, // TLS settings
)
}()
}
// We want to block forever to let the HTTP and HTTPS handler serve the APIs
base.WaitForShutdown()
}

View file

@ -1,77 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"flag"
"os"
"strings"
"github.com/matrix-org/dendrite/cmd/dendrite-polylith-multi/personalities"
"github.com/matrix-org/dendrite/setup"
"github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
"github.com/sirupsen/logrus"
)
type entrypoint func(base *base.BaseDendrite, cfg *config.Dendrite)
func main() {
cfg := setup.ParseFlags(false)
component := ""
if flag.NFlag() > 0 {
component = flag.Arg(0) // ./dendrite-polylith-multi --config=... clientapi
} else if len(os.Args) > 1 {
component = os.Args[1] // ./dendrite-polylith-multi clientapi
}
components := map[string]entrypoint{
"appservice": personalities.Appservice,
"clientapi": personalities.ClientAPI,
"federationapi": personalities.FederationAPI,
"keyserver": personalities.KeyServer,
"mediaapi": personalities.MediaAPI,
"roomserver": personalities.RoomServer,
"syncapi": personalities.SyncAPI,
"userapi": personalities.UserAPI,
}
start, ok := components[component]
if !ok {
if component == "" {
logrus.Errorf("No component specified")
logrus.Info("The first argument on the command line must be the name of the component to run")
} else {
logrus.Errorf("Unknown component %q specified", component)
}
var list []string
for c := range components {
list = append(list, c)
}
logrus.Infof("Valid components: %s", strings.Join(list, ", "))
os.Exit(1)
}
logrus.Infof("Starting %q component", component)
base := base.NewBaseDendrite(cfg, component, base.PolylithMode) // TODO
defer base.Close() // nolint: errcheck
go start(base, cfg)
base.WaitForShutdown()
}

View file

@ -1,36 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
import (
"github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/setup/base"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
)
func Appservice(base *base.BaseDendrite, cfg *config.Dendrite) {
userAPI := base.UserAPIClient()
rsAPI := base.RoomserverHTTPClient()
intAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
appservice.AddInternalRoutes(base.InternalAPIMux, intAPI, base.EnableMetrics)
base.SetupAndServeHTTP(
base.Cfg.AppServiceAPI.InternalAPI.Listen, // internal listener
basepkg.NoListener, // external listener
nil, nil,
)
}

View file

@ -1,44 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
import (
"github.com/matrix-org/dendrite/clientapi"
"github.com/matrix-org/dendrite/internal/transactions"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
)
func ClientAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
federation := base.CreateFederationClient()
asQuery := base.AppserviceHTTPClient()
rsAPI := base.RoomserverHTTPClient()
fsAPI := base.FederationAPIHTTPClient()
userAPI := base.UserAPIClient()
keyAPI := base.KeyServerHTTPClient()
clientapi.AddPublicRoutes(
base, federation, rsAPI, asQuery,
transactions.New(), fsAPI, userAPI, userAPI,
keyAPI, nil,
)
base.SetupAndServeHTTP(
base.Cfg.ClientAPI.InternalAPI.Listen,
base.Cfg.ClientAPI.ExternalAPI.Listen,
nil, nil,
)
}

View file

@ -1,44 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
import (
"github.com/matrix-org/dendrite/federationapi"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
)
func FederationAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
userAPI := base.UserAPIClient()
federation := base.CreateFederationClient()
rsAPI := base.RoomserverHTTPClient()
keyAPI := base.KeyServerHTTPClient()
fsAPI := federationapi.NewInternalAPI(base, federation, rsAPI, base.Caches, nil, true)
keyRing := fsAPI.KeyRing()
federationapi.AddPublicRoutes(
base,
userAPI, federation, keyRing,
rsAPI, fsAPI, keyAPI, nil,
)
federationapi.AddInternalRoutes(base.InternalAPIMux, fsAPI, base.EnableMetrics)
base.SetupAndServeHTTP(
base.Cfg.FederationAPI.InternalAPI.Listen,
base.Cfg.FederationAPI.ExternalAPI.Listen,
nil, nil,
)
}

View file

@ -1,36 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
import (
"github.com/matrix-org/dendrite/keyserver"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
)
func KeyServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
fsAPI := base.FederationAPIHTTPClient()
rsAPI := base.RoomserverHTTPClient()
intAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI, rsAPI)
intAPI.SetUserAPI(base.UserAPIClient())
keyserver.AddInternalRoutes(base.InternalAPIMux, intAPI, base.EnableMetrics)
base.SetupAndServeHTTP(
base.Cfg.KeyServer.InternalAPI.Listen, // internal listener
basepkg.NoListener, // external listener
nil, nil,
)
}

View file

@ -1,36 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
import (
"github.com/matrix-org/dendrite/mediaapi"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
)
func MediaAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
userAPI := base.UserAPIClient()
client := base.CreateClient()
mediaapi.AddPublicRoutes(
base, userAPI, client,
)
base.SetupAndServeHTTP(
base.Cfg.MediaAPI.InternalAPI.Listen,
base.Cfg.MediaAPI.ExternalAPI.Listen,
nil, nil,
)
}

View file

@ -1,36 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
import (
"github.com/matrix-org/dendrite/roomserver"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
)
func RoomServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
asAPI := base.AppserviceHTTPClient()
fsAPI := base.FederationAPIHTTPClient()
rsAPI := roomserver.NewInternalAPI(base)
rsAPI.SetFederationAPI(fsAPI, fsAPI.KeyRing())
rsAPI.SetAppserviceAPI(asAPI)
roomserver.AddInternalRoutes(base.InternalAPIMux, rsAPI, base.EnableMetrics)
base.SetupAndServeHTTP(
base.Cfg.RoomServer.InternalAPI.Listen, // internal listener
basepkg.NoListener, // external listener
nil, nil,
)
}

View file

@ -1,39 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
import (
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/syncapi"
)
func SyncAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
userAPI := base.UserAPIClient()
rsAPI := base.RoomserverHTTPClient()
syncapi.AddPublicRoutes(
base,
userAPI, rsAPI,
base.KeyServerHTTPClient(),
)
base.SetupAndServeHTTP(
base.Cfg.SyncAPI.InternalAPI.Listen,
base.Cfg.SyncAPI.ExternalAPI.Listen,
nil, nil,
)
}

View file

@ -1,37 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package personalities
import (
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/userapi"
)
func UserAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
userAPI := userapi.NewInternalAPI(
base, &cfg.UserAPI, cfg.Derived.ApplicationServices,
base.KeyServerHTTPClient(), base.RoomserverHTTPClient(),
base.PushGatewayHTTPClient(),
)
userapi.AddInternalRoutes(base.InternalAPIMux, userAPI, base.EnableMetrics)
base.SetupAndServeHTTP(
base.Cfg.UserAPI.InternalAPI.Listen, // internal listener
basepkg.NoListener, // external listener
nil, nil,
)
}

View file

@ -45,6 +45,10 @@ var (
const HEAD = "HEAD"
// The binary was renamed after v0.11.1, so everything after that should use the new name
var binaryChangeVersion, _ = semver.NewVersion("v0.11.1")
var latest, _ = semver.NewVersion("v6.6.6") // Dummy version, used as "HEAD"
// Embed the Dockerfile to use when building dendrite versions.
// We cannot use the dockerfile associated with the repo with each version sadly due to changes in
// Docker versions. Specifically, earlier Dendrite versions are incompatible with newer Docker clients
@ -54,12 +58,13 @@ const HEAD = "HEAD"
const DockerfilePostgreSQL = `FROM golang:1.18-stretch as build
RUN apt-get update && apt-get install -y postgresql
WORKDIR /build
ARG BINARY
# Copy the build context to the repo as this is the right dendrite code. This is different to the
# Complement Dockerfile which wgets a branch.
COPY . .
RUN go build ./cmd/dendrite-monolith-server
RUN go build ./cmd/${BINARY}
RUN go build ./cmd/generate-keys
RUN go build ./cmd/generate-config
RUN go build ./cmd/create-account
@ -88,22 +93,24 @@ done \n\
\n\
sed -i "s/server_name: localhost/server_name: ${SERVER_NAME}/g" dendrite.yaml \n\
PARAMS="--tls-cert server.crt --tls-key server.key --config dendrite.yaml" \n\
./dendrite-monolith-server --really-enable-open-registration ${PARAMS} || ./dendrite-monolith-server ${PARAMS} \n\
./${BINARY} --really-enable-open-registration ${PARAMS} || ./${BINARY} ${PARAMS} \n\
' > run_dendrite.sh && chmod +x run_dendrite.sh
ENV SERVER_NAME=localhost
ENV BINARY=dendrite
EXPOSE 8008 8448
CMD /build/run_dendrite.sh`
const DockerfileSQLite = `FROM golang:1.18-stretch as build
RUN apt-get update && apt-get install -y postgresql
WORKDIR /build
ARG BINARY
# Copy the build context to the repo as this is the right dendrite code. This is different to the
# Complement Dockerfile which wgets a branch.
COPY . .
RUN go build ./cmd/dendrite-monolith-server
RUN go build ./cmd/${BINARY}
RUN go build ./cmd/generate-keys
RUN go build ./cmd/generate-config
RUN go build ./cmd/create-account
@ -118,10 +125,11 @@ RUN sed -i "s%connection_string:.file:%connection_string: file:\/var\/lib\/postg
RUN echo '\
sed -i "s/server_name: localhost/server_name: ${SERVER_NAME}/g" dendrite.yaml \n\
PARAMS="--tls-cert server.crt --tls-key server.key --config dendrite.yaml" \n\
./dendrite-monolith-server --really-enable-open-registration ${PARAMS} || ./dendrite-monolith-server ${PARAMS} \n\
./${BINARY} --really-enable-open-registration ${PARAMS} || ./${BINARY} ${PARAMS} \n\
' > run_dendrite.sh && chmod +x run_dendrite.sh
ENV SERVER_NAME=localhost
ENV BINARY=dendrite
EXPOSE 8008 8448
CMD /build/run_dendrite.sh `
@ -182,7 +190,7 @@ func downloadArchive(cli *http.Client, tmpDir, archiveURL string, dockerfile []b
}
// buildDendrite builds Dendrite on the branchOrTagName given. Returns the image ID or an error
func buildDendrite(httpClient *http.Client, dockerClient *client.Client, tmpDir, branchOrTagName string) (string, error) {
func buildDendrite(httpClient *http.Client, dockerClient *client.Client, tmpDir string, branchOrTagName, binary string) (string, error) {
var tarball *bytes.Buffer
var err error
// If a custom HEAD location is given, use that, else pull from github. Mostly useful for CI
@ -216,6 +224,9 @@ func buildDendrite(httpClient *http.Client, dockerClient *client.Client, tmpDir,
log.Printf("%s: Building version %s\n", branchOrTagName, branchOrTagName)
res, err := dockerClient.ImageBuild(context.Background(), tarball, types.ImageBuildOptions{
Tags: []string{"dendrite-upgrade"},
BuildArgs: map[string]*string{
"BINARY": &binary,
},
})
if err != nil {
return "", fmt.Errorf("failed to start building image: %s", err)
@ -272,7 +283,7 @@ func getAndSortVersionsFromGithub(httpClient *http.Client) (semVers []*semver.Ve
return semVers, nil
}
func calculateVersions(cli *http.Client, from, to string, direct bool) []string {
func calculateVersions(cli *http.Client, from, to string, direct bool) []*semver.Version {
semvers, err := getAndSortVersionsFromGithub(cli)
if err != nil {
log.Fatalf("failed to collect semvers from github: %s", err)
@ -320,28 +331,25 @@ func calculateVersions(cli *http.Client, from, to string, direct bool) []string
}
semvers = semvers[:i+1]
}
var versions []string
for _, sv := range semvers {
versions = append(versions, sv.Original())
}
if to == HEAD {
versions = append(versions, HEAD)
semvers = append(semvers, latest)
}
if direct {
versions = []string{versions[0], versions[len(versions)-1]}
semvers = []*semver.Version{semvers[0], semvers[len(semvers)-1]}
}
return versions
return semvers
}
func buildDendriteImages(httpClient *http.Client, dockerClient *client.Client, baseTempDir string, concurrency int, branchOrTagNames []string) map[string]string {
func buildDendriteImages(httpClient *http.Client, dockerClient *client.Client, baseTempDir string, concurrency int, versions []*semver.Version) map[string]string {
// concurrently build all versions, this can be done in any order. The mutex protects the map
branchToImageID := make(map[string]string)
var mu sync.Mutex
var wg sync.WaitGroup
wg.Add(concurrency)
ch := make(chan string, len(branchOrTagNames))
for _, branchName := range branchOrTagNames {
ch := make(chan *semver.Version, len(versions))
for _, branchName := range versions {
ch <- branchName
}
close(ch)
@ -349,11 +357,13 @@ func buildDendriteImages(httpClient *http.Client, dockerClient *client.Client, b
for i := 0; i < concurrency; i++ {
go func() {
defer wg.Done()
for branchName := range ch {
for version := range ch {
branchName, binary := versionToBranchAndBinary(version)
log.Printf("Building version %s with binary %s", branchName, binary)
tmpDir := baseTempDir + alphaNumerics.ReplaceAllString(branchName, "")
imgID, err := buildDendrite(httpClient, dockerClient, tmpDir, branchName)
imgID, err := buildDendrite(httpClient, dockerClient, tmpDir, branchName, binary)
if err != nil {
log.Fatalf("%s: failed to build dendrite image: %s", branchName, err)
log.Fatalf("%s: failed to build dendrite image: %s", version, err)
}
mu.Lock()
branchToImageID[branchName] = imgID
@ -365,13 +375,14 @@ func buildDendriteImages(httpClient *http.Client, dockerClient *client.Client, b
return branchToImageID
}
func runImage(dockerClient *client.Client, volumeName, version, imageID string) (csAPIURL, containerID string, err error) {
log.Printf("%s: running image %s\n", version, imageID)
func runImage(dockerClient *client.Client, volumeName string, branchNameToImageID map[string]string, version *semver.Version) (csAPIURL, containerID string, err error) {
branchName, binary := versionToBranchAndBinary(version)
imageID := branchNameToImageID[branchName]
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
defer cancel()
body, err := dockerClient.ContainerCreate(ctx, &container.Config{
Image: imageID,
Env: []string{"SERVER_NAME=hs1"},
Env: []string{"SERVER_NAME=hs1", fmt.Sprintf("BINARY=%s", binary)},
Labels: map[string]string{
dendriteUpgradeTestLabel: "yes",
},
@ -384,7 +395,7 @@ func runImage(dockerClient *client.Client, volumeName, version, imageID string)
Target: "/var/lib/postgresql/9.6/main",
},
},
}, nil, nil, "dendrite_upgrade_test_"+version)
}, nil, nil, "dendrite_upgrade_test_"+branchName)
if err != nil {
return "", "", fmt.Errorf("failed to ContainerCreate: %s", err)
}
@ -451,8 +462,8 @@ func destroyContainer(dockerClient *client.Client, containerID string) {
}
}
func loadAndRunTests(dockerClient *client.Client, volumeName, v string, branchToImageID map[string]string) error {
csAPIURL, containerID, err := runImage(dockerClient, volumeName, v, branchToImageID[v])
func loadAndRunTests(dockerClient *client.Client, volumeName string, v *semver.Version, branchToImageID map[string]string) error {
csAPIURL, containerID, err := runImage(dockerClient, volumeName, branchToImageID, v)
if err != nil {
return fmt.Errorf("failed to run container for branch %v: %v", v, err)
}
@ -470,9 +481,10 @@ func loadAndRunTests(dockerClient *client.Client, volumeName, v string, branchTo
}
// test that create-account is working
func testCreateAccount(dockerClient *client.Client, v string, containerID string) error {
createUser := strings.ToLower("createaccountuser-" + v)
log.Printf("%s: Creating account %s with create-account\n", v, createUser)
func testCreateAccount(dockerClient *client.Client, version *semver.Version, containerID string) error {
branchName, _ := versionToBranchAndBinary(version)
createUser := strings.ToLower("createaccountuser-" + branchName)
log.Printf("%s: Creating account %s with create-account\n", branchName, createUser)
respID, err := dockerClient.ContainerExecCreate(context.Background(), containerID, types.ExecConfig{
AttachStderr: true,
@ -504,9 +516,21 @@ func testCreateAccount(dockerClient *client.Client, v string, containerID string
return nil
}
func verifyTests(dockerClient *client.Client, volumeName string, versions []string, branchToImageID map[string]string) error {
func versionToBranchAndBinary(version *semver.Version) (branchName, binary string) {
binary = "dendrite-monolith-server"
branchName = version.Original()
if version.GreaterThan(binaryChangeVersion) {
binary = "dendrite"
if version.Equal(latest) {
branchName = HEAD
}
}
return
}
func verifyTests(dockerClient *client.Client, volumeName string, versions []*semver.Version, branchToImageID map[string]string) error {
lastVer := versions[len(versions)-1]
csAPIURL, containerID, err := runImage(dockerClient, volumeName, lastVer, branchToImageID[lastVer])
csAPIURL, containerID, err := runImage(dockerClient, volumeName, branchToImageID, lastVer)
if err != nil {
return fmt.Errorf("failed to run container for branch %v: %v", lastVer, err)
}

View file

@ -6,6 +6,7 @@ import (
"strings"
"time"
"github.com/Masterminds/semver/v3"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/gomatrixserverlib"
)
@ -22,7 +23,8 @@ type user struct {
// - register alice and bob with branch name muxed into the localpart
// - create a DM room for the 2 users and exchange messages
// - create/join a public #global room and exchange messages
func runTests(baseURL, branchName string) error {
func runTests(baseURL string, v *semver.Version) error {
branchName, _ := versionToBranchAndBinary(v)
// register 2 users
users := []user{
{
@ -164,15 +166,16 @@ func runTests(baseURL, branchName string) error {
}
// verifyTestsRan checks that the HS has the right rooms/messages
func verifyTestsRan(baseURL string, branchNames []string) error {
func verifyTestsRan(baseURL string, versions []*semver.Version) error {
log.Println("Verifying tests....")
// check we can login as all users
var resp *gomatrix.RespLogin
for _, branchName := range branchNames {
for _, version := range versions {
client, err := gomatrix.NewClient(baseURL, "", "")
if err != nil {
return err
}
branchName, _ := versionToBranchAndBinary(version)
userLocalparts := []string{
"alice" + branchName,
"bob" + branchName,
@ -224,7 +227,7 @@ func verifyTestsRan(baseURL string, branchNames []string) error {
msgCount += 1
}
}
wantMsgCount := len(branchNames) * 4
wantMsgCount := len(versions) * 4
if msgCount != wantMsgCount {
return fmt.Errorf("got %d messages in global room, want %d", msgCount, wantMsgCount)
}

109
cmd/dendrite/main.go Normal file
View file

@ -0,0 +1,109 @@
// Copyright 2017 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"flag"
"github.com/sirupsen/logrus"
"github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/federationapi"
"github.com/matrix-org/dendrite/keyserver"
"github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/setup"
basepkg "github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/setup/mscs"
"github.com/matrix-org/dendrite/userapi"
)
var (
httpBindAddr = flag.String("http-bind-address", ":8008", "The HTTP listening port for the server")
httpsBindAddr = flag.String("https-bind-address", ":8448", "The HTTPS listening port for the server")
certFile = flag.String("tls-cert", "", "The PEM formatted X509 certificate to use for TLS")
keyFile = flag.String("tls-key", "", "The PEM private key to use for TLS")
)
func main() {
cfg := setup.ParseFlags(true)
httpAddr := config.HTTPAddress("http://" + *httpBindAddr)
httpsAddr := config.HTTPAddress("https://" + *httpsBindAddr)
options := []basepkg.BaseDendriteOptions{}
base := basepkg.NewBaseDendrite(cfg, options...)
defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient()
rsAPI := roomserver.NewInternalAPI(base)
fsAPI := federationapi.NewInternalAPI(
base, federation, rsAPI, base.Caches, nil, false,
)
keyRing := fsAPI.KeyRing()
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI, rsAPI)
pgClient := base.PushGatewayHTTPClient()
userAPI := userapi.NewInternalAPI(base, &cfg.UserAPI, cfg.Derived.ApplicationServices, keyAPI, rsAPI, pgClient)
asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
// The underlying roomserver implementation needs to be able to call the fedsender.
// This is different to rsAPI which can be the http client which doesn't need this
// dependency. Other components also need updating after their dependencies are up.
rsAPI.SetFederationAPI(fsAPI, keyRing)
rsAPI.SetAppserviceAPI(asAPI)
rsAPI.SetUserAPI(userAPI)
keyAPI.SetUserAPI(userAPI)
monolith := setup.Monolith{
Config: base.Cfg,
Client: base.CreateClient(),
FedClient: federation,
KeyRing: keyRing,
AppserviceAPI: asAPI,
// always use the concrete impl here even in -http mode because adding public routes
// must be done on the concrete impl not an HTTP client else fedapi will call itself
FederationAPI: fsAPI,
RoomserverAPI: rsAPI,
UserAPI: userAPI,
KeyAPI: keyAPI,
}
monolith.AddAllPublicRoutes(base)
if len(base.Cfg.MSCs.MSCs) > 0 {
if err := mscs.Enable(base, &monolith); err != nil {
logrus.WithError(err).Fatalf("Failed to enable MSCs")
}
}
// Expose the matrix APIs directly rather than putting them under a /api path.
go func() {
base.SetupAndServeHTTP(httpAddr, nil, nil)
}()
// Handle HTTPS if certificate and key are provided
if *certFile != "" && *keyFile != "" {
go func() {
base.SetupAndServeHTTP(httpsAddr, certFile, keyFile)
}()
}
// We want to block forever to let the HTTP and HTTPS handler serve the APIs
base.WaitForShutdown()
}

View file

@ -18,7 +18,6 @@ func main() {
dbURI := flag.String("db", "", "The DB URI to use for all components (PostgreSQL only)")
dirPath := flag.String("dir", "./", "The folder to use for paths (like SQLite databases, media storage)")
normalise := flag.String("normalise", "", "Normalise an existing configuration file by adding new/missing options and defaults")
polylith := flag.Bool("polylith", false, "Generate a config that makes sense for polylith deployments")
flag.Parse()
var cfg *config.Dendrite
@ -28,13 +27,13 @@ func main() {
}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: !*polylith,
SingleDatabase: true,
})
if *serverName != "" {
cfg.Global.ServerName = gomatrixserverlib.ServerName(*serverName)
}
uri := config.DataSource(*dbURI)
if *polylith || uri.IsSQLite() || uri == "" {
if uri.IsSQLite() || uri == "" {
for name, db := range map[string]*config.DatabaseOptions{
"federationapi": &cfg.FederationAPI.Database,
"keyserver": &cfg.KeyServer.Database,
@ -43,6 +42,7 @@ func main() {
"roomserver": &cfg.RoomServer.Database,
"syncapi": &cfg.SyncAPI.Database,
"userapi": &cfg.UserAPI.AccountDatabase,
"relayapi": &cfg.RelayAPI.Database,
} {
if uri == "" {
path := filepath.Join(*dirPath, fmt.Sprintf("dendrite_%s.db", name))
@ -96,7 +96,7 @@ func main() {
}
} else {
var err error
if cfg, err = config.Load(*normalise, !*polylith); err != nil {
if cfg, err = config.Load(*normalise); err != nil {
panic(err)
}
}

View file

@ -40,7 +40,7 @@ func main() {
Level: "error",
})
cfg.ClientAPI.RegistrationDisabled = true
base := base.NewBaseDendrite(cfg, "ResolveState", base.DisableMetrics)
base := base.NewBaseDendrite(cfg, base.DisableMetrics)
args := flag.Args()
fmt.Println("Room version", *roomVersion)

View file

@ -1,417 +0,0 @@
# This is the Dendrite configuration file.
#
# The configuration is split up into sections - each Dendrite component has a
# configuration section, in addition to the "global" section which applies to
# all components.
# The version of the configuration file.
version: 2
# Global Matrix configuration. This configuration applies to all components.
global:
# The domain name of this homeserver.
server_name: localhost
# The path to the signing private key file, used to sign requests and events.
# Note that this is NOT the same private key as used for TLS! To generate a
# signing key, use "./bin/generate-keys --private-key matrix_key.pem".
private_key: matrix_key.pem
# The paths and expiry timestamps (as a UNIX timestamp in millisecond precision)
# to old signing keys that were formerly in use on this domain name. These
# keys will not be used for federation request or event signing, but will be
# provided to any other homeserver that asks when trying to verify old events.
old_private_keys:
# If the old private key file is available:
# - private_key: old_matrix_key.pem
# expired_at: 1601024554498
# If only the public key (in base64 format) and key ID are known:
# - public_key: mn59Kxfdq9VziYHSBzI7+EDPDcBS2Xl7jeUdiiQcOnM=
# key_id: ed25519:mykeyid
# expired_at: 1601024554498
# How long a remote server can cache our server signing key before requesting it
# again. Increasing this number will reduce the number of requests made by other
# servers for our key but increases the period that a compromised key will be
# considered valid by other homeservers.
key_validity_period: 168h0m0s
# Configuration for in-memory caches. Caches can often improve performance by
# keeping frequently accessed items (like events, identifiers etc.) in memory
# rather than having to read them from the database.
cache:
# The estimated maximum size for the global cache in bytes, or in terabytes,
# gigabytes, megabytes or kilobytes when the appropriate 'tb', 'gb', 'mb' or
# 'kb' suffix is specified. Note that this is not a hard limit, nor is it a
# memory limit for the entire process. A cache that is too small may ultimately
# provide little or no benefit.
max_size_estimated: 1gb
# The maximum amount of time that a cache entry can live for in memory before
# it will be evicted and/or refreshed from the database. Lower values result in
# easier admission of new cache entries but may also increase database load in
# comparison to higher values, so adjust conservatively. Higher values may make
# it harder for new items to make it into the cache, e.g. if new rooms suddenly
# become popular.
max_age: 1h
# The server name to delegate server-server communications to, with optional port
# e.g. localhost:443
well_known_server_name: ""
# The server name to delegate client-server communications to, with optional port
# e.g. localhost:443
well_known_client_name: ""
# Lists of domains that the server will trust as identity servers to verify third
# party identifiers such as phone numbers and email addresses.
trusted_third_party_id_servers:
- matrix.org
- vector.im
# Disables federation. Dendrite will not be able to communicate with other servers
# in the Matrix federation and the federation API will not be exposed.
disable_federation: false
# Configures the handling of presence events. Inbound controls whether we receive
# presence events from other servers, outbound controls whether we send presence
# events for our local users to other servers.
presence:
enable_inbound: false
enable_outbound: false
# Configures phone-home statistics reporting. These statistics contain the server
# name, number of active users and some information on your deployment config.
# We use this information to understand how Dendrite is being used in the wild.
report_stats:
enabled: false
endpoint: https://matrix.org/report-usage-stats/push
# Server notices allows server admins to send messages to all users on the server.
server_notices:
enabled: false
# The local part, display name and avatar URL (as a mxc:// URL) for the user that
# will send the server notices. These are visible to all users on the deployment.
local_part: "_server"
display_name: "Server Alerts"
avatar_url: ""
# The room name to be used when sending server notices. This room name will
# appear in user clients.
room_name: "Server Alerts"
# Configuration for NATS JetStream
jetstream:
# A list of NATS Server addresses to connect to. If none are specified, an
# internal NATS server will be started automatically when running Dendrite in
# monolith mode. For polylith deployments, it is required to specify the address
# of at least one NATS Server node.
addresses:
- hostname:4222
# Disable the validation of TLS certificates of NATS. This is
# not recommended in production since it may allow NATS traffic
# to be sent to an insecure endpoint.
disable_tls_validation: false
# The prefix to use for stream names for this homeserver - really only useful
# if you are running more than one Dendrite server on the same NATS deployment.
topic_prefix: Dendrite
# Configuration for Prometheus metric collection.
metrics:
enabled: false
basic_auth:
username: metrics
password: metrics
# Optional DNS cache. The DNS cache may reduce the load on DNS servers if there
# is no local caching resolver available for use.
dns_cache:
enabled: false
cache_size: 256
cache_lifetime: "5m" # 5 minutes; https://pkg.go.dev/time@master#ParseDuration
# Configuration for the Appservice API.
app_service_api:
internal_api:
listen: http://[::]:7777 # The listen address for incoming API requests
connect: http://app_service_api:7777 # The connect address for other components to use
# Disable the validation of TLS certificates of appservices. This is
# not recommended in production since it may allow appservice traffic
# to be sent to an insecure endpoint.
disable_tls_validation: false
# Appservice configuration files to load into this homeserver.
config_files:
# - /path/to/appservice_registration.yaml
# Configuration for the Client API.
client_api:
internal_api:
listen: http://[::]:7771 # The listen address for incoming API requests
connect: http://client_api:7771 # The connect address for other components to use
external_api:
listen: http://[::]:8071
# Prevents new users from being able to register on this homeserver, except when
# using the registration shared secret below.
registration_disabled: true
# Prevents new guest accounts from being created. Guest registration is also
# disabled implicitly by setting 'registration_disabled' above.
guests_disabled: true
# If set, allows registration by anyone who knows the shared secret, regardless
# of whether registration is otherwise disabled.
registration_shared_secret: ""
# Whether to require reCAPTCHA for registration. If you have enabled registration
# then this is HIGHLY RECOMMENDED to reduce the risk of your homeserver being used
# for coordinated spam attacks.
enable_registration_captcha: false
# Settings for ReCAPTCHA.
recaptcha_public_key: ""
recaptcha_private_key: ""
recaptcha_bypass_secret: ""
# To use hcaptcha.com instead of ReCAPTCHA, set the following parameters, otherwise just keep them empty.
# recaptcha_siteverify_api: "https://hcaptcha.com/siteverify"
# recaptcha_api_js_url: "https://js.hcaptcha.com/1/api.js"
# recaptcha_form_field: "h-captcha-response"
# recaptcha_sitekey_class: "h-captcha"
# TURN server information that this homeserver should send to clients.
turn:
turn_user_lifetime: "5m"
turn_uris:
# - turn:turn.server.org?transport=udp
# - turn:turn.server.org?transport=tcp
turn_shared_secret: ""
# If your TURN server requires static credentials, then you will need to enter
# them here instead of supplying a shared secret. Note that these credentials
# will be visible to clients!
# turn_username: ""
# turn_password: ""
# Settings for rate-limited endpoints. Rate limiting kicks in after the threshold
# number of "slots" have been taken by requests from a specific host. Each "slot"
# will be released after the cooloff time in milliseconds. Server administrators
# and appservice users are exempt from rate limiting by default.
rate_limiting:
enabled: true
threshold: 20
cooloff_ms: 500
exempt_user_ids:
# - "@user:domain.com"
# Configuration for the Federation API.
federation_api:
internal_api:
listen: http://[::]:7772 # The listen address for incoming API requests
connect: http://federation_api:7772 # The connect address for other components to use
external_api:
listen: http://[::]:8072
database:
connection_string: postgresql://username:password@hostname/dendrite_federationapi?sslmode=disable
max_open_conns: 10
max_idle_conns: 2
conn_max_lifetime: -1
# How many times we will try to resend a failed transaction to a specific server. The
# backoff is 2**x seconds, so 1 = 2 seconds, 2 = 4 seconds, 3 = 8 seconds etc. Once
# the max retries are exceeded, Dendrite will no longer try to send transactions to
# that server until it comes back to life and connects to us again.
send_max_retries: 16
# Disable the validation of TLS certificates of remote federated homeservers. Do not
# enable this option in production as it presents a security risk!
disable_tls_validation: false
# Disable HTTP keepalives, which also prevents connection reuse. Dendrite will typically
# keep HTTP connections open to remote hosts for 5 minutes as they can be reused much
# more quickly than opening new connections each time. Disabling keepalives will close
# HTTP connections immediately after a successful request but may result in more CPU and
# memory being used on TLS handshakes for each new connection instead.
disable_http_keepalives: false
# Perspective keyservers to use as a backup when direct key fetches fail. This may
# be required to satisfy key requests for servers that are no longer online when
# joining some rooms.
key_perspectives:
- server_name: matrix.org
keys:
- key_id: ed25519:auto
public_key: Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw
- key_id: ed25519:a_RXGa
public_key: l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ
# This option will control whether Dendrite will prefer to look up keys directly
# or whether it should try perspective servers first, using direct fetches as a
# last resort.
prefer_direct_fetch: false
# Configuration for the Key Server (for end-to-end encryption).
key_server:
internal_api:
listen: http://[::]:7779 # The listen address for incoming API requests
connect: http://key_server:7779 # The connect address for other components to use
database:
connection_string: postgresql://username:password@hostname/dendrite_keyserver?sslmode=disable
max_open_conns: 10
max_idle_conns: 2
conn_max_lifetime: -1
# Configuration for the Media API.
media_api:
internal_api:
listen: http://[::]:7774 # The listen address for incoming API requests
connect: http://media_api:7774 # The connect address for other components to use
external_api:
listen: http://[::]:8074
database:
connection_string: postgresql://username:password@hostname/dendrite_mediaapi?sslmode=disable
max_open_conns: 5
max_idle_conns: 2
conn_max_lifetime: -1
# Storage path for uploaded media. May be relative or absolute.
base_path: ./media_store
# The maximum allowed file size (in bytes) for media uploads to this homeserver
# (0 = unlimited). If using a reverse proxy, ensure it allows requests at least
#this large (e.g. the client_max_body_size setting in nginx).
max_file_size_bytes: 10485760
# Whether to dynamically generate thumbnails if needed.
dynamic_thumbnails: false
# The maximum number of simultaneous thumbnail generators to run.
max_thumbnail_generators: 10
# A list of thumbnail sizes to be generated for media content.
thumbnail_sizes:
- width: 32
height: 32
method: crop
- width: 96
height: 96
method: crop
- width: 640
height: 480
method: scale
# Configuration for enabling experimental MSCs on this homeserver.
mscs:
mscs:
# - msc2836 # (Threading, see https://github.com/matrix-org/matrix-doc/pull/2836)
# - msc2946 # (Spaces Summary, see https://github.com/matrix-org/matrix-doc/pull/2946)
database:
connection_string: postgresql://username:password@hostname/dendrite_mscs?sslmode=disable
max_open_conns: 5
max_idle_conns: 2
conn_max_lifetime: -1
# Configuration for the Room Server.
room_server:
internal_api:
listen: http://[::]:7770 # The listen address for incoming API requests
connect: http://room_server:7770 # The connect address for other components to use
database:
connection_string: postgresql://username:password@hostname/dendrite_roomserver?sslmode=disable
max_open_conns: 10
max_idle_conns: 2
conn_max_lifetime: -1
# Configuration for the Sync API.
sync_api:
internal_api:
listen: http://[::]:7773 # The listen address for incoming API requests
connect: http://sync_api:7773 # The connect address for other components to use
external_api:
listen: http://[::]:8073
database:
connection_string: postgresql://username:password@hostname/dendrite_syncapi?sslmode=disable
max_open_conns: 10
max_idle_conns: 2
conn_max_lifetime: -1
# Configuration for the full-text search engine.
search:
# Whether or not search is enabled.
enabled: false
# The path where the search index will be created in.
index_path: "./searchindex"
# The language most likely to be used on the server - used when indexing, to
# ensure the returned results match expectations. A full list of possible languages
# can be found at https://github.com/blevesearch/bleve/tree/master/analysis/lang
language: "en"
# This option controls which HTTP header to inspect to find the real remote IP
# address of the client. This is likely required if Dendrite is running behind
# a reverse proxy server.
# real_ip_header: X-Real-IP
# Configuration for the User API.
user_api:
internal_api:
listen: http://[::]:7781 # The listen address for incoming API requests
connect: http://user_api:7781 # The connect address for other components to use
account_database:
connection_string: postgresql://username:password@hostname/dendrite_userapi?sslmode=disable
max_open_conns: 10
max_idle_conns: 2
conn_max_lifetime: -1
# The cost when hashing passwords on registration/login. Default: 10. Min: 4, Max: 31
# See https://pkg.go.dev/golang.org/x/crypto/bcrypt for more information.
# Setting this lower makes registration/login consume less CPU resources at the cost
# of security should the database be compromised. Setting this higher makes registration/login
# consume more CPU resources but makes it harder to brute force password hashes. This value
# can be lowered if performing tests or on embedded Dendrite instances (e.g WASM builds).
bcrypt_cost: 10
# The length of time that a token issued for a relying party from
# /_matrix/client/r0/user/{userId}/openid/request_token endpoint
# is considered to be valid in milliseconds.
# The default lifetime is 3600000ms (60 minutes).
# openid_token_lifetime_ms: 3600000
# Users who register on this homeserver will automatically be joined to the rooms listed under "auto_join_rooms" option.
# By default, any room aliases included in this list will be created as a publicly joinable room
# when the first user registers for the homeserver. If the room already exists,
# make certain it is a publicly joinable room, i.e. the join rule of the room must be set to 'public'.
# As Spaces are just rooms under the hood, Space aliases may also be used.
auto_join_rooms:
# - "#main:matrix.org"
# Configuration for Opentracing.
# See https://github.com/matrix-org/dendrite/tree/master/docs/tracing for information on
# how this works and how to set it up.
tracing:
enabled: false
jaeger:
serviceName: ""
disabled: false
rpc_metrics: false
tags: []
sampler: null
reporter: null
headers: null
baggage_restrictions: null
throttler: null
# Logging configuration. The "std" logging type controls the logs being sent to
# stdout. The "file" logging type controls logs being written to a log folder on
# the disk. Supported log levels are "debug", "info", "warn", "error".
logging:
- type: std
level: info
- type: file
level: info
params:
path: ./logs

View file

@ -38,7 +38,7 @@ global:
# Global database connection pool, for PostgreSQL monolith deployments only. If
# this section is populated then you can omit the "database" blocks in all other
# sections. For polylith deployments, or monolith deployments using SQLite databases,
# sections. For monolith deployments using SQLite databases,
# you must configure the "database" block for each component instead.
database:
connection_string: postgresql://username:password@hostname/dendrite?sslmode=disable
@ -113,8 +113,7 @@ global:
jetstream:
# A list of NATS Server addresses to connect to. If none are specified, an
# internal NATS server will be started automatically when running Dendrite in
# monolith mode. For polylith deployments, it is required to specify the address
# of at least one NATS Server node.
# monolith mode.
addresses:
# - localhost:4222

View file

@ -35,11 +35,6 @@ possible to migrate an existing Synapse deployment to Dendrite.
No, Dendrite has a very different database schema to Synapse and the two are not interchangeable.
## Should I run a monolith or a polylith deployment?
Monolith deployments are always preferred where possible, and at this time, are far better tested than polylith deployments are. The only reason to consider a polylith deployment is if you wish to run different Dendrite components on separate physical machines, but this is an advanced configuration which we don't
recommend.
## Can I configure which port Dendrite listens on?
Yes, use the cli flag `-http-bind-address`.

View file

@ -9,7 +9,5 @@ or alternatively, in the [installation](installation/) folder:
3. [Preparing database storage](installation/3_database.md)
4. [Generating signing keys](installation/4_signingkey.md)
5. [Installing as a monolith](installation/5_install_monolith.md)
6. [Installing as a polylith](installation/6_install_polylith.md)
7. [Populate the configuration](installation/7_configuration.md)
8. [Starting the monolith](installation/8_starting_monolith.md)
9. [Starting the polylith](installation/9_starting_polylith.md)
6. [Populate the configuration](installation/7_configuration.md)
7. [Starting the monolith](installation/8_starting_monolith.md)

View file

@ -57,22 +57,16 @@ github.com/matrix-org/util/unique.go:55: UniqueStrings 100.0%
total: (statements) 53.7%
```
The total coverage for this run is the last line at the bottom. However, this value is misleading because Dendrite can run in many different configurations,
which will never be tested in a single test run (e.g sqlite or postgres, monolith or polylith). To get a more accurate value, additional processing is required
which will never be tested in a single test run (e.g sqlite or postgres). To get a more accurate value, additional processing is required
to remove packages which will never be tested and extension MSCs:
```bash
# These commands are all similar but change which package paths are _removed_ from the output.
# For Postgres (monolith)
# For Postgres
go tool cover -func=/path/to/server-0/integrationcover.log | grep 'github.com/matrix-org/dendrite' | grep -Ev 'inthttp|sqlite|setup/mscs|api_trace' > coverage.txt
# For Postgres (polylith)
go tool cover -func=/path/to/server-0/integrationcover.log | grep 'github.com/matrix-org/dendrite' | grep -Ev 'sqlite|setup/mscs|api_trace' > coverage.txt
# For SQLite (monolith)
# For SQLite
go tool cover -func=/path/to/server-0/integrationcover.log | grep 'github.com/matrix-org/dendrite' | grep -Ev 'inthttp|postgres|setup/mscs|api_trace' > coverage.txt
# For SQLite (polylith)
go tool cover -func=/path/to/server-0/integrationcover.log | grep 'github.com/matrix-org/dendrite' | grep -Ev 'postgres|setup/mscs|api_trace' > coverage.txt
```
A total value can then be calculated using:

View file

@ -46,10 +46,10 @@ tracing:
param: 1
```
then run the monolith server with `--api true` to use polylith components which do tracing spans:
then run the monolith server:
```
./dendrite-monolith-server --tls-cert server.crt --tls-key server.key --config dendrite.yaml --api true
./dendrite-monolith-server --tls-cert server.crt --tls-key server.key --config dendrite.yaml
```
## Checking traces

View file

@ -1,73 +0,0 @@
---
title: Starting the polylith
parent: Installation
has_toc: true
nav_order: 10
permalink: /installation/start/polylith
---
# Starting the polylith
Once you have completed all of the preparation and installation steps,
you can start your Dendrite polylith deployment by starting the various components
using the `dendrite-polylith-multi` personalities.
## Start the reverse proxy
Ensure that your reverse proxy is started and is proxying the correct
endpoints to the correct components. Software such as [NGINX](https://www.nginx.com) or
[HAProxy](http://www.haproxy.org) can be used for this purpose. A [sample configuration
for NGINX](https://github.com/matrix-org/dendrite/blob/main/docs/nginx/polylith-sample.conf)
is provided.
## Starting the components
Each component must be started individually:
### Client API
```bash
./dendrite-polylith-multi -config /path/to/dendrite.yaml clientapi
```
### Sync API
```bash
./dendrite-polylith-multi -config /path/to/dendrite.yaml syncapi
```
### Media API
```bash
./dendrite-polylith-multi -config /path/to/dendrite.yaml mediaapi
```
### Federation API
```bash
./dendrite-polylith-multi -config /path/to/dendrite.yaml federationapi
```
### Roomserver
```bash
./dendrite-polylith-multi -config /path/to/dendrite.yaml roomserver
```
### Appservice API
```bash
./dendrite-polylith-multi -config /path/to/dendrite.yaml appservice
```
### User API
```bash
./dendrite-polylith-multi -config /path/to/dendrite.yaml userapi
```
### Key server
```bash
./dendrite-polylith-multi -config /path/to/dendrite.yaml keyserver
```

View file

@ -16,12 +16,6 @@ Users can run Dendrite in one of two modes which dictate how these components ar
server with generally low overhead. This mode dramatically simplifies deployment complexity and offers the
best balance between performance and resource usage for low-to-mid volume deployments.
* **Polylith mode** runs all components in isolated processes. Components communicate through an external NATS
server and HTTP APIs, which incur considerable overhead. While this mode allows for more granular control of
resources dedicated toward individual processes, given the additional communications overhead, it is only
necessary for very large deployments.
Given our current state of development, **we recommend monolith mode** for all deployments.
## Databases
@ -85,21 +79,15 @@ If using the PostgreSQL database engine, you should install PostgreSQL 12 or lat
### NATS Server
Monolith deployments come with a built-in [NATS Server](https://github.com/nats-io/nats-server) and
therefore do not need this to be manually installed. If you are planning a monolith installation, you
Dendrite comes with a built-in [NATS Server](https://github.com/nats-io/nats-server) and
therefore does not need this to be manually installed. If you are planning a monolith installation, you
do not need to do anything.
Polylith deployments, however, currently need a standalone NATS Server installation with JetStream
enabled.
To do so, follow the [NATS Server installation instructions](https://docs.nats.io/running-a-nats-service/introduction/installation) and then [start your NATS deployment](https://docs.nats.io/running-a-nats-service/introduction/running). JetStream must be enabled, either by passing the `-js` flag to `nats-server`,
or by specifying the `store_dir` option in the the `jetstream` configuration.
### Reverse proxy
A reverse proxy such as [Caddy](https://caddyserver.com), [NGINX](https://www.nginx.com) or
[HAProxy](http://www.haproxy.org) is required for polylith deployments and is useful for monolith
deployments. Configuring those is not covered in this documentation, although sample configurations
[HAProxy](http://www.haproxy.org) is useful for deployments. Configuring those is not covered in this documentation, although sample configurations
for [Caddy](https://github.com/matrix-org/dendrite/blob/main/docs/caddy) and
[NGINX](https://github.com/matrix-org/dendrite/blob/main/docs/nginx) are provided.

View file

@ -1,34 +0,0 @@
---
title: Installing as a polylith
parent: Installation
has_toc: true
nav_order: 6
permalink: /installation/install/polylith
---
# Installing as a polylith
You can install the Dendrite polylith binary into `$GOPATH/bin` by using `go install`:
```sh
go install ./cmd/dendrite-polylith-multi
```
Alternatively, you can specify a custom path for the binary to be written to using `go build`:
```sh
go build -o /usr/local/bin/ ./cmd/dendrite-polylith-multi
```
The `dendrite-polylith-multi` binary is a "multi-personality" binary which can run as
any of the components depending on the supplied command line parameters.
## Reverse proxy
Polylith deployments require a reverse proxy in order to ensure that requests are
sent to the correct endpoint. You must ensure that a suitable reverse proxy is installed
and configured.
Sample configurations are provided
for [Caddy](https://github.com/matrix-org/dendrite/blob/main/docs/caddy/polylith/Caddyfile)
and [NGINX](https://github.com/matrix-org/dendrite/blob/main/docs/nginx/polylith-sample.conf).

View file

@ -7,11 +7,10 @@ permalink: /installation/configuration
# Configuring Dendrite
A YAML configuration file is used to configure Dendrite. Sample configuration files are
A YAML configuration file is used to configure Dendrite. A sample configuration file is
present in the top level of the Dendrite repository:
* [`dendrite-sample.monolith.yaml`](https://github.com/matrix-org/dendrite/blob/main/dendrite-sample.monolith.yaml)
* [`dendrite-sample.polylith.yaml`](https://github.com/matrix-org/dendrite/blob/main/dendrite-sample.polylith.yaml)
You will need to duplicate the sample, calling it `dendrite.yaml` for example, and then
tailor it to your installation. At a minimum, you will need to populate the following
@ -46,10 +45,9 @@ global:
## JetStream configuration
Monolith deployments can use the built-in NATS Server rather than running a standalone
server. If you are building a polylith deployment, or you want to use a standalone NATS
Server anyway, you can also configure that too.
server. If you want to use a standalone NATS Server anyway, you can also configure that too.
### Built-in NATS Server (monolith only)
### Built-in NATS Server
In the `global` section, under the `jetstream` key, ensure that no server addresses are
configured and set a `storage_path` to a persistent folder on the filesystem:
@ -63,7 +61,7 @@ global:
topic_prefix: Dendrite
```
### Standalone NATS Server (monolith and polylith)
### Standalone NATS Server
To use a standalone NATS Server instance, you will need to configure `addresses` field
to point to the port that your NATS Server is listening on:
@ -86,7 +84,7 @@ one address in the `addresses` field.
Configuring database connections varies based on the [database configuration](database)
that you chose.
### Global connection pool (monolith with a single PostgreSQL database only)
### Global connection pool
If you are running a monolith deployment and want to use a single connection pool to a
single PostgreSQL database, then you must uncomment and configure the `database` section
@ -109,7 +107,7 @@ override the `global` database configuration.
### Per-component connections (all other configurations)
If you are building a polylith deployment, are using SQLite databases or separate PostgreSQL
If you are are using SQLite databases or separate PostgreSQL
databases per component, then you must instead configure the `database` sections under each
of the component blocks ,e.g. under the `app_service_api`, `federation_api`, `key_server`,
`media_api`, `mscs`, `room_server`, `sync_api` and `user_api` blocks.

View file

@ -17,14 +17,12 @@ package federationapi
import (
"time"
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
"github.com/matrix-org/dendrite/federationapi/api"
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
"github.com/matrix-org/dendrite/federationapi/consumers"
"github.com/matrix-org/dendrite/federationapi/internal"
"github.com/matrix-org/dendrite/federationapi/inthttp"
"github.com/matrix-org/dendrite/federationapi/producers"
"github.com/matrix-org/dendrite/federationapi/queue"
"github.com/matrix-org/dendrite/federationapi/statistics"
@ -41,12 +39,6 @@ import (
"github.com/matrix-org/dendrite/federationapi/routing"
)
// AddInternalRoutes registers HTTP handlers for the internal API. Invokes functions
// on the given input API.
func AddInternalRoutes(router *mux.Router, intAPI api.FederationInternalAPI, enableMetrics bool) {
inthttp.AddRoutes(intAPI, router, enableMetrics)
}
// AddPublicRoutes sets up and registers HTTP handlers on the base API muxes for the FederationAPI component.
func AddPublicRoutes(
base *base.BaseDendrite,

View file

@ -78,7 +78,7 @@ func TestMain(m *testing.M) {
cfg := &config.Dendrite{}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: false,
})
cfg.Global.ServerName = gomatrixserverlib.ServerName(s.name)
cfg.Global.PrivateKey = testPriv
@ -109,7 +109,7 @@ func TestMain(m *testing.M) {
)
// Finally, build the server key APIs.
sbase := base.NewBaseDendrite(cfg, "Monolith", base.DisableMetrics)
sbase := base.NewBaseDendrite(cfg, base.DisableMetrics)
s.api = NewInternalAPI(sbase, s.fedclient, nil, s.cache, nil, true)
}

View file

@ -267,13 +267,13 @@ func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
cfg := &config.Dendrite{}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: false,
})
cfg.Global.KeyID = gomatrixserverlib.KeyID("ed25519:auto")
cfg.Global.ServerName = gomatrixserverlib.ServerName("localhost")
cfg.Global.PrivateKey = privKey
cfg.Global.JetStream.InMemory = true
b := base.NewBaseDendrite(cfg, "Monolith", base.DisableMetrics)
b := base.NewBaseDendrite(cfg, base.DisableMetrics)
keyRing := &test.NopJSONVerifier{}
// TODO: This is pretty fragile, as if anything calls anything on these nils this test will break.
// Unfortunately, it makes little sense to instantiate these dependencies when we just want to test routing.

View file

@ -121,8 +121,6 @@ func (r *FederationInternalAPI) PerformJoin(
var httpErr gomatrix.HTTPError
if ok := errors.As(lastErr, &httpErr); ok {
httpErr.Message = string(httpErr.Contents)
// Clear the wrapped error, else serialising to JSON (in polylith mode) will fail
httpErr.WrappedError = nil
response.LastError = &httpErr
} else {
response.LastError = &gomatrix.HTTPError{
@ -391,8 +389,6 @@ func (r *FederationInternalAPI) PerformOutboundPeek(
var httpErr gomatrix.HTTPError
if ok := errors.As(lastErr, &httpErr); ok {
httpErr.Message = string(httpErr.Contents)
// Clear the wrapped error, else serialising to JSON (in polylith mode) will fail
httpErr.WrappedError = nil
response.LastError = &httpErr
} else {
response.LastError = &gomatrix.HTTPError{

View file

@ -1,548 +0,0 @@
package inthttp
import (
"context"
"errors"
"net/http"
"github.com/matrix-org/dendrite/federationapi/api"
"github.com/matrix-org/dendrite/internal/caching"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/gomatrixserverlib"
)
// HTTP paths for the internal HTTP API
const (
FederationAPIQueryJoinedHostServerNamesInRoomPath = "/federationapi/queryJoinedHostServerNamesInRoom"
FederationAPIQueryServerKeysPath = "/federationapi/queryServerKeys"
FederationAPIPerformDirectoryLookupRequestPath = "/federationapi/performDirectoryLookup"
FederationAPIPerformJoinRequestPath = "/federationapi/performJoinRequest"
FederationAPIPerformLeaveRequestPath = "/federationapi/performLeaveRequest"
FederationAPIPerformInviteRequestPath = "/federationapi/performInviteRequest"
FederationAPIPerformOutboundPeekRequestPath = "/federationapi/performOutboundPeekRequest"
FederationAPIPerformBroadcastEDUPath = "/federationapi/performBroadcastEDU"
FederationAPIPerformWakeupServers = "/federationapi/performWakeupServers"
FederationAPIQueryRelayServers = "/federationapi/queryRelayServers"
FederationAPIAddRelayServers = "/federationapi/addRelayServers"
FederationAPIRemoveRelayServers = "/federationapi/removeRelayServers"
FederationAPIGetUserDevicesPath = "/federationapi/client/getUserDevices"
FederationAPIClaimKeysPath = "/federationapi/client/claimKeys"
FederationAPIQueryKeysPath = "/federationapi/client/queryKeys"
FederationAPIBackfillPath = "/federationapi/client/backfill"
FederationAPILookupStatePath = "/federationapi/client/lookupState"
FederationAPILookupStateIDsPath = "/federationapi/client/lookupStateIDs"
FederationAPILookupMissingEventsPath = "/federationapi/client/lookupMissingEvents"
FederationAPIGetEventPath = "/federationapi/client/getEvent"
FederationAPILookupServerKeysPath = "/federationapi/client/lookupServerKeys"
FederationAPIEventRelationshipsPath = "/federationapi/client/msc2836eventRelationships"
FederationAPISpacesSummaryPath = "/federationapi/client/msc2946spacesSummary"
FederationAPIGetEventAuthPath = "/federationapi/client/getEventAuth"
FederationAPIInputPublicKeyPath = "/federationapi/inputPublicKey"
FederationAPIQueryPublicKeyPath = "/federationapi/queryPublicKey"
)
// NewFederationAPIClient creates a FederationInternalAPI implemented by talking to a HTTP POST API.
// If httpClient is nil an error is returned
func NewFederationAPIClient(federationSenderURL string, httpClient *http.Client, cache caching.ServerKeyCache) (api.FederationInternalAPI, error) {
if httpClient == nil {
return nil, errors.New("NewFederationInternalAPIHTTP: httpClient is <nil>")
}
return &httpFederationInternalAPI{
federationAPIURL: federationSenderURL,
httpClient: httpClient,
cache: cache,
}, nil
}
type httpFederationInternalAPI struct {
federationAPIURL string
httpClient *http.Client
cache caching.ServerKeyCache
}
// Handle an instruction to make_leave & send_leave with a remote server.
func (h *httpFederationInternalAPI) PerformLeave(
ctx context.Context,
request *api.PerformLeaveRequest,
response *api.PerformLeaveResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformLeave", h.federationAPIURL+FederationAPIPerformLeaveRequestPath,
h.httpClient, ctx, request, response,
)
}
// Handle sending an invite to a remote server.
func (h *httpFederationInternalAPI) PerformInvite(
ctx context.Context,
request *api.PerformInviteRequest,
response *api.PerformInviteResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformInvite", h.federationAPIURL+FederationAPIPerformInviteRequestPath,
h.httpClient, ctx, request, response,
)
}
// Handle starting a peek on a remote server.
func (h *httpFederationInternalAPI) PerformOutboundPeek(
ctx context.Context,
request *api.PerformOutboundPeekRequest,
response *api.PerformOutboundPeekResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformOutboundPeek", h.federationAPIURL+FederationAPIPerformOutboundPeekRequestPath,
h.httpClient, ctx, request, response,
)
}
// QueryJoinedHostServerNamesInRoom implements FederationInternalAPI
func (h *httpFederationInternalAPI) QueryJoinedHostServerNamesInRoom(
ctx context.Context,
request *api.QueryJoinedHostServerNamesInRoomRequest,
response *api.QueryJoinedHostServerNamesInRoomResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryJoinedHostServerNamesInRoom", h.federationAPIURL+FederationAPIQueryJoinedHostServerNamesInRoomPath,
h.httpClient, ctx, request, response,
)
}
// Handle an instruction to make_join & send_join with a remote server.
func (h *httpFederationInternalAPI) PerformJoin(
ctx context.Context,
request *api.PerformJoinRequest,
response *api.PerformJoinResponse,
) {
if err := httputil.CallInternalRPCAPI(
"PerformJoinRequest", h.federationAPIURL+FederationAPIPerformJoinRequestPath,
h.httpClient, ctx, request, response,
); err != nil {
response.LastError = &gomatrix.HTTPError{
Message: err.Error(),
Code: 0,
WrappedError: err,
}
}
}
// Handle an instruction to make_join & send_join with a remote server.
func (h *httpFederationInternalAPI) PerformDirectoryLookup(
ctx context.Context,
request *api.PerformDirectoryLookupRequest,
response *api.PerformDirectoryLookupResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformDirectoryLookup", h.federationAPIURL+FederationAPIPerformDirectoryLookupRequestPath,
h.httpClient, ctx, request, response,
)
}
// Handle an instruction to broadcast an EDU to all servers in rooms we are joined to.
func (h *httpFederationInternalAPI) PerformBroadcastEDU(
ctx context.Context,
request *api.PerformBroadcastEDURequest,
response *api.PerformBroadcastEDUResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformBroadcastEDU", h.federationAPIURL+FederationAPIPerformBroadcastEDUPath,
h.httpClient, ctx, request, response,
)
}
// Handle an instruction to remove the respective servers from being blacklisted.
func (h *httpFederationInternalAPI) PerformWakeupServers(
ctx context.Context,
request *api.PerformWakeupServersRequest,
response *api.PerformWakeupServersResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformWakeupServers", h.federationAPIURL+FederationAPIPerformWakeupServers,
h.httpClient, ctx, request, response,
)
}
type getUserDevices struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
UserID string
}
func (h *httpFederationInternalAPI) GetUserDevices(
ctx context.Context, origin, s gomatrixserverlib.ServerName, userID string,
) (gomatrixserverlib.RespUserDevices, error) {
return httputil.CallInternalProxyAPI[getUserDevices, gomatrixserverlib.RespUserDevices, *api.FederationClientError](
"GetUserDevices", h.federationAPIURL+FederationAPIGetUserDevicesPath, h.httpClient,
ctx, &getUserDevices{
S: s,
Origin: origin,
UserID: userID,
},
)
}
type claimKeys struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
OneTimeKeys map[string]map[string]string
}
func (h *httpFederationInternalAPI) ClaimKeys(
ctx context.Context, origin, s gomatrixserverlib.ServerName, oneTimeKeys map[string]map[string]string,
) (gomatrixserverlib.RespClaimKeys, error) {
return httputil.CallInternalProxyAPI[claimKeys, gomatrixserverlib.RespClaimKeys, *api.FederationClientError](
"ClaimKeys", h.federationAPIURL+FederationAPIClaimKeysPath, h.httpClient,
ctx, &claimKeys{
S: s,
Origin: origin,
OneTimeKeys: oneTimeKeys,
},
)
}
type queryKeys struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
Keys map[string][]string
}
func (h *httpFederationInternalAPI) QueryKeys(
ctx context.Context, origin, s gomatrixserverlib.ServerName, keys map[string][]string,
) (gomatrixserverlib.RespQueryKeys, error) {
return httputil.CallInternalProxyAPI[queryKeys, gomatrixserverlib.RespQueryKeys, *api.FederationClientError](
"QueryKeys", h.federationAPIURL+FederationAPIQueryKeysPath, h.httpClient,
ctx, &queryKeys{
S: s,
Origin: origin,
Keys: keys,
},
)
}
type backfill struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
RoomID string
Limit int
EventIDs []string
}
func (h *httpFederationInternalAPI) Backfill(
ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID string, limit int, eventIDs []string,
) (gomatrixserverlib.Transaction, error) {
return httputil.CallInternalProxyAPI[backfill, gomatrixserverlib.Transaction, *api.FederationClientError](
"Backfill", h.federationAPIURL+FederationAPIBackfillPath, h.httpClient,
ctx, &backfill{
S: s,
Origin: origin,
RoomID: roomID,
Limit: limit,
EventIDs: eventIDs,
},
)
}
type lookupState struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
RoomID string
EventID string
RoomVersion gomatrixserverlib.RoomVersion
}
func (h *httpFederationInternalAPI) LookupState(
ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID, eventID string, roomVersion gomatrixserverlib.RoomVersion,
) (gomatrixserverlib.RespState, error) {
return httputil.CallInternalProxyAPI[lookupState, gomatrixserverlib.RespState, *api.FederationClientError](
"LookupState", h.federationAPIURL+FederationAPILookupStatePath, h.httpClient,
ctx, &lookupState{
S: s,
Origin: origin,
RoomID: roomID,
EventID: eventID,
RoomVersion: roomVersion,
},
)
}
type lookupStateIDs struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
RoomID string
EventID string
}
func (h *httpFederationInternalAPI) LookupStateIDs(
ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID, eventID string,
) (gomatrixserverlib.RespStateIDs, error) {
return httputil.CallInternalProxyAPI[lookupStateIDs, gomatrixserverlib.RespStateIDs, *api.FederationClientError](
"LookupStateIDs", h.federationAPIURL+FederationAPILookupStateIDsPath, h.httpClient,
ctx, &lookupStateIDs{
S: s,
Origin: origin,
RoomID: roomID,
EventID: eventID,
},
)
}
type lookupMissingEvents struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
RoomID string
Missing gomatrixserverlib.MissingEvents
RoomVersion gomatrixserverlib.RoomVersion
}
func (h *httpFederationInternalAPI) LookupMissingEvents(
ctx context.Context, origin, s gomatrixserverlib.ServerName, roomID string,
missing gomatrixserverlib.MissingEvents, roomVersion gomatrixserverlib.RoomVersion,
) (res gomatrixserverlib.RespMissingEvents, err error) {
return httputil.CallInternalProxyAPI[lookupMissingEvents, gomatrixserverlib.RespMissingEvents, *api.FederationClientError](
"LookupMissingEvents", h.federationAPIURL+FederationAPILookupMissingEventsPath, h.httpClient,
ctx, &lookupMissingEvents{
S: s,
Origin: origin,
RoomID: roomID,
Missing: missing,
RoomVersion: roomVersion,
},
)
}
type getEvent struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
EventID string
}
func (h *httpFederationInternalAPI) GetEvent(
ctx context.Context, origin, s gomatrixserverlib.ServerName, eventID string,
) (gomatrixserverlib.Transaction, error) {
return httputil.CallInternalProxyAPI[getEvent, gomatrixserverlib.Transaction, *api.FederationClientError](
"GetEvent", h.federationAPIURL+FederationAPIGetEventPath, h.httpClient,
ctx, &getEvent{
S: s,
Origin: origin,
EventID: eventID,
},
)
}
type getEventAuth struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
RoomVersion gomatrixserverlib.RoomVersion
RoomID string
EventID string
}
func (h *httpFederationInternalAPI) GetEventAuth(
ctx context.Context, origin, s gomatrixserverlib.ServerName,
roomVersion gomatrixserverlib.RoomVersion, roomID, eventID string,
) (gomatrixserverlib.RespEventAuth, error) {
return httputil.CallInternalProxyAPI[getEventAuth, gomatrixserverlib.RespEventAuth, *api.FederationClientError](
"GetEventAuth", h.federationAPIURL+FederationAPIGetEventAuthPath, h.httpClient,
ctx, &getEventAuth{
S: s,
Origin: origin,
RoomVersion: roomVersion,
RoomID: roomID,
EventID: eventID,
},
)
}
func (h *httpFederationInternalAPI) QueryServerKeys(
ctx context.Context, req *api.QueryServerKeysRequest, res *api.QueryServerKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryServerKeys", h.federationAPIURL+FederationAPIQueryServerKeysPath,
h.httpClient, ctx, req, res,
)
}
type lookupServerKeys struct {
S gomatrixserverlib.ServerName
KeyRequests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp
}
func (h *httpFederationInternalAPI) LookupServerKeys(
ctx context.Context, s gomatrixserverlib.ServerName, keyRequests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
) ([]gomatrixserverlib.ServerKeys, error) {
return httputil.CallInternalProxyAPI[lookupServerKeys, []gomatrixserverlib.ServerKeys, *api.FederationClientError](
"LookupServerKeys", h.federationAPIURL+FederationAPILookupServerKeysPath, h.httpClient,
ctx, &lookupServerKeys{
S: s,
KeyRequests: keyRequests,
},
)
}
type eventRelationships struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
Req gomatrixserverlib.MSC2836EventRelationshipsRequest
RoomVer gomatrixserverlib.RoomVersion
}
func (h *httpFederationInternalAPI) MSC2836EventRelationships(
ctx context.Context, origin, s gomatrixserverlib.ServerName, r gomatrixserverlib.MSC2836EventRelationshipsRequest,
roomVersion gomatrixserverlib.RoomVersion,
) (res gomatrixserverlib.MSC2836EventRelationshipsResponse, err error) {
return httputil.CallInternalProxyAPI[eventRelationships, gomatrixserverlib.MSC2836EventRelationshipsResponse, *api.FederationClientError](
"MSC2836EventRelationships", h.federationAPIURL+FederationAPIEventRelationshipsPath, h.httpClient,
ctx, &eventRelationships{
S: s,
Origin: origin,
Req: r,
RoomVer: roomVersion,
},
)
}
type spacesReq struct {
S gomatrixserverlib.ServerName
Origin gomatrixserverlib.ServerName
SuggestedOnly bool
RoomID string
}
func (h *httpFederationInternalAPI) MSC2946Spaces(
ctx context.Context, origin, dst gomatrixserverlib.ServerName, roomID string, suggestedOnly bool,
) (res gomatrixserverlib.MSC2946SpacesResponse, err error) {
return httputil.CallInternalProxyAPI[spacesReq, gomatrixserverlib.MSC2946SpacesResponse, *api.FederationClientError](
"MSC2836EventRelationships", h.federationAPIURL+FederationAPISpacesSummaryPath, h.httpClient,
ctx, &spacesReq{
S: dst,
Origin: origin,
SuggestedOnly: suggestedOnly,
RoomID: roomID,
},
)
}
func (s *httpFederationInternalAPI) KeyRing() *gomatrixserverlib.KeyRing {
// This is a bit of a cheat - we tell gomatrixserverlib that this API is
// both the key database and the key fetcher. While this does have the
// rather unfortunate effect of preventing gomatrixserverlib from handling
// key fetchers directly, we can at least reimplement this behaviour on
// the other end of the API.
return &gomatrixserverlib.KeyRing{
KeyDatabase: s,
KeyFetchers: []gomatrixserverlib.KeyFetcher{},
}
}
func (s *httpFederationInternalAPI) FetcherName() string {
return "httpServerKeyInternalAPI"
}
func (s *httpFederationInternalAPI) StoreKeys(
_ context.Context,
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
) error {
// Run in a background context - we don't want to stop this work just
// because the caller gives up waiting.
ctx := context.Background()
request := api.InputPublicKeysRequest{
Keys: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult),
}
response := api.InputPublicKeysResponse{}
for req, res := range results {
request.Keys[req] = res
s.cache.StoreServerKey(req, res)
}
return s.InputPublicKeys(ctx, &request, &response)
}
func (s *httpFederationInternalAPI) FetchKeys(
_ context.Context,
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
// Run in a background context - we don't want to stop this work just
// because the caller gives up waiting.
ctx := context.Background()
result := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult)
request := api.QueryPublicKeysRequest{
Requests: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp),
}
response := api.QueryPublicKeysResponse{
Results: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult),
}
for req, ts := range requests {
if res, ok := s.cache.GetServerKey(req, ts); ok {
result[req] = res
continue
}
request.Requests[req] = ts
}
err := s.QueryPublicKeys(ctx, &request, &response)
if err != nil {
return nil, err
}
for req, res := range response.Results {
result[req] = res
s.cache.StoreServerKey(req, res)
}
return result, nil
}
func (h *httpFederationInternalAPI) InputPublicKeys(
ctx context.Context,
request *api.InputPublicKeysRequest,
response *api.InputPublicKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"InputPublicKey", h.federationAPIURL+FederationAPIInputPublicKeyPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpFederationInternalAPI) QueryPublicKeys(
ctx context.Context,
request *api.QueryPublicKeysRequest,
response *api.QueryPublicKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryPublicKeys", h.federationAPIURL+FederationAPIQueryPublicKeyPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpFederationInternalAPI) P2PQueryRelayServers(
ctx context.Context,
request *api.P2PQueryRelayServersRequest,
response *api.P2PQueryRelayServersResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryRelayServers", h.federationAPIURL+FederationAPIQueryRelayServers,
h.httpClient, ctx, request, response,
)
}
func (h *httpFederationInternalAPI) P2PAddRelayServers(
ctx context.Context,
request *api.P2PAddRelayServersRequest,
response *api.P2PAddRelayServersResponse,
) error {
return httputil.CallInternalRPCAPI(
"AddRelayServers", h.federationAPIURL+FederationAPIAddRelayServers,
h.httpClient, ctx, request, response,
)
}
func (h *httpFederationInternalAPI) P2PRemoveRelayServers(
ctx context.Context,
request *api.P2PRemoveRelayServersRequest,
response *api.P2PRemoveRelayServersResponse,
) error {
return httputil.CallInternalRPCAPI(
"RemoveRelayServers", h.federationAPIURL+FederationAPIRemoveRelayServers,
h.httpClient, ctx, request, response,
)
}

View file

@ -1,257 +0,0 @@
package inthttp
import (
"context"
"encoding/json"
"net/http"
"net/url"
"github.com/gorilla/mux"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/matrix-org/dendrite/federationapi/api"
"github.com/matrix-org/dendrite/internal/httputil"
)
// AddRoutes adds the FederationInternalAPI handlers to the http.ServeMux.
// nolint:gocyclo
func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router, enableMetrics bool) {
internalAPIMux.Handle(
FederationAPIQueryJoinedHostServerNamesInRoomPath,
httputil.MakeInternalRPCAPI("FederationAPIQueryJoinedHostServerNamesInRoom", enableMetrics, intAPI.QueryJoinedHostServerNamesInRoom),
)
internalAPIMux.Handle(
FederationAPIPerformInviteRequestPath,
httputil.MakeInternalRPCAPI("FederationAPIPerformInvite", enableMetrics, intAPI.PerformInvite),
)
internalAPIMux.Handle(
FederationAPIPerformLeaveRequestPath,
httputil.MakeInternalRPCAPI("FederationAPIPerformLeave", enableMetrics, intAPI.PerformLeave),
)
internalAPIMux.Handle(
FederationAPIPerformDirectoryLookupRequestPath,
httputil.MakeInternalRPCAPI("FederationAPIPerformDirectoryLookupRequest", enableMetrics, intAPI.PerformDirectoryLookup),
)
internalAPIMux.Handle(
FederationAPIPerformBroadcastEDUPath,
httputil.MakeInternalRPCAPI("FederationAPIPerformBroadcastEDU", enableMetrics, intAPI.PerformBroadcastEDU),
)
internalAPIMux.Handle(
FederationAPIPerformWakeupServers,
httputil.MakeInternalRPCAPI("FederationAPIPerformWakeupServers", enableMetrics, intAPI.PerformWakeupServers),
)
internalAPIMux.Handle(
FederationAPIPerformJoinRequestPath,
httputil.MakeInternalRPCAPI(
"FederationAPIPerformJoinRequest", enableMetrics,
func(ctx context.Context, req *api.PerformJoinRequest, res *api.PerformJoinResponse) error {
intAPI.PerformJoin(ctx, req, res)
return nil
},
),
)
internalAPIMux.Handle(
FederationAPIGetUserDevicesPath,
httputil.MakeInternalProxyAPI(
"FederationAPIGetUserDevices", enableMetrics,
func(ctx context.Context, req *getUserDevices) (*gomatrixserverlib.RespUserDevices, error) {
res, err := intAPI.GetUserDevices(ctx, req.Origin, req.S, req.UserID)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPIClaimKeysPath,
httputil.MakeInternalProxyAPI(
"FederationAPIClaimKeys", enableMetrics,
func(ctx context.Context, req *claimKeys) (*gomatrixserverlib.RespClaimKeys, error) {
res, err := intAPI.ClaimKeys(ctx, req.Origin, req.S, req.OneTimeKeys)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPIQueryKeysPath,
httputil.MakeInternalProxyAPI(
"FederationAPIQueryKeys", enableMetrics,
func(ctx context.Context, req *queryKeys) (*gomatrixserverlib.RespQueryKeys, error) {
res, err := intAPI.QueryKeys(ctx, req.Origin, req.S, req.Keys)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPIBackfillPath,
httputil.MakeInternalProxyAPI(
"FederationAPIBackfill", enableMetrics,
func(ctx context.Context, req *backfill) (*gomatrixserverlib.Transaction, error) {
res, err := intAPI.Backfill(ctx, req.Origin, req.S, req.RoomID, req.Limit, req.EventIDs)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPILookupStatePath,
httputil.MakeInternalProxyAPI(
"FederationAPILookupState", enableMetrics,
func(ctx context.Context, req *lookupState) (*gomatrixserverlib.RespState, error) {
res, err := intAPI.LookupState(ctx, req.Origin, req.S, req.RoomID, req.EventID, req.RoomVersion)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPILookupStateIDsPath,
httputil.MakeInternalProxyAPI(
"FederationAPILookupStateIDs", enableMetrics,
func(ctx context.Context, req *lookupStateIDs) (*gomatrixserverlib.RespStateIDs, error) {
res, err := intAPI.LookupStateIDs(ctx, req.Origin, req.S, req.RoomID, req.EventID)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPILookupMissingEventsPath,
httputil.MakeInternalProxyAPI(
"FederationAPILookupMissingEvents", enableMetrics,
func(ctx context.Context, req *lookupMissingEvents) (*gomatrixserverlib.RespMissingEvents, error) {
res, err := intAPI.LookupMissingEvents(ctx, req.Origin, req.S, req.RoomID, req.Missing, req.RoomVersion)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPIGetEventPath,
httputil.MakeInternalProxyAPI(
"FederationAPIGetEvent", enableMetrics,
func(ctx context.Context, req *getEvent) (*gomatrixserverlib.Transaction, error) {
res, err := intAPI.GetEvent(ctx, req.Origin, req.S, req.EventID)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPIGetEventAuthPath,
httputil.MakeInternalProxyAPI(
"FederationAPIGetEventAuth", enableMetrics,
func(ctx context.Context, req *getEventAuth) (*gomatrixserverlib.RespEventAuth, error) {
res, err := intAPI.GetEventAuth(ctx, req.Origin, req.S, req.RoomVersion, req.RoomID, req.EventID)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPIQueryServerKeysPath,
httputil.MakeInternalRPCAPI("FederationAPIQueryServerKeys", enableMetrics, intAPI.QueryServerKeys),
)
internalAPIMux.Handle(
FederationAPILookupServerKeysPath,
httputil.MakeInternalProxyAPI(
"FederationAPILookupServerKeys", enableMetrics,
func(ctx context.Context, req *lookupServerKeys) (*[]gomatrixserverlib.ServerKeys, error) {
res, err := intAPI.LookupServerKeys(ctx, req.S, req.KeyRequests)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPIEventRelationshipsPath,
httputil.MakeInternalProxyAPI(
"FederationAPIMSC2836EventRelationships", enableMetrics,
func(ctx context.Context, req *eventRelationships) (*gomatrixserverlib.MSC2836EventRelationshipsResponse, error) {
res, err := intAPI.MSC2836EventRelationships(ctx, req.Origin, req.S, req.Req, req.RoomVer)
return &res, federationClientError(err)
},
),
)
internalAPIMux.Handle(
FederationAPISpacesSummaryPath,
httputil.MakeInternalProxyAPI(
"FederationAPIMSC2946SpacesSummary", enableMetrics,
func(ctx context.Context, req *spacesReq) (*gomatrixserverlib.MSC2946SpacesResponse, error) {
res, err := intAPI.MSC2946Spaces(ctx, req.Origin, req.S, req.RoomID, req.SuggestedOnly)
return &res, federationClientError(err)
},
),
)
// TODO: Look at this shape
internalAPIMux.Handle(FederationAPIQueryPublicKeyPath,
httputil.MakeInternalAPI("FederationAPIQueryPublicKeys", enableMetrics, func(req *http.Request) util.JSONResponse {
request := api.QueryPublicKeysRequest{}
response := api.QueryPublicKeysResponse{}
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
keys, err := intAPI.FetchKeys(req.Context(), request.Requests)
if err != nil {
return util.ErrorResponse(err)
}
response.Results = keys
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
// TODO: Look at this shape
internalAPIMux.Handle(FederationAPIInputPublicKeyPath,
httputil.MakeInternalAPI("FederationAPIInputPublicKeys", enableMetrics, func(req *http.Request) util.JSONResponse {
request := api.InputPublicKeysRequest{}
response := api.InputPublicKeysResponse{}
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
if err := intAPI.StoreKeys(req.Context(), request.Keys); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
}
func federationClientError(err error) error {
switch ferr := err.(type) {
case nil:
return nil
case api.FederationClientError:
return &ferr
case *api.FederationClientError:
return ferr
case gomatrix.HTTPError:
return &api.FederationClientError{
Code: ferr.Code,
}
case *url.Error: // e.g. certificate error, unable to connect
return &api.FederationClientError{
Err: ferr.Error(),
Code: 400,
}
default:
// We don't know what exactly failed, but we probably don't
// want to retry the request immediately in the device list updater
return &api.FederationClientError{
Err: err.Error(),
Code: 400,
}
}
}

2
go.mod
View file

@ -46,7 +46,6 @@ require (
golang.org/x/crypto v0.5.0
golang.org/x/image v0.1.0
golang.org/x/mobile v0.0.0-20221020085226-b36e6246172e
golang.org/x/net v0.5.0
golang.org/x/term v0.4.0
gopkg.in/h2non/bimg.v1 v1.1.9
gopkg.in/yaml.v2 v2.4.0
@ -124,6 +123,7 @@ require (
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
golang.org/x/mod v0.6.0 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect
golang.org/x/time v0.1.0 // indirect

View file

@ -1,93 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httputil
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
)
// PostJSON performs a POST request with JSON on an internal HTTP API.
// The error will match the errtype if returned from the remote API, or
// will be a different type if there was a problem reaching the API.
func PostJSON[reqtype, restype any, errtype error](
ctx context.Context, span opentracing.Span, httpClient *http.Client,
apiURL string, request *reqtype, response *restype,
) error {
jsonBytes, err := json.Marshal(request)
if err != nil {
return err
}
parsedAPIURL, err := url.Parse(apiURL)
if err != nil {
return err
}
parsedAPIURL.Path = InternalPathPrefix + strings.TrimLeft(parsedAPIURL.Path, "/")
apiURL = parsedAPIURL.String()
req, err := http.NewRequest(http.MethodPost, apiURL, bytes.NewReader(jsonBytes))
if err != nil {
return err
}
// Mark the span as being an RPC client.
ext.SpanKindRPCClient.Set(span)
carrier := opentracing.HTTPHeadersCarrier(req.Header)
tracer := opentracing.GlobalTracer()
if err = tracer.Inject(span.Context(), opentracing.HTTPHeaders, carrier); err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
res, err := httpClient.Do(req.WithContext(ctx))
if res != nil {
defer (func() { err = res.Body.Close() })()
}
if err != nil {
return err
}
var body []byte
body, err = io.ReadAll(res.Body)
if err != nil {
return err
}
if res.StatusCode != http.StatusOK {
if len(body) == 0 {
return fmt.Errorf("HTTP %d from %s (no response body)", res.StatusCode, apiURL)
}
var reserr errtype
if err = json.Unmarshal(body, &reserr); err != nil {
return fmt.Errorf("HTTP %d from %s - %w", res.StatusCode, apiURL, err)
}
return reserr
}
if err = json.Unmarshal(body, response); err != nil {
return fmt.Errorf("json.Unmarshal: %w", err)
}
return nil
}

View file

@ -1,93 +0,0 @@
// Copyright 2022 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httputil
import (
"context"
"encoding/json"
"fmt"
"net/http"
"reflect"
"github.com/matrix-org/util"
"github.com/opentracing/opentracing-go"
)
type InternalAPIError struct {
Type string
Message string
}
func (e InternalAPIError) Error() string {
return fmt.Sprintf("internal API returned %q error: %s", e.Type, e.Message)
}
func MakeInternalRPCAPI[reqtype, restype any](metricsName string, enableMetrics bool, f func(context.Context, *reqtype, *restype) error) http.Handler {
return MakeInternalAPI(metricsName, enableMetrics, func(req *http.Request) util.JSONResponse {
var request reqtype
var response restype
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
if err := f(req.Context(), &request, &response); err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: &InternalAPIError{
Type: reflect.TypeOf(err).String(),
Message: fmt.Sprintf("%s", err),
},
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: &response,
}
})
}
func MakeInternalProxyAPI[reqtype, restype any](metricsName string, enableMetrics bool, f func(context.Context, *reqtype) (*restype, error)) http.Handler {
return MakeInternalAPI(metricsName, enableMetrics, func(req *http.Request) util.JSONResponse {
var request reqtype
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
response, err := f(req.Context(), &request)
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: err,
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: response,
}
})
}
func CallInternalRPCAPI[reqtype, restype any](name, url string, client *http.Client, ctx context.Context, request *reqtype, response *restype) error {
span, ctx := opentracing.StartSpanFromContext(ctx, name)
defer span.Finish()
return PostJSON[reqtype, restype, InternalAPIError](ctx, span, client, url, request, response)
}
func CallInternalProxyAPI[reqtype, restype any, errtype error](name, url string, client *http.Client, ctx context.Context, request *reqtype) (restype, error) {
span, ctx := opentracing.StartSpanFromContext(ctx, name)
defer span.Finish()
var response restype
return response, PostJSON[reqtype, restype, errtype](ctx, span, client, url, request, &response)
}

View file

@ -21,7 +21,6 @@ const (
PublicMediaPathPrefix = "/_matrix/media/"
PublicStaticPath = "/_matrix/static/"
PublicWellKnownPrefix = "/.well-known/matrix/"
InternalPathPrefix = "/api/"
DendriteAdminPathPrefix = "/_dendrite/"
SynapseAdminPathPrefix = "/_synapse/"
)

View file

@ -129,9 +129,9 @@ func checkFileHookParams(params map[string]interface{}) {
}
// Add a new FSHook to the logger. Each component will log in its own file
func setupFileHook(hook config.LogrusHook, level logrus.Level, componentName string) {
func setupFileHook(hook config.LogrusHook, level logrus.Level) {
dirPath := (hook.Params["path"]).(string)
fullPath := filepath.Join(dirPath, componentName+".log")
fullPath := filepath.Join(dirPath, "dendrite.log")
if err := os.MkdirAll(path.Dir(fullPath), os.ModePerm); err != nil {
logrus.Fatalf("Couldn't create directory %s: %q", path.Dir(fullPath), err)

View file

@ -31,7 +31,7 @@ import (
// SetupHookLogging configures the logging hooks defined in the configuration.
// If something fails here it means that the logging was improperly configured,
// so we just exit with the error
func SetupHookLogging(hooks []config.LogrusHook, componentName string) {
func SetupHookLogging(hooks []config.LogrusHook) {
levelLogAddedMu.Lock()
defer levelLogAddedMu.Unlock()
for _, hook := range hooks {
@ -50,10 +50,10 @@ func SetupHookLogging(hooks []config.LogrusHook, componentName string) {
switch hook.Type {
case "file":
checkFileHookParams(hook.Params)
setupFileHook(hook, level, componentName)
setupFileHook(hook, level)
case "syslog":
checkSyslogHookParams(hook.Params)
setupSyslogHook(hook, level, componentName)
setupSyslogHook(hook, level)
case "std":
setupStdLogHook(level)
default:
@ -94,8 +94,8 @@ func setupStdLogHook(level logrus.Level) {
stdLevelLogAdded[level] = true
}
func setupSyslogHook(hook config.LogrusHook, level logrus.Level, componentName string) {
syslogHook, err := lSyslog.NewSyslogHook(hook.Params["protocol"].(string), hook.Params["address"].(string), syslog.LOG_INFO, componentName)
func setupSyslogHook(hook config.LogrusHook, level logrus.Level) {
syslogHook, err := lSyslog.NewSyslogHook(hook.Params["protocol"].(string), hook.Params["address"].(string), syslog.LOG_INFO, "dendrite")
if err == nil {
logrus.AddHook(&logLevelHook{level, syslogHook})
}

View file

@ -22,7 +22,7 @@ import (
// SetupHookLogging configures the logging hooks defined in the configuration.
// If something fails here it means that the logging was improperly configured,
// so we just exit with the error
func SetupHookLogging(hooks []config.LogrusHook, componentName string) {
func SetupHookLogging(hooks []config.LogrusHook) {
logrus.SetReportCaller(true)
for _, hook := range hooks {
// Check we received a proper logging level
@ -40,7 +40,7 @@ func SetupHookLogging(hooks []config.LogrusHook, componentName string) {
switch hook.Type {
case "file":
checkFileHookParams(hook.Params)
setupFileHook(hook, level, componentName)
setupFileHook(hook, level)
default:
logrus.Fatalf("Unrecognised logging hook type: %s", hook.Type)
}

View file

@ -199,7 +199,7 @@ func createTransactionWithEDU(ctx *process.ProcessContext, edus []gomatrixserver
cfg := &config.Dendrite{}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
cfg.Global.JetStream.InMemory = true
natsInstance := &jetstream.NATSInstance{}
@ -647,7 +647,7 @@ func init() {
}
type testRoomserverAPI struct {
rsAPI.RoomserverInternalAPITrace
rsAPI.RoomserverInternalAPI
inputRoomEvents []rsAPI.InputRoomEvent
queryStateAfterEvents func(*rsAPI.QueryStateAfterEventsRequest) rsAPI.QueryStateAfterEventsResponse
queryEventsByID func(req *rsAPI.QueryEventsByIDRequest) rsAPI.QueryEventsByIDResponse

View file

@ -477,10 +477,6 @@ func (u *DeviceListUpdater) processServerUser(ctx context.Context, serverName go
return e.RetryAfter, err
} else if e.Blacklisted {
return time.Hour * 8, err
} else if e.Code >= 300 {
// We didn't get a real FederationClientError (e.g. in polylith mode, where gomatrix.HTTPError
// are "converted" to FederationClientError), but we probably shouldn't hit them every $waitTime seconds.
return hourWaitTime, err
}
case net.Error:
// Use the default waitTime, if it's a timeout.

View file

@ -1,186 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package inthttp
import (
"context"
"errors"
"net/http"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/keyserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
)
// HTTP paths for the internal HTTP APIs
const (
InputDeviceListUpdatePath = "/keyserver/inputDeviceListUpdate"
PerformUploadKeysPath = "/keyserver/performUploadKeys"
PerformClaimKeysPath = "/keyserver/performClaimKeys"
PerformDeleteKeysPath = "/keyserver/performDeleteKeys"
PerformUploadDeviceKeysPath = "/keyserver/performUploadDeviceKeys"
PerformUploadDeviceSignaturesPath = "/keyserver/performUploadDeviceSignatures"
QueryKeysPath = "/keyserver/queryKeys"
QueryKeyChangesPath = "/keyserver/queryKeyChanges"
QueryOneTimeKeysPath = "/keyserver/queryOneTimeKeys"
QueryDeviceMessagesPath = "/keyserver/queryDeviceMessages"
QuerySignaturesPath = "/keyserver/querySignatures"
PerformMarkAsStalePath = "/keyserver/markAsStale"
)
// NewKeyServerClient creates a KeyInternalAPI implemented by talking to a HTTP POST API.
// If httpClient is nil an error is returned
func NewKeyServerClient(
apiURL string,
httpClient *http.Client,
) (api.KeyInternalAPI, error) {
if httpClient == nil {
return nil, errors.New("NewKeyServerClient: httpClient is <nil>")
}
return &httpKeyInternalAPI{
apiURL: apiURL,
httpClient: httpClient,
}, nil
}
type httpKeyInternalAPI struct {
apiURL string
httpClient *http.Client
}
func (h *httpKeyInternalAPI) SetUserAPI(i userapi.KeyserverUserAPI) {
// no-op: doesn't need it
}
func (h *httpKeyInternalAPI) PerformClaimKeys(
ctx context.Context,
request *api.PerformClaimKeysRequest,
response *api.PerformClaimKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformClaimKeys", h.apiURL+PerformClaimKeysPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) PerformDeleteKeys(
ctx context.Context,
request *api.PerformDeleteKeysRequest,
response *api.PerformDeleteKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformDeleteKeys", h.apiURL+PerformDeleteKeysPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) PerformUploadKeys(
ctx context.Context,
request *api.PerformUploadKeysRequest,
response *api.PerformUploadKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformUploadKeys", h.apiURL+PerformUploadKeysPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) QueryKeys(
ctx context.Context,
request *api.QueryKeysRequest,
response *api.QueryKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryKeys", h.apiURL+QueryKeysPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) QueryOneTimeKeys(
ctx context.Context,
request *api.QueryOneTimeKeysRequest,
response *api.QueryOneTimeKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryOneTimeKeys", h.apiURL+QueryOneTimeKeysPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) QueryDeviceMessages(
ctx context.Context,
request *api.QueryDeviceMessagesRequest,
response *api.QueryDeviceMessagesResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryDeviceMessages", h.apiURL+QueryDeviceMessagesPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) QueryKeyChanges(
ctx context.Context,
request *api.QueryKeyChangesRequest,
response *api.QueryKeyChangesResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryKeyChanges", h.apiURL+QueryKeyChangesPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) PerformUploadDeviceKeys(
ctx context.Context,
request *api.PerformUploadDeviceKeysRequest,
response *api.PerformUploadDeviceKeysResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformUploadDeviceKeys", h.apiURL+PerformUploadDeviceKeysPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) PerformUploadDeviceSignatures(
ctx context.Context,
request *api.PerformUploadDeviceSignaturesRequest,
response *api.PerformUploadDeviceSignaturesResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformUploadDeviceSignatures", h.apiURL+PerformUploadDeviceSignaturesPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) QuerySignatures(
ctx context.Context,
request *api.QuerySignaturesRequest,
response *api.QuerySignaturesResponse,
) error {
return httputil.CallInternalRPCAPI(
"QuerySignatures", h.apiURL+QuerySignaturesPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpKeyInternalAPI) PerformMarkAsStaleIfNeeded(
ctx context.Context,
request *api.PerformMarkAsStaleRequest,
response *struct{},
) error {
return httputil.CallInternalRPCAPI(
"MarkAsStale", h.apiURL+PerformMarkAsStalePath,
h.httpClient, ctx, request, response,
)
}

View file

@ -1,79 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package inthttp
import (
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/keyserver/api"
)
func AddRoutes(internalAPIMux *mux.Router, s api.KeyInternalAPI, enableMetrics bool) {
internalAPIMux.Handle(
PerformClaimKeysPath,
httputil.MakeInternalRPCAPI("KeyserverPerformClaimKeys", enableMetrics, s.PerformClaimKeys),
)
internalAPIMux.Handle(
PerformDeleteKeysPath,
httputil.MakeInternalRPCAPI("KeyserverPerformDeleteKeys", enableMetrics, s.PerformDeleteKeys),
)
internalAPIMux.Handle(
PerformUploadKeysPath,
httputil.MakeInternalRPCAPI("KeyserverPerformUploadKeys", enableMetrics, s.PerformUploadKeys),
)
internalAPIMux.Handle(
PerformUploadDeviceKeysPath,
httputil.MakeInternalRPCAPI("KeyserverPerformUploadDeviceKeys", enableMetrics, s.PerformUploadDeviceKeys),
)
internalAPIMux.Handle(
PerformUploadDeviceSignaturesPath,
httputil.MakeInternalRPCAPI("KeyserverPerformUploadDeviceSignatures", enableMetrics, s.PerformUploadDeviceSignatures),
)
internalAPIMux.Handle(
QueryKeysPath,
httputil.MakeInternalRPCAPI("KeyserverQueryKeys", enableMetrics, s.QueryKeys),
)
internalAPIMux.Handle(
QueryOneTimeKeysPath,
httputil.MakeInternalRPCAPI("KeyserverQueryOneTimeKeys", enableMetrics, s.QueryOneTimeKeys),
)
internalAPIMux.Handle(
QueryDeviceMessagesPath,
httputil.MakeInternalRPCAPI("KeyserverQueryDeviceMessages", enableMetrics, s.QueryDeviceMessages),
)
internalAPIMux.Handle(
QueryKeyChangesPath,
httputil.MakeInternalRPCAPI("KeyserverQueryKeyChanges", enableMetrics, s.QueryKeyChanges),
)
internalAPIMux.Handle(
QuerySignaturesPath,
httputil.MakeInternalRPCAPI("KeyserverQuerySignatures", enableMetrics, s.QuerySignatures),
)
internalAPIMux.Handle(
PerformMarkAsStalePath,
httputil.MakeInternalRPCAPI("KeyserverMarkAsStale", enableMetrics, s.PerformMarkAsStaleIfNeeded),
)
}

View file

@ -15,7 +15,6 @@
package keyserver
import (
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
rsapi "github.com/matrix-org/dendrite/roomserver/api"
@ -24,7 +23,6 @@ import (
"github.com/matrix-org/dendrite/keyserver/api"
"github.com/matrix-org/dendrite/keyserver/consumers"
"github.com/matrix-org/dendrite/keyserver/internal"
"github.com/matrix-org/dendrite/keyserver/inthttp"
"github.com/matrix-org/dendrite/keyserver/producers"
"github.com/matrix-org/dendrite/keyserver/storage"
"github.com/matrix-org/dendrite/setup/base"
@ -32,12 +30,6 @@ import (
"github.com/matrix-org/dendrite/setup/jetstream"
)
// AddInternalRoutes registers HTTP handlers for the internal API. Invokes functions
// on the given input API.
func AddInternalRoutes(router *mux.Router, intAPI api.KeyInternalAPI, enableMetrics bool) {
inthttp.AddRoutes(router, intAPI, enableMetrics)
}
// NewInternalAPI returns a concerete implementation of the internal API. Callers
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI(

View file

@ -1,427 +0,0 @@
package api
import (
"context"
"encoding/json"
"fmt"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
asAPI "github.com/matrix-org/dendrite/appservice/api"
fsAPI "github.com/matrix-org/dendrite/federationapi/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
)
// RoomserverInternalAPITrace wraps a RoomserverInternalAPI and logs the
// complete request/response/error
type RoomserverInternalAPITrace struct {
Impl RoomserverInternalAPI
}
func (t *RoomserverInternalAPITrace) QueryLeftUsers(ctx context.Context, req *QueryLeftUsersRequest, res *QueryLeftUsersResponse) error {
err := t.Impl.QueryLeftUsers(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryLeftUsers req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) SetFederationAPI(fsAPI fsAPI.RoomserverFederationAPI, keyRing *gomatrixserverlib.KeyRing) {
t.Impl.SetFederationAPI(fsAPI, keyRing)
}
func (t *RoomserverInternalAPITrace) SetAppserviceAPI(asAPI asAPI.AppServiceInternalAPI) {
t.Impl.SetAppserviceAPI(asAPI)
}
func (t *RoomserverInternalAPITrace) SetUserAPI(userAPI userapi.RoomserverUserAPI) {
t.Impl.SetUserAPI(userAPI)
}
func (t *RoomserverInternalAPITrace) InputRoomEvents(
ctx context.Context,
req *InputRoomEventsRequest,
res *InputRoomEventsResponse,
) error {
err := t.Impl.InputRoomEvents(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("InputRoomEvents req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformInvite(
ctx context.Context,
req *PerformInviteRequest,
res *PerformInviteResponse,
) error {
err := t.Impl.PerformInvite(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformInvite req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformPeek(
ctx context.Context,
req *PerformPeekRequest,
res *PerformPeekResponse,
) error {
err := t.Impl.PerformPeek(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformPeek req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformUnpeek(
ctx context.Context,
req *PerformUnpeekRequest,
res *PerformUnpeekResponse,
) error {
err := t.Impl.PerformUnpeek(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformUnpeek req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformRoomUpgrade(
ctx context.Context,
req *PerformRoomUpgradeRequest,
res *PerformRoomUpgradeResponse,
) error {
err := t.Impl.PerformRoomUpgrade(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformRoomUpgrade req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformJoin(
ctx context.Context,
req *PerformJoinRequest,
res *PerformJoinResponse,
) error {
err := t.Impl.PerformJoin(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformJoin req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformLeave(
ctx context.Context,
req *PerformLeaveRequest,
res *PerformLeaveResponse,
) error {
err := t.Impl.PerformLeave(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformLeave req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformPublish(
ctx context.Context,
req *PerformPublishRequest,
res *PerformPublishResponse,
) error {
err := t.Impl.PerformPublish(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformPublish req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformAdminEvacuateRoom(
ctx context.Context,
req *PerformAdminEvacuateRoomRequest,
res *PerformAdminEvacuateRoomResponse,
) error {
err := t.Impl.PerformAdminEvacuateRoom(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformAdminEvacuateRoom req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformAdminEvacuateUser(
ctx context.Context,
req *PerformAdminEvacuateUserRequest,
res *PerformAdminEvacuateUserResponse,
) error {
err := t.Impl.PerformAdminEvacuateUser(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformAdminEvacuateUser req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformAdminPurgeRoom(
ctx context.Context,
req *PerformAdminPurgeRoomRequest,
res *PerformAdminPurgeRoomResponse,
) error {
err := t.Impl.PerformAdminPurgeRoom(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformAdminPurgeRoom req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformAdminDownloadState(
ctx context.Context,
req *PerformAdminDownloadStateRequest,
res *PerformAdminDownloadStateResponse,
) error {
err := t.Impl.PerformAdminDownloadState(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformAdminDownloadState req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformInboundPeek(
ctx context.Context,
req *PerformInboundPeekRequest,
res *PerformInboundPeekResponse,
) error {
err := t.Impl.PerformInboundPeek(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformInboundPeek req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryPublishedRooms(
ctx context.Context,
req *QueryPublishedRoomsRequest,
res *QueryPublishedRoomsResponse,
) error {
err := t.Impl.QueryPublishedRooms(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryPublishedRooms req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryLatestEventsAndState(
ctx context.Context,
req *QueryLatestEventsAndStateRequest,
res *QueryLatestEventsAndStateResponse,
) error {
err := t.Impl.QueryLatestEventsAndState(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryLatestEventsAndState req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryStateAfterEvents(
ctx context.Context,
req *QueryStateAfterEventsRequest,
res *QueryStateAfterEventsResponse,
) error {
err := t.Impl.QueryStateAfterEvents(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryStateAfterEvents req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryEventsByID(
ctx context.Context,
req *QueryEventsByIDRequest,
res *QueryEventsByIDResponse,
) error {
err := t.Impl.QueryEventsByID(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryEventsByID req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryMembershipForUser(
ctx context.Context,
req *QueryMembershipForUserRequest,
res *QueryMembershipForUserResponse,
) error {
err := t.Impl.QueryMembershipForUser(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryMembershipForUser req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryMembershipsForRoom(
ctx context.Context,
req *QueryMembershipsForRoomRequest,
res *QueryMembershipsForRoomResponse,
) error {
err := t.Impl.QueryMembershipsForRoom(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryMembershipsForRoom req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryServerJoinedToRoom(
ctx context.Context,
req *QueryServerJoinedToRoomRequest,
res *QueryServerJoinedToRoomResponse,
) error {
err := t.Impl.QueryServerJoinedToRoom(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryServerJoinedToRoom req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryServerAllowedToSeeEvent(
ctx context.Context,
req *QueryServerAllowedToSeeEventRequest,
res *QueryServerAllowedToSeeEventResponse,
) error {
err := t.Impl.QueryServerAllowedToSeeEvent(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryServerAllowedToSeeEvent req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryMissingEvents(
ctx context.Context,
req *QueryMissingEventsRequest,
res *QueryMissingEventsResponse,
) error {
err := t.Impl.QueryMissingEvents(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryMissingEvents req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryStateAndAuthChain(
ctx context.Context,
req *QueryStateAndAuthChainRequest,
res *QueryStateAndAuthChainResponse,
) error {
err := t.Impl.QueryStateAndAuthChain(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryStateAndAuthChain req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformBackfill(
ctx context.Context,
req *PerformBackfillRequest,
res *PerformBackfillResponse,
) error {
err := t.Impl.PerformBackfill(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformBackfill req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) PerformForget(
ctx context.Context,
req *PerformForgetRequest,
res *PerformForgetResponse,
) error {
err := t.Impl.PerformForget(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("PerformForget req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryRoomVersionCapabilities(
ctx context.Context,
req *QueryRoomVersionCapabilitiesRequest,
res *QueryRoomVersionCapabilitiesResponse,
) error {
err := t.Impl.QueryRoomVersionCapabilities(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryRoomVersionCapabilities req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryRoomVersionForRoom(
ctx context.Context,
req *QueryRoomVersionForRoomRequest,
res *QueryRoomVersionForRoomResponse,
) error {
err := t.Impl.QueryRoomVersionForRoom(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryRoomVersionForRoom req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) SetRoomAlias(
ctx context.Context,
req *SetRoomAliasRequest,
res *SetRoomAliasResponse,
) error {
err := t.Impl.SetRoomAlias(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("SetRoomAlias req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) GetRoomIDForAlias(
ctx context.Context,
req *GetRoomIDForAliasRequest,
res *GetRoomIDForAliasResponse,
) error {
err := t.Impl.GetRoomIDForAlias(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("GetRoomIDForAlias req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) GetAliasesForRoomID(
ctx context.Context,
req *GetAliasesForRoomIDRequest,
res *GetAliasesForRoomIDResponse,
) error {
err := t.Impl.GetAliasesForRoomID(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("GetAliasesForRoomID req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) RemoveRoomAlias(
ctx context.Context,
req *RemoveRoomAliasRequest,
res *RemoveRoomAliasResponse,
) error {
err := t.Impl.RemoveRoomAlias(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("RemoveRoomAlias req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error {
err := t.Impl.QueryCurrentState(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryCurrentState req=%+v res=%+v", js(req), js(res))
return err
}
// QueryRoomsForUser retrieves a list of room IDs matching the given query.
func (t *RoomserverInternalAPITrace) QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error {
err := t.Impl.QueryRoomsForUser(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryRoomsForUser req=%+v res=%+v", js(req), js(res))
return err
}
// QueryBulkStateContent does a bulk query for state event content in the given rooms.
func (t *RoomserverInternalAPITrace) QueryBulkStateContent(ctx context.Context, req *QueryBulkStateContentRequest, res *QueryBulkStateContentResponse) error {
err := t.Impl.QueryBulkStateContent(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryBulkStateContent req=%+v res=%+v", js(req), js(res))
return err
}
// QuerySharedUsers returns a list of users who share at least 1 room in common with the given user.
func (t *RoomserverInternalAPITrace) QuerySharedUsers(ctx context.Context, req *QuerySharedUsersRequest, res *QuerySharedUsersResponse) error {
err := t.Impl.QuerySharedUsers(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QuerySharedUsers req=%+v res=%+v", js(req), js(res))
return err
}
// QueryKnownUsers returns a list of users that we know about from our joined rooms.
func (t *RoomserverInternalAPITrace) QueryKnownUsers(ctx context.Context, req *QueryKnownUsersRequest, res *QueryKnownUsersResponse) error {
err := t.Impl.QueryKnownUsers(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryKnownUsers req=%+v res=%+v", js(req), js(res))
return err
}
// QueryServerBannedFromRoom returns whether a server is banned from a room by server ACLs.
func (t *RoomserverInternalAPITrace) QueryServerBannedFromRoom(ctx context.Context, req *QueryServerBannedFromRoomRequest, res *QueryServerBannedFromRoomResponse) error {
err := t.Impl.QueryServerBannedFromRoom(ctx, req, res)
util.GetLogger(ctx).WithError(err).Infof("QueryServerBannedFromRoom req=%+v res=%+v", js(req), js(res))
return err
}
func (t *RoomserverInternalAPITrace) QueryAuthChain(
ctx context.Context,
request *QueryAuthChainRequest,
response *QueryAuthChainResponse,
) error {
err := t.Impl.QueryAuthChain(ctx, request, response)
util.GetLogger(ctx).WithError(err).Infof("QueryAuthChain req=%+v res=%+v", js(request), js(response))
return err
}
func (t *RoomserverInternalAPITrace) QueryRestrictedJoinAllowed(
ctx context.Context,
request *QueryRestrictedJoinAllowedRequest,
response *QueryRestrictedJoinAllowedResponse,
) error {
err := t.Impl.QueryRestrictedJoinAllowed(ctx, request, response)
util.GetLogger(ctx).WithError(err).Infof("QueryRestrictedJoinAllowed req=%+v res=%+v", js(request), js(response))
return err
}
func (t *RoomserverInternalAPITrace) QueryMembershipAtEvent(
ctx context.Context,
request *QueryMembershipAtEventRequest,
response *QueryMembershipAtEventResponse,
) error {
err := t.Impl.QueryMembershipAtEvent(ctx, request, response)
util.GetLogger(ctx).WithError(err).Infof("QueryMembershipAtEvent req=%+v res=%+v", js(request), js(response))
return err
}
func js(thing interface{}) string {
b, err := json.Marshal(thing)
if err != nil {
return fmt.Sprintf("Marshal error:%s", err)
}
return string(b)
}

View file

@ -1,575 +0,0 @@
package inthttp
import (
"context"
"errors"
"net/http"
"github.com/matrix-org/gomatrixserverlib"
asAPI "github.com/matrix-org/dendrite/appservice/api"
fsInputAPI "github.com/matrix-org/dendrite/federationapi/api"
"github.com/matrix-org/dendrite/internal/caching"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/roomserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
)
const (
// Alias operations
RoomserverSetRoomAliasPath = "/roomserver/setRoomAlias"
RoomserverGetRoomIDForAliasPath = "/roomserver/GetRoomIDForAlias"
RoomserverGetAliasesForRoomIDPath = "/roomserver/GetAliasesForRoomID"
RoomserverGetCreatorIDForAliasPath = "/roomserver/GetCreatorIDForAlias"
RoomserverRemoveRoomAliasPath = "/roomserver/removeRoomAlias"
// Input operations
RoomserverInputRoomEventsPath = "/roomserver/inputRoomEvents"
// Perform operations
RoomserverPerformInvitePath = "/roomserver/performInvite"
RoomserverPerformPeekPath = "/roomserver/performPeek"
RoomserverPerformUnpeekPath = "/roomserver/performUnpeek"
RoomserverPerformRoomUpgradePath = "/roomserver/performRoomUpgrade"
RoomserverPerformJoinPath = "/roomserver/performJoin"
RoomserverPerformLeavePath = "/roomserver/performLeave"
RoomserverPerformBackfillPath = "/roomserver/performBackfill"
RoomserverPerformPublishPath = "/roomserver/performPublish"
RoomserverPerformInboundPeekPath = "/roomserver/performInboundPeek"
RoomserverPerformForgetPath = "/roomserver/performForget"
RoomserverPerformAdminEvacuateRoomPath = "/roomserver/performAdminEvacuateRoom"
RoomserverPerformAdminEvacuateUserPath = "/roomserver/performAdminEvacuateUser"
RoomserverPerformAdminDownloadStatePath = "/roomserver/performAdminDownloadState"
RoomserverPerformAdminPurgeRoomPath = "/roomserver/performAdminPurgeRoom"
// Query operations
RoomserverQueryLatestEventsAndStatePath = "/roomserver/queryLatestEventsAndState"
RoomserverQueryStateAfterEventsPath = "/roomserver/queryStateAfterEvents"
RoomserverQueryEventsByIDPath = "/roomserver/queryEventsByID"
RoomserverQueryMembershipForUserPath = "/roomserver/queryMembershipForUser"
RoomserverQueryMembershipsForRoomPath = "/roomserver/queryMembershipsForRoom"
RoomserverQueryServerJoinedToRoomPath = "/roomserver/queryServerJoinedToRoomPath"
RoomserverQueryServerAllowedToSeeEventPath = "/roomserver/queryServerAllowedToSeeEvent"
RoomserverQueryMissingEventsPath = "/roomserver/queryMissingEvents"
RoomserverQueryStateAndAuthChainPath = "/roomserver/queryStateAndAuthChain"
RoomserverQueryRoomVersionCapabilitiesPath = "/roomserver/queryRoomVersionCapabilities"
RoomserverQueryRoomVersionForRoomPath = "/roomserver/queryRoomVersionForRoom"
RoomserverQueryPublishedRoomsPath = "/roomserver/queryPublishedRooms"
RoomserverQueryCurrentStatePath = "/roomserver/queryCurrentState"
RoomserverQueryRoomsForUserPath = "/roomserver/queryRoomsForUser"
RoomserverQueryBulkStateContentPath = "/roomserver/queryBulkStateContent"
RoomserverQuerySharedUsersPath = "/roomserver/querySharedUsers"
RoomserverQueryKnownUsersPath = "/roomserver/queryKnownUsers"
RoomserverQueryServerBannedFromRoomPath = "/roomserver/queryServerBannedFromRoom"
RoomserverQueryAuthChainPath = "/roomserver/queryAuthChain"
RoomserverQueryRestrictedJoinAllowed = "/roomserver/queryRestrictedJoinAllowed"
RoomserverQueryMembershipAtEventPath = "/roomserver/queryMembershipAtEvent"
RoomserverQueryLeftMembersPath = "/roomserver/queryLeftMembers"
)
type httpRoomserverInternalAPI struct {
roomserverURL string
httpClient *http.Client
cache caching.RoomVersionCache
}
// NewRoomserverClient creates a RoomserverInputAPI implemented by talking to a HTTP POST API.
// If httpClient is nil an error is returned
func NewRoomserverClient(
roomserverURL string,
httpClient *http.Client,
cache caching.RoomVersionCache,
) (api.RoomserverInternalAPI, error) {
if httpClient == nil {
return nil, errors.New("NewRoomserverInternalAPIHTTP: httpClient is <nil>")
}
return &httpRoomserverInternalAPI{
roomserverURL: roomserverURL,
httpClient: httpClient,
cache: cache,
}, nil
}
// SetFederationInputAPI no-ops in HTTP client mode as there is no chicken/egg scenario
func (h *httpRoomserverInternalAPI) SetFederationAPI(fsAPI fsInputAPI.RoomserverFederationAPI, keyRing *gomatrixserverlib.KeyRing) {
}
// SetAppserviceAPI no-ops in HTTP client mode as there is no chicken/egg scenario
func (h *httpRoomserverInternalAPI) SetAppserviceAPI(asAPI asAPI.AppServiceInternalAPI) {
}
// SetUserAPI no-ops in HTTP client mode as there is no chicken/egg scenario
func (h *httpRoomserverInternalAPI) SetUserAPI(userAPI userapi.RoomserverUserAPI) {
}
// SetRoomAlias implements RoomserverAliasAPI
func (h *httpRoomserverInternalAPI) SetRoomAlias(
ctx context.Context,
request *api.SetRoomAliasRequest,
response *api.SetRoomAliasResponse,
) error {
return httputil.CallInternalRPCAPI(
"SetRoomAlias", h.roomserverURL+RoomserverSetRoomAliasPath,
h.httpClient, ctx, request, response,
)
}
// GetRoomIDForAlias implements RoomserverAliasAPI
func (h *httpRoomserverInternalAPI) GetRoomIDForAlias(
ctx context.Context,
request *api.GetRoomIDForAliasRequest,
response *api.GetRoomIDForAliasResponse,
) error {
return httputil.CallInternalRPCAPI(
"GetRoomIDForAlias", h.roomserverURL+RoomserverGetRoomIDForAliasPath,
h.httpClient, ctx, request, response,
)
}
// GetAliasesForRoomID implements RoomserverAliasAPI
func (h *httpRoomserverInternalAPI) GetAliasesForRoomID(
ctx context.Context,
request *api.GetAliasesForRoomIDRequest,
response *api.GetAliasesForRoomIDResponse,
) error {
return httputil.CallInternalRPCAPI(
"GetAliasesForRoomID", h.roomserverURL+RoomserverGetAliasesForRoomIDPath,
h.httpClient, ctx, request, response,
)
}
// RemoveRoomAlias implements RoomserverAliasAPI
func (h *httpRoomserverInternalAPI) RemoveRoomAlias(
ctx context.Context,
request *api.RemoveRoomAliasRequest,
response *api.RemoveRoomAliasResponse,
) error {
return httputil.CallInternalRPCAPI(
"RemoveRoomAlias", h.roomserverURL+RoomserverRemoveRoomAliasPath,
h.httpClient, ctx, request, response,
)
}
// InputRoomEvents implements RoomserverInputAPI
func (h *httpRoomserverInternalAPI) InputRoomEvents(
ctx context.Context,
request *api.InputRoomEventsRequest,
response *api.InputRoomEventsResponse,
) error {
if err := httputil.CallInternalRPCAPI(
"InputRoomEvents", h.roomserverURL+RoomserverInputRoomEventsPath,
h.httpClient, ctx, request, response,
); err != nil {
response.ErrMsg = err.Error()
}
return nil
}
func (h *httpRoomserverInternalAPI) PerformInvite(
ctx context.Context,
request *api.PerformInviteRequest,
response *api.PerformInviteResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformInvite", h.roomserverURL+RoomserverPerformInvitePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformJoin(
ctx context.Context,
request *api.PerformJoinRequest,
response *api.PerformJoinResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformJoin", h.roomserverURL+RoomserverPerformJoinPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformPeek(
ctx context.Context,
request *api.PerformPeekRequest,
response *api.PerformPeekResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformPeek", h.roomserverURL+RoomserverPerformPeekPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformInboundPeek(
ctx context.Context,
request *api.PerformInboundPeekRequest,
response *api.PerformInboundPeekResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformInboundPeek", h.roomserverURL+RoomserverPerformInboundPeekPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformUnpeek(
ctx context.Context,
request *api.PerformUnpeekRequest,
response *api.PerformUnpeekResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformUnpeek", h.roomserverURL+RoomserverPerformUnpeekPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformRoomUpgrade(
ctx context.Context,
request *api.PerformRoomUpgradeRequest,
response *api.PerformRoomUpgradeResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformRoomUpgrade", h.roomserverURL+RoomserverPerformRoomUpgradePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformLeave(
ctx context.Context,
request *api.PerformLeaveRequest,
response *api.PerformLeaveResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformLeave", h.roomserverURL+RoomserverPerformLeavePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformPublish(
ctx context.Context,
request *api.PerformPublishRequest,
response *api.PerformPublishResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformPublish", h.roomserverURL+RoomserverPerformPublishPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformAdminEvacuateRoom(
ctx context.Context,
request *api.PerformAdminEvacuateRoomRequest,
response *api.PerformAdminEvacuateRoomResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformAdminEvacuateRoom", h.roomserverURL+RoomserverPerformAdminEvacuateRoomPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformAdminDownloadState(
ctx context.Context,
request *api.PerformAdminDownloadStateRequest,
response *api.PerformAdminDownloadStateResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformAdminDownloadState", h.roomserverURL+RoomserverPerformAdminDownloadStatePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformAdminEvacuateUser(
ctx context.Context,
request *api.PerformAdminEvacuateUserRequest,
response *api.PerformAdminEvacuateUserResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformAdminEvacuateUser", h.roomserverURL+RoomserverPerformAdminEvacuateUserPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformAdminPurgeRoom(
ctx context.Context,
request *api.PerformAdminPurgeRoomRequest,
response *api.PerformAdminPurgeRoomResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformAdminPurgeRoom", h.roomserverURL+RoomserverPerformAdminPurgeRoomPath,
h.httpClient, ctx, request, response,
)
}
// QueryLatestEventsAndState implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryLatestEventsAndState(
ctx context.Context,
request *api.QueryLatestEventsAndStateRequest,
response *api.QueryLatestEventsAndStateResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryLatestEventsAndState", h.roomserverURL+RoomserverQueryLatestEventsAndStatePath,
h.httpClient, ctx, request, response,
)
}
// QueryStateAfterEvents implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryStateAfterEvents(
ctx context.Context,
request *api.QueryStateAfterEventsRequest,
response *api.QueryStateAfterEventsResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryStateAfterEvents", h.roomserverURL+RoomserverQueryStateAfterEventsPath,
h.httpClient, ctx, request, response,
)
}
// QueryEventsByID implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryEventsByID(
ctx context.Context,
request *api.QueryEventsByIDRequest,
response *api.QueryEventsByIDResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryEventsByID", h.roomserverURL+RoomserverQueryEventsByIDPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryPublishedRooms(
ctx context.Context,
request *api.QueryPublishedRoomsRequest,
response *api.QueryPublishedRoomsResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryPublishedRooms", h.roomserverURL+RoomserverQueryPublishedRoomsPath,
h.httpClient, ctx, request, response,
)
}
// QueryMembershipForUser implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryMembershipForUser(
ctx context.Context,
request *api.QueryMembershipForUserRequest,
response *api.QueryMembershipForUserResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryMembershipForUser", h.roomserverURL+RoomserverQueryMembershipForUserPath,
h.httpClient, ctx, request, response,
)
}
// QueryMembershipsForRoom implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryMembershipsForRoom(
ctx context.Context,
request *api.QueryMembershipsForRoomRequest,
response *api.QueryMembershipsForRoomResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryMembershipsForRoom", h.roomserverURL+RoomserverQueryMembershipsForRoomPath,
h.httpClient, ctx, request, response,
)
}
// QueryMembershipsForRoom implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryServerJoinedToRoom(
ctx context.Context,
request *api.QueryServerJoinedToRoomRequest,
response *api.QueryServerJoinedToRoomResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryServerJoinedToRoom", h.roomserverURL+RoomserverQueryServerJoinedToRoomPath,
h.httpClient, ctx, request, response,
)
}
// QueryServerAllowedToSeeEvent implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryServerAllowedToSeeEvent(
ctx context.Context,
request *api.QueryServerAllowedToSeeEventRequest,
response *api.QueryServerAllowedToSeeEventResponse,
) (err error) {
return httputil.CallInternalRPCAPI(
"QueryServerAllowedToSeeEvent", h.roomserverURL+RoomserverQueryServerAllowedToSeeEventPath,
h.httpClient, ctx, request, response,
)
}
// QueryMissingEvents implements RoomServerQueryAPI
func (h *httpRoomserverInternalAPI) QueryMissingEvents(
ctx context.Context,
request *api.QueryMissingEventsRequest,
response *api.QueryMissingEventsResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryMissingEvents", h.roomserverURL+RoomserverQueryMissingEventsPath,
h.httpClient, ctx, request, response,
)
}
// QueryStateAndAuthChain implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryStateAndAuthChain(
ctx context.Context,
request *api.QueryStateAndAuthChainRequest,
response *api.QueryStateAndAuthChainResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryStateAndAuthChain", h.roomserverURL+RoomserverQueryStateAndAuthChainPath,
h.httpClient, ctx, request, response,
)
}
// PerformBackfill implements RoomServerQueryAPI
func (h *httpRoomserverInternalAPI) PerformBackfill(
ctx context.Context,
request *api.PerformBackfillRequest,
response *api.PerformBackfillResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformBackfill", h.roomserverURL+RoomserverPerformBackfillPath,
h.httpClient, ctx, request, response,
)
}
// QueryRoomVersionCapabilities implements RoomServerQueryAPI
func (h *httpRoomserverInternalAPI) QueryRoomVersionCapabilities(
ctx context.Context,
request *api.QueryRoomVersionCapabilitiesRequest,
response *api.QueryRoomVersionCapabilitiesResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryRoomVersionCapabilities", h.roomserverURL+RoomserverQueryRoomVersionCapabilitiesPath,
h.httpClient, ctx, request, response,
)
}
// QueryRoomVersionForRoom implements RoomServerQueryAPI
func (h *httpRoomserverInternalAPI) QueryRoomVersionForRoom(
ctx context.Context,
request *api.QueryRoomVersionForRoomRequest,
response *api.QueryRoomVersionForRoomResponse,
) error {
if roomVersion, ok := h.cache.GetRoomVersion(request.RoomID); ok {
response.RoomVersion = roomVersion
return nil
}
err := httputil.CallInternalRPCAPI(
"QueryRoomVersionForRoom", h.roomserverURL+RoomserverQueryRoomVersionForRoomPath,
h.httpClient, ctx, request, response,
)
if err == nil {
h.cache.StoreRoomVersion(request.RoomID, response.RoomVersion)
}
return err
}
func (h *httpRoomserverInternalAPI) QueryCurrentState(
ctx context.Context,
request *api.QueryCurrentStateRequest,
response *api.QueryCurrentStateResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryCurrentState", h.roomserverURL+RoomserverQueryCurrentStatePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryRoomsForUser(
ctx context.Context,
request *api.QueryRoomsForUserRequest,
response *api.QueryRoomsForUserResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryRoomsForUser", h.roomserverURL+RoomserverQueryRoomsForUserPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryBulkStateContent(
ctx context.Context,
request *api.QueryBulkStateContentRequest,
response *api.QueryBulkStateContentResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryBulkStateContent", h.roomserverURL+RoomserverQueryBulkStateContentPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QuerySharedUsers(
ctx context.Context,
request *api.QuerySharedUsersRequest,
response *api.QuerySharedUsersResponse,
) error {
return httputil.CallInternalRPCAPI(
"QuerySharedUsers", h.roomserverURL+RoomserverQuerySharedUsersPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryKnownUsers(
ctx context.Context,
request *api.QueryKnownUsersRequest,
response *api.QueryKnownUsersResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryKnownUsers", h.roomserverURL+RoomserverQueryKnownUsersPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryAuthChain(
ctx context.Context,
request *api.QueryAuthChainRequest,
response *api.QueryAuthChainResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryAuthChain", h.roomserverURL+RoomserverQueryAuthChainPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryServerBannedFromRoom(
ctx context.Context,
request *api.QueryServerBannedFromRoomRequest,
response *api.QueryServerBannedFromRoomResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryServerBannedFromRoom", h.roomserverURL+RoomserverQueryServerBannedFromRoomPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryRestrictedJoinAllowed(
ctx context.Context,
request *api.QueryRestrictedJoinAllowedRequest,
response *api.QueryRestrictedJoinAllowedResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryRestrictedJoinAllowed", h.roomserverURL+RoomserverQueryRestrictedJoinAllowed,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) PerformForget(
ctx context.Context,
request *api.PerformForgetRequest,
response *api.PerformForgetResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformForget", h.roomserverURL+RoomserverPerformForgetPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryMembershipAtEvent(ctx context.Context, request *api.QueryMembershipAtEventRequest, response *api.QueryMembershipAtEventResponse) error {
return httputil.CallInternalRPCAPI(
"QueryMembershiptAtEvent", h.roomserverURL+RoomserverQueryMembershipAtEventPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpRoomserverInternalAPI) QueryLeftUsers(ctx context.Context, request *api.QueryLeftUsersRequest, response *api.QueryLeftUsersResponse) error {
return httputil.CallInternalRPCAPI(
"RoomserverQueryLeftMembers", h.roomserverURL+RoomserverQueryLeftMembersPath,
h.httpClient, ctx, request, response,
)
}

View file

@ -1,216 +0,0 @@
package inthttp
import (
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/roomserver/api"
)
// AddRoutes adds the RoomserverInternalAPI handlers to the http.ServeMux.
// nolint: gocyclo
func AddRoutes(r api.RoomserverInternalAPI, internalAPIMux *mux.Router, enableMetrics bool) {
internalAPIMux.Handle(
RoomserverInputRoomEventsPath,
httputil.MakeInternalRPCAPI("RoomserverInputRoomEvents", enableMetrics, r.InputRoomEvents),
)
internalAPIMux.Handle(
RoomserverPerformInvitePath,
httputil.MakeInternalRPCAPI("RoomserverPerformInvite", enableMetrics, r.PerformInvite),
)
internalAPIMux.Handle(
RoomserverPerformJoinPath,
httputil.MakeInternalRPCAPI("RoomserverPerformJoin", enableMetrics, r.PerformJoin),
)
internalAPIMux.Handle(
RoomserverPerformLeavePath,
httputil.MakeInternalRPCAPI("RoomserverPerformLeave", enableMetrics, r.PerformLeave),
)
internalAPIMux.Handle(
RoomserverPerformPeekPath,
httputil.MakeInternalRPCAPI("RoomserverPerformPeek", enableMetrics, r.PerformPeek),
)
internalAPIMux.Handle(
RoomserverPerformInboundPeekPath,
httputil.MakeInternalRPCAPI("RoomserverPerformInboundPeek", enableMetrics, r.PerformInboundPeek),
)
internalAPIMux.Handle(
RoomserverPerformUnpeekPath,
httputil.MakeInternalRPCAPI("RoomserverPerformUnpeek", enableMetrics, r.PerformUnpeek),
)
internalAPIMux.Handle(
RoomserverPerformRoomUpgradePath,
httputil.MakeInternalRPCAPI("RoomserverPerformRoomUpgrade", enableMetrics, r.PerformRoomUpgrade),
)
internalAPIMux.Handle(
RoomserverPerformPublishPath,
httputil.MakeInternalRPCAPI("RoomserverPerformPublish", enableMetrics, r.PerformPublish),
)
internalAPIMux.Handle(
RoomserverPerformAdminEvacuateRoomPath,
httputil.MakeInternalRPCAPI("RoomserverPerformAdminEvacuateRoom", enableMetrics, r.PerformAdminEvacuateRoom),
)
internalAPIMux.Handle(
RoomserverPerformAdminEvacuateUserPath,
httputil.MakeInternalRPCAPI("RoomserverPerformAdminEvacuateUser", enableMetrics, r.PerformAdminEvacuateUser),
)
internalAPIMux.Handle(
RoomserverPerformAdminPurgeRoomPath,
httputil.MakeInternalRPCAPI("RoomserverPerformAdminPurgeRoom", enableMetrics, r.PerformAdminPurgeRoom),
)
internalAPIMux.Handle(
RoomserverPerformAdminDownloadStatePath,
httputil.MakeInternalRPCAPI("RoomserverPerformAdminDownloadState", enableMetrics, r.PerformAdminDownloadState),
)
internalAPIMux.Handle(
RoomserverQueryPublishedRoomsPath,
httputil.MakeInternalRPCAPI("RoomserverQueryPublishedRooms", enableMetrics, r.QueryPublishedRooms),
)
internalAPIMux.Handle(
RoomserverQueryLatestEventsAndStatePath,
httputil.MakeInternalRPCAPI("RoomserverQueryLatestEventsAndState", enableMetrics, r.QueryLatestEventsAndState),
)
internalAPIMux.Handle(
RoomserverQueryStateAfterEventsPath,
httputil.MakeInternalRPCAPI("RoomserverQueryStateAfterEvents", enableMetrics, r.QueryStateAfterEvents),
)
internalAPIMux.Handle(
RoomserverQueryEventsByIDPath,
httputil.MakeInternalRPCAPI("RoomserverQueryEventsByID", enableMetrics, r.QueryEventsByID),
)
internalAPIMux.Handle(
RoomserverQueryMembershipForUserPath,
httputil.MakeInternalRPCAPI("RoomserverQueryMembershipForUser", enableMetrics, r.QueryMembershipForUser),
)
internalAPIMux.Handle(
RoomserverQueryMembershipsForRoomPath,
httputil.MakeInternalRPCAPI("RoomserverQueryMembershipsForRoom", enableMetrics, r.QueryMembershipsForRoom),
)
internalAPIMux.Handle(
RoomserverQueryServerJoinedToRoomPath,
httputil.MakeInternalRPCAPI("RoomserverQueryServerJoinedToRoom", enableMetrics, r.QueryServerJoinedToRoom),
)
internalAPIMux.Handle(
RoomserverQueryServerAllowedToSeeEventPath,
httputil.MakeInternalRPCAPI("RoomserverQueryServerAllowedToSeeEvent", enableMetrics, r.QueryServerAllowedToSeeEvent),
)
internalAPIMux.Handle(
RoomserverQueryMissingEventsPath,
httputil.MakeInternalRPCAPI("RoomserverQueryMissingEvents", enableMetrics, r.QueryMissingEvents),
)
internalAPIMux.Handle(
RoomserverQueryStateAndAuthChainPath,
httputil.MakeInternalRPCAPI("RoomserverQueryStateAndAuthChain", enableMetrics, r.QueryStateAndAuthChain),
)
internalAPIMux.Handle(
RoomserverPerformBackfillPath,
httputil.MakeInternalRPCAPI("RoomserverPerformBackfill", enableMetrics, r.PerformBackfill),
)
internalAPIMux.Handle(
RoomserverPerformForgetPath,
httputil.MakeInternalRPCAPI("RoomserverPerformForget", enableMetrics, r.PerformForget),
)
internalAPIMux.Handle(
RoomserverQueryRoomVersionCapabilitiesPath,
httputil.MakeInternalRPCAPI("RoomserverQueryRoomVersionCapabilities", enableMetrics, r.QueryRoomVersionCapabilities),
)
internalAPIMux.Handle(
RoomserverQueryRoomVersionForRoomPath,
httputil.MakeInternalRPCAPI("RoomserverQueryRoomVersionForRoom", enableMetrics, r.QueryRoomVersionForRoom),
)
internalAPIMux.Handle(
RoomserverSetRoomAliasPath,
httputil.MakeInternalRPCAPI("RoomserverSetRoomAlias", enableMetrics, r.SetRoomAlias),
)
internalAPIMux.Handle(
RoomserverGetRoomIDForAliasPath,
httputil.MakeInternalRPCAPI("RoomserverGetRoomIDForAlias", enableMetrics, r.GetRoomIDForAlias),
)
internalAPIMux.Handle(
RoomserverGetAliasesForRoomIDPath,
httputil.MakeInternalRPCAPI("RoomserverGetAliasesForRoomID", enableMetrics, r.GetAliasesForRoomID),
)
internalAPIMux.Handle(
RoomserverRemoveRoomAliasPath,
httputil.MakeInternalRPCAPI("RoomserverRemoveRoomAlias", enableMetrics, r.RemoveRoomAlias),
)
internalAPIMux.Handle(
RoomserverQueryCurrentStatePath,
httputil.MakeInternalRPCAPI("RoomserverQueryCurrentState", enableMetrics, r.QueryCurrentState),
)
internalAPIMux.Handle(
RoomserverQueryRoomsForUserPath,
httputil.MakeInternalRPCAPI("RoomserverQueryRoomsForUser", enableMetrics, r.QueryRoomsForUser),
)
internalAPIMux.Handle(
RoomserverQueryBulkStateContentPath,
httputil.MakeInternalRPCAPI("RoomserverQueryBulkStateContent", enableMetrics, r.QueryBulkStateContent),
)
internalAPIMux.Handle(
RoomserverQuerySharedUsersPath,
httputil.MakeInternalRPCAPI("RoomserverQuerySharedUsers", enableMetrics, r.QuerySharedUsers),
)
internalAPIMux.Handle(
RoomserverQueryKnownUsersPath,
httputil.MakeInternalRPCAPI("RoomserverQueryKnownUsers", enableMetrics, r.QueryKnownUsers),
)
internalAPIMux.Handle(
RoomserverQueryServerBannedFromRoomPath,
httputil.MakeInternalRPCAPI("RoomserverQueryServerBannedFromRoom", enableMetrics, r.QueryServerBannedFromRoom),
)
internalAPIMux.Handle(
RoomserverQueryAuthChainPath,
httputil.MakeInternalRPCAPI("RoomserverQueryAuthChain", enableMetrics, r.QueryAuthChain),
)
internalAPIMux.Handle(
RoomserverQueryRestrictedJoinAllowed,
httputil.MakeInternalRPCAPI("RoomserverQueryRestrictedJoinAllowed", enableMetrics, r.QueryRestrictedJoinAllowed),
)
internalAPIMux.Handle(
RoomserverQueryMembershipAtEventPath,
httputil.MakeInternalRPCAPI("RoomserverQueryMembershipAtEventPath", enableMetrics, r.QueryMembershipAtEvent),
)
internalAPIMux.Handle(
RoomserverQueryLeftMembersPath,
httputil.MakeInternalRPCAPI("RoomserverQueryLeftMembersPath", enableMetrics, r.QueryLeftUsers),
)
}

View file

@ -15,22 +15,14 @@
package roomserver
import (
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/roomserver/internal"
"github.com/matrix-org/dendrite/roomserver/inthttp"
"github.com/matrix-org/dendrite/roomserver/storage"
"github.com/matrix-org/dendrite/setup/base"
)
// AddInternalRoutes registers HTTP handlers for the internal API. Invokes functions
// on the given input API.
func AddInternalRoutes(router *mux.Router, intAPI api.RoomserverInternalAPI, enableMetrics bool) {
inthttp.AddRoutes(intAPI, router, enableMetrics)
}
// NewInternalAPI returns a concerete implementation of the internal API. Callers
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI(

View file

@ -2,13 +2,10 @@ package roomserver_test
import (
"context"
"net/http"
"reflect"
"testing"
"time"
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/userapi"
@ -22,7 +19,6 @@ import (
"github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/roomserver/inthttp"
"github.com/matrix-org/dendrite/roomserver/storage"
"github.com/matrix-org/dendrite/test"
"github.com/matrix-org/dendrite/test/testrig"
@ -207,24 +203,7 @@ func Test_QueryLeftUsers(t *testing.T) {
}
}
t.Run("HTTP API", func(t *testing.T) {
router := mux.NewRouter().PathPrefix(httputil.InternalPathPrefix).Subrouter()
roomserver.AddInternalRoutes(router, rsAPI, false)
apiURL, cancel := test.ListenAndServe(t, router, false)
defer cancel()
httpAPI, err := inthttp.NewRoomserverClient(apiURL, &http.Client{Timeout: time.Second * 5}, nil)
if err != nil {
t.Fatalf("failed to create HTTP client")
}
testCase(httpAPI)
})
t.Run("Monolith", func(t *testing.T) {
testCase(rsAPI)
// also test tracing
traceAPI := &api.RoomserverInternalAPITrace{Impl: rsAPI}
testCase(traceAPI)
})
})
}

View file

@ -17,7 +17,6 @@ package base
import (
"bytes"
"context"
"crypto/tls"
"database/sql"
"embed"
"encoding/json"
@ -38,8 +37,6 @@ import (
"github.com/matrix-org/gomatrixserverlib"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/atomic"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/caching"
@ -53,19 +50,9 @@ import (
"github.com/sirupsen/logrus"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
asinthttp "github.com/matrix-org/dendrite/appservice/inthttp"
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
federationIntHTTP "github.com/matrix-org/dendrite/federationapi/inthttp"
keyserverAPI "github.com/matrix-org/dendrite/keyserver/api"
keyinthttp "github.com/matrix-org/dendrite/keyserver/inthttp"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
rsinthttp "github.com/matrix-org/dendrite/roomserver/inthttp"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/setup/jetstream"
"github.com/matrix-org/dendrite/setup/process"
userapi "github.com/matrix-org/dendrite/userapi/api"
userapiinthttp "github.com/matrix-org/dendrite/userapi/inthttp"
)
//go:embed static/*.gotmpl
@ -78,7 +65,6 @@ var staticContent embed.FS
// Must be closed when shutting down.
type BaseDendrite struct {
*process.ProcessContext
componentName string
tracerCloser io.Closer
PublicClientAPIMux *mux.Router
PublicFederationAPIMux *mux.Router
@ -86,12 +72,9 @@ type BaseDendrite struct {
PublicMediaAPIMux *mux.Router
PublicWellKnownAPIMux *mux.Router
PublicStaticMux *mux.Router
InternalAPIMux *mux.Router
DendriteAdminMux *mux.Router
SynapseAdminMux *mux.Router
NATS *jetstream.NATSInstance
UseHTTPAPIs bool
apiHttpClient *http.Client
Cfg *config.Dendrite
Caches *caching.Caches
DNSCache *gomatrixserverlib.DNSCache
@ -105,38 +88,26 @@ type BaseDendrite struct {
const NoListener = ""
const HTTPServerTimeout = time.Minute * 5
const HTTPClientTimeout = time.Second * 30
type BaseDendriteOptions int
const (
DisableMetrics BaseDendriteOptions = iota
UseHTTPAPIs
PolylithMode
)
// NewBaseDendrite creates a new instance to be used by a component.
// The componentName is used for logging purposes, and should be a friendly name
// of the compontent running, e.g. "SyncAPI"
func NewBaseDendrite(cfg *config.Dendrite, componentName string, options ...BaseDendriteOptions) *BaseDendrite {
func NewBaseDendrite(cfg *config.Dendrite, options ...BaseDendriteOptions) *BaseDendrite {
platformSanityChecks()
useHTTPAPIs := false
enableMetrics := true
isMonolith := true
for _, opt := range options {
switch opt {
case DisableMetrics:
enableMetrics = false
case UseHTTPAPIs:
useHTTPAPIs = true
case PolylithMode:
isMonolith = false
useHTTPAPIs = true
}
}
configErrors := &config.ConfigErrors{}
cfg.Verify(configErrors, isMonolith)
cfg.Verify(configErrors)
if len(*configErrors) > 0 {
for _, err := range *configErrors {
logrus.Errorf("Configuration error: %s", err)
@ -145,7 +116,7 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, options ...Base
}
internal.SetupStdLogging()
internal.SetupHookLogging(cfg.Logging, componentName)
internal.SetupHookLogging(cfg.Logging)
internal.SetupPprof()
logrus.Infof("Dendrite version %s", internal.VersionString())
@ -154,14 +125,13 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, options ...Base
logrus.Warn("Open registration is enabled")
}
closer, err := cfg.SetupTracing("Dendrite" + componentName)
closer, err := cfg.SetupTracing()
if err != nil {
logrus.WithError(err).Panicf("failed to start opentracing")
}
var fts *fulltext.Search
isSyncOrMonolith := componentName == "syncapi" || isMonolith
if cfg.SyncAPI.Fulltext.Enabled && isSyncOrMonolith {
if cfg.SyncAPI.Fulltext.Enabled {
fts, err = fulltext.New(cfg.SyncAPI.Fulltext)
if err != nil {
logrus.WithError(err).Panicf("failed to create full text")
@ -196,32 +166,12 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, options ...Base
)
}
apiClient := http.Client{
Timeout: time.Minute * 10,
Transport: &http2.Transport{
AllowHTTP: true,
DialTLS: func(network, addr string, _ *tls.Config) (net.Conn, error) {
// Ordinarily HTTP/2 would expect TLS, but the remote listener is
// H2C-enabled (HTTP/2 without encryption). Overriding the DialTLS
// function with a plain Dial allows us to trick the HTTP client
// into establishing a HTTP/2 connection without TLS.
// TODO: Eventually we will want to look at authenticating and
// encrypting these internal HTTP APIs, at which point we will have
// to reconsider H2C and change all this anyway.
return net.Dial(network, addr)
},
},
}
// If we're in monolith mode, we'll set up a global pool of database
// connections. A component is welcome to use this pool if they don't
// have a separate database config of their own.
var db *sql.DB
var writer sqlutil.Writer
if cfg.Global.DatabaseOptions.ConnectionString != "" {
if !isMonolith {
logrus.Panic("Using a global database connection pool is not supported in polylith deployments")
}
if cfg.Global.DatabaseOptions.ConnectionString.IsSQLite() {
logrus.Panic("Using a global database connection pool is not supported with SQLite databases")
}
@ -246,8 +196,6 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, options ...Base
return &BaseDendrite{
ProcessContext: process.NewProcessContext(),
componentName: componentName,
UseHTTPAPIs: useHTTPAPIs,
tracerCloser: closer,
Cfg: cfg,
Caches: caching.NewRistrettoCache(cfg.Global.Cache.EstimatedMaxSize, cfg.Global.Cache.MaxAge, enableMetrics),
@ -258,11 +206,9 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, options ...Base
PublicMediaAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicMediaPathPrefix).Subrouter().UseEncodedPath(),
PublicWellKnownAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicWellKnownPrefix).Subrouter().UseEncodedPath(),
PublicStaticMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicStaticPath).Subrouter().UseEncodedPath(),
InternalAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
DendriteAdminMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.DendriteAdminPathPrefix).Subrouter().UseEncodedPath(),
SynapseAdminMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.SynapseAdminPathPrefix).Subrouter().UseEncodedPath(),
NATS: &jetstream.NATSInstance{},
apiHttpClient: &apiClient,
Database: db, // set if monolith with global connection pool only
DatabaseWriter: writer, // set if monolith with global connection pool only
EnableMetrics: enableMetrics,
@ -300,52 +246,6 @@ func (b *BaseDendrite) DatabaseConnection(dbProperties *config.DatabaseOptions,
return nil, nil, fmt.Errorf("no database connections configured")
}
// AppserviceHTTPClient returns the AppServiceInternalAPI for hitting the appservice component over HTTP.
func (b *BaseDendrite) AppserviceHTTPClient() appserviceAPI.AppServiceInternalAPI {
a, err := asinthttp.NewAppserviceClient(b.Cfg.AppServiceURL(), b.apiHttpClient)
if err != nil {
logrus.WithError(err).Panic("CreateHTTPAppServiceAPIs failed")
}
return a
}
// RoomserverHTTPClient returns RoomserverInternalAPI for hitting the roomserver over HTTP.
func (b *BaseDendrite) RoomserverHTTPClient() roomserverAPI.RoomserverInternalAPI {
rsAPI, err := rsinthttp.NewRoomserverClient(b.Cfg.RoomServerURL(), b.apiHttpClient, b.Caches)
if err != nil {
logrus.WithError(err).Panic("RoomserverHTTPClient failed", b.apiHttpClient)
}
return rsAPI
}
// UserAPIClient returns UserInternalAPI for hitting the userapi over HTTP.
func (b *BaseDendrite) UserAPIClient() userapi.UserInternalAPI {
userAPI, err := userapiinthttp.NewUserAPIClient(b.Cfg.UserAPIURL(), b.apiHttpClient)
if err != nil {
logrus.WithError(err).Panic("UserAPIClient failed", b.apiHttpClient)
}
return userAPI
}
// FederationAPIHTTPClient returns FederationInternalAPI for hitting
// the federation API server over HTTP
func (b *BaseDendrite) FederationAPIHTTPClient() federationAPI.FederationInternalAPI {
f, err := federationIntHTTP.NewFederationAPIClient(b.Cfg.FederationAPIURL(), b.apiHttpClient, b.Caches)
if err != nil {
logrus.WithError(err).Panic("FederationAPIHTTPClient failed", b.apiHttpClient)
}
return f
}
// KeyServerHTTPClient returns KeyInternalAPI for hitting the key server over HTTP
func (b *BaseDendrite) KeyServerHTTPClient() keyserverAPI.KeyInternalAPI {
f, err := keyinthttp.NewKeyServerClient(b.Cfg.KeyServerURL(), b.apiHttpClient)
if err != nil {
logrus.WithError(err).Panic("KeyServerHTTPClient failed", b.apiHttpClient)
}
return f
}
// PushGatewayHTTPClient returns a new client for interacting with (external) Push Gateways.
func (b *BaseDendrite) PushGatewayHTTPClient() pushgateway.Client {
return pushgateway.NewHTTPClient(b.Cfg.UserAPI.PushGatewayDisableTLSValidation)
@ -442,20 +342,18 @@ func (b *BaseDendrite) ConfigureAdminEndpoints() {
})
}
// SetupAndServeHTTP sets up the HTTP server to serve endpoints registered on
// ApiMux under /api/ and adds a prometheus handler under /metrics.
// SetupAndServeHTTP sets up the HTTP server to serve client & federation APIs
// and adds a prometheus handler under /_dendrite/metrics.
func (b *BaseDendrite) SetupAndServeHTTP(
internalHTTPAddr, externalHTTPAddr config.HTTPAddress,
externalHTTPAddr config.HTTPAddress,
certFile, keyFile *string,
) {
// Manually unlocked right before actually serving requests,
// as we don't return from this method (defer doesn't work).
b.startupLock.Lock()
internalAddr, _ := internalHTTPAddr.Address()
externalAddr, _ := externalHTTPAddr.Address()
externalRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
internalRouter := externalRouter
externalServ := &http.Server{
Addr: string(externalAddr),
@ -465,25 +363,6 @@ func (b *BaseDendrite) SetupAndServeHTTP(
return b.ProcessContext.Context()
},
}
internalServ := externalServ
if internalAddr != NoListener && externalAddr != internalAddr {
// H2C allows us to accept HTTP/2 connections without TLS
// encryption. Since we don't currently require any form of
// authentication or encryption on these internal HTTP APIs,
// H2C gives us all of the advantages of HTTP/2 (such as
// stream multiplexing and avoiding head-of-line blocking)
// without enabling TLS.
internalH2S := &http2.Server{}
internalRouter = mux.NewRouter().SkipClean(true).UseEncodedPath()
internalServ = &http.Server{
Addr: string(internalAddr),
Handler: h2c.NewHandler(internalRouter, internalH2S),
BaseContext: func(_ net.Listener) context.Context {
return b.ProcessContext.Context()
},
}
}
b.configureHTTPErrors()
@ -492,9 +371,8 @@ func (b *BaseDendrite) SetupAndServeHTTP(
http.Redirect(w, r, httputil.PublicStaticPath, http.StatusFound)
})
internalRouter.PathPrefix(httputil.InternalPathPrefix).Handler(b.InternalAPIMux)
if b.Cfg.Global.Metrics.Enabled {
internalRouter.Handle("/metrics", httputil.WrapHandlerInBasicAuth(promhttp.Handler(), b.Cfg.Global.Metrics.BasicAuth))
externalRouter.Handle("/metrics", httputil.WrapHandlerInBasicAuth(promhttp.Handler(), b.Cfg.Global.Metrics.BasicAuth))
}
b.ConfigureAdminEndpoints()
@ -528,7 +406,7 @@ func (b *BaseDendrite) SetupAndServeHTTP(
})
federationHandler = sentryHandler.Handle(b.PublicFederationAPIMux)
}
internalRouter.PathPrefix(httputil.DendriteAdminPathPrefix).Handler(b.DendriteAdminMux)
externalRouter.PathPrefix(httputil.DendriteAdminPathPrefix).Handler(b.DendriteAdminMux)
externalRouter.PathPrefix(httputil.PublicClientPathPrefix).Handler(clientHandler)
if !b.Cfg.Global.DisableFederation {
externalRouter.PathPrefix(httputil.PublicKeyPathPrefix).Handler(b.PublicKeyAPIMux)
@ -540,38 +418,11 @@ func (b *BaseDendrite) SetupAndServeHTTP(
externalRouter.PathPrefix(httputil.PublicStaticPath).Handler(b.PublicStaticMux)
b.startupLock.Unlock()
if internalAddr != NoListener && internalAddr != externalAddr {
go func() {
var internalShutdown atomic.Bool // RegisterOnShutdown can be called more than once
logrus.Infof("Starting internal %s listener on %s", b.componentName, internalServ.Addr)
b.ProcessContext.ComponentStarted()
internalServ.RegisterOnShutdown(func() {
if internalShutdown.CompareAndSwap(false, true) {
b.ProcessContext.ComponentFinished()
logrus.Infof("Stopped internal HTTP listener")
}
})
if certFile != nil && keyFile != nil {
if err := internalServ.ListenAndServeTLS(*certFile, *keyFile); err != nil {
if err != http.ErrServerClosed {
logrus.WithError(err).Fatal("failed to serve HTTPS")
}
}
} else {
if err := internalServ.ListenAndServe(); err != nil {
if err != http.ErrServerClosed {
logrus.WithError(err).Fatal("failed to serve HTTP")
}
}
}
logrus.Infof("Stopped internal %s listener on %s", b.componentName, internalServ.Addr)
}()
}
if externalAddr != NoListener {
go func() {
var externalShutdown atomic.Bool // RegisterOnShutdown can be called more than once
logrus.Infof("Starting external %s listener on %s", b.componentName, externalServ.Addr)
logrus.Infof("Starting external listener on %s", externalServ.Addr)
b.ProcessContext.ComponentStarted()
externalServ.RegisterOnShutdown(func() {
if externalShutdown.CompareAndSwap(false, true) {
@ -592,7 +443,7 @@ func (b *BaseDendrite) SetupAndServeHTTP(
}
}
}
logrus.Infof("Stopped external %s listener on %s", b.componentName, externalServ.Addr)
logrus.Infof("Stopped external listener on %s", externalServ.Addr)
}()
}
@ -600,7 +451,6 @@ func (b *BaseDendrite) SetupAndServeHTTP(
<-b.ProcessContext.WaitForShutdown()
logrus.Infof("Stopping HTTP listeners")
_ = internalServ.Shutdown(context.Background())
_ = externalServ.Shutdown(context.Background())
logrus.Infof("Stopped HTTP listeners")
}

View file

@ -35,7 +35,7 @@ func TestLandingPage(t *testing.T) {
s.Close()
// start base with the listener and wait for it to be started
go b.SetupAndServeHTTP("", config.HTTPAddress(s.URL), nil, nil)
go b.SetupAndServeHTTP(config.HTTPAddress(s.URL), nil, nil)
time.Sleep(time.Millisecond * 10)
// When hitting /, we should be redirected to /_matrix/static, which should contain the landing page

View file

@ -79,8 +79,6 @@ type Dendrite struct {
// Any information derived from the configuration options for later use.
Derived Derived `yaml:"-"`
IsMonolith bool `yaml:"-"`
}
// TODO: Kill Derived
@ -114,15 +112,6 @@ type Derived struct {
// servers from creating RoomIDs in exclusive application service namespaces
}
type InternalAPIOptions struct {
Listen HTTPAddress `yaml:"listen"`
Connect HTTPAddress `yaml:"connect"`
}
type ExternalAPIOptions struct {
Listen HTTPAddress `yaml:"listen"`
}
// A Path on the filesystem.
type Path string
@ -191,7 +180,7 @@ type ConfigErrors []string
// Load a yaml config file for a server run as multiple processes or as a monolith.
// Checks the config to ensure that it is valid.
func Load(configPath string, monolith bool) (*Dendrite, error) {
func Load(configPath string) (*Dendrite, error) {
configData, err := os.ReadFile(configPath)
if err != nil {
return nil, err
@ -202,28 +191,26 @@ func Load(configPath string, monolith bool) (*Dendrite, error) {
}
// Pass the current working directory and os.ReadFile so that they can
// be mocked in the tests
return loadConfig(basePath, configData, os.ReadFile, monolith)
return loadConfig(basePath, configData, os.ReadFile)
}
func loadConfig(
basePath string,
configData []byte,
readFile func(string) ([]byte, error),
monolithic bool,
) (*Dendrite, error) {
var c Dendrite
c.Defaults(DefaultOpts{
Generate: false,
Monolithic: monolithic,
SingleDatabase: true,
})
c.IsMonolith = monolithic
var err error
if err = yaml.Unmarshal(configData, &c); err != nil {
return nil, err
}
if err = c.check(monolithic); err != nil {
if err = c.check(); err != nil {
return nil, err
}
@ -334,7 +321,7 @@ func (config *Dendrite) Derive() error {
type DefaultOpts struct {
Generate bool
Monolithic bool
SingleDatabase bool
}
// SetDefaults sets default config values if they are not explicitly set.
@ -355,9 +342,9 @@ func (c *Dendrite) Defaults(opts DefaultOpts) {
c.Wiring()
}
func (c *Dendrite) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *Dendrite) Verify(configErrs *ConfigErrors) {
type verifiable interface {
Verify(configErrs *ConfigErrors, isMonolith bool)
Verify(configErrs *ConfigErrors)
}
for _, c := range []verifiable{
&c.Global, &c.ClientAPI, &c.FederationAPI,
@ -365,7 +352,7 @@ func (c *Dendrite) Verify(configErrs *ConfigErrors, isMonolith bool) {
&c.SyncAPI, &c.UserAPI,
&c.AppServiceAPI, &c.RelayAPI, &c.MSCs,
} {
c.Verify(configErrs, isMonolith)
c.Verify(configErrs)
}
}
@ -415,14 +402,6 @@ func checkNotEmpty(configErrs *ConfigErrors, key, value string) {
}
}
// checkNotZero verifies the given value is not zero in the configuration.
// If it is, adds an error to the list.
func checkNotZero(configErrs *ConfigErrors, key string, value int64) {
if value == 0 {
configErrs.Add(fmt.Sprintf("missing config key %q", key))
}
}
// checkPositive verifies the given value is positive (zero included)
// in the configuration. If it is not, adds an error to the list.
func checkPositive(configErrs *ConfigErrors, key string, value int64) {
@ -431,26 +410,6 @@ func checkPositive(configErrs *ConfigErrors, key string, value int64) {
}
}
// checkURL verifies that the parameter is a valid URL
func checkURL(configErrs *ConfigErrors, key, value string) {
if value == "" {
configErrs.Add(fmt.Sprintf("missing config key %q", key))
return
}
url, err := url.Parse(value)
if err != nil {
configErrs.Add(fmt.Sprintf("config key %q contains invalid URL (%s)", key, err.Error()))
return
}
switch url.Scheme {
case "http":
case "https":
default:
configErrs.Add(fmt.Sprintf("config key %q URL should be http:// or https://", key))
return
}
}
// checkLogging verifies the parameters logging.* are valid.
func (config *Dendrite) checkLogging(configErrs *ConfigErrors) {
for _, logrusHook := range config.Logging {
@ -461,7 +420,7 @@ func (config *Dendrite) checkLogging(configErrs *ConfigErrors) {
// check returns an error type containing all errors found within the config
// file.
func (config *Dendrite) check(_ bool) error { // monolithic
func (config *Dendrite) check() error { // monolithic
var configErrs ConfigErrors
if config.Version != Version {
@ -528,58 +487,13 @@ func readKeyPEM(path string, data []byte, enforceKeyIDFormat bool) (gomatrixserv
}
}
// AppServiceURL returns a HTTP URL for where the appservice component is listening.
func (config *Dendrite) AppServiceURL() string {
// Hard code the appservice server to talk HTTP for now.
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
return string(config.AppServiceAPI.InternalAPI.Connect)
}
// FederationAPIURL returns an HTTP URL for where the federation API is listening.
func (config *Dendrite) FederationAPIURL() string {
// Hard code the federationapi to talk HTTP for now.
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
return string(config.FederationAPI.InternalAPI.Connect)
}
// RoomServerURL returns an HTTP URL for where the roomserver is listening.
func (config *Dendrite) RoomServerURL() string {
// Hard code the roomserver to talk HTTP for now.
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
return string(config.RoomServer.InternalAPI.Connect)
}
// UserAPIURL returns an HTTP URL for where the userapi is listening.
func (config *Dendrite) UserAPIURL() string {
// Hard code the userapi to talk HTTP for now.
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
return string(config.UserAPI.InternalAPI.Connect)
}
// KeyServerURL returns an HTTP URL for where the key server is listening.
func (config *Dendrite) KeyServerURL() string {
// Hard code the key server to talk HTTP for now.
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
return string(config.KeyServer.InternalAPI.Connect)
}
// SetupTracing configures the opentracing using the supplied configuration.
func (config *Dendrite) SetupTracing(serviceName string) (closer io.Closer, err error) {
func (config *Dendrite) SetupTracing() (closer io.Closer, err error) {
if !config.Tracing.Enabled {
return io.NopCloser(bytes.NewReader([]byte{})), nil
}
return config.Tracing.Jaeger.InitGlobalTracer(
serviceName,
"Dendrite",
jaegerconfig.Logger(logrusLogger{logrus.StandardLogger()}),
jaegerconfig.Metrics(jaegermetrics.NullFactory),
)

View file

@ -22,15 +22,13 @@ import (
"strings"
log "github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"
"gopkg.in/yaml.v2"
)
type AppServiceAPI struct {
Matrix *Global `yaml:"-"`
Derived *Derived `yaml:"-"` // TODO: Nuke Derived from orbit
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
// DisableTLSValidation disables the validation of X.509 TLS certs
// on appservice endpoints. This is not recommended in production!
DisableTLSValidation bool `yaml:"disable_tls_validation"`
@ -39,18 +37,9 @@ type AppServiceAPI struct {
}
func (c *AppServiceAPI) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7777"
c.InternalAPI.Connect = "http://localhost:7777"
}
}
func (c *AppServiceAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
if isMonolith { // polylith required configs below
return
}
checkURL(configErrs, "app_service_api.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "app_service_api.internal_api.connect", string(c.InternalAPI.Connect))
func (c *AppServiceAPI) Verify(configErrs *ConfigErrors) {
}
// ApplicationServiceNamespace is the namespace that a specific application

View file

@ -9,9 +9,6 @@ type ClientAPI struct {
Matrix *Global `yaml:"-"`
Derived *Derived `yaml:"-"` // TODO: Nuke Derived from orbit
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
// If set disables new users from registering (except via shared
// secrets)
RegistrationDisabled bool `yaml:"registration_disabled"`
@ -58,11 +55,6 @@ type ClientAPI struct {
}
func (c *ClientAPI) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7771"
c.InternalAPI.Connect = "http://localhost:7771"
c.ExternalAPI.Listen = "http://[::]:8071"
}
c.RegistrationSharedSecret = ""
c.RecaptchaPublicKey = ""
c.RecaptchaPrivateKey = ""
@ -74,7 +66,7 @@ func (c *ClientAPI) Defaults(opts DefaultOpts) {
c.RateLimiting.Defaults()
}
func (c *ClientAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *ClientAPI) Verify(configErrs *ConfigErrors) {
c.TURN.Verify(configErrs)
c.RateLimiting.Verify(configErrs)
if c.RecaptchaEnabled {
@ -108,12 +100,6 @@ func (c *ClientAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
)
}
}
if isMonolith { // polylith required configs below
return
}
checkURL(configErrs, "client_api.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "client_api.internal_api.connect", string(c.InternalAPI.Connect))
checkURL(configErrs, "client_api.external_api.listen", string(c.ExternalAPI.Listen))
}
type TURN struct {

View file

@ -1,13 +1,12 @@
package config
import "github.com/matrix-org/gomatrixserverlib"
import (
"github.com/matrix-org/gomatrixserverlib"
)
type FederationAPI struct {
Matrix *Global `yaml:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
// The database stores information used by the federation destination queues to
// send transactions to remote servers.
Database DatabaseOptions `yaml:"database,omitempty"`
@ -42,12 +41,6 @@ type FederationAPI struct {
}
func (c *FederationAPI) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7772"
c.InternalAPI.Connect = "http://localhost:7772"
c.ExternalAPI.Listen = "http://[::]:8072"
c.Database.Defaults(10)
}
c.FederationMaxRetries = 16
c.P2PFederationRetriesUntilAssumedOffline = 1
c.DisableTLSValidation = false
@ -68,22 +61,16 @@ func (c *FederationAPI) Defaults(opts DefaultOpts) {
},
},
}
if !opts.Monolithic {
if !opts.SingleDatabase {
c.Database.ConnectionString = "file:federationapi.db"
}
}
}
func (c *FederationAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
if isMonolith { // polylith required configs below
return
}
func (c *FederationAPI) Verify(configErrs *ConfigErrors) {
if c.Matrix.DatabaseOptions.ConnectionString == "" {
checkNotEmpty(configErrs, "federation_api.database.connection_string", string(c.Database.ConnectionString))
}
checkURL(configErrs, "federation_api.external_api.listen", string(c.ExternalAPI.Listen))
checkURL(configErrs, "federation_api.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "federation_api.internal_api.connect", string(c.InternalAPI.Connect))
}
// The config for setting a proxy to use for server->server requests

View file

@ -38,7 +38,6 @@ type Global struct {
// component does not specify any database options of its own, then this pool of
// connections will be used instead. This way we don't have to manage connection
// counts on a per-component basis, but can instead do it for the entire monolith.
// In a polylith deployment, this will be ignored.
DatabaseOptions DatabaseOptions `yaml:"database,omitempty"`
// The server name to delegate server-server communications to, with optional port
@ -93,7 +92,7 @@ func (c *Global) Defaults(opts DefaultOpts) {
}
}
c.KeyValidityPeriod = time.Hour * 24 * 7
if opts.Monolithic {
if opts.SingleDatabase {
c.DatabaseOptions.Defaults(90)
}
c.JetStream.Defaults(opts)
@ -105,7 +104,7 @@ func (c *Global) Defaults(opts DefaultOpts) {
c.Cache.Defaults()
}
func (c *Global) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *Global) Verify(configErrs *ConfigErrors) {
checkNotEmpty(configErrs, "global.server_name", string(c.ServerName))
checkNotEmpty(configErrs, "global.private_key", string(c.PrivateKeyPath))
@ -113,13 +112,13 @@ func (c *Global) Verify(configErrs *ConfigErrors, isMonolith bool) {
v.Verify(configErrs)
}
c.JetStream.Verify(configErrs, isMonolith)
c.Metrics.Verify(configErrs, isMonolith)
c.Sentry.Verify(configErrs, isMonolith)
c.DNSCache.Verify(configErrs, isMonolith)
c.ServerNotices.Verify(configErrs, isMonolith)
c.ReportStats.Verify(configErrs, isMonolith)
c.Cache.Verify(configErrs, isMonolith)
c.JetStream.Verify(configErrs)
c.Metrics.Verify(configErrs)
c.Sentry.Verify(configErrs)
c.DNSCache.Verify(configErrs)
c.ServerNotices.Verify(configErrs)
c.ReportStats.Verify(configErrs)
c.Cache.Verify(configErrs)
}
func (c *Global) IsLocalServerName(serverName gomatrixserverlib.ServerName) bool {
@ -267,7 +266,7 @@ func (c *Metrics) Defaults(opts DefaultOpts) {
}
}
func (c *Metrics) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *Metrics) Verify(configErrs *ConfigErrors) {
}
// ServerNotices defines the configuration used for sending server notices
@ -293,7 +292,7 @@ func (c *ServerNotices) Defaults(opts DefaultOpts) {
}
}
func (c *ServerNotices) Verify(errors *ConfigErrors, isMonolith bool) {}
func (c *ServerNotices) Verify(errors *ConfigErrors) {}
type Cache struct {
EstimatedMaxSize DataUnit `yaml:"max_size_estimated"`
@ -305,7 +304,7 @@ func (c *Cache) Defaults() {
c.MaxAge = time.Hour
}
func (c *Cache) Verify(errors *ConfigErrors, isMonolith bool) {
func (c *Cache) Verify(errors *ConfigErrors) {
checkPositive(errors, "max_size_estimated", int64(c.EstimatedMaxSize))
}
@ -323,7 +322,7 @@ func (c *ReportStats) Defaults() {
c.Endpoint = "https://matrix.org/report-usage-stats/push"
}
func (c *ReportStats) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *ReportStats) Verify(configErrs *ConfigErrors) {
if c.Enabled {
checkNotEmpty(configErrs, "global.report_stats.endpoint", c.Endpoint)
}
@ -344,7 +343,7 @@ func (c *Sentry) Defaults() {
c.Enabled = false
}
func (c *Sentry) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *Sentry) Verify(configErrs *ConfigErrors) {
}
type DatabaseOptions struct {
@ -364,8 +363,7 @@ func (c *DatabaseOptions) Defaults(conns int) {
c.ConnMaxLifetimeSeconds = -1
}
func (c *DatabaseOptions) Verify(configErrs *ConfigErrors, isMonolith bool) {
}
func (c *DatabaseOptions) Verify(configErrs *ConfigErrors) {}
// MaxIdleConns returns maximum idle connections to the DB
func (c DatabaseOptions) MaxIdleConns() int {
@ -397,7 +395,7 @@ func (c *DNSCacheOptions) Defaults() {
c.CacheLifetime = time.Minute * 5
}
func (c *DNSCacheOptions) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *DNSCacheOptions) Verify(configErrs *ConfigErrors) {
checkPositive(configErrs, "cache_size", int64(c.CacheSize))
checkPositive(configErrs, "cache_lifetime", int64(c.CacheLifetime))
}

View file

@ -41,11 +41,4 @@ func (c *JetStream) Defaults(opts DefaultOpts) {
}
}
func (c *JetStream) Verify(configErrs *ConfigErrors, isMonolith bool) {
if isMonolith { // polylith required configs below
return
}
// If we are running in a polylith deployment then we need at least
// one NATS JetStream server to talk to.
checkNotZero(configErrs, "global.jetstream.addresses", int64(len(c.Addresses)))
}
func (c *JetStream) Verify(configErrs *ConfigErrors) {}

View file

@ -3,31 +3,19 @@ package config
type KeyServer struct {
Matrix *Global `yaml:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
Database DatabaseOptions `yaml:"database,omitempty"`
}
func (c *KeyServer) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7779"
c.InternalAPI.Connect = "http://localhost:7779"
c.Database.Defaults(10)
}
if opts.Generate {
if !opts.Monolithic {
if !opts.SingleDatabase {
c.Database.ConnectionString = "file:keyserver.db"
}
}
}
func (c *KeyServer) Verify(configErrs *ConfigErrors, isMonolith bool) {
if isMonolith { // polylith required configs below
return
}
func (c *KeyServer) Verify(configErrs *ConfigErrors) {
if c.Matrix.DatabaseOptions.ConnectionString == "" {
checkNotEmpty(configErrs, "key_server.database.connection_string", string(c.Database.ConnectionString))
}
checkURL(configErrs, "key_server.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "key_server.internal_api.connect", string(c.InternalAPI.Connect))
}

View file

@ -7,9 +7,6 @@ import (
type MediaAPI struct {
Matrix *Global `yaml:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
// The MediaAPI database stores information about files uploaded and downloaded
// by local users. It is only accessed by the MediaAPI.
Database DatabaseOptions `yaml:"database,omitempty"`
@ -39,12 +36,6 @@ type MediaAPI struct {
var DefaultMaxFileSizeBytes = FileSizeBytes(10485760)
func (c *MediaAPI) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7774"
c.InternalAPI.Connect = "http://localhost:7774"
c.ExternalAPI.Listen = "http://[::]:8074"
c.Database.Defaults(5)
}
c.MaxFileSizeBytes = DefaultMaxFileSizeBytes
c.MaxThumbnailGenerators = 10
if opts.Generate {
@ -65,14 +56,14 @@ func (c *MediaAPI) Defaults(opts DefaultOpts) {
ResizeMethod: "scale",
},
}
if !opts.Monolithic {
if !opts.SingleDatabase {
c.Database.ConnectionString = "file:mediaapi.db"
}
c.BasePath = "./media_store"
}
}
func (c *MediaAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *MediaAPI) Verify(configErrs *ConfigErrors) {
checkNotEmpty(configErrs, "media_api.base_path", string(c.BasePath))
checkPositive(configErrs, "media_api.max_file_size_bytes", int64(c.MaxFileSizeBytes))
checkPositive(configErrs, "media_api.max_thumbnail_generators", int64(c.MaxThumbnailGenerators))
@ -81,13 +72,8 @@ func (c *MediaAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
checkPositive(configErrs, fmt.Sprintf("media_api.thumbnail_sizes[%d].width", i), int64(size.Width))
checkPositive(configErrs, fmt.Sprintf("media_api.thumbnail_sizes[%d].height", i), int64(size.Height))
}
if isMonolith { // polylith required configs below
return
}
if c.Matrix.DatabaseOptions.ConnectionString == "" {
checkNotEmpty(configErrs, "media_api.database.connection_string", string(c.Database.ConnectionString))
}
checkURL(configErrs, "media_api.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "media_api.internal_api.connect", string(c.InternalAPI.Connect))
checkURL(configErrs, "media_api.external_api.listen", string(c.ExternalAPI.Listen))
}

View file

@ -14,11 +14,8 @@ type MSCs struct {
}
func (c *MSCs) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.Database.Defaults(5)
}
if opts.Generate {
if !opts.Monolithic {
if !opts.SingleDatabase {
c.Database.ConnectionString = "file:mscs.db"
}
}
@ -34,10 +31,7 @@ func (c *MSCs) Enabled(msc string) bool {
return false
}
func (c *MSCs) Verify(configErrs *ConfigErrors, isMonolith bool) {
if isMonolith { // polylith required configs below
return
}
func (c *MSCs) Verify(configErrs *ConfigErrors) {
if c.Matrix.DatabaseOptions.ConnectionString == "" {
checkNotEmpty(configErrs, "mscs.database.connection_string", string(c.Database.ConnectionString))
}

View file

@ -17,36 +17,21 @@ package config
type RelayAPI struct {
Matrix *Global `yaml:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
// The database stores information used by the relay queue to
// forward transactions to remote servers.
Database DatabaseOptions `yaml:"database,omitempty"`
}
func (c *RelayAPI) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7775"
c.InternalAPI.Connect = "http://localhost:7775"
c.ExternalAPI.Listen = "http://[::]:8075"
c.Database.Defaults(10)
}
if opts.Generate {
if !opts.Monolithic {
if !opts.SingleDatabase {
c.Database.ConnectionString = "file:relayapi.db"
}
}
}
func (c *RelayAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
if isMonolith { // polylith required configs below
return
}
func (c *RelayAPI) Verify(configErrs *ConfigErrors) {
if c.Matrix.DatabaseOptions.ConnectionString == "" {
checkNotEmpty(configErrs, "relay_api.database.connection_string", string(c.Database.ConnectionString))
}
checkURL(configErrs, "relay_api.external_api.listen", string(c.ExternalAPI.Listen))
checkURL(configErrs, "relay_api.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "relay_api.internal_api.connect", string(c.InternalAPI.Connect))
}

View file

@ -3,31 +3,19 @@ package config
type RoomServer struct {
Matrix *Global `yaml:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
Database DatabaseOptions `yaml:"database,omitempty"`
}
func (c *RoomServer) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7770"
c.InternalAPI.Connect = "http://localhost:7770"
c.Database.Defaults(20)
}
if opts.Generate {
if !opts.Monolithic {
if !opts.SingleDatabase {
c.Database.ConnectionString = "file:roomserver.db"
}
}
}
func (c *RoomServer) Verify(configErrs *ConfigErrors, isMonolith bool) {
if isMonolith { // polylith required configs below
return
}
func (c *RoomServer) Verify(configErrs *ConfigErrors) {
if c.Matrix.DatabaseOptions.ConnectionString == "" {
checkNotEmpty(configErrs, "room_server.database.connection_string", string(c.Database.ConnectionString))
}
checkURL(configErrs, "room_server.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "room_server.internal_ap.connect", string(c.InternalAPI.Connect))
}

View file

@ -3,9 +3,6 @@ package config
type SyncAPI struct {
Matrix *Global `yaml:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
ExternalAPI ExternalAPIOptions `yaml:"external_api,omitempty"`
Database DatabaseOptions `yaml:"database,omitempty"`
RealIPHeader string `yaml:"real_ip_header"`
@ -14,31 +11,19 @@ type SyncAPI struct {
}
func (c *SyncAPI) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7773"
c.InternalAPI.Connect = "http://localhost:7773"
c.ExternalAPI.Listen = "http://localhost:8073"
c.Database.Defaults(20)
}
c.Fulltext.Defaults(opts)
if opts.Generate {
if !opts.Monolithic {
if !opts.SingleDatabase {
c.Database.ConnectionString = "file:syncapi.db"
}
}
}
func (c *SyncAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
c.Fulltext.Verify(configErrs, isMonolith)
if isMonolith { // polylith required configs below
return
}
func (c *SyncAPI) Verify(configErrs *ConfigErrors) {
c.Fulltext.Verify(configErrs)
if c.Matrix.DatabaseOptions.ConnectionString == "" {
checkNotEmpty(configErrs, "sync_api.database", string(c.Database.ConnectionString))
}
checkURL(configErrs, "sync_api.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "sync_api.internal_api.connect", string(c.InternalAPI.Connect))
checkURL(configErrs, "sync_api.external_api.listen", string(c.ExternalAPI.Listen))
}
type Fulltext struct {
@ -54,7 +39,7 @@ func (f *Fulltext) Defaults(opts DefaultOpts) {
f.Language = "en"
}
func (f *Fulltext) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (f *Fulltext) Verify(configErrs *ConfigErrors) {
if !f.Enabled {
return
}

View file

@ -30,14 +30,13 @@ func TestLoadConfigRelative(t *testing.T) {
"/my/config/dir/matrix_key.pem": testKey,
"/my/config/dir/tls_cert.pem": testCert,
}.readFile,
false,
)
if err != nil {
t.Error("failed to load config:", err)
}
configErrors := &ConfigErrors{}
cfg.Verify(configErrors, false)
cfg.Verify(configErrors)
if len(*configErrors) > 0 {
for _, err := range *configErrors {
logrus.Errorf("Configuration error: %s", err)
@ -81,9 +80,6 @@ global:
jetstream:
addresses: ["test"]
app_service_api:
internal_api:
listen: http://localhost:7777
connect: http://localhost:7777
database:
connection_string: file:appservice.db
max_open_conns: 100
@ -91,11 +87,6 @@ app_service_api:
conn_max_lifetime: -1
config_files: []
client_api:
internal_api:
listen: http://localhost:7771
connect: http://localhost:7771
external_api:
listen: http://[::]:8071
registration_disabled: true
registration_shared_secret: ""
enable_registration_captcha: false
@ -109,38 +100,16 @@ client_api:
turn_shared_secret: ""
turn_username: ""
turn_password: ""
current_state_server:
internal_api:
listen: http://localhost:7782
connect: http://localhost:7782
database:
connection_string: file:currentstate.db
max_open_conns: 100
max_idle_conns: 2
conn_max_lifetime: -1
federation_api:
internal_api:
listen: http://localhost:7772
connect: http://localhost:7772
external_api:
listen: http://[::]:8072
database:
connection_string: file:federationapi.db
key_server:
internal_api:
listen: http://localhost:7779
connect: http://localhost:7779
database:
connection_string: file:keyserver.db
max_open_conns: 100
max_idle_conns: 2
conn_max_lifetime: -1
media_api:
internal_api:
listen: http://localhost:7774
connect: http://localhost:7774
external_api:
listen: http://[::]:8074
database:
connection_string: file:mediaapi.db
max_open_conns: 100
@ -161,18 +130,12 @@ media_api:
height: 480
method: scale
room_server:
internal_api:
listen: http://localhost:7770
connect: http://localhost:7770
database:
connection_string: file:roomserver.db
max_open_conns: 100
max_idle_conns: 2
conn_max_lifetime: -1
server_key_api:
internal_api:
listen: http://localhost:7780
connect: http://localhost:7780
database:
connection_string: file:serverkeyapi.db
max_open_conns: 100
@ -186,18 +149,12 @@ server_key_api:
- key_id: ed25519:a_RXGa
public_key: l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ
sync_api:
internal_api:
listen: http://localhost:7773
connect: http://localhost:7773
database:
connection_string: file:syncapi.db
max_open_conns: 100
max_idle_conns: 2
conn_max_lifetime: -1
user_api:
internal_api:
listen: http://localhost:7781
connect: http://localhost:7781
account_database:
connection_string: file:userapi_accounts.db
max_open_conns: 100
@ -209,11 +166,6 @@ user_api:
max_idle_conns: 2
conn_max_lifetime: -1
relay_api:
internal_api:
listen: http://localhost:7775
connect: http://localhost:7775
external_api:
listen: http://[::]:8075
database:
connection_string: file:relayapi.db
mscs:

View file

@ -5,8 +5,6 @@ import "golang.org/x/crypto/bcrypt"
type UserAPI struct {
Matrix *Global `yaml:"-"`
InternalAPI InternalAPIOptions `yaml:"internal_api,omitempty"`
// The cost when hashing passwords.
BCryptCost int `yaml:"bcrypt_cost"`
@ -28,28 +26,18 @@ type UserAPI struct {
const DefaultOpenIDTokenLifetimeMS = 3600000 // 60 minutes
func (c *UserAPI) Defaults(opts DefaultOpts) {
if !opts.Monolithic {
c.InternalAPI.Listen = "http://localhost:7781"
c.InternalAPI.Connect = "http://localhost:7781"
c.AccountDatabase.Defaults(10)
}
c.BCryptCost = bcrypt.DefaultCost
c.OpenIDTokenLifetimeMS = DefaultOpenIDTokenLifetimeMS
if opts.Generate {
if !opts.Monolithic {
if !opts.SingleDatabase {
c.AccountDatabase.ConnectionString = "file:userapi_accounts.db"
}
}
}
func (c *UserAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
func (c *UserAPI) Verify(configErrs *ConfigErrors) {
checkPositive(configErrs, "user_api.openid_token_lifetime_ms", c.OpenIDTokenLifetimeMS)
if isMonolith { // polylith required configs below
return
}
if c.Matrix.DatabaseOptions.ConnectionString == "" {
checkNotEmpty(configErrs, "user_api.account_database.connection_string", string(c.AccountDatabase.ConnectionString))
}
checkURL(configErrs, "user_api.internal_api.listen", string(c.InternalAPI.Listen))
checkURL(configErrs, "user_api.internal_api.connect", string(c.InternalAPI.Connect))
}

View file

@ -43,7 +43,7 @@ func ParseFlags(monolith bool) *config.Dendrite {
logrus.Fatal("--config must be supplied")
}
cfg, err := config.Load(*configPath, monolith)
cfg, err := config.Load(*configPath)
if err != nil {
logrus.Fatalf("Invalid config file: %s", err)

View file

@ -499,7 +499,7 @@ func assertUnsignedChildren(t *testing.T, ev gomatrixserverlib.ClientEvent, relT
}
type testUserAPI struct {
userapi.UserInternalAPITrace
userapi.UserInternalAPI
accessTokens map[string]userapi.Device
}
@ -516,7 +516,7 @@ func (u *testUserAPI) QueryAccessToken(ctx context.Context, req *userapi.QueryAc
type testRoomserverAPI struct {
// use a trace API as it implements method stubs so we don't need to have them here.
// We'll override the functions we care about.
roomserver.RoomserverInternalAPITrace
roomserver.RoomserverInternalAPI
userToJoinedRooms map[string][]string
events map[string]*gomatrixserverlib.HeaderedEvent
}
@ -549,7 +549,7 @@ func injectEvents(t *testing.T, userAPI userapi.UserInternalAPI, rsAPI roomserve
cfg := &config.Dendrite{}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
cfg.Global.ServerName = "localhost"
cfg.MSCs.Database.ConnectionString = "file:msc2836_test.db"

View file

@ -33,8 +33,7 @@ func init() {
}
// calculateHistoryVisibilityDuration stores the time it takes to
// calculate the history visibility. In polylith mode the roundtrip
// to the roomserver is included in this time.
// calculate the history visibility.
var calculateHistoryVisibilityDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: "dendrite",

View file

@ -64,7 +64,7 @@ func (k *mockKeyAPI) QuerySignatures(ctx context.Context, req *keyapi.QuerySigna
}
type mockRoomserverAPI struct {
api.RoomserverInternalAPITrace
api.RoomserverInternalAPI
roomIDToJoinedMembers map[string][]string
}

View file

@ -29,7 +29,7 @@ func CreateBaseDendrite(t *testing.T, dbType test.DBType) (*base.BaseDendrite, f
var cfg config.Dendrite
cfg.Defaults(config.DefaultOpts{
Generate: false,
Monolithic: true,
SingleDatabase: true,
})
cfg.Global.JetStream.InMemory = true
cfg.FederationAPI.KeyPerspectives = nil
@ -37,15 +37,15 @@ func CreateBaseDendrite(t *testing.T, dbType test.DBType) (*base.BaseDendrite, f
case test.DBTypePostgres:
cfg.Global.Defaults(config.DefaultOpts{ // autogen a signing key
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
cfg.MediaAPI.Defaults(config.DefaultOpts{ // autogen a media path
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
cfg.SyncAPI.Fulltext.Defaults(config.DefaultOpts{ // use in memory fts
Generate: true,
Monolithic: true,
SingleDatabase: true,
})
cfg.Global.ServerName = "test"
// use a distinct prefix else concurrent postgres/sqlite runs will clash since NATS will use
@ -58,7 +58,7 @@ func CreateBaseDendrite(t *testing.T, dbType test.DBType) (*base.BaseDendrite, f
MaxIdleConnections: 2,
ConnMaxLifetimeSeconds: 60,
}
base := base.NewBaseDendrite(&cfg, "Test", base.DisableMetrics)
base := base.NewBaseDendrite(&cfg, base.DisableMetrics)
return base, func() {
base.ShutdownDendrite()
base.WaitForShutdown()
@ -67,7 +67,7 @@ func CreateBaseDendrite(t *testing.T, dbType test.DBType) (*base.BaseDendrite, f
case test.DBTypeSQLite:
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: false,
})
cfg.Global.ServerName = "test"
@ -86,7 +86,7 @@ func CreateBaseDendrite(t *testing.T, dbType test.DBType) (*base.BaseDendrite, f
cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(filepath.Join("file://", tempDir, "userapi.db"))
cfg.RelayAPI.Database.ConnectionString = config.DataSource(filepath.Join("file://", tempDir, "relayapi.db"))
base := base.NewBaseDendrite(&cfg, "Test", base.DisableMetrics)
base := base.NewBaseDendrite(&cfg, base.DisableMetrics)
return base, func() {
base.ShutdownDendrite()
base.WaitForShutdown()
@ -103,13 +103,13 @@ func Base(cfg *config.Dendrite) (*base.BaseDendrite, nats.JetStreamContext, *nat
cfg = &config.Dendrite{}
cfg.Defaults(config.DefaultOpts{
Generate: true,
Monolithic: true,
SingleDatabase: false,
})
}
cfg.Global.JetStream.InMemory = true
cfg.SyncAPI.Fulltext.InMemory = true
cfg.FederationAPI.KeyPerspectives = nil
base := base.NewBaseDendrite(cfg, "Tests", base.DisableMetrics)
base := base.NewBaseDendrite(cfg, base.DisableMetrics)
js, jc := base.NATS.Prepare(base.ProcessContext, &cfg.Global.JetStream)
return base, js, jc
}

View file

@ -1,219 +0,0 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package api
import (
"context"
"encoding/json"
"fmt"
"github.com/matrix-org/util"
)
// UserInternalAPITrace wraps a RoomserverInternalAPI and logs the
// complete request/response/error
type UserInternalAPITrace struct {
Impl UserInternalAPI
}
func (t *UserInternalAPITrace) InputAccountData(ctx context.Context, req *InputAccountDataRequest, res *InputAccountDataResponse) error {
err := t.Impl.InputAccountData(ctx, req, res)
util.GetLogger(ctx).Infof("InputAccountData req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformAccountCreation(ctx context.Context, req *PerformAccountCreationRequest, res *PerformAccountCreationResponse) error {
err := t.Impl.PerformAccountCreation(ctx, req, res)
util.GetLogger(ctx).Infof("PerformAccountCreation req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformPasswordUpdate(ctx context.Context, req *PerformPasswordUpdateRequest, res *PerformPasswordUpdateResponse) error {
err := t.Impl.PerformPasswordUpdate(ctx, req, res)
util.GetLogger(ctx).Infof("PerformPasswordUpdate req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformDeviceCreation(ctx context.Context, req *PerformDeviceCreationRequest, res *PerformDeviceCreationResponse) error {
err := t.Impl.PerformDeviceCreation(ctx, req, res)
util.GetLogger(ctx).Infof("PerformDeviceCreation req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformDeviceDeletion(ctx context.Context, req *PerformDeviceDeletionRequest, res *PerformDeviceDeletionResponse) error {
err := t.Impl.PerformDeviceDeletion(ctx, req, res)
util.GetLogger(ctx).Infof("PerformDeviceDeletion req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformLastSeenUpdate(ctx context.Context, req *PerformLastSeenUpdateRequest, res *PerformLastSeenUpdateResponse) error {
err := t.Impl.PerformLastSeenUpdate(ctx, req, res)
util.GetLogger(ctx).Infof("PerformLastSeenUpdate req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformDeviceUpdate(ctx context.Context, req *PerformDeviceUpdateRequest, res *PerformDeviceUpdateResponse) error {
err := t.Impl.PerformDeviceUpdate(ctx, req, res)
util.GetLogger(ctx).Infof("PerformDeviceUpdate req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformAccountDeactivation(ctx context.Context, req *PerformAccountDeactivationRequest, res *PerformAccountDeactivationResponse) error {
err := t.Impl.PerformAccountDeactivation(ctx, req, res)
util.GetLogger(ctx).Infof("PerformAccountDeactivation req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformOpenIDTokenCreation(ctx context.Context, req *PerformOpenIDTokenCreationRequest, res *PerformOpenIDTokenCreationResponse) error {
err := t.Impl.PerformOpenIDTokenCreation(ctx, req, res)
util.GetLogger(ctx).Infof("PerformOpenIDTokenCreation req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformKeyBackup(ctx context.Context, req *PerformKeyBackupRequest, res *PerformKeyBackupResponse) error {
err := t.Impl.PerformKeyBackup(ctx, req, res)
util.GetLogger(ctx).Infof("PerformKeyBackup req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformPusherSet(ctx context.Context, req *PerformPusherSetRequest, res *struct{}) error {
err := t.Impl.PerformPusherSet(ctx, req, res)
util.GetLogger(ctx).Infof("PerformPusherSet req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformPusherDeletion(ctx context.Context, req *PerformPusherDeletionRequest, res *struct{}) error {
err := t.Impl.PerformPusherDeletion(ctx, req, res)
util.GetLogger(ctx).Infof("PerformPusherDeletion req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformPushRulesPut(ctx context.Context, req *PerformPushRulesPutRequest, res *struct{}) error {
err := t.Impl.PerformPushRulesPut(ctx, req, res)
util.GetLogger(ctx).Infof("PerformPushRulesPut req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryKeyBackup(ctx context.Context, req *QueryKeyBackupRequest, res *QueryKeyBackupResponse) error {
err := t.Impl.QueryKeyBackup(ctx, req, res)
util.GetLogger(ctx).Infof("QueryKeyBackup req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryProfile(ctx context.Context, req *QueryProfileRequest, res *QueryProfileResponse) error {
err := t.Impl.QueryProfile(ctx, req, res)
util.GetLogger(ctx).Infof("QueryProfile req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryAccessToken(ctx context.Context, req *QueryAccessTokenRequest, res *QueryAccessTokenResponse) error {
err := t.Impl.QueryAccessToken(ctx, req, res)
util.GetLogger(ctx).Infof("QueryAccessToken req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryDevices(ctx context.Context, req *QueryDevicesRequest, res *QueryDevicesResponse) error {
err := t.Impl.QueryDevices(ctx, req, res)
util.GetLogger(ctx).Infof("QueryDevices req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryAccountData(ctx context.Context, req *QueryAccountDataRequest, res *QueryAccountDataResponse) error {
err := t.Impl.QueryAccountData(ctx, req, res)
util.GetLogger(ctx).Infof("QueryAccountData req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryDeviceInfos(ctx context.Context, req *QueryDeviceInfosRequest, res *QueryDeviceInfosResponse) error {
err := t.Impl.QueryDeviceInfos(ctx, req, res)
util.GetLogger(ctx).Infof("QueryDeviceInfos req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QuerySearchProfiles(ctx context.Context, req *QuerySearchProfilesRequest, res *QuerySearchProfilesResponse) error {
err := t.Impl.QuerySearchProfiles(ctx, req, res)
util.GetLogger(ctx).Infof("QuerySearchProfiles req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryOpenIDToken(ctx context.Context, req *QueryOpenIDTokenRequest, res *QueryOpenIDTokenResponse) error {
err := t.Impl.QueryOpenIDToken(ctx, req, res)
util.GetLogger(ctx).Infof("QueryOpenIDToken req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryPushers(ctx context.Context, req *QueryPushersRequest, res *QueryPushersResponse) error {
err := t.Impl.QueryPushers(ctx, req, res)
util.GetLogger(ctx).Infof("QueryPushers req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryPushRules(ctx context.Context, req *QueryPushRulesRequest, res *QueryPushRulesResponse) error {
err := t.Impl.QueryPushRules(ctx, req, res)
util.GetLogger(ctx).Infof("QueryPushRules req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryNotifications(ctx context.Context, req *QueryNotificationsRequest, res *QueryNotificationsResponse) error {
err := t.Impl.QueryNotifications(ctx, req, res)
util.GetLogger(ctx).Infof("QueryNotifications req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) SetAvatarURL(ctx context.Context, req *PerformSetAvatarURLRequest, res *PerformSetAvatarURLResponse) error {
err := t.Impl.SetAvatarURL(ctx, req, res)
util.GetLogger(ctx).Infof("SetAvatarURL req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryNumericLocalpart(ctx context.Context, req *QueryNumericLocalpartRequest, res *QueryNumericLocalpartResponse) error {
err := t.Impl.QueryNumericLocalpart(ctx, req, res)
util.GetLogger(ctx).Infof("QueryNumericLocalpart req= res=%+v", js(res))
return err
}
func (t *UserInternalAPITrace) QueryAccountAvailability(ctx context.Context, req *QueryAccountAvailabilityRequest, res *QueryAccountAvailabilityResponse) error {
err := t.Impl.QueryAccountAvailability(ctx, req, res)
util.GetLogger(ctx).Infof("QueryAccountAvailability req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) SetDisplayName(ctx context.Context, req *PerformUpdateDisplayNameRequest, res *PerformUpdateDisplayNameResponse) error {
err := t.Impl.SetDisplayName(ctx, req, res)
util.GetLogger(ctx).Infof("SetDisplayName req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryAccountByPassword(ctx context.Context, req *QueryAccountByPasswordRequest, res *QueryAccountByPasswordResponse) error {
err := t.Impl.QueryAccountByPassword(ctx, req, res)
util.GetLogger(ctx).Infof("QueryAccountByPassword req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryLocalpartForThreePID(ctx context.Context, req *QueryLocalpartForThreePIDRequest, res *QueryLocalpartForThreePIDResponse) error {
err := t.Impl.QueryLocalpartForThreePID(ctx, req, res)
util.GetLogger(ctx).Infof("QueryLocalpartForThreePID req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryThreePIDsForLocalpart(ctx context.Context, req *QueryThreePIDsForLocalpartRequest, res *QueryThreePIDsForLocalpartResponse) error {
err := t.Impl.QueryThreePIDsForLocalpart(ctx, req, res)
util.GetLogger(ctx).Infof("QueryThreePIDsForLocalpart req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformForgetThreePID(ctx context.Context, req *PerformForgetThreePIDRequest, res *struct{}) error {
err := t.Impl.PerformForgetThreePID(ctx, req, res)
util.GetLogger(ctx).Infof("PerformForgetThreePID req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformSaveThreePIDAssociation(ctx context.Context, req *PerformSaveThreePIDAssociationRequest, res *struct{}) error {
err := t.Impl.PerformSaveThreePIDAssociation(ctx, req, res)
util.GetLogger(ctx).Infof("PerformSaveThreePIDAssociation req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryAccountByLocalpart(ctx context.Context, req *QueryAccountByLocalpartRequest, res *QueryAccountByLocalpartResponse) error {
err := t.Impl.QueryAccountByLocalpart(ctx, req, res)
util.GetLogger(ctx).Infof("QueryAccountByLocalpart req=%+v res=%+v", js(req), js(res))
return err
}
func js(thing interface{}) string {
b, err := json.Marshal(thing)
if err != nil {
return fmt.Sprintf("Marshal error:%s", err)
}
return string(b)
}

View file

@ -1,39 +0,0 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package api
import (
"context"
"github.com/matrix-org/util"
)
func (t *UserInternalAPITrace) PerformLoginTokenCreation(ctx context.Context, req *PerformLoginTokenCreationRequest, res *PerformLoginTokenCreationResponse) error {
err := t.Impl.PerformLoginTokenCreation(ctx, req, res)
util.GetLogger(ctx).Infof("PerformLoginTokenCreation req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) PerformLoginTokenDeletion(ctx context.Context, req *PerformLoginTokenDeletionRequest, res *PerformLoginTokenDeletionResponse) error {
err := t.Impl.PerformLoginTokenDeletion(ctx, req, res)
util.GetLogger(ctx).Infof("PerformLoginTokenDeletion req=%+v res=%+v", js(req), js(res))
return err
}
func (t *UserInternalAPITrace) QueryLoginToken(ctx context.Context, req *QueryLoginTokenRequest, res *QueryLoginTokenResponse) error {
err := t.Impl.QueryLoginToken(ctx, req, res)
util.GetLogger(ctx).Infof("QueryLoginToken req=%+v res=%+v", js(req), js(res))
return err
}

View file

@ -1,454 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package inthttp
import (
"context"
"errors"
"net/http"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/userapi/api"
)
// HTTP paths for the internal HTTP APIs
const (
InputAccountDataPath = "/userapi/inputAccountData"
PerformDeviceCreationPath = "/userapi/performDeviceCreation"
PerformAccountCreationPath = "/userapi/performAccountCreation"
PerformPasswordUpdatePath = "/userapi/performPasswordUpdate"
PerformDeviceDeletionPath = "/userapi/performDeviceDeletion"
PerformLastSeenUpdatePath = "/userapi/performLastSeenUpdate"
PerformDeviceUpdatePath = "/userapi/performDeviceUpdate"
PerformAccountDeactivationPath = "/userapi/performAccountDeactivation"
PerformOpenIDTokenCreationPath = "/userapi/performOpenIDTokenCreation"
PerformKeyBackupPath = "/userapi/performKeyBackup"
PerformPusherSetPath = "/pushserver/performPusherSet"
PerformPusherDeletionPath = "/pushserver/performPusherDeletion"
PerformPushRulesPutPath = "/pushserver/performPushRulesPut"
PerformSetAvatarURLPath = "/userapi/performSetAvatarURL"
PerformSetDisplayNamePath = "/userapi/performSetDisplayName"
PerformForgetThreePIDPath = "/userapi/performForgetThreePID"
PerformSaveThreePIDAssociationPath = "/userapi/performSaveThreePIDAssociation"
QueryKeyBackupPath = "/userapi/queryKeyBackup"
QueryProfilePath = "/userapi/queryProfile"
QueryAccessTokenPath = "/userapi/queryAccessToken"
QueryDevicesPath = "/userapi/queryDevices"
QueryAccountDataPath = "/userapi/queryAccountData"
QueryDeviceInfosPath = "/userapi/queryDeviceInfos"
QuerySearchProfilesPath = "/userapi/querySearchProfiles"
QueryOpenIDTokenPath = "/userapi/queryOpenIDToken"
QueryPushersPath = "/pushserver/queryPushers"
QueryPushRulesPath = "/pushserver/queryPushRules"
QueryNotificationsPath = "/pushserver/queryNotifications"
QueryNumericLocalpartPath = "/userapi/queryNumericLocalpart"
QueryAccountAvailabilityPath = "/userapi/queryAccountAvailability"
QueryAccountByPasswordPath = "/userapi/queryAccountByPassword"
QueryLocalpartForThreePIDPath = "/userapi/queryLocalpartForThreePID"
QueryThreePIDsForLocalpartPath = "/userapi/queryThreePIDsForLocalpart"
QueryAccountByLocalpartPath = "/userapi/queryAccountType"
)
// NewUserAPIClient creates a UserInternalAPI implemented by talking to a HTTP POST API.
// If httpClient is nil an error is returned
func NewUserAPIClient(
apiURL string,
httpClient *http.Client,
) (api.UserInternalAPI, error) {
if httpClient == nil {
return nil, errors.New("NewUserAPIClient: httpClient is <nil>")
}
return &httpUserInternalAPI{
apiURL: apiURL,
httpClient: httpClient,
}, nil
}
type httpUserInternalAPI struct {
apiURL string
httpClient *http.Client
}
func (h *httpUserInternalAPI) InputAccountData(ctx context.Context, req *api.InputAccountDataRequest, res *api.InputAccountDataResponse) error {
return httputil.CallInternalRPCAPI(
"InputAccountData", h.apiURL+InputAccountDataPath,
h.httpClient, ctx, req, res,
)
}
func (h *httpUserInternalAPI) PerformAccountCreation(
ctx context.Context,
request *api.PerformAccountCreationRequest,
response *api.PerformAccountCreationResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformAccountCreation", h.apiURL+PerformAccountCreationPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformPasswordUpdate(
ctx context.Context,
request *api.PerformPasswordUpdateRequest,
response *api.PerformPasswordUpdateResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformPasswordUpdate", h.apiURL+PerformPasswordUpdatePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformDeviceCreation(
ctx context.Context,
request *api.PerformDeviceCreationRequest,
response *api.PerformDeviceCreationResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformDeviceCreation", h.apiURL+PerformDeviceCreationPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformDeviceDeletion(
ctx context.Context,
request *api.PerformDeviceDeletionRequest,
response *api.PerformDeviceDeletionResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformDeviceDeletion", h.apiURL+PerformDeviceDeletionPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformLastSeenUpdate(
ctx context.Context,
request *api.PerformLastSeenUpdateRequest,
response *api.PerformLastSeenUpdateResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformLastSeen", h.apiURL+PerformLastSeenUpdatePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformDeviceUpdate(
ctx context.Context,
request *api.PerformDeviceUpdateRequest,
response *api.PerformDeviceUpdateResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformDeviceUpdate", h.apiURL+PerformDeviceUpdatePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformAccountDeactivation(
ctx context.Context,
request *api.PerformAccountDeactivationRequest,
response *api.PerformAccountDeactivationResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformAccountDeactivation", h.apiURL+PerformAccountDeactivationPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformOpenIDTokenCreation(
ctx context.Context,
request *api.PerformOpenIDTokenCreationRequest,
response *api.PerformOpenIDTokenCreationResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformOpenIDTokenCreation", h.apiURL+PerformOpenIDTokenCreationPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryProfile(
ctx context.Context,
request *api.QueryProfileRequest,
response *api.QueryProfileResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryProfile", h.apiURL+QueryProfilePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryDeviceInfos(
ctx context.Context,
request *api.QueryDeviceInfosRequest,
response *api.QueryDeviceInfosResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryDeviceInfos", h.apiURL+QueryDeviceInfosPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryAccessToken(
ctx context.Context,
request *api.QueryAccessTokenRequest,
response *api.QueryAccessTokenResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryAccessToken", h.apiURL+QueryAccessTokenPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryDevices(
ctx context.Context,
request *api.QueryDevicesRequest,
response *api.QueryDevicesResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryDevices", h.apiURL+QueryDevicesPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryAccountData(
ctx context.Context,
request *api.QueryAccountDataRequest,
response *api.QueryAccountDataResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryAccountData", h.apiURL+QueryAccountDataPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QuerySearchProfiles(
ctx context.Context,
request *api.QuerySearchProfilesRequest,
response *api.QuerySearchProfilesResponse,
) error {
return httputil.CallInternalRPCAPI(
"QuerySearchProfiles", h.apiURL+QuerySearchProfilesPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryOpenIDToken(
ctx context.Context,
request *api.QueryOpenIDTokenRequest,
response *api.QueryOpenIDTokenResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryOpenIDToken", h.apiURL+QueryOpenIDTokenPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformKeyBackup(
ctx context.Context,
request *api.PerformKeyBackupRequest,
response *api.PerformKeyBackupResponse,
) error {
return httputil.CallInternalRPCAPI(
"PerformKeyBackup", h.apiURL+PerformKeyBackupPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryKeyBackup(
ctx context.Context,
request *api.QueryKeyBackupRequest,
response *api.QueryKeyBackupResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryKeyBackup", h.apiURL+QueryKeyBackupPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryNotifications(
ctx context.Context,
request *api.QueryNotificationsRequest,
response *api.QueryNotificationsResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryNotifications", h.apiURL+QueryNotificationsPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformPusherSet(
ctx context.Context,
request *api.PerformPusherSetRequest,
response *struct{},
) error {
return httputil.CallInternalRPCAPI(
"PerformPusherSet", h.apiURL+PerformPusherSetPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformPusherDeletion(
ctx context.Context,
request *api.PerformPusherDeletionRequest,
response *struct{},
) error {
return httputil.CallInternalRPCAPI(
"PerformPusherDeletion", h.apiURL+PerformPusherDeletionPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryPushers(
ctx context.Context,
request *api.QueryPushersRequest,
response *api.QueryPushersResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryPushers", h.apiURL+QueryPushersPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformPushRulesPut(
ctx context.Context,
request *api.PerformPushRulesPutRequest,
response *struct{},
) error {
return httputil.CallInternalRPCAPI(
"PerformPushRulesPut", h.apiURL+PerformPushRulesPutPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryPushRules(
ctx context.Context,
request *api.QueryPushRulesRequest,
response *api.QueryPushRulesResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryPushRules", h.apiURL+QueryPushRulesPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) SetAvatarURL(
ctx context.Context,
request *api.PerformSetAvatarURLRequest,
response *api.PerformSetAvatarURLResponse,
) error {
return httputil.CallInternalRPCAPI(
"SetAvatarURL", h.apiURL+PerformSetAvatarURLPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryNumericLocalpart(
ctx context.Context,
request *api.QueryNumericLocalpartRequest,
response *api.QueryNumericLocalpartResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryNumericLocalpart", h.apiURL+QueryNumericLocalpartPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryAccountAvailability(
ctx context.Context,
request *api.QueryAccountAvailabilityRequest,
response *api.QueryAccountAvailabilityResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryAccountAvailability", h.apiURL+QueryAccountAvailabilityPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryAccountByPassword(
ctx context.Context,
request *api.QueryAccountByPasswordRequest,
response *api.QueryAccountByPasswordResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryAccountByPassword", h.apiURL+QueryAccountByPasswordPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) SetDisplayName(
ctx context.Context,
request *api.PerformUpdateDisplayNameRequest,
response *api.PerformUpdateDisplayNameResponse,
) error {
return httputil.CallInternalRPCAPI(
"SetDisplayName", h.apiURL+PerformSetDisplayNamePath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryLocalpartForThreePID(
ctx context.Context,
request *api.QueryLocalpartForThreePIDRequest,
response *api.QueryLocalpartForThreePIDResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryLocalpartForThreePID", h.apiURL+QueryLocalpartForThreePIDPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryThreePIDsForLocalpart(
ctx context.Context,
request *api.QueryThreePIDsForLocalpartRequest,
response *api.QueryThreePIDsForLocalpartResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryThreePIDsForLocalpart", h.apiURL+QueryThreePIDsForLocalpartPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformForgetThreePID(
ctx context.Context,
request *api.PerformForgetThreePIDRequest,
response *struct{},
) error {
return httputil.CallInternalRPCAPI(
"PerformForgetThreePID", h.apiURL+PerformForgetThreePIDPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) PerformSaveThreePIDAssociation(
ctx context.Context,
request *api.PerformSaveThreePIDAssociationRequest,
response *struct{},
) error {
return httputil.CallInternalRPCAPI(
"PerformSaveThreePIDAssociation", h.apiURL+PerformSaveThreePIDAssociationPath,
h.httpClient, ctx, request, response,
)
}
func (h *httpUserInternalAPI) QueryAccountByLocalpart(
ctx context.Context,
req *api.QueryAccountByLocalpartRequest,
res *api.QueryAccountByLocalpartResponse,
) error {
return httputil.CallInternalRPCAPI(
"QueryAccountByLocalpart", h.apiURL+QueryAccountByLocalpartPath,
h.httpClient, ctx, req, res,
)
}

Some files were not shown because too many files have changed in this diff Show more