activityPubClientRouter.get('/videos/watch/:id',
executeIfActivityPub,
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS)),
asyncMiddleware(videosCustomGetValidator('only-video-with-rights')),
asyncMiddleware(videoController)
)
const overviewsRouter = express.Router()
overviewsRouter.get('/videos',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)),
asyncMiddleware(getVideosOverview)
)
const statsRouter = express.Router()
statsRouter.get('/stats',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.STATS)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.STATS)),
asyncMiddleware(getStats)
)
// Special route that add OpenGraph and oEmbed tags
// Do not use a template engine for a so little thing
botsRouter.use('/sitemap.xml',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.SITEMAP)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.SITEMAP)),
asyncMiddleware(getSitemap)
)
setDefaultSort,
videoCommentsFeedsValidator,
videoFeedsValidator,
- videosSortValidator
+ videosSortValidator,
+ feedsFormatValidator,
+ setFeedFormatContentType
} from '../middlewares'
import { VideoModel } from '../models/video/video'
import * as Feed from 'pfeed'
const feedsRouter = express.Router()
feedsRouter.get('/feeds/video-comments.:format',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.FEEDS)),
+ feedsFormatValidator,
+ setFeedFormatContentType,
+ asyncMiddleware(cacheRoute({
+ headerBlacklist: [
+ 'Content-Type'
+ ]
+ })(ROUTE_CACHE_LIFETIME.FEEDS)),
asyncMiddleware(videoCommentsFeedsValidator),
asyncMiddleware(generateVideoCommentsFeed)
)
feedsRouter.get('/feeds/videos.:format',
videosSortValidator,
setDefaultSort,
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.FEEDS)),
+ feedsFormatValidator,
+ setFeedFormatContentType,
+ asyncMiddleware(cacheRoute({
+ headerBlacklist: [
+ 'Content-Type'
+ ]
+ })(ROUTE_CACHE_LIFETIME.FEEDS)),
commonVideosFiltersValidator,
asyncMiddleware(videoFeedsValidator),
asyncMiddleware(generateVideoFeed)
const format = req.params.format
if (format === 'atom' || format === 'atom1') {
- res.set('Content-Type', 'application/atom+xml')
return res.send(feed.atom1()).end()
}
if (format === 'json' || format === 'json1') {
- res.set('Content-Type', 'application/json')
return res.send(feed.json1()).end()
}
if (format === 'rss' || format === 'rss2') {
- res.set('Content-Type', 'application/rss+xml')
return res.send(feed.rss2()).end()
}
// We're in the ambiguous '.xml' case and we look at the format query parameter
if (req.query.format === 'atom' || req.query.format === 'atom1') {
- res.set('Content-Type', 'application/atom+xml')
return res.send(feed.atom1()).end()
}
- res.set('Content-Type', 'application/rss+xml')
return res.send(feed.rss2()).end()
}
// robots.txt service
staticRouter.get('/robots.txt',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ROBOTS)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.ROBOTS)),
(_, res: express.Response) => {
res.type('text/plain')
return res.send(CONFIG.INSTANCE.ROBOTS)
)
staticRouter.get('/.well-known/security.txt',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.SECURITYTXT)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.SECURITYTXT)),
(_, res: express.Response) => {
res.type('text/plain')
return res.send(CONFIG.INSTANCE.SECURITYTXT + CONFIG.INSTANCE.SECURITYTXT_CONTACT)
// nodeinfo service
staticRouter.use('/.well-known/nodeinfo',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.NODEINFO)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.NODEINFO)),
(_, res: express.Response) => {
return res.json({
links: [
}
)
staticRouter.use('/nodeinfo/:version.json',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.NODEINFO)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.NODEINFO)),
asyncMiddleware(generateNodeinfo)
)
// dnt-policy.txt service (see https://www.eff.org/dnt-policy)
staticRouter.use('/.well-known/dnt-policy.txt',
- asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.DNT_POLICY)),
+ asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.DNT_POLICY)),
(_, res: express.Response) => {
res.type('text/plain')
// Ensure Redis is initialized
Redis.Instance.init()
-const options = {
+const defaultOptions = {
redisClient: Redis.Instance.getClient(),
- appendKey: () => Redis.Instance.getPrefix()
+ appendKey: () => Redis.Instance.getPrefix(),
+ statusCodes: {
+ exclude: [ 404, 403 ]
+ }
}
-const cacheRoute = apicache.options(options).middleware
+const cacheRoute = (extraOptions = {}) => apicache.options({
+ ...defaultOptions,
+ ...extraOptions
+}).middleware
// ---------------------------------------------------------------------------
doesVideoChannelNameWithHostExist
} from '../../helpers/middlewares'
-const videoFeedsValidator = [
+const feedsFormatValidator = [
param('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'),
- query('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'),
+ query('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)')
+]
+
+function setFeedFormatContentType (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const format = req.query.format || req.params.format || 'rss'
+
+ let acceptableContentTypes: string[]
+ if (format === 'atom' || format === 'atom1') {
+ acceptableContentTypes = ['application/atom+xml', 'application/xml', 'text/xml']
+ } else if (format === 'json' || format === 'json1') {
+ acceptableContentTypes = ['application/json']
+ } else if (format === 'rss' || format === 'rss2') {
+ acceptableContentTypes = ['application/rss+xml', 'application/xml', 'text/xml']
+ } else {
+ acceptableContentTypes = ['application/xml', 'text/xml']
+ }
+
+ if (req.accepts(acceptableContentTypes)) {
+ res.set('Content-Type', req.accepts(acceptableContentTypes) as string)
+ } else {
+ return res.status(406).send({
+ message: `You should accept at least one of the following content-types: ${acceptableContentTypes.join(', ')}`
+ }).end()
+ }
+
+ return next()
+}
+
+const videoFeedsValidator = [
query('accountId').optional().custom(isIdValid),
query('accountName').optional(),
query('videoChannelId').optional().custom(isIdValid),
]
const videoCommentsFeedsValidator = [
- param('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'),
- query('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'),
query('videoId').optional().custom(isIdOrUUIDValid),
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
// ---------------------------------------------------------------------------
export {
+ feedsFormatValidator,
+ setFeedFormatContentType,
videoFeedsValidator,
videoCommentsFeedsValidator
}