diff options
-rw-r--r-- | server/controllers/activitypub/client.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/overviews.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/server/stats.ts | 2 | ||||
-rw-r--r-- | server/controllers/bots.ts | 2 | ||||
-rw-r--r-- | server/controllers/feeds.ts | 25 | ||||
-rw-r--r-- | server/controllers/static.ts | 10 | ||||
-rw-r--r-- | server/middlewares/cache.ts | 12 | ||||
-rw-r--r-- | server/middlewares/validators/feeds.ts | 36 |
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 | ||
75 | activityPubClientRouter.get('/videos/watch/:id', | 75 | activityPubClientRouter.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' | |||
11 | const overviewsRouter = express.Router() | 11 | const overviewsRouter = express.Router() |
12 | 12 | ||
13 | overviewsRouter.get('/videos', | 13 | overviewsRouter.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' | |||
14 | const statsRouter = express.Router() | 14 | const statsRouter = express.Router() |
15 | 15 | ||
16 | statsRouter.get('/stats', | 16 | statsRouter.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 |
16 | botsRouter.use('/sitemap.xml', | 16 | botsRouter.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' |
11 | import { VideoModel } from '../models/video/video' | 13 | import { VideoModel } from '../models/video/video' |
12 | import * as Feed from 'pfeed' | 14 | import * as Feed from 'pfeed' |
@@ -18,7 +20,13 @@ import { CONFIG } from '../initializers/config' | |||
18 | const feedsRouter = express.Router() | 20 | const feedsRouter = express.Router() |
19 | 21 | ||
20 | feedsRouter.get('/feeds/video-comments.:format', | 22 | feedsRouter.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', | |||
26 | feedsRouter.get('/feeds/videos.:format', | 34 | feedsRouter.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 |
114 | staticRouter.get('/robots.txt', | 114 | staticRouter.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 | ||
129 | staticRouter.get('/.well-known/security.txt', | 129 | staticRouter.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 |
138 | staticRouter.use('/.well-known/nodeinfo', | 138 | staticRouter.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 | ) |
151 | staticRouter.use('/nodeinfo/:version.json', | 151 | staticRouter.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) |
157 | staticRouter.use('/.well-known/dnt-policy.txt', | 157 | staticRouter.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 |
5 | Redis.Instance.init() | 5 | Redis.Instance.init() |
6 | 6 | ||
7 | const options = { | 7 | const 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 | ||
12 | const cacheRoute = apicache.options(options).middleware | 15 | const 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 | ||
15 | const videoFeedsValidator = [ | 15 | const 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 | |||
20 | function 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 | |||
45 | const 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 | ||
37 | const videoCommentsFeedsValidator = [ | 65 | const 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 | ||
55 | export { | 81 | export { |
82 | feedsFormatValidator, | ||
83 | setFeedFormatContentType, | ||
56 | videoFeedsValidator, | 84 | videoFeedsValidator, |
57 | videoCommentsFeedsValidator | 85 | videoCommentsFeedsValidator |
58 | } | 86 | } |