1
0
Fork 0

Adapt feeds content-type to accept header

This commit is contained in:
Rigel Kent 2020-01-09 16:51:51 +01:00 committed by Chocobozzz
parent 9270ccf6dc
commit f2f0eda543
8 changed files with 67 additions and 24 deletions

View File

@ -74,7 +74,7 @@ activityPubClientRouter.get('/accounts?/:name/dislikes/:videoId',
activityPubClientRouter.get('/videos/watch/:id', activityPubClientRouter.get('/videos/watch/:id',
executeIfActivityPub, executeIfActivityPub,
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS)), asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS)),
asyncMiddleware(videosCustomGetValidator('only-video-with-rights')), asyncMiddleware(videosCustomGetValidator('only-video-with-rights')),
asyncMiddleware(videoController) asyncMiddleware(videoController)
) )

View File

@ -11,7 +11,7 @@ import * as memoizee from 'memoizee'
const overviewsRouter = express.Router() const overviewsRouter = express.Router()
overviewsRouter.get('/videos', overviewsRouter.get('/videos',
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)), asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)),
asyncMiddleware(getVideosOverview) asyncMiddleware(getVideosOverview)
) )

View File

@ -14,7 +14,7 @@ import { CONFIG } from '../../../initializers/config'
const statsRouter = express.Router() const statsRouter = express.Router()
statsRouter.get('/stats', statsRouter.get('/stats',
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.STATS)), asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.STATS)),
asyncMiddleware(getStats) asyncMiddleware(getStats)
) )

View File

@ -14,7 +14,7 @@ const botsRouter = express.Router()
// Special route that add OpenGraph and oEmbed tags // Special route that add OpenGraph and oEmbed tags
// Do not use a template engine for a so little thing // Do not use a template engine for a so little thing
botsRouter.use('/sitemap.xml', botsRouter.use('/sitemap.xml',
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.SITEMAP)), asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.SITEMAP)),
asyncMiddleware(getSitemap) asyncMiddleware(getSitemap)
) )

View File

@ -6,7 +6,9 @@ import {
setDefaultSort, setDefaultSort,
videoCommentsFeedsValidator, videoCommentsFeedsValidator,
videoFeedsValidator, videoFeedsValidator,
videosSortValidator videosSortValidator,
feedsFormatValidator,
setFeedFormatContentType
} from '../middlewares' } from '../middlewares'
import { VideoModel } from '../models/video/video' import { VideoModel } from '../models/video/video'
import * as Feed from 'pfeed' import * as Feed from 'pfeed'
@ -18,7 +20,13 @@ import { CONFIG } from '../initializers/config'
const feedsRouter = express.Router() const feedsRouter = express.Router()
feedsRouter.get('/feeds/video-comments.:format', 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(videoCommentsFeedsValidator),
asyncMiddleware(generateVideoCommentsFeed) asyncMiddleware(generateVideoCommentsFeed)
) )
@ -26,7 +34,13 @@ feedsRouter.get('/feeds/video-comments.:format',
feedsRouter.get('/feeds/videos.:format', feedsRouter.get('/feeds/videos.:format',
videosSortValidator, videosSortValidator,
setDefaultSort, setDefaultSort,
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.FEEDS)), feedsFormatValidator,
setFeedFormatContentType,
asyncMiddleware(cacheRoute({
headerBlacklist: [
'Content-Type'
]
})(ROUTE_CACHE_LIFETIME.FEEDS)),
commonVideosFiltersValidator, commonVideosFiltersValidator,
asyncMiddleware(videoFeedsValidator), asyncMiddleware(videoFeedsValidator),
asyncMiddleware(generateVideoFeed) asyncMiddleware(generateVideoFeed)
@ -224,26 +238,21 @@ function sendFeed (feed, req: express.Request, res: express.Response) {
const format = req.params.format const format = req.params.format
if (format === 'atom' || format === 'atom1') { if (format === 'atom' || format === 'atom1') {
res.set('Content-Type', 'application/atom+xml')
return res.send(feed.atom1()).end() return res.send(feed.atom1()).end()
} }
if (format === 'json' || format === 'json1') { if (format === 'json' || format === 'json1') {
res.set('Content-Type', 'application/json')
return res.send(feed.json1()).end() return res.send(feed.json1()).end()
} }
if (format === 'rss' || format === 'rss2') { if (format === 'rss' || format === 'rss2') {
res.set('Content-Type', 'application/rss+xml')
return res.send(feed.rss2()).end() return res.send(feed.rss2()).end()
} }
// We're in the ambiguous '.xml' case and we look at the format query parameter // We're in the ambiguous '.xml' case and we look at the format query parameter
if (req.query.format === 'atom' || req.query.format === 'atom1') { if (req.query.format === 'atom' || req.query.format === 'atom1') {
res.set('Content-Type', 'application/atom+xml')
return res.send(feed.atom1()).end() return res.send(feed.atom1()).end()
} }
res.set('Content-Type', 'application/rss+xml')
return res.send(feed.rss2()).end() return res.send(feed.rss2()).end()
} }

View File

@ -112,7 +112,7 @@ staticRouter.use(
// robots.txt service // robots.txt service
staticRouter.get('/robots.txt', staticRouter.get('/robots.txt',
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ROBOTS)), asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.ROBOTS)),
(_, res: express.Response) => { (_, res: express.Response) => {
res.type('text/plain') res.type('text/plain')
return res.send(CONFIG.INSTANCE.ROBOTS) return res.send(CONFIG.INSTANCE.ROBOTS)
@ -127,7 +127,7 @@ staticRouter.get('/security.txt',
) )
staticRouter.get('/.well-known/security.txt', staticRouter.get('/.well-known/security.txt',
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.SECURITYTXT)), asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.SECURITYTXT)),
(_, res: express.Response) => { (_, res: express.Response) => {
res.type('text/plain') res.type('text/plain')
return res.send(CONFIG.INSTANCE.SECURITYTXT + CONFIG.INSTANCE.SECURITYTXT_CONTACT) return res.send(CONFIG.INSTANCE.SECURITYTXT + CONFIG.INSTANCE.SECURITYTXT_CONTACT)
@ -136,7 +136,7 @@ staticRouter.get('/.well-known/security.txt',
// nodeinfo service // nodeinfo service
staticRouter.use('/.well-known/nodeinfo', staticRouter.use('/.well-known/nodeinfo',
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.NODEINFO)), asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.NODEINFO)),
(_, res: express.Response) => { (_, res: express.Response) => {
return res.json({ return res.json({
links: [ links: [
@ -149,13 +149,13 @@ staticRouter.use('/.well-known/nodeinfo',
} }
) )
staticRouter.use('/nodeinfo/:version.json', staticRouter.use('/nodeinfo/:version.json',
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.NODEINFO)), asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.NODEINFO)),
asyncMiddleware(generateNodeinfo) asyncMiddleware(generateNodeinfo)
) )
// dnt-policy.txt service (see https://www.eff.org/dnt-policy) // dnt-policy.txt service (see https://www.eff.org/dnt-policy)
staticRouter.use('/.well-known/dnt-policy.txt', 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: express.Response) => {
res.type('text/plain') res.type('text/plain')

View File

@ -4,12 +4,18 @@ import * as apicache from 'apicache'
// Ensure Redis is initialized // Ensure Redis is initialized
Redis.Instance.init() Redis.Instance.init()
const options = { const defaultOptions = {
redisClient: Redis.Instance.getClient(), 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
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -12,9 +12,37 @@ import {
doesVideoChannelNameWithHostExist doesVideoChannelNameWithHostExist
} from '../../helpers/middlewares' } from '../../helpers/middlewares'
const videoFeedsValidator = [ const feedsFormatValidator = [
param('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'), 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('accountId').optional().custom(isIdValid),
query('accountName').optional(), query('accountName').optional(),
query('videoChannelId').optional().custom(isIdValid), query('videoChannelId').optional().custom(isIdValid),
@ -35,8 +63,6 @@ const videoFeedsValidator = [
] ]
const videoCommentsFeedsValidator = [ 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), query('videoId').optional().custom(isIdOrUUIDValid),
async (req: express.Request, res: express.Response, next: express.NextFunction) => { async (req: express.Request, res: express.Response, next: express.NextFunction) => {
@ -53,6 +79,8 @@ const videoCommentsFeedsValidator = [
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export { export {
feedsFormatValidator,
setFeedFormatContentType,
videoFeedsValidator, videoFeedsValidator,
videoCommentsFeedsValidator videoCommentsFeedsValidator
} }