mirror of https://github.com/Chocobozzz/PeerTube
Adapt feeds content-type to accept header
parent
9270ccf6dc
commit
f2f0eda543
|
@ -74,7 +74,7 @@ activityPubClientRouter.get('/accounts?/:name/dislikes/:videoId',
|
|||
|
||||
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)
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ import * as memoizee from 'memoizee'
|
|||
const overviewsRouter = express.Router()
|
||||
|
||||
overviewsRouter.get('/videos',
|
||||
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)),
|
||||
asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)),
|
||||
asyncMiddleware(getVideosOverview)
|
||||
)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import { CONFIG } from '../../../initializers/config'
|
|||
const statsRouter = express.Router()
|
||||
|
||||
statsRouter.get('/stats',
|
||||
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.STATS)),
|
||||
asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.STATS)),
|
||||
asyncMiddleware(getStats)
|
||||
)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ const botsRouter = express.Router()
|
|||
// 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)
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@ import {
|
|||
setDefaultSort,
|
||||
videoCommentsFeedsValidator,
|
||||
videoFeedsValidator,
|
||||
videosSortValidator
|
||||
videosSortValidator,
|
||||
feedsFormatValidator,
|
||||
setFeedFormatContentType
|
||||
} from '../middlewares'
|
||||
import { VideoModel } from '../models/video/video'
|
||||
import * as Feed from 'pfeed'
|
||||
|
@ -18,7 +20,13 @@ import { CONFIG } from '../initializers/config'
|
|||
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)
|
||||
)
|
||||
|
@ -26,7 +34,13 @@ feedsRouter.get('/feeds/video-comments.:format',
|
|||
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)
|
||||
|
@ -224,26 +238,21 @@ function sendFeed (feed, req: express.Request, res: express.Response) {
|
|||
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()
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ staticRouter.use(
|
|||
|
||||
// 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)
|
||||
|
@ -127,7 +127,7 @@ staticRouter.get('/security.txt',
|
|||
)
|
||||
|
||||
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)
|
||||
|
@ -136,7 +136,7 @@ staticRouter.get('/.well-known/security.txt',
|
|||
|
||||
// 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: [
|
||||
|
@ -149,13 +149,13 @@ staticRouter.use('/.well-known/nodeinfo',
|
|||
}
|
||||
)
|
||||
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')
|
||||
|
||||
|
|
|
@ -4,12 +4,18 @@ import * as apicache from 'apicache'
|
|||
// 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
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -12,9 +12,37 @@ import {
|
|||
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),
|
||||
|
@ -35,8 +63,6 @@ const videoFeedsValidator = [
|
|||
]
|
||||
|
||||
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) => {
|
||||
|
@ -53,6 +79,8 @@ const videoCommentsFeedsValidator = [
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
feedsFormatValidator,
|
||||
setFeedFormatContentType,
|
||||
videoFeedsValidator,
|
||||
videoCommentsFeedsValidator
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue