Skip to content

Commit

Permalink
memory optimization for text segmentation implementation, add malform…
Browse files Browse the repository at this point in the history
…ed uri middleware, fix offline rate limiter warning (#184)
  • Loading branch information
mdtanrikulu authored Dec 2, 2024
1 parent 25083fe commit f5b7905
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"dependencies": {
"@adraffy/ens-normalize": "^1.11.0",
"@ensdomains/ens-avatar": "^1.0.0",
"@ensdomains/ens-avatar": "^1.0.3",
"@ensdomains/ensjs": "^3.7.0",
"@types/lodash": "^4.14.170",
"btoa": "^1.2.1",
Expand Down
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import docUI from 'redoc-express';
import endpoints from './endpoint';
import { blockRecursiveCalls } from './utils/blockRecursiveCalls';
import { rateLimitMiddleware } from './utils/rateLimiter';
import { malformedURIMiddleware } from './utils/malformedURI';

const setCacheHeader = function (
req: Request,
Expand Down Expand Up @@ -63,7 +64,7 @@ app.use(blockRecursiveCalls);
// apply cache header for all get requests
app.use(setCacheHeader);
endpoints(app);

app.use(malformedURIMiddleware);
app.use(compression({ filter: shouldCompress }));

function shouldCompress(req: Request, res: Response) {
Expand All @@ -81,7 +82,7 @@ app.listen(PORT, () => {
console.log(`APP_LOG::App listening on port ${PORT}`);
});

app.get('/favicon.ico', (req, res) => res.status(204).end());
app.get('/favicon.ico', (_, res) => res.status(204).end());

app.get(
'/docs',
Expand Down
4 changes: 2 additions & 2 deletions src/service/avatar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { IPFS_GATEWAY } from '../config';
const test = avaTest as TestFn<TestContext>;

test('should return data URIs without any changes', async (t: ExecutionContext<TestContext>) => {
const uri = 'data:text/plain;base64,dGVzdGluZw==';
const uri = 'data:image/png;base64,dGVzdGluZw==';
const { uri: resolvedURI } = utils.resolveURI(uri, { ipfs: IPFS_GATEWAY } );
t.is(uri, resolvedURI);
t.is(uri, 'data:image/png;base64,' + resolvedURI);
});

test('should return http URIs without any changes', async (t: ExecutionContext<TestContext>) => {
Expand Down
5 changes: 3 additions & 2 deletions src/service/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ export async function getDomain(
);
}
}
const isAvatarExist = resolver?.texts && resolver.texts.includes('avatar');
await Promise.all([requestMedia(isAvatarExist), requestAttributes()]);
// disable onchain guard to be able to retrieve offchain avatars
// const isAvatarExist = resolver?.texts && resolver.texts.includes('avatar');
await Promise.all([requestMedia(true), requestAttributes()]);
return metadata;
}
14 changes: 11 additions & 3 deletions src/utils/charLength.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ declare namespace Intl {
}

export function getSegmentLength(name: string): number {
return [...new Intl.Segmenter().segment(name)].length;
let count = 0;
for (const _ of new Intl.Segmenter().segment(name)) {
count++;
}
return count;
}

export function getCodePointLength(name: string): number {
// spread operator will split string into its codepoints
return [...name].length;
// for...of operator will split string into its codepoints
let count = 0;
for (const _ of name) {
count++;
}
return count;
}
15 changes: 15 additions & 0 deletions src/utils/malformedURI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Request, Response, NextFunction } from 'express';

export function malformedURIMiddleware(
err: Error,
_: Request,
res: Response,
next: NextFunction
) {
if (err instanceof URIError) {
console.error('Malformed URI:', err.message);
res.status(400).send({ error: `Malformed URI`, message: err.message });
} else {
next(err);
}
}
19 changes: 13 additions & 6 deletions src/utils/rateLimiter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { RateLimiterRedis, RateLimiterRes } from 'rate-limiter-flexible';
import { REDIS_URL } from '../config';

let rateLimiter: RateLimiterRedis | null = null;
let redisClient: Redis | null = null;

if (REDIS_URL) {
const redisClient = new Redis({
redisClient = new Redis({
port: 6379,
host: REDIS_URL,
enableOfflineQueue: false
enableOfflineQueue: false,
});

redisClient.on('error', (error: any) => {
Expand All @@ -18,10 +19,10 @@ if (REDIS_URL) {

const opts = {
storeClient: redisClient,
points: 40, // Number of total points
duration: 2, // Per second(s)
execEvenly: false, // Do not delay actions evenly
blockDuration: 0, // Do not block the caller if consumed more than points
points: 40, // Number of total points
duration: 2, // Per second(s)
execEvenly: false, // Do not delay actions evenly
blockDuration: 0, // Do not block the caller if consumed more than points
keyPrefix: 'ensrl', // Assign unique keys for each limiters with different purposes
};

Expand All @@ -34,6 +35,12 @@ export async function rateLimitMiddleware(
next: NextFunction
) {
if (!rateLimiter) {
console.warn('Rate limiter not ready, skipping...');
return next();
}

if (redisClient?.status !== 'ready') {
console.warn('Redis client not ready, skipping...');
return next();
}

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,10 @@
dns-packet "^5.6.1"
typescript-logging "^1.0.1"

"@ensdomains/ens-avatar@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@ensdomains/ens-avatar/-/ens-avatar-1.0.0.tgz#731b02477f88c0abc3e2132465f1c4a427682bd2"
integrity sha512-coz6kMnQJAHxWTQ/fLGxYiJy8m5xURxMndrKKfTHZDw7rlSoVjXYywAhrasr3Vu8e2IqeLjSGVAb5KZArN7chQ==
"@ensdomains/ens-avatar@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@ensdomains/ens-avatar/-/ens-avatar-1.0.3.tgz#f9f6922f60e7d30552b8a32fed39d17cabc65d91"
integrity sha512-iNJfhzJMhyXJTdtGs518X2dTC39sD3TKZ68q0QgUnv7T8jPBlJCcREUrHnZy/NuW6H+fmZl5xihFparfAjI8cg==
dependencies:
"@ethersproject/contracts" "^5.7.0"
"@ethersproject/providers" "^5.7.0"
Expand Down

0 comments on commit f5b7905

Please sign in to comment.