aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2020-01-09 16:51:51 +0100
committerChocobozzz <chocobozzz@cpy.re>2020-01-10 10:14:04 +0100
commitf2f0eda543ab54eec0f6bcdd8ccf6e382d5cafb6 (patch)
tree2786e879b381bd637ebaaf84f7fa7f1ad08d8279
parent9270ccf6dca5b2955ad126947d4296deb385fdcb (diff)
downloadPeerTube-f2f0eda543ab54eec0f6bcdd8ccf6e382d5cafb6.tar.gz
PeerTube-f2f0eda543ab54eec0f6bcdd8ccf6e382d5cafb6.tar.zst
PeerTube-f2f0eda543ab54eec0f6bcdd8ccf6e382d5cafb6.zip
Adapt feeds content-type to accept header
-rw-r--r--server/controllers/activitypub/client.ts2
-rw-r--r--server/controllers/api/overviews.ts2
-rw-r--r--server/controllers/api/server/stats.ts2
-rw-r--r--server/controllers/bots.ts2
-rw-r--r--server/controllers/feeds.ts25
-rw-r--r--server/controllers/static.ts10
-rw-r--r--server/middlewares/cache.ts12
-rw-r--r--server/middlewares/validators/feeds.ts36
8 files changed, 67 insertions, 24 deletions
diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts
index 5ed0435ff..62412cd62 100644
--- a/server/controllers/activitypub/client.ts
+++ b/server/controllers/activitypub/client.ts
@@ -74,7 +74,7 @@ activityPubClientRouter.get('/accounts?/:name/dislikes/:videoId',
74 74
75activityPubClientRouter.get('/videos/watch/:id', 75activityPubClientRouter.get('/videos/watch/:id',
76 executeIfActivityPub, 76 executeIfActivityPub,
77 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS)), 77 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS)),
78 asyncMiddleware(videosCustomGetValidator('only-video-with-rights')), 78 asyncMiddleware(videosCustomGetValidator('only-video-with-rights')),
79 asyncMiddleware(videoController) 79 asyncMiddleware(videoController)
80) 80)
diff --git a/server/controllers/api/overviews.ts b/server/controllers/api/overviews.ts
index 23706767a..46e76ac6b 100644
--- a/server/controllers/api/overviews.ts
+++ b/server/controllers/api/overviews.ts
@@ -11,7 +11,7 @@ import * as memoizee from 'memoizee'
11const overviewsRouter = express.Router() 11const overviewsRouter = express.Router()
12 12
13overviewsRouter.get('/videos', 13overviewsRouter.get('/videos',
14 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)), 14 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)),
15 asyncMiddleware(getVideosOverview) 15 asyncMiddleware(getVideosOverview)
16) 16)
17 17
diff --git a/server/controllers/api/server/stats.ts b/server/controllers/api/server/stats.ts
index 951b98209..3616c074d 100644
--- a/server/controllers/api/server/stats.ts
+++ b/server/controllers/api/server/stats.ts
@@ -14,7 +14,7 @@ import { CONFIG } from '../../../initializers/config'
14const statsRouter = express.Router() 14const statsRouter = express.Router()
15 15
16statsRouter.get('/stats', 16statsRouter.get('/stats',
17 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.STATS)), 17 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.STATS)),
18 asyncMiddleware(getStats) 18 asyncMiddleware(getStats)
19) 19)
20 20
diff --git a/server/controllers/bots.ts b/server/controllers/bots.ts
index f3e778b04..63280dabb 100644
--- a/server/controllers/bots.ts
+++ b/server/controllers/bots.ts
@@ -14,7 +14,7 @@ const botsRouter = express.Router()
14// Special route that add OpenGraph and oEmbed tags 14// Special route that add OpenGraph and oEmbed tags
15// Do not use a template engine for a so little thing 15// Do not use a template engine for a so little thing
16botsRouter.use('/sitemap.xml', 16botsRouter.use('/sitemap.xml',
17 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.SITEMAP)), 17 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.SITEMAP)),
18 asyncMiddleware(getSitemap) 18 asyncMiddleware(getSitemap)
19) 19)
20 20
diff --git a/server/controllers/feeds.ts b/server/controllers/feeds.ts
index fa6c7ac71..72628dffb 100644
--- a/server/controllers/feeds.ts
+++ b/server/controllers/feeds.ts
@@ -6,7 +6,9 @@ import {
6 setDefaultSort, 6 setDefaultSort,
7 videoCommentsFeedsValidator, 7 videoCommentsFeedsValidator,
8 videoFeedsValidator, 8 videoFeedsValidator,
9 videosSortValidator 9 videosSortValidator,
10 feedsFormatValidator,
11 setFeedFormatContentType
10} from '../middlewares' 12} from '../middlewares'
11import { VideoModel } from '../models/video/video' 13import { VideoModel } from '../models/video/video'
12import * as Feed from 'pfeed' 14import * as Feed from 'pfeed'
@@ -18,7 +20,13 @@ import { CONFIG } from '../initializers/config'
18const feedsRouter = express.Router() 20const feedsRouter = express.Router()
19 21
20feedsRouter.get('/feeds/video-comments.:format', 22feedsRouter.get('/feeds/video-comments.:format',
21 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.FEEDS)), 23 feedsFormatValidator,
24 setFeedFormatContentType,
25 asyncMiddleware(cacheRoute({
26 headerBlacklist: [
27 'Content-Type'
28 ]
29 })(ROUTE_CACHE_LIFETIME.FEEDS)),
22 asyncMiddleware(videoCommentsFeedsValidator), 30 asyncMiddleware(videoCommentsFeedsValidator),
23 asyncMiddleware(generateVideoCommentsFeed) 31 asyncMiddleware(generateVideoCommentsFeed)
24) 32)
@@ -26,7 +34,13 @@ feedsRouter.get('/feeds/video-comments.:format',
26feedsRouter.get('/feeds/videos.:format', 34feedsRouter.get('/feeds/videos.:format',
27 videosSortValidator, 35 videosSortValidator,
28 setDefaultSort, 36 setDefaultSort,
29 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.FEEDS)), 37 feedsFormatValidator,
38 setFeedFormatContentType,
39 asyncMiddleware(cacheRoute({
40 headerBlacklist: [
41 'Content-Type'
42 ]
43 })(ROUTE_CACHE_LIFETIME.FEEDS)),
30 commonVideosFiltersValidator, 44 commonVideosFiltersValidator,
31 asyncMiddleware(videoFeedsValidator), 45 asyncMiddleware(videoFeedsValidator),
32 asyncMiddleware(generateVideoFeed) 46 asyncMiddleware(generateVideoFeed)
@@ -224,26 +238,21 @@ function sendFeed (feed, req: express.Request, res: express.Response) {
224 const format = req.params.format 238 const format = req.params.format
225 239
226 if (format === 'atom' || format === 'atom1') { 240 if (format === 'atom' || format === 'atom1') {
227 res.set('Content-Type', 'application/atom+xml')
228 return res.send(feed.atom1()).end() 241 return res.send(feed.atom1()).end()
229 } 242 }
230 243
231 if (format === 'json' || format === 'json1') { 244 if (format === 'json' || format === 'json1') {
232 res.set('Content-Type', 'application/json')
233 return res.send(feed.json1()).end() 245 return res.send(feed.json1()).end()
234 } 246 }
235 247
236 if (format === 'rss' || format === 'rss2') { 248 if (format === 'rss' || format === 'rss2') {
237 res.set('Content-Type', 'application/rss+xml')
238 return res.send(feed.rss2()).end() 249 return res.send(feed.rss2()).end()
239 } 250 }
240 251
241 // We're in the ambiguous '.xml' case and we look at the format query parameter 252 // We're in the ambiguous '.xml' case and we look at the format query parameter
242 if (req.query.format === 'atom' || req.query.format === 'atom1') { 253 if (req.query.format === 'atom' || req.query.format === 'atom1') {
243 res.set('Content-Type', 'application/atom+xml')
244 return res.send(feed.atom1()).end() 254 return res.send(feed.atom1()).end()
245 } 255 }
246 256
247 res.set('Content-Type', 'application/rss+xml')
248 return res.send(feed.rss2()).end() 257 return res.send(feed.rss2()).end()
249} 258}
diff --git a/server/controllers/static.ts b/server/controllers/static.ts
index f86a0cb5b..a4bb3a4d9 100644
--- a/server/controllers/static.ts
+++ b/server/controllers/static.ts
@@ -112,7 +112,7 @@ staticRouter.use(
112 112
113// robots.txt service 113// robots.txt service
114staticRouter.get('/robots.txt', 114staticRouter.get('/robots.txt',
115 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ROBOTS)), 115 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.ROBOTS)),
116 (_, res: express.Response) => { 116 (_, res: express.Response) => {
117 res.type('text/plain') 117 res.type('text/plain')
118 return res.send(CONFIG.INSTANCE.ROBOTS) 118 return res.send(CONFIG.INSTANCE.ROBOTS)
@@ -127,7 +127,7 @@ staticRouter.get('/security.txt',
127) 127)
128 128
129staticRouter.get('/.well-known/security.txt', 129staticRouter.get('/.well-known/security.txt',
130 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.SECURITYTXT)), 130 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.SECURITYTXT)),
131 (_, res: express.Response) => { 131 (_, res: express.Response) => {
132 res.type('text/plain') 132 res.type('text/plain')
133 return res.send(CONFIG.INSTANCE.SECURITYTXT + CONFIG.INSTANCE.SECURITYTXT_CONTACT) 133 return res.send(CONFIG.INSTANCE.SECURITYTXT + CONFIG.INSTANCE.SECURITYTXT_CONTACT)
@@ -136,7 +136,7 @@ staticRouter.get('/.well-known/security.txt',
136 136
137// nodeinfo service 137// nodeinfo service
138staticRouter.use('/.well-known/nodeinfo', 138staticRouter.use('/.well-known/nodeinfo',
139 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.NODEINFO)), 139 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.NODEINFO)),
140 (_, res: express.Response) => { 140 (_, res: express.Response) => {
141 return res.json({ 141 return res.json({
142 links: [ 142 links: [
@@ -149,13 +149,13 @@ staticRouter.use('/.well-known/nodeinfo',
149 } 149 }
150) 150)
151staticRouter.use('/nodeinfo/:version.json', 151staticRouter.use('/nodeinfo/:version.json',
152 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.NODEINFO)), 152 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.NODEINFO)),
153 asyncMiddleware(generateNodeinfo) 153 asyncMiddleware(generateNodeinfo)
154) 154)
155 155
156// dnt-policy.txt service (see https://www.eff.org/dnt-policy) 156// dnt-policy.txt service (see https://www.eff.org/dnt-policy)
157staticRouter.use('/.well-known/dnt-policy.txt', 157staticRouter.use('/.well-known/dnt-policy.txt',
158 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.DNT_POLICY)), 158 asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.DNT_POLICY)),
159 (_, res: express.Response) => { 159 (_, res: express.Response) => {
160 res.type('text/plain') 160 res.type('text/plain')
161 161
diff --git a/server/middlewares/cache.ts b/server/middlewares/cache.ts
index ef8611875..cb24d9e0e 100644
--- a/server/middlewares/cache.ts
+++ b/server/middlewares/cache.ts
@@ -4,12 +4,18 @@ import * as apicache from 'apicache'
4// Ensure Redis is initialized 4// Ensure Redis is initialized
5Redis.Instance.init() 5Redis.Instance.init()
6 6
7const options = { 7const defaultOptions = {
8 redisClient: Redis.Instance.getClient(), 8 redisClient: Redis.Instance.getClient(),
9 appendKey: () => Redis.Instance.getPrefix() 9 appendKey: () => Redis.Instance.getPrefix(),
10 statusCodes: {
11 exclude: [ 404, 403 ]
12 }
10} 13}
11 14
12const cacheRoute = apicache.options(options).middleware 15const cacheRoute = (extraOptions = {}) => apicache.options({
16 ...defaultOptions,
17 ...extraOptions
18}).middleware
13 19
14// --------------------------------------------------------------------------- 20// ---------------------------------------------------------------------------
15 21
diff --git a/server/middlewares/validators/feeds.ts b/server/middlewares/validators/feeds.ts
index 1bef9891b..29f6c87be 100644
--- a/server/middlewares/validators/feeds.ts
+++ b/server/middlewares/validators/feeds.ts
@@ -12,9 +12,37 @@ import {
12 doesVideoChannelNameWithHostExist 12 doesVideoChannelNameWithHostExist
13} from '../../helpers/middlewares' 13} from '../../helpers/middlewares'
14 14
15const videoFeedsValidator = [ 15const feedsFormatValidator = [
16 param('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'), 16 param('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'),
17 query('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'), 17 query('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)')
18]
19
20function setFeedFormatContentType (req: express.Request, res: express.Response, next: express.NextFunction) {
21 const format = req.query.format || req.params.format || 'rss'
22
23 let acceptableContentTypes: string[]
24 if (format === 'atom' || format === 'atom1') {
25 acceptableContentTypes = ['application/atom+xml', 'application/xml', 'text/xml']
26 } else if (format === 'json' || format === 'json1') {
27 acceptableContentTypes = ['application/json']
28 } else if (format === 'rss' || format === 'rss2') {
29 acceptableContentTypes = ['application/rss+xml', 'application/xml', 'text/xml']
30 } else {
31 acceptableContentTypes = ['application/xml', 'text/xml']
32 }
33
34 if (req.accepts(acceptableContentTypes)) {
35 res.set('Content-Type', req.accepts(acceptableContentTypes) as string)
36 } else {
37 return res.status(406).send({
38 message: `You should accept at least one of the following content-types: ${acceptableContentTypes.join(', ')}`
39 }).end()
40 }
41
42 return next()
43}
44
45const videoFeedsValidator = [
18 query('accountId').optional().custom(isIdValid), 46 query('accountId').optional().custom(isIdValid),
19 query('accountName').optional(), 47 query('accountName').optional(),
20 query('videoChannelId').optional().custom(isIdValid), 48 query('videoChannelId').optional().custom(isIdValid),
@@ -35,8 +63,6 @@ const videoFeedsValidator = [
35] 63]
36 64
37const videoCommentsFeedsValidator = [ 65const videoCommentsFeedsValidator = [
38 param('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'),
39 query('format').optional().custom(isValidRSSFeed).withMessage('Should have a valid format (rss, atom, json)'),
40 query('videoId').optional().custom(isIdOrUUIDValid), 66 query('videoId').optional().custom(isIdOrUUIDValid),
41 67
42 async (req: express.Request, res: express.Response, next: express.NextFunction) => { 68 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
@@ -53,6 +79,8 @@ const videoCommentsFeedsValidator = [
53// --------------------------------------------------------------------------- 79// ---------------------------------------------------------------------------
54 80
55export { 81export {
82 feedsFormatValidator,
83 setFeedFormatContentType,
56 videoFeedsValidator, 84 videoFeedsValidator,
57 videoCommentsFeedsValidator 85 videoCommentsFeedsValidator
58} 86}