Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
feat(csi-48): removed content-length header, moved http-request as de…
Browse files Browse the repository at this point in the history
…ps to ispa
  • Loading branch information
geka-evk committed Jun 12, 2024
1 parent 0da16bc commit 15b1934
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 32 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"start": "node dist/index.js",
"start:build": "npm run build && npm start",
"start:dev": "ts-node -r dotenv/config -P ./tsconfig.json src/index.ts",
"start:unauth": "NODE_TLS_REJECT_UNAUTHORIZED=0 npm run start:dev",
"start:tls": "ts-node -r dotenv/config -P ./tsconfig.json src/tlsExample.ts",
"test": "npm run test:unit",
"test:unit": "jest --testMatch='**/unit/**/*.test.ts'",
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ import { name, version } from '../package.json';
export const SERVICE_NAME = `${name}@${version}`;

export const PROXY_HEADER = 'FSPIOP-Proxy';
export const AUTH_HEADER = 'Authorization';
16 changes: 13 additions & 3 deletions src/domain/ISPAService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import config from '../config';
import { PROXY_HEADER } from '../constants';
import { ISPAServiceInterface, ISPAServiceDeps, ILogger, ProxyHandlerInput } from './types';
import { PROXY_HEADER, AUTH_HEADER } from '../constants';
import { ISPAServiceInterface, ISPAServiceDeps, ILogger, IncomingRequestDetails } from './types';

const { PROXY_DFSP_ID } = config.get(); // or pass it as a parameter in ctor?

Expand All @@ -11,18 +11,28 @@ export class ISPAService implements ISPAServiceInterface {
this.log = deps.logger.child(ISPAService.name);
}

getProxyTarget(input: ProxyHandlerInput) {
getProxyTarget(input: IncomingRequestDetails) {
const { pathname, search } = input.url;
const { baseUrl } = input.proxyDetails;

delete input.headers['content-length'];
// todo: clarify, why without removing content-length header request just stuck
const token = this.getBearerToken();

const proxyTarget = {
url: `${baseUrl}${pathname}${search}`,
headers: {
...input.headers,
[PROXY_HEADER]: PROXY_DFSP_ID,
[AUTH_HEADER]: `Bearer ${token}`,
},
};
this.log.verbose('proxyTarget: ', proxyTarget);
return proxyTarget;
}

private getBearerToken() {
// todo: implement token retrieval
return 'TOKEN_NOT_IMPLEMENTED_YET';
}
}
13 changes: 6 additions & 7 deletions src/domain/InterSchemeProxyAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,21 @@
--------------
**********/

import { iISPA, ISPADeps, ProxyHandlerInput } from './types';
import { httpRequest } from '../infra'; // todo: avoid this dependency (pass in ctor
import { IProxyAdapter, ISPADeps, IncomingRequestDetails } from './types';

export class InterSchemeProxyAdapter implements iISPA {
export class InterSchemeProxyAdapter implements IProxyAdapter {
constructor(private readonly deps: ISPADeps) {
this.handleProxyRequest = this.handleProxyRequest.bind(this);
}

async handleProxyRequest(input: ProxyHandlerInput) {
const { ispaService, logger } = this.deps;
async handleProxyRequest(input: IncomingRequestDetails) {
const { ispaService, httpRequest, logger } = this.deps;
const proxyTarget = ispaService.getProxyTarget(input);

// todo: think, if it's better to move the logic to ISPAService
// todo: think, if it's ok to use the same agent to call both hubs
const response = await httpRequest({
url: proxyTarget.url,
// headers: proxyTarget.headers,
headers: proxyTarget.headers,
method: input.method,
data: input.payload,
});
Expand Down
23 changes: 16 additions & 7 deletions src/domain/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { URL } from 'node:url';
import { ServerInfo, Server } from '@hapi/hapi';
import { LogMethods, LogContext } from '../utils/types';

type Headers = Record<string, string>;

export type ProxyDetails = {
baseUrl: string;
};
Expand All @@ -11,9 +13,7 @@ export type ProxyTarget = {
headers: Headers;
};

type Headers = Record<string, string>;

export type ProxyHandlerInput = {
export type IncomingRequestDetails = {
url: URL; // incoming url
method: string;
headers: Headers;
Expand All @@ -27,23 +27,23 @@ export type ProxyHandlerResponse = {
headers?: unknown;
};

export type ProxyHandlerFn = (args: ProxyHandlerInput) => Promise<ProxyHandlerResponse>;
export type ProxyHandlerFn = (args: IncomingRequestDetails) => Promise<ProxyHandlerResponse>;

export interface iISPA {
// todo: find better name
export interface IProxyAdapter {
start: () => Promise<void>;
stop: () => Promise<void>;
handleProxyRequest: ProxyHandlerFn;
}

export interface ISPAServiceInterface {
getProxyTarget: (args: ProxyHandlerInput) => ProxyTarget;
getProxyTarget: (args: IncomingRequestDetails) => ProxyTarget;
}

export type ISPADeps = {
ispaService: ISPAServiceInterface;
httpServerA: IHttpServer;
httpServerB: IHttpServer;
httpRequest: HttpRequest;
logger: ILogger;
};

Expand All @@ -52,6 +52,15 @@ export type ISPAServiceDeps = {
// todo: add axios instance here
};

export type HttpRequestOptions = {
url: string;
method: string;
headers: Headers;
data?: unknown; // rename to payload?
};

export type HttpRequest = (options: HttpRequestOptions) => Promise<ProxyHandlerResponse>;

export interface ILogger extends LogMethods {
child(context?: LogContext): ILogger;
}
Expand Down
7 changes: 4 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
******/

import config from './config';
import { ISPAService, InterSchemeProxyAdapter, iISPA } from './domain';
import { createHttpServers } from './infra';
import { InterSchemeProxyAdapter, ISPAService } from './domain';
import { createHttpServers, httpRequest } from './infra';
import { startingProcess, loggerFactory } from './utils';

let proxyAdapter: iISPA;
let proxyAdapter: InterSchemeProxyAdapter;

const start = async () => {
const logger = loggerFactory(`ISPA-${config.get('PROXY_DFSP_ID')}`);
Expand All @@ -37,6 +37,7 @@ const start = async () => {
ispaService,
httpServerA,
httpServerB,
httpRequest,
logger,
});
await proxyAdapter.start();
Expand Down
9 changes: 1 addition & 8 deletions src/infra/httpRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import https from 'node:https';
import axios from 'axios';

import config from '../config';
import { ProxyHandlerResponse } from '../domain/types';
import { HttpRequestOptions, ProxyHandlerResponse } from '../domain/types';
import { loggerFactory } from '../utils';
import { ProxyTlsAgent } from './types';
import { readCertsFromFile } from './readCertsFromFile';
Expand All @@ -20,13 +20,6 @@ const createTlsProxyAgent = (): ProxyTlsAgent => {

const httpsAgent = createTlsProxyAgent();

export type HttpRequestOptions = {
url: string;
method: string;
// headers: Record<string, string>;
data?: unknown;
};

export const httpRequest = async (options: HttpRequestOptions): Promise<ProxyHandlerResponse> => {
try {
const result = await axios({
Expand Down
4 changes: 2 additions & 2 deletions src/infra/httpServer/plugins/loggingPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const loggingPlugin: Plugin<PluginOptions> = {
received,
};
Object.assign(req.app, { context });
logger.info(`[--> req] ${method.toUpperCase()} ${path}`, context);
logger.info(`[==> req] ${method.toUpperCase()} ${path}`, context);

return h.continue;
},
Expand All @@ -38,7 +38,7 @@ export const loggingPlugin: Plugin<PluginOptions> = {
if (statusCode >= 300) {
logger.warn('bad response:', response);
}
logger.info(`[<-- ${statusCode}][${responseTimeSec} s] ${method.toUpperCase()} ${path}`, context);
logger.info(`[<== ${statusCode}][${responseTimeSec} s] ${method.toUpperCase()} ${path}`, context);

return h.continue;
},
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const mockBearerToken = () => 'TOKEN_NOT_IMPLEMENTED_YET';
// todo: update after implement token retrieval
6 changes: 5 additions & 1 deletion test/unit/domain/ISPAService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@

import { ISPAService, ISPAServiceInterface } from '#src/domain';
import { loggerFactory } from '#src/utils';
import { PROXY_HEADER } from '#src/constants';
import { PROXY_HEADER, AUTH_HEADER } from '#src/constants';
import config from '#src/config';

// import * as fixtures from '#test/fixtures';

describe('ISPAService Tests -->', () => {
const logger = loggerFactory('test');

Expand All @@ -41,6 +43,7 @@ describe('ISPAService Tests -->', () => {
const incomingUrl = new URL(`http://localhost:12345${pathWithSearchParams}`);
const headers = { h: 'h1' };
const { baseUrl } = config.get('hubBConfig');
const token = 'TOKEN_NOT_IMPLEMENTED_YET'; // todo: update after implement token retrieval

const proxyDetails = service.getProxyTarget({
url: incomingUrl,
Expand All @@ -53,6 +56,7 @@ describe('ISPAService Tests -->', () => {
expect(proxyDetails.headers).toEqual({
...headers,
[PROXY_HEADER]: config.get('PROXY_DFSP_ID'),
[AUTH_HEADER]: `Bearer ${token}`,
});
});
});

0 comments on commit 15b1934

Please sign in to comment.