import { InstanceService } from '@app/shared/shared-instance'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
import { ServerConfig } from '@shared/models'
@Component({
},
err => {
- this.error = err.status === 403
+ this.error = err.status === HttpStatusCode.FORBIDDEN_403
? $localize`You already sent this form recently`
: err.message
}
import { Account, AccountService, DropdownAction, ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main'
import { AccountReportComponent } from '@app/shared/shared-moderation'
import { User, UserRight } from '@shared/models'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
@Component({
templateUrl: './accounts.component.html',
switchMap(accountId => this.accountService.getAccount(accountId)),
tap(account => this.onAccount(account)),
switchMap(account => this.videoChannelService.listAccountVideoChannels(account)),
- catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ]))
+ catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [
+ HttpStatusCode.BAD_REQUEST_400,
+ HttpStatusCode.NOT_FOUND_404
+ ]))
)
.subscribe(
videoChannels => this.videoChannels = videoChannels.data,
import { FormValidatorService } from '@app/shared/shared-forms'
import { VideoChannelService } from '@app/shared/shared-main'
import { VideoChannelCreate } from '@shared/models'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
import { MyVideoChannelEdit } from './my-video-channel-edit'
@Component({
},
err => {
- if (err.status === 409) {
+ if (err.status === HttpStatusCode.CONFLICT_409) {
this.error = $localize`This name already exists on this instance.`
return
}
import { AuthService, Notifier, RestExtractor, ScreenService } from '@app/core'
import { ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main'
import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
@Component({
templateUrl: './video-channels.component.html',
map(params => params[ 'videoChannelName' ]),
distinctUntilChanged(),
switchMap(videoChannelName => this.videoChannelService.getVideoChannel(videoChannelName)),
- catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ]))
+ catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [
+ HttpStatusCode.BAD_REQUEST_400,
+ HttpStatusCode.NOT_FOUND_404
+ ]))
)
.subscribe(videoChannel => {
this.videoChannel = videoChannel
import { LoadingBarService } from '@ngx-loading-bar/core'
import { VideoPrivacy } from '@shared/models'
import { VideoSend } from './video-send'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
@Component({
selector: 'my-video-upload',
cancelUpload () {
if (this.videoUploadObservable !== null) {
this.videoUploadObservable.unsubscribe()
+ }
- this.isUploadingVideo = false
- this.videoUploadPercents = 0
- this.videoUploadObservable = null
+ this.isUploadingVideo = false
+ this.videoUploadPercents = 0
+ this.videoUploadObservable = null
- this.firstStepError.emit()
- this.enableRetryAfterError = false
- this.error = ''
+ this.firstStepError.emit()
+ this.enableRetryAfterError = false
+ this.error = ''
- this.notifier.info($localize`Upload cancelled`)
- }
+ this.notifier.info($localize`Upload cancelled`)
}
uploadFirstStep (clickedOnButton = false) {
notifier: this.notifier,
sticky: false
})
+
+ if (err.status === HttpStatusCode.PAYLOAD_TOO_LARGE_413 ||
+ err.status === HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415) {
+ this.cancelUpload()
+ }
}
)
}
import { environment } from '../../../environments/environment'
import { VideoSupportComponent } from './modal/video-support.component'
import { VideoWatchPlaylistComponent } from './video-watch-playlist.component'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
type URLOptions = CustomizationOptions & { playerMode: PlayerMode }
$localize`This video is not available on this instance. Do you want to be redirected on the origin instance: <a href="${originUrl}">${originUrl}</a>?`,
$localize`Redirection`
).then(res => {
- if (res === false) return this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ])
+ if (res === false) {
+ return this.restExtractor.redirectTo404IfNotFound(err, [
+ HttpStatusCode.BAD_REQUEST_400,
+ HttpStatusCode.UNAUTHORIZED_401,
+ HttpStatusCode.FORBIDDEN_403,
+ HttpStatusCode.NOT_FOUND_404
+ ])
+ }
return window.location.href = originUrl
})
}
- return this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ])
+ return this.restExtractor.redirectTo404IfNotFound(err, [
+ HttpStatusCode.BAD_REQUEST_400,
+ HttpStatusCode.UNAUTHORIZED_401,
+ HttpStatusCode.FORBIDDEN_403,
+ HttpStatusCode.NOT_FOUND_404
+ ])
})
)
.subscribe(([ video, captionsResult ]) => {
this.playlistService.getVideoPlaylist(playlistId)
.pipe(
// If 401, the video is private or blocked so redirect to 404
- catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ]))
+ catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [
+ HttpStatusCode.BAD_REQUEST_400,
+ HttpStatusCode.UNAUTHORIZED_401,
+ HttpStatusCode.FORBIDDEN_403,
+ HttpStatusCode.NOT_FOUND_404
+ ]))
)
.subscribe(playlist => {
this.playlist = playlist
import { RestExtractor } from '../rest/rest-extractor.service'
import { AuthStatus } from './auth-status.model'
import { AuthUser } from './auth-user.model'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
interface UserLoginWithUsername extends UserLogin {
access_token: string
error => {
let errorMessage = error.message
- if (error.status === 403) {
+ if (error.status === HttpStatusCode.FORBIDDEN_403) {
errorMessage = $localize`Cannot retrieve OAuth Client credentials: ${error.text}.
Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.`
}
import { Router } from '@angular/router'
import { dateToHuman } from '@app/helpers'
import { ResultList } from '@shared/models'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
@Injectable()
export class RestExtractor {
errorMessage = errorsArray.join('. ')
} else if (err.error && err.error.error) {
errorMessage = err.error.error
- } else if (err.status === 413) {
+ } else if (err.status === HttpStatusCode.PAYLOAD_TOO_LARGE_413) {
errorMessage = $localize`Media is too large for the server. Please contact you administrator if you want to increase the limit size.`
- } else if (err.status === 429) {
+ } else if (err.status === HttpStatusCode.TOO_MANY_REQUESTS_429) {
const secondsLeft = err.headers.get('retry-after')
if (secondsLeft) {
const minutesLeft = Math.floor(parseInt(secondsLeft, 10) / 60)
} else {
errorMessage = $localize`Too many attempts, please try again later.`
}
- } else if (err.status === 500) {
+ } else if (err.status === HttpStatusCode.INTERNAL_SERVER_ERROR_500) {
errorMessage = $localize`Server error. Please retry later.`
}
return observableThrowError(errorObj)
}
- redirectTo404IfNotFound (obj: { status: number }, status = [ 404 ]) {
+ redirectTo404IfNotFound (obj: { status: number }, status = [ HttpStatusCode.NOT_FOUND_404 ]) {
if (obj && obj.status && status.indexOf(obj.status) !== -1) {
// Do not use redirectService to avoid circular dependencies
this.router.navigate([ '/404' ], { skipLocationChange: true })
PluginType,
ClientHookName
} from '../../../../shared/models'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
import { P2PMediaLoaderOptions, PeertubePlayerManagerOptions, PlayerMode } from '../../assets/player/peertube-player-manager'
import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings'
import { TranslationsManager } from '../../assets/player/translations-manager'
refreshFetch (url: string, options?: RequestInit) {
return fetch(url, options)
.then((res: Response) => {
- if (res.status !== 401) return res
+ if (res.status !== HttpStatusCode.UNAUTHORIZED_401) return res
const refreshingTokenPromise = new Promise((resolve, reject) => {
const clientId: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_ID)
method: 'POST',
body: objectToUrlEncoded(data)
}).then(res => {
- if (res.status === 401) return undefined
+ if (res.status === HttpStatusCode.UNAUTHORIZED_401) return undefined
return res.json()
}).then((obj: UserRefreshToken & { code: 'invalid_grant'}) => {
try {
playlistResponse = await playlistPromise
- isResponseOk = playlistResponse.status === 200
+ isResponseOk = playlistResponse.status === HttpStatusCode.OK_200
} catch (err) {
console.error(err)
isResponseOk = false
if (!isResponseOk) {
const serverTranslations = await this.translationsPromise
- if (playlistResponse?.status === 404) {
+ if (playlistResponse?.status === HttpStatusCode.NOT_FOUND_404) {
this.playlistNotFound(serverTranslations)
return undefined
}
try {
videoResponse = await videoPromise
- isResponseOk = videoResponse.status === 200
+ isResponseOk = videoResponse.status === HttpStatusCode.OK_200
} catch (err) {
console.error(err)
if (!isResponseOk) {
const serverTranslations = await this.translationsPromise
- if (videoResponse?.status === 404) {
+ if (videoResponse?.status === HttpStatusCode.NOT_FOUND_404) {
this.videoNotFound(serverTranslations)
return undefined
}
import { join } from 'path'
import { CONFIG } from '@server/initializers/config'
import { buildFileLocale, getCompleteLocale, is18nLocale, LOCALE_FILES } from '@shared/core-utils/i18n'
+import { HttpStatusCode } from '@shared/core-utils'
import { root } from '../helpers/core-utils'
-import { logger } from '../helpers/logger'
-import { ACCEPT_HEADERS, STATIC_MAX_AGE } from '../initializers/constants'
-import { ClientHtml } from '../lib/client-html'
+import { STATIC_MAX_AGE } from '../initializers/constants'
+import { ClientHtml, sendHTML, serveIndexHTML } from '../lib/client-html'
import { asyncMiddleware, embedCSP } from '../middlewares'
-import { HttpStatusCode } from '@shared/core-utils'
const clientsRouter = express.Router()
return res.sendStatus(HttpStatusCode.NOT_FOUND_404)
}
-async function serveIndexHTML (req: express.Request, res: express.Response) {
- if (req.accepts(ACCEPT_HEADERS) === 'html') {
- try {
- await generateHTMLPage(req, res, req.params.language)
- return
- } catch (err) {
- logger.error('Cannot generate HTML page.', err)
- }
- }
-
- return res.status(HttpStatusCode.INTERNAL_SERVER_ERROR_500).end()
-}
-
async function generateEmbedHtmlPage (req: express.Request, res: express.Response) {
const html = await ClientHtml.getEmbedHTML()
return sendHTML(html, res)
}
-async function generateHTMLPage (req: express.Request, res: express.Response, paramLang?: string) {
- const html = await ClientHtml.getDefaultHTMLPage(req, res, paramLang)
-
- return sendHTML(html, res)
-}
-
async function generateWatchHtmlPage (req: express.Request, res: express.Response) {
const html = await ClientHtml.getWatchHTMLPage(req.params.id + '', req, res)
return sendHTML(html, res)
}
-function sendHTML (html: string, res: express.Response) {
- res.set('Content-Type', 'text/html; charset=UTF-8')
-
- return res.send(html)
-}
-
async function generateManifest (req: express.Request, res: express.Response) {
const manifestPhysicalPath = join(root(), 'client', 'dist', 'manifest.webmanifest')
const manifestJson = await fs.readFile(manifestPhysicalPath, 'utf8')
import { getThemeOrDefault } from '../lib/plugins/theme-utils'
import { getEnabledResolutions, getRegisteredPlugins, getRegisteredThemes } from '@server/controllers/api/config'
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
+import { serveIndexHTML } from '@server/lib/client-html'
const staticRouter = express.Router()
}
)
+staticRouter.all('/teapot',
+ getCup,
+ asyncMiddleware(serveIndexHTML)
+)
+
// security.txt service
staticRouter.get('/security.txt',
(_, res: express.Response) => {
return Object.assign(playlist, { Video: video })
}
+
+function getCup (req: express.Request, res: express.Response, next: express.NextFunction) {
+ res.status(HttpStatusCode.I_AM_A_TEAPOT_418)
+ res.setHeader('Accept-Additions', 'Non-Dairy;1,Sugar;1')
+ res.setHeader('Safe', 'if-sepia-awake')
+
+ return next()
+}
return value.map(v => validator.toInt(v))
}
+function isFileFieldValid (
+ files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
+ field: string,
+ optional = false
+) {
+ // Should have files
+ if (!files) return optional
+ if (isArray(files)) return optional
+
+ // Should have a file
+ const fileArray = files[field]
+ if (!fileArray || fileArray.length === 0) {
+ return optional
+ }
+
+ // The file should exist
+ const file = fileArray[0]
+ if (!file || !file.originalname) return false
+ return file
+}
+
+function isFileMimeTypeValid (
+ files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
+ mimeTypeRegex: string,
+ field: string,
+ optional = false
+) {
+ // Should have files
+ if (!files) return optional
+ if (isArray(files)) return optional
+
+ // Should have a file
+ const fileArray = files[field]
+ if (!fileArray || fileArray.length === 0) {
+ return optional
+ }
+
+ // The file should exist
+ const file = fileArray[0]
+ if (!file || !file.originalname) return false
+
+ return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype)
+}
+
function isFileValid (
files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
mimeTypeRegex: string,
toIntOrNull,
toArray,
toIntArray,
+ isFileFieldValid,
+ isFileMimeTypeValid,
isFileValid
}
VIDEO_STATES,
VIDEO_LIVE
} from '../../initializers/constants'
-import { exists, isArray, isDateValid, isFileValid } from './misc'
+import { exists, isArray, isDateValid, isFileMimeTypeValid, isFileValid } from './misc'
import * as magnetUtil from 'magnet-uri'
const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
return exists(value) && (value === VIDEO_LIVE.EXTENSION || MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined)
}
-function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
- return isFileValid(files, MIMETYPES.VIDEO.MIMETYPES_REGEX, 'videofile', null)
+function isVideoFileMimeTypeValid (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
+ return isFileMimeTypeValid(files, MIMETYPES.VIDEO.MIMETYPES_REGEX, 'videofile')
}
const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
isVideoFPSResolutionValid,
isScheduleVideoUpdatePrivacyValid,
isVideoOriginallyPublishedAtValid,
- isVideoFile,
isVideoMagnetUriValid,
isVideoStateValid,
isVideoViewsValid,
isVideoRatingTypeValid,
isVideoFileExtnameValid,
+ isVideoFileMimeTypeValid,
isVideoDurationValid,
isVideoTagValid,
isVideoPrivacyValid,
import * as request from 'request'
import { createWriteStream } from 'fs'
import { CONFIG } from '@server/initializers/config'
+import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes'
export type YoutubeDLInfo = {
name?: string
return res()
}
- if (result.statusCode !== 302) {
+ if (result.statusCode !== HttpStatusCode.FOUND_302) {
logger.error('youtube-dl update error: did not get redirect for the latest version link. Status %d', result.statusCode)
return res()
}
const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(url)[1]
downloadFile.on('response', result => {
- if (result.statusCode !== 200) {
+ if (result.statusCode !== HttpStatusCode.OK_200) {
logger.error('Cannot update youtube-dl: new version response is not 200, it\'s %d.', result.statusCode)
return res()
}
} from '../../types/models'
import { extname } from 'path'
import { getServerActor } from '@server/models/application/application'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
// Set account keys, this could be long so process after the account creation and do not block the client
function setAsyncActorKeys <T extends MActor> (actor: T) {
const { result, statusCode } = await fetchRemoteActor(actorUrl)
- if (statusCode === 404) {
+ if (statusCode === HttpStatusCode.NOT_FOUND_404) {
logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url)
actor.Account
? await actor.Account.destroy()
import { FilteredModelAttributes } from '../../types/sequelize'
import { MAccountDefault, MAccountId, MVideoId } from '../../types/models'
import { MVideoPlaylist, MVideoPlaylistId, MVideoPlaylistOwner } from '../../types/models/video/video-playlist'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount: MAccountId, to: string[]) {
const privacy = to.includes(ACTIVITY_PUB.PUBLIC)
try {
const { statusCode, playlistObject } = await fetchRemoteVideoPlaylist(videoPlaylist.url)
- if (statusCode === 404) {
+ if (statusCode === HttpStatusCode.NOT_FOUND_404) {
logger.info('Cannot refresh remote video playlist %s: it does not exist anymore. Deleting it.', videoPlaylist.url)
await videoPlaylist.destroy()
import { addVideoShares, shareVideoByServerAndChannel } from './share'
import { addVideoComments } from './video-comments'
import { createRates } from './video-rates'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
async function federateVideoIfNeeded (videoArg: MVideoAPWithoutCaption, isNewVideo: boolean, transaction?: sequelize.Transaction) {
const video = videoArg as MVideoAP
try {
const { response, videoObject } = await fetchRemoteVideo(video.url)
- if (response.statusCode === 404) {
+ if (response.statusCode === HttpStatusCode.NOT_FOUND_404) {
logger.info('Cannot refresh remote video %s: video does not exist anymore. Deleting it.', video.url)
// Video does not exist anymore
import * as express from 'express'
+import * as Bluebird from 'bluebird'
import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/core-utils/i18n/i18n'
import {
AVATARS_SIZE,
EMBED_SIZE,
PLUGIN_GLOBAL_CSS_PATH,
WEBSERVER,
- FILES_CONTENT_HASH
+ FILES_CONTENT_HASH,
+ ACCEPT_HEADERS
} from '../initializers/constants'
import { join } from 'path'
import { escapeHTML, isTestInstance, sha256 } from '../helpers/core-utils'
import { getActivityStreamDuration } from '../models/video/video-format-utils'
import { AccountModel } from '../models/account/account'
import { VideoChannelModel } from '../models/video/video-channel'
-import * as Bluebird from 'bluebird'
import { CONFIG } from '../initializers/config'
import { logger } from '../helpers/logger'
import { MAccountActor, MChannelActor } from '../types/models'
}
}
-export class ClientHtml {
+class ClientHtml {
private static htmlCache: { [path: string]: string } = {}
return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.META_TAGS, tagsString)
}
}
+
+function sendHTML (html: string, res: express.Response) {
+ res.set('Content-Type', 'text/html; charset=UTF-8')
+
+ return res.send(html)
+}
+
+async function serveIndexHTML (req: express.Request, res: express.Response) {
+ if (req.accepts(ACCEPT_HEADERS) === 'html' ||
+ !req.headers.accept) {
+ try {
+ await generateHTMLPage(req, res, req.params.language)
+ return
+ } catch (err) {
+ logger.error('Cannot generate HTML page.', err)
+ return res.sendStatus(HttpStatusCode.INTERNAL_SERVER_ERROR_500)
+ }
+ }
+
+ return res.sendStatus(HttpStatusCode.NOT_ACCEPTABLE_406)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ ClientHtml,
+ sendHTML,
+ serveIndexHTML
+}
+
+async function generateHTMLPage (req: express.Request, res: express.Response, paramLang?: string) {
+ const html = await ClientHtml.getDefaultHTMLPage(req, res, paramLang)
+
+ return sendHTML(html, res)
+}
import { Redis } from '../lib/redis'
import * as apicache from 'apicache'
+import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes'
// Ensure Redis is initialized
Redis.Instance.init()
redisClient: Redis.Instance.getClient(),
appendKey: () => Redis.Instance.getPrefix(),
statusCodes: {
- exclude: [ 404, 403 ]
+ exclude: [
+ HttpStatusCode.FORBIDDEN_403,
+ HttpStatusCode.NOT_FOUND_404
+ ]
}
}
import {
isBooleanValid,
isDateValid,
+ isFileFieldValid,
isIdOrUUIDValid,
isIdValid,
isUUIDValid,
isScheduleVideoUpdatePrivacyValid,
isVideoCategoryValid,
isVideoDescriptionValid,
- isVideoFile,
+ isVideoFileMimeTypeValid,
+ isVideoFileSizeValid,
isVideoFilterValid,
isVideoImage,
isVideoLanguageValid,
const videosAddValidator = getCommonVideoEditAttributes().concat([
body('videofile')
- .custom((value, { req }) => isVideoFile(req.files)).withMessage(
- 'This file is not supported or too large. Please, make sure it is of the following type: ' +
- CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ')
- ),
- body('name').custom(isVideoNameValid).withMessage('Should have a valid name'),
+ .custom((value, { req }) => isFileFieldValid(req.files, 'videofile'))
+ .withMessage('Should have a file'),
+ body('name')
+ .custom(isVideoNameValid)
+ .withMessage('Should have a valid name'),
body('channelId')
.customSanitizer(toIntOrNull)
.custom(isIdValid).withMessage('Should have correct video channel id'),
if (!await doesVideoChannelOfAccountExist(req.body.channelId, user, res)) return cleanUpReqFiles(req)
+ if (!isVideoFileMimeTypeValid(req.files)) {
+ res.status(HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415)
+ .json({
+ error: 'This file is not supported. Please, make sure it is of the following type: ' +
+ CONSTRAINTS_FIELDS.VIDEOS.EXTNAME.join(', ')
+ })
+
+ return cleanUpReqFiles(req)
+ }
+
+ if (!isVideoFileSizeValid(videoFile.size.toString())) {
+ res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413)
+ .json({
+ error: 'This file is too large.'
+ })
+
+ return cleanUpReqFiles(req)
+ }
+
if (await isAbleToUploadVideo(user.id, videoFile.size) === false) {
- res.status(HttpStatusCode.FORBIDDEN_403)
+ res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413)
.json({ error: 'The user video quota is exceeded with this video.' })
return cleanUpReqFiles(req)
duration = await getDurationFromVideoFile(videoFile.path)
} catch (err) {
logger.error('Invalid input file in videosAddValidator.', { err })
- res.status(HttpStatusCode.BAD_REQUEST_400)
- .json({ error: 'Invalid input file.' })
+ res.status(HttpStatusCode.UNPROCESSABLE_ENTITY_422)
+ .json({ error: 'Video file unreadable.' })
return cleanUpReqFiles(req)
}
const videoChangeOwnership = res.locals.videoChangeOwnership
const isAble = await isAbleToUploadVideo(user.id, videoChangeOwnership.Video.getMaxQualityFile().size)
if (isAble === false) {
- res.status(HttpStatusCode.FORBIDDEN_403)
+ res.status(HttpStatusCode.PAYLOAD_TOO_LARGE_413)
.json({ error: 'The user video quota is exceeded with this video.' })
return
setAccessTokensToServers,
uploadVideo
} from '../../../../shared/extra-utils'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
})
it('Should redirect to the origin video object', async function () {
- const res = await makeActivityPubGetRequest(servers[1].url, '/videos/watch/' + videoUUID, 302)
+ const res = await makeActivityPubGetRequest(servers[1].url, '/videos/watch/' + videoUUID, HttpStatusCode.FOUND_302)
expect(res.header.location).to.equal('http://localhost:' + servers[0].port + '/videos/watch/' + videoUUID)
})
} from '../../../../shared/extra-utils'
import { getAccount } from '../../../../shared/extra-utils/users/accounts'
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
describe('Test AP refresher', function () {
let servers: ServerInfo[] = []
await waitJobs(servers)
- await getVideo(servers[0].url, videoUUID1, 404)
- await getVideo(servers[0].url, videoUUID2, 200)
+ await getVideo(servers[0].url, videoUUID1, HttpStatusCode.NOT_FOUND_404)
+ await getVideo(servers[0].url, videoUUID2, HttpStatusCode.OK_200)
})
it('Should not update a remote video if the remote instance is down', async function () {
await reRunServer(servers[1])
- await getVideo(servers[0].url, videoUUID3, 200)
+ await getVideo(servers[0].url, videoUUID3, HttpStatusCode.OK_200)
})
})
await waitJobs(servers)
- await getAccount(servers[0].url, 'user1@localhost:' + servers[1].port, 200)
- await getAccount(servers[0].url, 'user2@localhost:' + servers[1].port, 404)
+ await getAccount(servers[0].url, 'user1@localhost:' + servers[1].port, HttpStatusCode.OK_200)
+ await getAccount(servers[0].url, 'user2@localhost:' + servers[1].port, HttpStatusCode.NOT_FOUND_404)
})
})
await waitJobs(servers)
- await getVideoPlaylist(servers[0].url, playlistUUID1, 200)
- await getVideoPlaylist(servers[0].url, playlistUUID2, 404)
+ await getVideoPlaylist(servers[0].url, playlistUUID1, HttpStatusCode.OK_200)
+ await getVideoPlaylist(servers[0].url, playlistUUID2, HttpStatusCode.NOT_FOUND_404)
})
})
checkBadStartPagination
} from '../../../../shared/extra-utils/requests/check-api-params'
import { getAccount } from '../../../../shared/extra-utils/users/accounts'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
describe('Test accounts API validators', function () {
const path = '/api/v1/accounts/'
describe('When getting an account', function () {
it('Should return 404 with a non existing name', async function () {
- await getAccount(server.url, 'arfaze', 404)
+ await getAccount(server.url, 'arfaze', HttpStatusCode.NOT_FOUND_404)
})
})
import { cleanupTests, flushAndRunServer, immutableAssign, killallServers, reRunServer, ServerInfo } from '../../../../shared/extra-utils'
import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form'
import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
describe('Test contact form API validators', function () {
let server: ServerInfo
})
it('Should not accept a contact form if emails are disabled', async function () {
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 409 }))
+ await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: HttpStatusCode.CONFLICT_409 }))
})
it('Should not accept a contact form if it is disabled in the configuration', async function () {
// Contact form is disabled
await reRunServer(server, { smtp: { hostname: 'localhost', port: emailPort }, contact_form: { enabled: false } })
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 409 }))
+ await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: HttpStatusCode.CONFLICT_409 }))
})
it('Should not accept a contact form if from email is invalid', async function () {
// Email & contact form enabled
await reRunServer(server, { smtp: { hostname: 'localhost', port: emailPort } })
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: 'badEmail' }))
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: 'badEmail@' }))
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: undefined }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ fromEmail: 'badEmail'
+ }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ fromEmail: 'badEmail@'
+ }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ fromEmail: undefined
+ }))
})
it('Should not accept a contact form if from name is invalid', async function () {
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: 'name'.repeat(100) }))
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: '' }))
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: undefined }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ fromName: 'name'.repeat(100)
+ }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ fromName: ''
+ }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ fromName: undefined
+ }))
})
it('Should not accept a contact form if body is invalid', async function () {
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: 'body'.repeat(5000) }))
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: 'a' }))
- await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: undefined }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ body: 'body'.repeat(5000)
+ }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ body: 'a'
+ }))
+ await sendContactForm(immutableAssign(defaultBody, {
+ url: server.url,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400,
+ body: undefined
+ }))
})
it('Should accept a contact form with the correct parameters', async function () {
videoQuota: 42
})
- await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.FORBIDDEN_403)
+ await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413)
})
it('Should fail with a registered user having too many videos', async function () {
await uploadVideo(server.url, userAccessToken, videoAttributes)
await uploadVideo(server.url, userAccessToken, videoAttributes)
await uploadVideo(server.url, userAccessToken, videoAttributes)
- await uploadVideo(server.url, userAccessToken, videoAttributes, HttpStatusCode.FORBIDDEN_403)
+ await uploadVideo(server.url, userAccessToken, videoAttributes, HttpStatusCode.PAYLOAD_TOO_LARGE_413)
})
it('Should fail to import with HTTP/Torrent/magnet', async function () {
})
describe('When having a daily video quota', function () {
- it('Should fail with a user having too many videos', async function () {
+ it('Should fail with a user having too many videos daily', async function () {
await updateUser({
url: server.url,
userId: rootId,
videoQuotaDaily: 42
})
- await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.FORBIDDEN_403)
+ await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413)
})
})
videoQuotaDaily: 1024 * 1024 * 1024
})
- await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.FORBIDDEN_403)
+ await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413)
})
it('Should fail if exceeding daily quota', async function () {
videoQuotaDaily: 42
})
- await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.FORBIDDEN_403)
+ await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413)
})
})
let attaches = {
videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short_fake.webm')
}
- await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
+ await makeUploadRequest({
+ url: server.url,
+ path: path + '/upload',
+ token: server.accessToken,
+ fields,
+ attaches,
+ statusCodeExpected: HttpStatusCode.UNPROCESSABLE_ENTITY_422
+ })
attaches = {
videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mkv')
}
- await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
+ await makeUploadRequest({
+ url: server.url,
+ path: path + '/upload',
+ token: server.accessToken,
+ fields,
+ attaches,
+ statusCodeExpected: HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415
+ })
})
it('Should fail with an incorrect thumbnail file', async function () {
waitJobs,
waitUntilLiveStarts
} from '../../../../shared/extra-utils'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, false, 200)
+ await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
})
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, true, 200)
+ await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
})
await waitJobs(servers)
// Live still exist, but cannot be played anymore
- await checkVideosExist(liveVideoUUID, false, 200)
+ await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED)
// No resolutions saved since we did not save replay
await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, true, 200)
+ await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
await Promise.all([
addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
await checkVideosExist(liveVideoUUID, false)
- await getVideo(servers[0].url, liveVideoUUID, 401)
- await getVideo(servers[1].url, liveVideoUUID, 404)
+ await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
+ await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
await checkLiveCleanup(servers[0], liveVideoUUID, [])
})
await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, true, 200)
+ await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
await Promise.all([
testFfmpegStreamError(ffmpegCommand, true),
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, false, 404)
+ await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
await checkLiveCleanup(servers[0], liveVideoUUID, [])
})
})
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, false, 200)
+ await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
})
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, true, 200)
+ await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
})
await waitJobs(servers)
// Live has been transcoded
- await checkVideosExist(liveVideoUUID, true, 200)
+ await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
})
await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, true, 200)
+ await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
await Promise.all([
addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
await checkVideosExist(liveVideoUUID, false)
- await getVideo(servers[0].url, liveVideoUUID, 401)
- await getVideo(servers[1].url, liveVideoUUID, 404)
+ await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
+ await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
})
await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, true, 200)
+ await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
await Promise.all([
removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID),
await waitJobs(servers)
- await checkVideosExist(liveVideoUUID, false, 404)
+ await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
await checkLiveCleanup(servers[0], liveVideoUUID, [])
})
})
waitUntilLiveStarts,
waitUntilLog
} from '../../../../shared/extra-utils'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
expect(video.privacy.id).to.equal(VideoPrivacy.UNLISTED)
expect(video.nsfw).to.be.true
- await makeRawRequest(server.url + video.thumbnailPath, 200)
- await makeRawRequest(server.url + video.previewPath, 200)
+ await makeRawRequest(server.url + video.thumbnailPath, HttpStatusCode.OK_200)
+ await makeRawRequest(server.url + video.previewPath, HttpStatusCode.OK_200)
}
})
})
it('Should not be able to update a live of another server', async function () {
- await updateLive(servers[1].url, servers[1].accessToken, liveVideoUUID, { saveReplay: false }, 403)
+ await updateLive(servers[1].url, servers[1].accessToken, liveVideoUUID, { saveReplay: false }, HttpStatusCode.FORBIDDEN_403)
})
it('Should update the live', async function () {
it('Should have the live deleted', async function () {
for (const server of servers) {
- await getVideo(server.url, liveVideoUUID, 404)
- await getLive(server.url, server.accessToken, liveVideoUUID, 404)
+ await getVideo(server.url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
+ await getLive(server.url, server.accessToken, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
}
})
})
expect(video.files).to.have.lengthOf(0)
const hlsPlaylist = video.streamingPlaylists.find(s => s.type === VideoStreamingPlaylistType.HLS)
- await makeRawRequest(hlsPlaylist.playlistUrl, 200)
- await makeRawRequest(hlsPlaylist.segmentsSha256Url, 200)
+ await makeRawRequest(hlsPlaylist.playlistUrl, HttpStatusCode.OK_200)
+ await makeRawRequest(hlsPlaylist.segmentsSha256Url, HttpStatusCode.OK_200)
expect(hlsPlaylist.files).to.have.lengthOf(resolutions.length)
expect(probe.format.bit_rate).to.be.below(bitrateLimits[videoStream.height])
- await makeRawRequest(file.torrentUrl, 200)
- await makeRawRequest(file.fileUrl, 200)
+ await makeRawRequest(file.torrentUrl, HttpStatusCode.OK_200)
+ await makeRawRequest(file.fileUrl, HttpStatusCode.OK_200)
}
}
})
uploadVideo
} from '../../../../shared/extra-utils'
import { ServerConfig } from '../../../../shared/models'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
expect(data.video.file.extensions).to.contain('.webm')
expect(data.video.file.extensions).to.contain('.ogv')
- await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.mkv' }, 400)
- await uploadVideo(server.url, server.accessToken, { fixture: 'sample.ogg' }, 400)
+ await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.mkv' }, HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415)
+ await uploadVideo(server.url, server.accessToken, { fixture: 'sample.ogg' }, HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415)
expect(data.contactForm.enabled).to.be.true
})
expect(data.video.file.extensions).to.contain('.ogg')
expect(data.video.file.extensions).to.contain('.flac')
- await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.mkv' }, 200)
- await uploadVideo(server.url, server.accessToken, { fixture: 'sample.ogg' }, 200)
+ await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.mkv' }, HttpStatusCode.OK_200)
+ await uploadVideo(server.url, server.accessToken, { fixture: 'sample.ogg' }, HttpStatusCode.OK_200)
})
it('Should have the configuration updated after a restart', async function () {
import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
body: 'my super message',
fromName: 'Super toto',
subject: 'my subject',
- expectedStatus: 403
+ expectedStatus: HttpStatusCode.FORBIDDEN_403
})
})
} from '../../../../shared/extra-utils'
import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
})
it('Should not reset the password with an invalid verification string', async function () {
- await resetPassword(server.url, userId, verificationString + 'b', 'super_password2', 403)
+ await resetPassword(server.url, userId, verificationString + 'b', 'super_password2', HttpStatusCode.FORBIDDEN_403)
})
it('Should reset the password', async function () {
})
it('Should not reset the password with the same verification string', async function () {
- await resetPassword(server.url, userId, verificationString, 'super_password3', 403)
+ await resetPassword(server.url, userId, verificationString, 'super_password3', HttpStatusCode.FORBIDDEN_403)
})
it('Should login with this new password', async function () {
})
it('Should not reset the password with an invalid verification string', async function () {
- await resetPassword(server.url, userId2, verificationString2 + 'c', 'newly_created_password', 403)
+ await resetPassword(server.url, userId2, verificationString2 + 'c', 'newly_created_password', HttpStatusCode.FORBIDDEN_403)
})
it('Should reset the password', async function () {
this.timeout(10000)
const reason = 'my super bad reason'
- await blockUser(server.url, userId, server.accessToken, 204, reason)
+ await blockUser(server.url, userId, server.accessToken, HttpStatusCode.NO_CONTENT_204, reason)
await waitJobs(server)
expect(emails).to.have.lengthOf(4)
it('Should send the notification email when unblocking a user', async function () {
this.timeout(10000)
- await unblockUser(server.url, userId, server.accessToken, 204)
+ await unblockUser(server.url, userId, server.accessToken, HttpStatusCode.NO_CONTENT_204)
await waitJobs(server)
expect(emails).to.have.lengthOf(5)
})
it('Should not verify the email with an invalid verification string', async function () {
- await verifyEmail(server.url, userId, verificationString + 'b', false, 403)
+ await verifyEmail(server.url, userId, verificationString + 'b', false, HttpStatusCode.FORBIDDEN_403)
})
it('Should verify the email', async function () {
import { unfollow } from '../../../../shared/extra-utils/server/follows'
import { userLogin } from '../../../../shared/extra-utils/users/login'
import { createUser } from '../../../../shared/extra-utils/users/users'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
describe('With an unlogged user', function () {
it('Should get the local video', async function () {
- await getVideo(servers[0].url, video1UUID, 200)
+ await getVideo(servers[0].url, video1UUID, HttpStatusCode.OK_200)
})
it('Should get the remote video', async function () {
- await getVideo(servers[0].url, video2UUID, 200)
+ await getVideo(servers[0].url, video2UUID, HttpStatusCode.OK_200)
})
it('Should list local account videos', async function () {
describe('With a logged user', function () {
it('Should get the local video', async function () {
- await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, 200)
+ await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, HttpStatusCode.OK_200)
})
it('Should get the remote video', async function () {
- await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, 200)
+ await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, HttpStatusCode.OK_200)
})
it('Should list local account videos', async function () {
describe('With an unlogged user', function () {
it('Should get the local video', async function () {
- await getVideo(servers[0].url, video1UUID, 200)
+ await getVideo(servers[0].url, video1UUID, HttpStatusCode.OK_200)
})
it('Should not get the remote video', async function () {
- await getVideo(servers[0].url, video2UUID, 403)
+ await getVideo(servers[0].url, video2UUID, HttpStatusCode.FORBIDDEN_403)
})
it('Should list local account videos', async function () {
describe('With a logged user', function () {
it('Should get the local video', async function () {
- await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, 200)
+ await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, HttpStatusCode.OK_200)
})
it('Should get the remote video', async function () {
- await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, 200)
+ await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, HttpStatusCode.OK_200)
})
it('Should list local account videos', async function () {
getVideoCommentThreads,
getVideoThreadComments
} from '../../../../shared/extra-utils/videos/video-comments'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
}
for (const id of videoIdsServer1) {
- await getVideo(servers[1].url, id, 403)
+ await getVideo(servers[1].url, id, HttpStatusCode.FORBIDDEN_403)
}
})
import * as request from 'supertest'
import { ServerInfo } from '../../../../shared/extra-utils'
import { cleanupTests, flushAndRunServer } from '../../../../shared/extra-utils/server/servers'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
describe('Start and stop server without web client routes', function () {
let server: ServerInfo
const req = request(server.url)
.get('/')
- return req.expect(404)
+ return req.expect(HttpStatusCode.NOT_FOUND_404)
})
after(async function () {
import * as chai from 'chai'
import { cleanupTests, getVideo, registerUser, uploadVideo, userLogin, viewVideo, wait } from '../../../../shared/extra-utils'
import { flushAndRunServer, setAccessTokensToServers } from '../../../../shared/extra-utils/index'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
it('Should view a video 2 times with the X-Forwarded-For header set', async function () {
this.timeout(20000)
- await viewVideo(server.url, videoId, 204, '0.0.0.1,127.0.0.1')
- await viewVideo(server.url, videoId, 204, '0.0.0.2,127.0.0.1')
+ await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.1,127.0.0.1')
+ await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.2,127.0.0.1')
// Wait the repeatable job
await wait(8000)
it('Should view a video only once with the same client IP in the X-Forwarded-For header', async function () {
this.timeout(20000)
- await viewVideo(server.url, videoId, 204, '0.0.0.4,0.0.0.3,::ffff:127.0.0.1')
- await viewVideo(server.url, videoId, 204, '0.0.0.5,0.0.0.3,127.0.0.1')
+ await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.4,0.0.0.3,::ffff:127.0.0.1')
+ await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.5,0.0.0.3,127.0.0.1')
// Wait the repeatable job
await wait(8000)
it('Should view a video two times with a different client IP in the X-Forwarded-For header', async function () {
this.timeout(20000)
- await viewVideo(server.url, videoId, 204, '0.0.0.8,0.0.0.6,127.0.0.1')
- await viewVideo(server.url, videoId, 204, '0.0.0.8,0.0.0.7,127.0.0.1')
+ await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.8,0.0.0.6,127.0.0.1')
+ await viewVideo(server.url, videoId, HttpStatusCode.NO_CONTENT_204, '0.0.0.8,0.0.0.7,127.0.0.1')
// Wait the repeatable job
await wait(8000)
const user = { username: 'root', password: 'fail' }
for (let i = 0; i < 19; i++) {
- await userLogin(server, user, 400)
+ await userLogin(server, user, HttpStatusCode.BAD_REQUEST_400)
}
- await userLogin(server, user, 429)
+ await userLogin(server, user, HttpStatusCode.TOO_MANY_REQUESTS_429)
})
it('Should rate limit signup', async function () {
}
}
- await registerUser(server.url, 'test42', 'password', 429)
+ await registerUser(server.url, 'test42', 'password', HttpStatusCode.TOO_MANY_REQUESTS_429)
})
it('Should not rate limit failed signup', async function () {
await wait(7000)
for (let i = 0; i < 3; i++) {
- await registerUser(server.url, 'test' + i, 'password', 409)
+ await registerUser(server.url, 'test' + i, 'password', HttpStatusCode.CONFLICT_409)
}
- await registerUser(server.url, 'test43', 'password', 204)
+ await registerUser(server.url, 'test43', 'password', HttpStatusCode.NO_CONTENT_204)
})
}
}
- await getVideo(server.url, videoId, 429)
+ await getVideo(server.url, videoId, HttpStatusCode.TOO_MANY_REQUESTS_429)
})
after(async function () {
findCommentId
} from '../../../../shared/extra-utils/videos/video-comments'
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
expect(res.body.downloadEnabled).to.be.false
const text = 'my super forbidden comment'
- await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, 409)
+ await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, HttpStatusCode.CONFLICT_409)
}
})
})
const filePath = join(__dirname, '..', '..', 'fixtures', 'video_short.webm')
await req.attach('videofile', filePath)
- .expect(200)
+ .expect(HttpStatusCode.OK_200)
await waitJobs(servers)
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
import { User } from '../../../../shared/models/users'
import { VideoDetails } from '../../../../shared/models/videos'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
it('Should not be possible to refuse the change of ownership from first user', async function () {
this.timeout(10000)
- await refuseChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, 403)
+ await refuseChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, HttpStatusCode.FORBIDDEN_403)
})
it('Should be possible to refuse the change of ownership from second user', async function () {
const secondUserInformationResponse = await getMyUserInformation(servers[0].url, secondUserAccessToken)
const secondUserInformation: User = secondUserInformationResponse.body
const channelId = secondUserInformation.videoChannels[0].id
- await acceptChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, channelId, 403)
+ await acceptChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, channelId, HttpStatusCode.FORBIDDEN_403)
})
it('Should be possible to accept the change of ownership from second user', async function () {
const secondUserInformationResponse = await getMyUserInformation(server.url, secondUserAccessToken)
const secondUserInformation: User = secondUserInformationResponse.body
const channelId = secondUserInformation.videoChannels[0].id
- await acceptChangeOwnership(server.url, secondUserAccessToken, lastRequestChangeOwnershipId, channelId, 403)
+
+ await acceptChangeOwnership(
+ server.url,
+ secondUserAccessToken,
+ lastRequestChangeOwnershipId,
+ channelId,
+ HttpStatusCode.PAYLOAD_TOO_LARGE_413
+ )
})
after(async function () {
import { VideoDetails } from '../../../../shared/models/videos'
import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type'
import { DEFAULT_AUDIO_RESOLUTION } from '../../../initializers/constants'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
)
expect(file.resolution.label).to.equal(resolution + 'p')
- await makeRawRequest(file.torrentUrl, 200)
- await makeRawRequest(file.fileUrl, 200)
+ await makeRawRequest(file.torrentUrl, HttpStatusCode.OK_200)
+ await makeRawRequest(file.fileUrl, HttpStatusCode.OK_200)
const torrent = await webtorrentAdd(file.magnetUri, true)
expect(torrent.files).to.be.an('array')
await waitJobs(servers)
for (const server of servers) {
- await getVideo(server.url, videoUUID, 404)
- await getVideo(server.url, videoAudioUUID, 404)
+ await getVideo(server.url, videoUUID, HttpStatusCode.NOT_FOUND_404)
+ await getVideo(server.url, videoAudioUUID, HttpStatusCode.NOT_FOUND_404)
}
})
removeServerFromAccountBlocklist,
removeServerFromServerBlocklist
} from '../../../../shared/extra-utils/users/blocklist'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
await waitJobs(servers)
for (const server of servers) {
- await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 200)
+ await getVideoPlaylist(server.url, videoPlaylistIds.uuid, HttpStatusCode.OK_200)
}
const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE }
await waitJobs(servers)
for (const server of [ servers[1], servers[2] ]) {
- await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 404)
+ await getVideoPlaylist(server.url, videoPlaylistIds.uuid, HttpStatusCode.NOT_FOUND_404)
}
- await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, 401)
+ await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, HttpStatusCode.UNAUTHORIZED_401)
- await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, 200)
+ await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, HttpStatusCode.OK_200)
})
})
await waitJobs(servers)
for (const server of servers) {
- await getVideoPlaylist(server.url, playlistServer1UUID, 404)
+ await getVideoPlaylist(server.url, playlistServer1UUID, HttpStatusCode.NOT_FOUND_404)
}
})
expect(res3.body.displayName).to.equal('channel playlist')
expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE)
- await getVideoPlaylist(servers[1].url, videoPlaylistUUID, 404)
+ await getVideoPlaylist(servers[1].url, videoPlaylistUUID, HttpStatusCode.NOT_FOUND_404)
})
it('Should delete an account and delete its playlists', async function () {
import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../../../shared/extra-utils/videos/videos'
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
import { Video } from '@shared/models'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
})
it('Should not be able to watch the private/internal video with non authenticated user', async function () {
- await getVideo(servers[0].url, privateVideoUUID, 401)
- await getVideo(servers[0].url, internalVideoUUID, 401)
+ await getVideo(servers[0].url, privateVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
+ await getVideo(servers[0].url, internalVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
})
it('Should not be able to watch the private video with another user', async function () {
await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
anotherUserToken = await userLogin(servers[0], user)
- await getVideoWithToken(servers[0].url, anotherUserToken, privateVideoUUID, 403)
+ await getVideoWithToken(servers[0].url, anotherUserToken, privateVideoUUID, HttpStatusCode.FORBIDDEN_403)
})
it('Should be able to watch the internal video with another user', async function () {
- await getVideoWithToken(servers[0].url, anotherUserToken, internalVideoUUID, 200)
+ await getVideoWithToken(servers[0].url, anotherUserToken, internalVideoUUID, HttpStatusCode.OK_200)
})
it('Should be able to watch the private video with the correct user', async function () {
- await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID, 200)
+ await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID, HttpStatusCode.OK_200)
})
it('Should upload an unlisted video on server 2', async function () {
})
it('Should not be able to get non-federated unlisted video from federated server', async function () {
- await getVideo(servers[1].url, nonFederatedUnlistedVideoUUID, 404)
+ await getVideo(servers[1].url, nonFederatedUnlistedVideoUUID, HttpStatusCode.NOT_FOUND_404)
})
it('Should update the private and internal videos to public on server 1', async function () {
} from '../../../../shared/extra-utils'
import { Video, VideoDetails } from '../../../../shared/models/videos'
import { listMyVideosHistory, removeMyVideosHistory, userWatchVideo } from '../../../../shared/extra-utils/videos/video-history'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
videosHistoryEnabled: false
})
- await userWatchVideo(server.url, server.accessToken, video2UUID, 8, 409)
+ await userWatchVideo(server.url, server.accessToken, video2UUID, 8, HttpStatusCode.CONFLICT_409)
})
it('Should re-enable videos history', async function () {
ServerInfo,
setAccessTokensToServers
} from '../../../shared/extra-utils'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
describe('Test reset password scripts', function () {
let server: ServerInfo
const env = getEnvCli(server)
await execCLI(`echo coucou | ${env} npm run reset-password -- -u user_1`)
- await login(server.url, server.client, { username: 'user_1', password: 'coucou' }, 200)
+ await login(server.url, server.client, { username: 'user_1', password: 'coucou' }, HttpStatusCode.OK_200)
})
after(async function () {
import { waitJobs } from '../../../shared/extra-utils/server/jobs'
import { addVideoCommentThread } from '../../../shared/extra-utils/videos/video-comments'
import { User } from '../../../shared/models/users'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
chai.use(require('chai-xml'))
chai.use(require('chai-json-schema'))
})
it('Should fail with an invalid token', async function () {
- await getJSONfeed(servers[0].url, 'subscriptions', { accountId: feeduserAccountId, token: 'toto' }, 403)
+ await getJSONfeed(servers[0].url, 'subscriptions', { accountId: feeduserAccountId, token: 'toto' }, HttpStatusCode.FORBIDDEN_403)
})
it('Should fail with a token of another user', async function () {
- await getJSONfeed(servers[0].url, 'subscriptions', { accountId: feeduserAccountId, token: userFeedToken }, 403)
+ await getJSONfeed(
+ servers[0].url,
+ 'subscriptions',
+ { accountId: feeduserAccountId, token: userFeedToken },
+ HttpStatusCode.FORBIDDEN_403
+ )
})
it('Should list no videos for a user with videos but no subscriptions', async function () {
it('Should renew the token, and so have an invalid old token', async function () {
await renewUserScopedTokens(servers[0].url, userAccessToken)
- await getJSONfeed(servers[0].url, 'subscriptions', { accountId: userAccountId, token: userFeedToken, version: 3 }, 403)
+ await getJSONfeed(
+ servers[0].url,
+ 'subscriptions',
+ { accountId: userAccountId, token: userFeedToken, version: 3 },
+ HttpStatusCode.FORBIDDEN_403
+ )
})
it('Should succeed with the new token', async function () {
import { getGoodVideoUrl, getMyVideoImports, importVideo } from '../../../shared/extra-utils/videos/video-imports'
import { VideoDetails, VideoImport, VideoImportState, VideoPrivacy } from '../../../shared/models/videos'
import { VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
})
it('Should run filter:api.video.upload.accept.result', async function () {
- await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video with bad word' }, 403)
+ await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video with bad word' }, HttpStatusCode.FORBIDDEN_403)
})
it('Should run filter:api.live-video.create.accept.result', async function () {
channelId: servers[0].videoChannel.id
}
- await createLive(servers[0].url, servers[0].accessToken, attributes, 403)
+ await createLive(servers[0].url, servers[0].accessToken, attributes, HttpStatusCode.FORBIDDEN_403)
})
it('Should run filter:api.video.pre-import-url.accept.result', async function () {
channelId: servers[0].videoChannel.id,
targetUrl: getGoodVideoUrl() + 'bad'
}
- await importVideo(servers[0].url, servers[0].accessToken, baseAttributes, 403)
+ await importVideo(servers[0].url, servers[0].accessToken, baseAttributes, HttpStatusCode.FORBIDDEN_403)
})
it('Should run filter:api.video.pre-import-torrent.accept.result', async function () {
channelId: servers[0].videoChannel.id,
torrentfile: 'video-720p.torrent' as any
}
- await importVideo(servers[0].url, servers[0].accessToken, baseAttributes, 403)
+ await importVideo(servers[0].url, servers[0].accessToken, baseAttributes, HttpStatusCode.FORBIDDEN_403)
})
it('Should run filter:api.video.post-import-url.accept.result', async function () {
})
it('Should run filter:api.video-thread.create.accept.result', async function () {
- await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment with bad word', 403)
+ await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment with bad word', HttpStatusCode.FORBIDDEN_403)
})
it('Should run filter:api.video-comment-reply.create.accept.result', async function () {
const res = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'thread')
threadId = res.body.comment.id
- await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with bad word', 403)
- await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with good word', 200)
+ await addVideoCommentReply(
+ servers[0].url,
+ servers[0].accessToken,
+ videoUUID,
+ threadId,
+ 'comment with bad word',
+ HttpStatusCode.FORBIDDEN_403
+ )
+ await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with good word', HttpStatusCode.OK_200)
})
it('Should run filter:api.video-threads.list.params', async function () {
})
it('Should not allow a signup', async function () {
- const res = await registerUser(servers[0].url, 'jma', 'password', 403)
+ const res = await registerUser(servers[0].url, 'jma', 'password', HttpStatusCode.FORBIDDEN_403)
expect(res.body.error).to.equal('No jma')
})
uploadVideo
} from '../../../shared/extra-utils'
import { VideoDetails, VideoPlaylistPrivacy } from '../../../shared/models/videos'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
const expect = chai.expect
it('Should not be able to create a video with this privacy', async function () {
const attrs = { name: 'video', privacy: 2 }
- await uploadVideo(server.url, server.accessToken, attrs, 400)
+ await uploadVideo(server.url, server.accessToken, attrs, HttpStatusCode.BAD_REQUEST_400)
})
it('Should not be able to create a video with this privacy', async function () {
const attrs = { displayName: 'video playlist', privacy: VideoPlaylistPrivacy.PRIVATE }
- await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attrs, expectedStatus: 400 })
+ await createVideoPlaylist({
+ url: server.url,
+ token: server.accessToken,
+ playlistAttrs: attrs,
+ expectedStatus: HttpStatusCode.BAD_REQUEST_400
+ })
})
it('Should be able to upload a video with these values', async function () {
import { getAdminTokenOrDie, getServerCredentials } from './cli'
import { VideoRedundanciesTarget, VideoRedundancy } from '@shared/models'
import { addVideoRedundancy, listVideoRedundancies, removeVideoRedundancy } from '@shared/extra-utils/server/redundancy'
+import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
import validator from 'validator'
import * as CliTable3 from 'cli-table3'
import { URL } from 'url'
process.exit(0)
} catch (err) {
- if (err.message.includes(409)) {
+ if (err.message.includes(HttpStatusCode.CONFLICT_409)) {
console.error('This video is already duplicated by your instance.')
- } else if (err.message.includes(404)) {
+ } else if (err.message.includes(HttpStatusCode.NOT_FOUND_404)) {
console.error('This video id does not exist.')
} else {
console.error(err)
/**
* Hypertext Transfer Protocol (HTTP) response status codes.
* @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
+ *
+ * WebDAV and other codes useless with regards to PeerTube are not listed.
*/
export enum HttpStatusCode {
*/
ACCEPTED_202 = 202,
- /**
- * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.3.4
- *
- * SINCE HTTP/1.1
- * The server is a transforming proxy that received a 200 OK from its origin,
- * but is returning a modified version of the origin's response.
- */
- NON_AUTHORITATIVE_INFORMATION_203 = 203,
-
/**
* Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.3.5
*
*/
PARTIAL_CONTENT_206 = 206,
- /**
- * The message body that follows is an XML message and can contain a number of separate response codes,
- * depending on how many sub-requests were made.
- */
- MULTI_STATUS_207 = 207,
-
- /**
- * The server has fulfilled a request for the resource,
- * and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
- */
- IM_USED_226 = 226,
-
/**
* Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation).
* For example, this code could be used to present multiple video format options,
*/
NOT_MODIFIED_304 = 304,
- /**
- * @deprecated
- * SINCE HTTP/1.1
- * The requested resource is available only through a proxy, the address for which is provided in the response.
- * Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status
- * code, primarily for security reasons.
- */
- USE_PROXY_305 = 305,
-
- /**
- * No longer used. Originally meant "Subsequent requests should use the specified proxy."
- */
- SWITCH_PROXY_306 = 306,
-
/**
* SINCE HTTP/1.1
* In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
UNAUTHORIZED_401 = 401,
/**
+ * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.5.2
+ *
* Reserved for future use. The original intention was that this code might be used as part of some form of digital
* cash or micro payment scheme, but that has not happened, and this code is not usually used.
* Google Developers API uses this status if a particular developer has exceeded the daily limit on requests.
*/
NOT_ACCEPTABLE_406 = 406,
- /**
- * The client must first authenticate itself with the proxy.
- */
- PROXY_AUTHENTICATION_REQUIRED_407 = 407,
-
/**
* Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.5.7
*
* It means that the server would like to shut down this unused connection. This response is used much more since
* some browsers, like Chrome, Firefox 27+, or IE9, use HTTP pre-connection mechanisms to speed up surfing. Also
* note that some servers merely shut down the connection without sending this message.
+ *
+ * @
*/
REQUEST_TIMEOUT_408 = 408,
/**
+ * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.5.8
+ *
* Indicates that the request could not be processed because of conflict in the request,
* such as an edit conflict between multiple simultaneous updates.
*/
RANGE_NOT_SATISFIABLE_416 = 416,
/**
- * The server cannot meet the requirements of the Expect request-header field.
+ * The server cannot meet the requirements of the `Expect` request-header field.
*/
EXPECTATION_FAILED_417 = 417,
/**
+ * Official Documentation @ https://tools.ietf.org/html/rfc2324
+ *
* This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol,
* and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by
* teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including PeerTube instances ;-).
*/
I_AM_A_TEAPOT_418 = 418,
- /**
- * The request was directed at a server that is not able to produce a response (for example because a connection reuse).
- */
- MISDIRECTED_REQUEST_421 = 421,
-
/**
* Official Documentation @ https://tools.ietf.org/html/rfc2518#section-10.3
*
* The request was well-formed but was unable to be followed due to semantic errors.
+ *
+ * @see HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415 if the `Content-Type` was not supported.
+ * @see HttpStatusCode.BAD_REQUEST_400 if the request was not parsable (broken JSON, XML)
*/
UNPROCESSABLE_ENTITY_422 = 422,
/**
- * The resource that is being accessed is locked.
+ * Official Documentation @ https://tools.ietf.org/html/rfc4918#section-11.3
+ *
+ * The resource that is being accessed is locked. WebDAV-specific but used by some HTTP services.
+ *
+ * @deprecated use `If-Match` / `If-None-Match` instead
+ * @see {@link https://evertpot.com/http/423-locked}
*/
LOCKED_423 = 423,
- /**
- * The request failed due to failure of a previous request (e.g., a PROPPATCH).
- */
- FAILED_DEPENDENCY_424 = 424,
-
- /**
- * The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.
- */
- UPGRADE_REQUIRED_426 = 426,
-
- /**
- * The origin server requires the request to be conditional.
- * Intended to prevent "the 'lost update' problem, where a client
- * GETs a resource's state, modifies it, and PUTs it back to the server,
- * when meanwhile a third party has modified the state on the server, leading to a conflict."
- */
- PRECONDITION_REQUIRED_428 = 428,
-
/**
* Official Documentation @ https://tools.ietf.org/html/rfc6585#section-4
*
INTERNAL_SERVER_ERROR_500 = 500,
/**
+ * Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.6.2
+ *
* The server either does not recognize the request method, or it lacks the ability to fulfill the request.
* Usually this implies future availability (e.g., a new feature of a web-service API).
*/
*/
HTTP_VERSION_NOT_SUPPORTED_505 = 505,
- /**
- * Transparent content negotiation for the request results in a circular reference.
- */
- VARIANT_ALSO_NEGOTIATES_506 = 506,
-
/**
* Official Documentation @ https://tools.ietf.org/html/rfc2518#section-10.6
*
* server is unable to store the representation needed to successfully complete the request. This condition is
* considered to be temporary. If the request which received this status code was the result of a user action,
* the request MUST NOT be repeated until it is requested by a separate user action.
+ *
+ * @see HttpStatusCode.PAYLOAD_TOO_LARGE_413 for quota errors
*/
INSUFFICIENT_STORAGE_507 = 507,
-
- /**
- * The server detected an infinite loop while processing the request.
- */
- LOOP_DETECTED_508 = 508,
-
- /**
- * Further extensions to the request are required for the server to fulfill it.
- */
- NOT_EXTENDED_510 = 510,
-
- /**
- * The client needs to authenticate to gain network access.
- * Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used
- * to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot).
- */
- NETWORK_AUTHENTICATION_REQUIRED_511 = 511
}
import * as request from 'supertest'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
-function makeActivityPubGetRequest (url: string, path: string, expectedStatus = 200) {
+function makeActivityPubGetRequest (url: string, path: string, expectedStatus = HttpStatusCode.OK_200) {
return request(url)
.get(path)
.set('Accept', 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8')
import { VideoRedundanciesTarget } from '@shared/models'
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
-function updateRedundancy (url: string, accessToken: string, host: string, redundancyAllowed: boolean, expectedStatus = 204) {
+function updateRedundancy (
+ url: string,
+ accessToken: string,
+ host: string,
+ redundancyAllowed: boolean,
+ expectedStatus = HttpStatusCode.NO_CONTENT_204
+) {
const path = '/api/v1/server/redundancy/' + host
return makePutBodyRequest({
import { ServerInfo } from '../server/servers'
import { getClient } from '../server/clients'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
type Client = { id: string, secret: string }
type User = { username: string, password: string }
type Server = { url: string, client: Client, user: User }
-function login (url: string, client: Client, user: User, expectedStatus = 200) {
+function login (url: string, client: Client, user: User, expectedStatus = HttpStatusCode.OK_200) {
const path = '/api/v1/users/token'
const body = {
.expect(expectedStatus)
}
-function logout (url: string, token: string, expectedStatus = 200) {
+function logout (url: string, token: string, expectedStatus = HttpStatusCode.OK_200) {
const path = '/api/v1/users/revoke-token'
return request(url)
}
async function serverLogin (server: Server) {
- const res = await login(server.url, server.client, server.user, 200)
+ const res = await login(server.url, server.client, server.user, HttpStatusCode.OK_200)
return res.body.access_token as string
}
-function refreshToken (server: ServerInfo, refreshToken: string, expectedStatus = 200) {
+function refreshToken (server: ServerInfo, refreshToken: string, expectedStatus = HttpStatusCode.OK_200) {
const path = '/api/v1/users/token'
const body = {
.expect(expectedStatus)
}
-async function userLogin (server: Server, user: User, expectedStatus = 200) {
+async function userLogin (server: Server, user: User, expectedStatus = HttpStatusCode.OK_200) {
const res = await login(server.url, server.client, user, expectedStatus)
return res.body.access_token as string
return Promise.all(tasks)
}
-function loginUsingExternalToken (server: Server, username: string, externalAuthToken: string, expectedStatus = 200) {
+function loginUsingExternalToken (server: Server, username: string, externalAuthToken: string, expectedStatus = HttpStatusCode.OK_200) {
const path = '/api/v1/users/token'
const body = {
import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
-function userWatchVideo (url: string, token: string, videoId: number | string, currentTime: number, statusCodeExpected = 204) {
+function userWatchVideo (
+ url: string,
+ token: string,
+ videoId: number | string,
+ currentTime: number,
+ statusCodeExpected = HttpStatusCode.NO_CONTENT_204
+) {
const path = '/api/v1/videos/' + videoId + '/watching'
const fields = { currentTime }
.set('Authorization', 'Bearer ' + token)
.query(immutableAssign(query, { sort: 'name' }))
.set('Accept', 'application/json')
- .expect(200)
+ .expect(HttpStatusCode.OK_200)
.expect('Content-Type', /json/)
}
.get(path)
.query({ sort: 'name', filter: 'local' })
.set('Accept', 'application/json')
- .expect(200)
+ .expect(HttpStatusCode.OK_200)
.expect('Content-Type', /json/)
}
application/json:
schema:
$ref: '#/components/schemas/VideoUploadResponse'
+ '400':
+ description: invalid file field, schedule date or parameter
'403':
- description: user video quota is exceeded with this video
+ description: video didn't pass upload filter
'408':
description: upload has timed out
'413':
- description: video file too large
+ description: video file too large, due to quota or max body size limit set by the reverse-proxy
headers:
X-File-Maximum-Size:
schema:
type: string
format: Nginx size
description: Maximum file size for the video
+ '415':
+ description: video type unsupported
'422':
- description: invalid input file
+ description: video unreadable
requestBody:
content:
multipart/form-data:
application/json:
schema:
$ref: '#/components/schemas/VideoUploadResponse'
- '409':
- description: HTTP or Torrent/magnetURI import not enabled
'400':
description: '`magnetUri` or `targetUrl` or a torrent file missing'
+ '403':
+ description: video didn't pass pre-import filter
+ '409':
+ description: HTTP or Torrent/magnetURI import not enabled
/videos/live:
post:
name: name
in: path
required: true
- description: The name of the account
+ description: The username or handle of the account
schema:
type: string
example: chocobozzz | chocobozzz@example.org
properties:
name:
type: string
- description: The name for the default channel
+ description: The username for the default channel
pattern: '/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.:]+$/'
displayName:
type: string