captions: 'storage/captions/'
cache: 'storage/cache/'
plugins: 'storage/plugins/'
+ well_known: 'storage/well-known/'
# Overridable client files in client/dist/assets/images:
# - logo.svg
# - favicon.png
captions: '/var/www/peertube/storage/captions/'
cache: '/var/www/peertube/storage/cache/'
plugins: '/var/www/peertube/storage/plugins/'
+ well_known: '/var/www/peertube/storage/well-known/'
# Overridable client files in client/dist/assets/images:
# - logo.svg
# - favicon.png
captions: 'test1/captions/'
cache: 'test1/cache/'
plugins: 'test1/plugins/'
+ well_known: 'test1/well-known/'
client_overrides: 'test1/client-overrides/'
admin:
captions: 'test2/captions/'
cache: 'test2/cache/'
plugins: 'test2/plugins/'
+ well_known: 'test2/well-known/'
client_overrides: 'test2/client-overrides/'
admin:
captions: 'test3/captions/'
cache: 'test3/cache/'
plugins: 'test3/plugins/'
+ well_known: 'test3/well-known/'
client_overrides: 'test3/client-overrides/'
admin:
captions: 'test4/captions/'
cache: 'test4/cache/'
plugins: 'test4/plugins/'
+ well_known: 'test4/well-known/'
client_overrides: 'test4/client-overrides/'
admin:
captions: 'test5/captions/'
cache: 'test5/cache/'
plugins: 'test5/plugins/'
+ well_known: 'test5/well-known/'
client_overrides: 'test5/client-overrides/'
admin:
captions: 'test6/captions/'
cache: 'test6/cache/'
plugins: 'test6/plugins/'
+ well_known: 'test6/well-known/'
client_overrides: 'test6/client-overrides/'
admin:
import { CONFIG } from '../initializers/config'
import { ROUTE_CACHE_LIFETIME, WEBSERVER } from '../initializers/constants'
import { cacheRoute } from '../middlewares/cache/cache'
+import { handleStaticError } from '@server/middlewares'
const wellKnownRouter = express.Router()
}
)
+wellKnownRouter.use('/.well-known/',
+ cacheRoute(ROUTE_CACHE_LIFETIME.WELL_KNOWN),
+ express.static(CONFIG.STORAGE.WELL_KNOWN_DIR, { fallthrough: false }),
+ handleStaticError
+)
+
// ---------------------------------------------------------------------------
export {
'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address',
'email.body.signature', 'email.subject.prefix',
'storage.avatars', 'storage.videos', 'storage.logs', 'storage.previews', 'storage.thumbnails', 'storage.torrents', 'storage.cache',
- 'storage.redundancy', 'storage.tmp', 'storage.streaming_playlists', 'storage.plugins',
+ 'storage.redundancy', 'storage.tmp', 'storage.streaming_playlists', 'storage.plugins', 'storage.well_known',
'log.level',
'user.video_quota', 'user.video_quota_daily',
'video_channels.max_per_user',
TORRENTS_DIR: buildPath(config.get<string>('storage.torrents')),
CACHE_DIR: buildPath(config.get<string>('storage.cache')),
PLUGINS_DIR: buildPath(config.get<string>('storage.plugins')),
- CLIENT_OVERRIDES_DIR: buildPath(config.get<string>('storage.client_overrides'))
+ CLIENT_OVERRIDES_DIR: buildPath(config.get<string>('storage.client_overrides')),
+ WELL_KNOWN_DIR: buildPath(config.get<string>('storage.well_known'))
},
OBJECT_STORAGE: {
ENABLED: config.get<boolean>('object_storage.enabled'),
ACTIVITY_PUB: {
VIDEOS: '1 second' // 1 second, cache concurrent requests after a broadcast for example
},
- STATS: '4 hours'
+ STATS: '4 hours',
+ WELL_KNOWN: '1 day'
}
// ---------------------------------------------------------------------------
const { webtorrentFilenames } = await ensureSameFilenames(videoUUID)
const directories = [
- 'test' + servers[0].internalServerNumber + '/redundancy',
- 'test' + servers[1].internalServerNumber + '/videos'
+ servers[0].getDirectoryPath('redundancy'),
+ servers[1].getDirectoryPath('videos')
]
for (const directory of directories) {
const { hlsFilenames } = await ensureSameFilenames(videoUUID)
const directories = [
- 'test' + servers[0].internalServerNumber + '/redundancy/hls',
- 'test' + servers[1].internalServerNumber + '/streaming-playlists/hls'
+ servers[0].getDirectoryPath('redundancy/hls'),
+ servers[1].getDirectoryPath('streaming-playlists/hls')
]
for (const directory of directories) {
it('Should not have actor files', async () => {
for (const server of servers) {
for (const userAvatarFilename of userAvatarFilenames) {
- await checkActorFilesWereRemoved(userAvatarFilename, server.internalServerNumber)
+ await checkActorFilesWereRemoved(userAvatarFilename, server)
}
}
})
this.timeout(30000)
for (const server of servers) {
- await checkPlaylistFilesWereRemoved(playlistServer1UUID, server.internalServerNumber)
+ await checkPlaylistFilesWereRemoved(playlistServer1UUID, server)
}
})
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import { expect } from 'chai'
-import { cleanupTests, createSingleServer, makeGetRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
+import { writeJson } from 'fs-extra'
+import { join } from 'path'
import { HttpStatusCode, VideoPrivacy } from '@shared/models'
+import { cleanupTests, createSingleServer, makeGetRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
import { expectLogDoesNotContain } from './shared'
describe('Test misc endpoints', function () {
let server: PeerTubeServer
+ let wellKnownPath: string
before(async function () {
this.timeout(120000)
server = await createSingleServer(1)
+
await setAccessTokensToServers([ server ])
+
+ wellKnownPath = server.getDirectoryPath('well-known')
})
describe('Test a well known endpoints', function () {
expect(remoteInteract).to.exist
expect(remoteInteract.template).to.equal(server.url + '/remote-interaction?uri={uri}')
})
+
+ it('Should return 404 for non-existing files in /.well-known', async function () {
+ await makeGetRequest({
+ url: server.url,
+ path: '/.well-known/non-existing-file',
+ expectedStatus: HttpStatusCode.NOT_FOUND_404
+ })
+ })
+
+ it('Should return custom file from /.well-known', async function () {
+ const filename = 'existing-file.json'
+
+ await writeJson(join(wellKnownPath, filename), { iThink: 'therefore I am' })
+
+ const { body } = await makeGetRequest({
+ url: server.url,
+ path: '/.well-known/' + filename,
+ expectedStatus: HttpStatusCode.OK_200
+ })
+
+ expect(body.iThink).to.equal('therefore I am')
+ })
})
describe('Test classic static endpoints', function () {
import { expect } from 'chai'
import { pathExists, readdir } from 'fs-extra'
-import { join } from 'path'
-import { root } from '@shared/core-utils'
import { Account, VideoChannel } from '@shared/models'
import { PeerTubeServer } from '@shared/server-commands'
return expectActorFollow({ ...options, data })
}
-async function checkActorFilesWereRemoved (filename: string, serverNumber: number) {
- const testDirectory = 'test' + serverNumber
-
+async function checkActorFilesWereRemoved (filename: string, server: PeerTubeServer) {
for (const directory of [ 'avatars' ]) {
- const directoryPath = join(root(), testDirectory, directory)
+ const directoryPath = server.getDirectoryPath(directory)
const directoryExists = await pathExists(directoryPath)
expect(directoryExists).to.be.true
import { expect } from 'chai'
import { pathExists, readdir } from 'fs-extra'
-import { join } from 'path'
-import { root } from '@shared/core-utils'
import { PeerTubeServer } from '@shared/server-commands'
async function checkTmpIsEmpty (server: PeerTubeServer) {
await checkDirectoryIsEmpty(server, 'tmp', [ 'plugins-global.css', 'hls', 'resumable-uploads' ])
- if (await pathExists(join('test' + server.internalServerNumber, 'tmp', 'hls'))) {
+ if (await pathExists(server.getDirectoryPath('tmp/hls'))) {
await checkDirectoryIsEmpty(server, 'tmp/hls')
}
}
async function checkDirectoryIsEmpty (server: PeerTubeServer, directory: string, exceptions: string[] = []) {
- const testDirectory = 'test' + server.internalServerNumber
-
- const directoryPath = join(root(), testDirectory, directory)
+ const directoryPath = server.getDirectoryPath(directory)
const directoryExists = await pathExists(directoryPath)
expect(directoryExists).to.be.true
import { expect } from 'chai'
import { readdir } from 'fs-extra'
-import { join } from 'path'
-import { root } from '@shared/core-utils'
+import { PeerTubeServer } from '@shared/server-commands'
async function checkPlaylistFilesWereRemoved (
playlistUUID: string,
- internalServerNumber: number,
+ server: PeerTubeServer,
directories = [ 'thumbnails' ]
) {
- const testDirectory = 'test' + internalServerNumber
-
for (const directory of directories) {
- const directoryPath = join(root(), testDirectory, directory)
+ const directoryPath = server.getDirectoryPath(directory)
const files = await readdir(directoryPath)
for (const file of files) {
this.port = parseInt(parsed.port)
}
+ getDirectoryPath (directoryName: string) {
+ const testDirectory = 'test' + this.internalServerNumber
+
+ return join(root(), testDirectory, directoryName)
+ }
+
async flushAndRun (configOverride?: Object, options: RunServerOptions = {}) {
await ServersCommand.flushTests(this.internalServerNumber)
suffix: '_test' + this.internalServerNumber
},
storage: {
- tmp: `test${this.internalServerNumber}/tmp/`,
- bin: `test${this.internalServerNumber}/bin/`,
- avatars: `test${this.internalServerNumber}/avatars/`,
- videos: `test${this.internalServerNumber}/videos/`,
- streaming_playlists: `test${this.internalServerNumber}/streaming-playlists/`,
- redundancy: `test${this.internalServerNumber}/redundancy/`,
- logs: `test${this.internalServerNumber}/logs/`,
- previews: `test${this.internalServerNumber}/previews/`,
- thumbnails: `test${this.internalServerNumber}/thumbnails/`,
- torrents: `test${this.internalServerNumber}/torrents/`,
- captions: `test${this.internalServerNumber}/captions/`,
- cache: `test${this.internalServerNumber}/cache/`,
- plugins: `test${this.internalServerNumber}/plugins/`
+ tmp: this.getDirectoryPath('tmp') + '/',
+ bin: this.getDirectoryPath('bin') + '/',
+ avatars: this.getDirectoryPath('avatars') + '/',
+ videos: this.getDirectoryPath('videos') + '/',
+ streaming_playlists: this.getDirectoryPath('streaming-playlists') + '/',
+ redundancy: this.getDirectoryPath('redundancy') + '/',
+ logs: this.getDirectoryPath('logs') + '/',
+ previews: this.getDirectoryPath('previews') + '/',
+ thumbnails: this.getDirectoryPath('thumbnails') + '/',
+ torrents: this.getDirectoryPath('torrents') + '/',
+ captions: this.getDirectoryPath('captions') + '/',
+ cache: this.getDirectoryPath('cache') + '/',
+ plugins: this.getDirectoryPath('plugins') + '/',
+ well_known: this.getDirectoryPath('well-known') + '/'
},
admin: {
email: `admin${this.internalServerNumber}@example.com`
captions: '../data/captions/'
cache: '../data/cache/'
plugins: '../data/plugins/'
+ well_known: '../data/well-known/'
# Overridable client files in client/dist/assets/images :
# - logo.svg
# - favicon.png