feat: add ratelimit middleware to API Routes

This commit is contained in:
hansputera
2022-01-14 02:35:51 +00:00
parent 7e7ed99a9d
commit 0cab764e91
7 changed files with 19 additions and 16 deletions

View File

@@ -9,6 +9,7 @@ const providersType = Providers.map((p) => p.resourceName());
export default async (req: VercelRequest, res: VercelResponse) => {
try {
await ratelimitMiddleware(req);
ow(req.method === 'POST' ? req.body : req.query, ow.object.partialShape({
'url': ow.string.url.validate((v) => ({
'validator': /^http(s?)(:\/\/)([a-z]+\.)*tiktok\.com\/(.*)?\/(.*)?$/gi
@@ -27,7 +28,8 @@ export default async (req: VercelRequest, res: VercelResponse) => {
ow.optional.boolean : ow.optional.string,
}));
const provider = getProvider((req.query && req.query.type || req.body && req.body.type) ?? 'random');
const provider = getProvider((req.query && req.query.type ||
req.body && req.body.type) ?? 'random');
if (!provider) {
return res.status(400).json({
'error': 'Invalid provider',
@@ -35,12 +37,11 @@ export default async (req: VercelRequest, res: VercelResponse) => {
});
}
const result = await rotateProvider(
provider as BaseProvider, req.query.url || req.body.url,
req.method === 'POST' ?
req.body.url : req.query.url, req.method === 'POST' ?
provider as BaseProvider, (req.query && req.query.url ||
req.body && req.body.url), req.method === 'POST' ?
req.body.rotateOnError :
!!req.query.rotateOnError);
await ratelimitMiddleware(req);
return res.status(200).json(result);
} catch (e) {
return res.status(400).json({

View File

@@ -6,6 +6,8 @@ export default async (_: VercelRequest, res: VercelResponse) => {
'endpoints': {
'ping': '/api/ping',
'download': '/api/download',
'stored-links': '/api/stored-links',
'providers': '/api/providers',
},
});
};

View File

@@ -1,7 +1,9 @@
import type {VercelRequest, VercelResponse} from '@vercel/node';
import {Providers} from '../lib';
import {ratelimitMiddleware} from '../middleware/ratelimit';
export default async (_: VercelRequest, res: VercelResponse) => {
await ratelimitMiddleware(_);
const providers = Providers.map((p) => ({
'name': p.resourceName(),
'url': p.client.defaults.options.prefixUrl,

View File

@@ -1,8 +1,10 @@
import {VercelRequest, VercelResponse} from '@vercel/node';
import {matchLink} from '../lib/providers/util';
import {client} from '../lib/redis';
import {ratelimitMiddleware} from '../middleware/ratelimit';
export default async (_: VercelRequest, res: VercelResponse) => {
await ratelimitMiddleware(_);
const keys = await client.keys('*');
res.status(200).json(keys.filter((x) => matchLink(x)));

View File

@@ -1,4 +1,3 @@
import Redis from 'ioredis';
export const client = new Redis(process.env.REDIS_URL);

View File

@@ -7,18 +7,17 @@ import {client as redisClient} from './redis';
* Rotate provider.
* @param {BaseProvider} provider Provider instance
* @param {string} url Video TikTok URL
* @param {boolean?} noCache NoCache option
* @param {boolean?} skipOnError Rotate when error
* @return {Promise<ExtractedInfo>}
*/
export const rotateProvider = async (
provider: BaseProvider, url: string,
noCache: boolean = false, skipOnError: boolean = true):
skipOnError: boolean = true):
Promise<ExtractedInfo & { provider: string; }> => {
// await redisClient.del(url);
// console.log(provider.resourceName());
if (provider.maintenance) {
return await rotateProvider(getRandomProvider(), url, noCache, skipOnError);
return await rotateProvider(getRandomProvider(), url, skipOnError);
}
const cachedData = await redisClient.get(url);
if (!cachedData) {
@@ -30,12 +29,10 @@ export const rotateProvider = async (
} else if (data.video && !data.video.urls.length) {
return await rotateProvider(getRandomProvider(), url);
} else {
if (!noCache) {
redisClient.set(url,
JSON.stringify(
{...data, provider: provider.resourceName()}), 'ex',
providerCache);
}
redisClient.set(url,
JSON.stringify(
{...data, provider: provider.resourceName()}), 'ex',
providerCache);
return {...data, provider: provider.resourceName()};
}
} catch (e) {

View File

@@ -1,6 +1,6 @@
{
"name": "tktk",
"version": "1.0.3",
"version": "1.4.2",
"main": "index.js",
"license": "MIT",
"dependencies": {