rsshub
Version:
Make RSS Great Again!
426 lines (388 loc) • 15.4 kB
text/typescript
import { Route, DataItem } from '@/types';
import { config } from '@/config';
import got from '@/utils/got';
import wait from '@/utils/wait';
import cache from '@/utils/cache';
import { fetchArticle } from '@/utils/wechat-mp';
import ConfigNotFoundError from '@/errors/types/config-not-found';
import InvalidParameterError from '@/errors/types/invalid-parameter';
import CaptchaError from '@/errors/types/captcha';
let cacheIndex = 0;
export const route: Route = {
path: '/:id/:params?',
name: 'Test',
maintainers: ['DIYgod', 'NeverBehave'],
handler,
};
async function handler(ctx) {
if (ctx.req.param('id') === 'error') {
throw new Error('Error test');
}
if (ctx.req.param('id') === 'httperror') {
await got({
method: 'get',
url: 'https://httpbingo.org/status/404',
});
}
if (ctx.req.param('id') === 'config-not-found-error') {
throw new ConfigNotFoundError('Test config not found error');
}
if (ctx.req.param('id') === 'invalid-parameter-error') {
throw new InvalidParameterError('Test invalid parameter error');
}
if (ctx.req.param('id') === 'captcha-error') {
throw new CaptchaError('Test captcha error');
}
if (ctx.req.param('id') === 'redirect') {
ctx.set('redirect', '/test/1');
return;
}
let item: DataItem[] = [];
let image: string | null = null;
switch (ctx.req.param('id')) {
case 'filter':
item = [
{
title: 'Filter Title1',
description: 'Description1',
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/-1`,
author: `DIYgod0`,
category: ['Category0', 'Category1'],
},
{
title: 'Filter Title2',
description: 'Description2',
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/0`,
author: `DIYgod0`,
category: ['Category0', 'Category1', 'Category2'],
},
{
title: 'Filter Title3',
description: 'Description3',
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/1`,
author: `DIYgod0`,
category: 'Category3',
},
];
break;
case 'filter-illegal-category':
item.push({
title: 'TitleIllegal',
description: 'DescriptionIllegal',
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/1`,
author: `DIYgod0`,
category: [1, 'CategoryIllegal', true, null, undefined, { type: 'object' }],
});
break;
case 'long':
item.push({
title: `Long Title `.repeat(50),
description: `Long Description `.repeat(10),
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/0`,
author: `DIYgod0`,
});
break;
case 'cache': {
const description = await cache.tryGet('test', () => ({
text: `Cache${++cacheIndex}`,
}));
item.push({
title: 'Cache Title',
description: description.text,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/0`,
author: `DIYgod0`,
});
break;
}
case 'refreshCache': {
let refresh = await cache.get('refreshCache');
let noRefresh = await cache.get('noRefreshCache', false);
if (!refresh) {
refresh = '0';
await cache.set('refreshCache', '1');
}
if (!noRefresh) {
noRefresh = '0';
await cache.set('noRefreshCache', '1', undefined);
}
item.push({
title: 'Cache Title',
description: refresh + ' ' + noRefresh,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/0`,
author: `DIYgod0`,
});
break;
}
case 'cacheUrlKey': {
const description = await cache.tryGet(
new URL('https://rsshub.app'),
() => ({
text: `Cache${++cacheIndex}`,
}),
config.cache.routeExpire * 2
);
item.push({
title: 'Cache Title',
description: description.text,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/0`,
author: `DIYgod0`,
});
break;
}
case 'complicated':
image = 'https://mock.com/DIYgod/RSSHub.png';
item.push(
{
title: `Complicated Title`,
description: `<a href="/DIYgod/RSSHub"></a>
<img src="/DIYgod/RSSHub.jpg">
<script>alert(1);</script>
<a href="http://mock.com/DIYgod/RSSHub"></a>
<img src="/DIYgod/RSSHub.jpg" data-src="/DIYgod/RSSHub0.jpg">
<img data-src="/DIYgod/RSSHub.jpg">
<img data-mock="/DIYgod/RSSHub.png">
<img mock="/DIYgod/RSSHub.gif">
<img src="http://mock.com/DIYgod/DIYgod/RSSHub">
<img src="/DIYgod/RSSHub.jpg" onclick="alert(1);" onerror="alert(1);" onload="alert(1);">
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">`,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `//mock.com/DIYgod/RSSHub`,
author: `DIYgod`,
},
{
title: `Complicated Title`,
description: `<a href="/DIYgod/RSSHub"></a>
<img src="/DIYgod/RSSHub.jpg">`,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://mock.com/DIYgod/RSSHub`,
author: `DIYgod`,
},
{
title: `Complicated Title`,
description: `<a href="/DIYgod/RSSHub"></a>
<img src="/DIYgod/RSSHub.jpg">
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">`,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `//mock.com/DIYgod/RSSHub`,
author: `DIYgod`,
enclosure_url: 'https://mock.com/DIYgod/RSSHub.png',
enclosure_type: 'image/png',
itunes_item_image: 'https://mock.com/DIYgod/RSSHub.gif',
},
{
title: `Complicated Title`,
description: `<a href="/DIYgod/RSSHub"></a>
<img src="/DIYgod/RSSHub.jpg">
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">`,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `//mock.com/DIYgod/RSSHub`,
author: `DIYgod`,
image: 'https://mock.com/DIYgod/RSSHub.jpg',
}
);
break;
case 'multimedia':
item.push(
{
title: `Multimedia Title`,
description: `<img src="/DIYgod/RSSHub.jpg">
<video src="/DIYgod/RSSHub.mp4"></video>
<video poster="/DIYgod/RSSHub.jpg">
<source src="/DIYgod/RSSHub.mp4" type="video/mp4">
<source src="/DIYgod/RSSHub.webm" type="video/webm">
</video>
<audio src="/DIYgod/RSSHub.mp3"></audio>
<iframe src="/DIYgod/RSSHub.html"></iframe>`,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://mock.com/DIYgod/RSSHub`,
author: `DIYgod`,
},
{
title: `Multimedia Title`,
description: `<img src="/DIYgod/RSSHub.jpg">
<video src="/DIYgod/RSSHub.mp4"></video>`,
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://mock.com/DIYgod/RSSHub`,
author: `DIYgod`,
enclosure_url: 'https://mock.com/DIYgod/RSSHub.mp4',
enclosure_type: 'video/mp4',
}
);
break;
case 'sort':
item.push(
{
title: `Sort Title 0`,
link: `https://github.com/DIYgod/RSSHub/issues/s1`,
author: `DIYgod0`,
},
{
title: `Sort Title 1`,
link: `https://github.com/DIYgod/RSSHub/issues/s1`,
author: `DIYgod0`,
},
{
title: `Sort Title 2`,
link: `https://github.com/DIYgod/RSSHub/issues/s2`,
pubDate: new Date(1_546_272_000_000 - 10 * 10 * 1000).toUTCString(),
author: `DIYgod0`,
},
{
title: `Sort Title 3`,
link: `https://github.com/DIYgod/RSSHub/issues/s3`,
pubDate: new Date(1_546_272_000_000).toUTCString(),
author: `DIYgod0`,
}
);
break;
case 'mess':
item.push({
title: `Mess Title`,
link: `/DIYgod/RSSHub/issues/0`,
pubDate: 1_546_272_000_000,
author: `DIYgod0`,
});
break;
case 'opencc':
item.push({
title: '小可愛',
description: '宇宙無敵',
link: `/DIYgod/RSSHub/issues/0`,
pubDate: new Date(1_546_272_000_000).toUTCString(),
author: `DIYgod0`,
});
break;
case 'brief':
item.push({
title: '小可愛',
description: '<p>宇宙無敵</p><br>'.repeat(1000),
link: `/DIYgod/RSSHub/issues/0`,
pubDate: new Date(1_546_272_000_000).toUTCString(),
author: `DIYgod0`,
});
break;
case 'json':
item.push(
{
title: 'Title0',
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/-3`,
},
{
title: 'Title1',
description: 'Description1',
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/-2`,
author: `DIYgod0 `,
category: 'Category0',
},
{
title: 'Title2 HTML in description',
description: '<a href="https://github.com/DIYgod/RSSHub">RSSHub</a>',
pubDate: new Date(`2019-3-1`).toUTCString(),
updated: new Date(`2019-3-2`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/-1`,
author: [{ name: ' DIYgod1' }, { name: 'DIYgod2 ' }],
category: ['Category0', 'Category1'],
},
{
title: 'Title3 HTML in content',
content: {
html: '<a href="https://github.com/DIYgod/RSSHub">DIYgod/RSSHub</a>',
},
pubDate: new Date(`2019-3-1`).toUTCString(),
updated: new Date(`2019-3-2`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/0`,
author: [{ name: ' DIYgod3' }, { name: 'DIYgod4 ' }, { name: 'DIYgod5 ' }],
category: ['Category1'],
enclosure_url: 'https://github.com/DIYgod/RSSHub/issues/0',
enclosure_type: 'image/jpeg',
enclosure_length: 3661,
itunes_duration: 36610,
},
{
title: 'Title4 author is null',
pubDate: new Date(`2019-3-1`).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/pull/11555`,
author: null,
}
);
break;
case 'gpt':
item.push({
title: 'Title0',
description: 'Description0',
pubDate: new Date(`2019-3-1`).toUTCString(),
link: 'https://github.com/DIYgod/RSSHub/issues/0',
});
break;
default:
// Do nothing
}
for (let i = 1; i < 6; i++) {
item.push({
title: `Title${i}`,
description: `Description${i}`,
pubDate: new Date((ctx.req.param('id') === 'current_time' ? new Date() : 1_546_272_000_000) - i * 10 * 1000).toUTCString(),
link: `https://github.com/DIYgod/RSSHub/issues/${i}`,
author: `DIYgod${i}`,
});
}
if (ctx.req.param('id') === 'empty') {
item = null;
}
if (ctx.req.param('id') === 'allow_empty') {
item = null;
}
if (ctx.req.param('id') === 'enclosure') {
item = [
{
title: '',
link: 'https://github.com/DIYgod/RSSHub/issues/1',
enclosure_url: 'https://github.com/DIYgod/RSSHub/issues/1',
enclosure_length: 3661,
itunes_duration: 36610,
},
];
}
if (ctx.req.param('id') === 'slow') {
await wait(1000);
}
if (ctx.req.param('id') === 'slow4') {
await wait(4000);
}
if (ctx.req.query('mode') === 'fulltext') {
item = [
{
title: '',
link: 'https://m.thepaper.cn/newsDetail_forward_4059298',
},
];
}
if (ctx.req.param('id') === 'wechat-mp') {
const params = ctx.req.param('params');
if (!params) {
throw new InvalidParameterError('Invalid parameter');
}
const mpUrl = 'https:/mp.weixin.qq.com/s' + (params.includes('&') ? '?' : '/') + params;
item = [await fetchArticle(mpUrl)];
}
return {
image,
title: `Test ${ctx.req.param('id')}`,
itunes_author: ctx.req.param('id') === 'enclosure' ? 'DIYgod' : null,
link: 'https://github.com/DIYgod/RSSHub',
item,
allowEmpty: ctx.req.param('id') === 'allow_empty',
description:
ctx.req.param('id') === 'complicated' ? '<img src="http://mock.com/DIYgod/DIYgod/RSSHub">' : ctx.req.param('id') === 'multimedia' ? '<video src="http://mock.com/DIYgod/DIYgod/RSSHub"></video>' : 'A test route for RSSHub',
};
}