add logger and fix url preview

This commit is contained in:
tamaina 2023-01-03 13:28:58 +00:00
parent 0f06a9ed0e
commit 0048f1538c
2 changed files with 59 additions and 13 deletions

View File

@ -9,6 +9,8 @@ import { StatusError } from '@/misc/status-error.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import * as undici from 'undici'; import * as undici from 'undici';
import { LookupFunction } from 'node:net'; import { LookupFunction } from 'node:net';
import { LoggerService } from '@/core/LoggerService.js';
import type Logger from '@/logger.js';
// true to allow, false to deny // true to allow, false to deny
export type IpChecker = (ip: string) => boolean; export type IpChecker = (ip: string) => boolean;
@ -32,27 +34,61 @@ export class UndiciFetcher {
private proxyBypassHosts: string[]; private proxyBypassHosts: string[];
private userAgent: string | undefined; private userAgent: string | undefined;
constructor(args: { private logger: Logger | undefined;
agentOptions: undici.Agent.Options;
proxy?: { constructor(
uri: string; args: {
options?: undici.Agent.Options; // Override of agentOptions agentOptions: undici.Agent.Options;
proxy?: {
uri: string;
options?: undici.Agent.Options; // Override of agentOptions
},
proxyBypassHosts?: string[];
userAgent?: string;
}, },
proxyBypassHosts?: string[]; logger?: Logger,
userAgent?: string; ) {
}) { this.logger = logger;
this.logger?.debug('UndiciFetcher constructor', args);
this.proxyBypassHosts = args.proxyBypassHosts ?? []; this.proxyBypassHosts = args.proxyBypassHosts ?? [];
this.userAgent = args.userAgent; this.userAgent = args.userAgent;
this.nonProxiedAgent = new undici.Agent({ this.nonProxiedAgent = new undici.Agent({
...args.agentOptions, ...args.agentOptions,
connect: (process.env.NODE_ENV !== 'production' && typeof args.agentOptions.connect !== 'function')
? (options, cb) => {
undici.buildConnector(args.agentOptions.connect as undici.buildConnector.BuildOptions)(options, (err, socket) => {
if (err) {
this.logger?.debug(`Socket error`, err);
cb(new Error(`Error while socket connecting\n${err}`), null);
return;
}
this.logger?.debug(`Socket connected: ${socket.localPort} => ${socket.remoteAddress}`);
cb(null, socket);
});
} : args.agentOptions.connect,
}); });
this.agent = args.proxy this.agent = args.proxy
? new undici.ProxyAgent({ ? new undici.ProxyAgent({
...args.agentOptions, ...args.agentOptions,
...args.proxy.options, ...args.proxy.options,
uri: args.proxy.uri, uri: args.proxy.uri,
connect: (process.env.NODE_ENV !== 'production' && typeof (args.proxy?.options?.connect ?? args.agentOptions.connect) !== 'function')
? (options, cb) => {
undici.buildConnector((args.proxy?.options?.connect ?? args.agentOptions.connect) as undici.buildConnector.BuildOptions)(options, (err, socket) => {
if (err) {
this.logger?.debug(`Socket error`, err);
cb(new Error(`Error while socket connecting\n${err}`), null);
return;
}
this.logger?.debug(`Socket connected: ${socket.localPort} => ${socket.remoteAddress}`);
cb(null, socket);
});
} : (args.proxy?.options?.connect ?? args.agentOptions.connect),
}) })
: this.nonProxiedAgent; : this.nonProxiedAgent;
} }
@ -144,10 +180,15 @@ export class HttpRequestService {
public readonly clientDefaults: undici.Agent.Options; public readonly clientDefaults: undici.Agent.Options;
private maxSockets: number; private maxSockets: number;
private logger: Logger;
constructor( constructor(
@Inject(DI.config) @Inject(DI.config)
private config: Config, private config: Config,
private loggerService: LoggerService,
) { ) {
this.logger = this.loggerService.getLogger('http-request');
this.dnsCache = new CacheableLookup({ this.dnsCache = new CacheableLookup({
maxTtl: 3600, // 1hours maxTtl: 3600, // 1hours
errorTtl: 30, // 30secs errorTtl: 30, // 30secs
@ -172,14 +213,14 @@ export class HttpRequestService {
this.maxSockets = Math.max(256, this.config.deliverJobConcurrency ?? 128); this.maxSockets = Math.max(256, this.config.deliverJobConcurrency ?? 128);
this.defaultFetcher = new UndiciFetcher(this.getStandardUndiciFetcherConstructorOption()); this.defaultFetcher = new UndiciFetcher(this.getStandardUndiciFetcherConstructorOption(), this.logger);
this.fetch = this.defaultFetcher.fetch; this.fetch = this.defaultFetcher.fetch;
this.getHtml = this.defaultFetcher.getHtml; this.getHtml = this.defaultFetcher.getHtml;
this.defaultJsonFetcher = new UndiciFetcher(this.getStandardUndiciFetcherConstructorOption({ this.defaultJsonFetcher = new UndiciFetcher(this.getStandardUndiciFetcherConstructorOption({
maxResponseSize: 1024 * 256, maxResponseSize: 1024 * 256,
})); }), this.logger);
this.getJson = this.defaultJsonFetcher.getJson; this.getJson = this.defaultJsonFetcher.getJson;
@ -263,25 +304,30 @@ export class HttpRequestService {
@bindThis @bindThis
public getConnectorWithIpCheck(connector: undici.buildConnector.connector, checkIp: IpChecker): undici.buildConnector.connectorAsync { public getConnectorWithIpCheck(connector: undici.buildConnector.connector, checkIp: IpChecker): undici.buildConnector.connectorAsync {
return (options, cb) => { return (options, cb) => {
this.logger.debug('socket connecting...')
connector(options, (err, socket) => { connector(options, (err, socket) => {
if (err) { if (err) {
cb(err, null); this.logger.error(`Socket error`, err)
cb(new Error(`Error while socket connecting\n${err}`), null);
return; return;
} }
if (socket.remoteAddress == undefined) { if (socket.remoteAddress == undefined) {
this.logger.error(`Socket error: remoteAddress is undefined`);
cb(new Error('remoteAddress is undefined (maybe socket destroyed)'), null); cb(new Error('remoteAddress is undefined (maybe socket destroyed)'), null);
return; return;
} }
// allow // allow
if (checkIp(socket.remoteAddress)) { if (checkIp(socket.remoteAddress)) {
this.logger.debug(`Socket connected (ip ok): ${socket.localPort} => ${socket.remoteAddress}`);
cb(null, socket); cb(null, socket);
return; return;
} }
socket.destroy(); this.logger.error('IP is not allowed', socket);
cb(new StatusError('IP is not allowed', 403, 'IP is not allowed'), null); cb(new StatusError('IP is not allowed', 403, 'IP is not allowed'), null);
socket.destroy();
}); });
}; };
} }

View File

@ -1,5 +1,5 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import * as summaly from 'summaly'; import summaly from 'summaly';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { UsersRepository } from '@/models/index.js'; import type { UsersRepository } from '@/models/index.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';