backend: implement HttpContextService and middleware for managing HTTP context. Refactor base URL retrieval logic
This commit is contained in:
parent
8894174eb9
commit
43839fdb9d
@ -8,6 +8,7 @@ import {
|
||||
FrontendEventService,
|
||||
GCSService,
|
||||
GCSStorageProvider,
|
||||
HttpContextService,
|
||||
LiveKitService,
|
||||
LivekitWebhookService,
|
||||
LoggerService,
|
||||
@ -52,6 +53,7 @@ export const registerDependencies = () => {
|
||||
container.bind(DistributedEventService).toSelf().inSingletonScope();
|
||||
container.bind(MutexService).toSelf().inSingletonScope();
|
||||
container.bind(TaskSchedulerService).toSelf().inSingletonScope();
|
||||
container.bind(HttpContextService).toSelf().inSingletonScope();
|
||||
|
||||
configureStorage(MEET_BLOB_STORAGE_MODE);
|
||||
container.bind(StorageFactory).toSelf().inSingletonScope();
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
rejectRequestFromMeetError
|
||||
} from '../models/error.model.js';
|
||||
import { AuthService, LoggerService, TokenService, UserService } from '../services/index.js';
|
||||
import { getCookieOptions } from '../utils/cookie-utils.js';
|
||||
import { getCookieOptions } from '../utils/index.js';
|
||||
|
||||
export const login = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
rejectRequestFromMeetError
|
||||
} from '../models/error.model.js';
|
||||
import { LoggerService, ParticipantService, RoomService, TokenService } from '../services/index.js';
|
||||
import { getCookieOptions } from '../utils/cookie-utils.js';
|
||||
import { getCookieOptions } from '../utils/index.js';
|
||||
|
||||
export const generateParticipantToken = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
|
||||
@ -3,7 +3,6 @@ import { Request, Response } from 'express';
|
||||
import { Readable } from 'stream';
|
||||
import { container } from '../config/index.js';
|
||||
import INTERNAL_CONFIG from '../config/internal-config.js';
|
||||
import { getBaseUrl } from '../environment.js';
|
||||
import { RecordingHelper } from '../helpers/index.js';
|
||||
import {
|
||||
errorRecordingNotFound,
|
||||
@ -13,6 +12,7 @@ import {
|
||||
rejectRequestFromMeetError
|
||||
} from '../models/error.model.js';
|
||||
import { LoggerService, MeetStorageService, RecordingService } from '../services/index.js';
|
||||
import { getBaseUrl } from '../utils/index.js';
|
||||
|
||||
export const startRecording = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
@ -125,10 +125,7 @@ export const stopRecording = async (req: Request, res: Response) => {
|
||||
const recordingService = container.get(RecordingService);
|
||||
|
||||
const recordingInfo = await recordingService.stopRecording(recordingId);
|
||||
res.setHeader(
|
||||
'Location',
|
||||
`${getBaseUrl()}${INTERNAL_CONFIG.API_BASE_PATH_V1}/recordings/${recordingId}`
|
||||
);
|
||||
res.setHeader('Location', `${getBaseUrl()}${INTERNAL_CONFIG.API_BASE_PATH_V1}/recordings/${recordingId}`);
|
||||
return res.status(202).json(recordingInfo);
|
||||
} catch (error) {
|
||||
handleError(res, error, `stopping recording '${recordingId}'`);
|
||||
|
||||
@ -10,10 +10,9 @@ import {
|
||||
import { Request, Response } from 'express';
|
||||
import { container } from '../config/index.js';
|
||||
import INTERNAL_CONFIG from '../config/internal-config.js';
|
||||
import { getBaseUrl } from '../environment.js';
|
||||
import { handleError } from '../models/error.model.js';
|
||||
import { LoggerService, ParticipantService, RoomService } from '../services/index.js';
|
||||
import { getCookieOptions } from '../utils/cookie-utils.js';
|
||||
import { getBaseUrl, getCookieOptions } from '../utils/index.js';
|
||||
|
||||
export const createRoom = async (req: Request, res: Response) => {
|
||||
const logger = container.get(LoggerService);
|
||||
|
||||
@ -20,7 +20,7 @@ export const {
|
||||
SERVER_CORS_ORIGIN = '*',
|
||||
MEET_LOG_LEVEL = 'info',
|
||||
MEET_NAME_ID = 'openviduMeet',
|
||||
MEET_BASE_URL = `http://localhost:${SERVER_PORT}`,
|
||||
MEET_BASE_URL = '',
|
||||
|
||||
/**
|
||||
* Authentication configuration
|
||||
@ -86,13 +86,6 @@ export const {
|
||||
ENABLED_MODULES = ''
|
||||
} = process.env;
|
||||
|
||||
/**
|
||||
* Gets the base URL without trailing slash
|
||||
*/
|
||||
export const getBaseUrl = (): string => {
|
||||
return MEET_BASE_URL.endsWith('/') ? MEET_BASE_URL.slice(0, -1) : MEET_BASE_URL;
|
||||
};
|
||||
|
||||
export function checkModuleEnabled() {
|
||||
if (MODULES_FILE) {
|
||||
const moduleName = MODULE_NAME;
|
||||
|
||||
15
backend/src/middlewares/http-context.middleware.ts
Normal file
15
backend/src/middlewares/http-context.middleware.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { container } from '../config/dependency-injector.config.js';
|
||||
import { HttpContextService } from '../services/index.js';
|
||||
|
||||
export const httpContextMiddleware = (req: Request, res: Response, next: NextFunction) => {
|
||||
const httpContextService = container.get(HttpContextService);
|
||||
httpContextService.setContext(req);
|
||||
|
||||
// Clear context after response is finished
|
||||
res.on('finish', () => {
|
||||
httpContextService.clearContext();
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
@ -1,4 +1,5 @@
|
||||
export * from './content-type.middleware.js';
|
||||
export * from './http-context.middleware.js';
|
||||
export * from './auth.middleware.js';
|
||||
export * from './room.middleware.js';
|
||||
export * from './participant.middleware.js';
|
||||
|
||||
@ -5,7 +5,7 @@ import express, { Express, Request, Response } from 'express';
|
||||
import { initializeEagerServices, registerDependencies } from './config/index.js';
|
||||
import INTERNAL_CONFIG from './config/internal-config.js';
|
||||
import { SERVER_CORS_ORIGIN, SERVER_PORT, logEnvVars } from './environment.js';
|
||||
import { jsonSyntaxErrorHandler } from './middlewares/index.js';
|
||||
import { httpContextMiddleware, jsonSyntaxErrorHandler } from './middlewares/index.js';
|
||||
import {
|
||||
authRouter,
|
||||
configRouter,
|
||||
@ -24,7 +24,7 @@ import {
|
||||
internalApiHtmlFilePath,
|
||||
publicApiHtmlFilePath,
|
||||
webcomponentBundlePath
|
||||
} from './utils/path-utils.js';
|
||||
} from './utils/path.utils.js';
|
||||
|
||||
const createApp = () => {
|
||||
const app: Express = express();
|
||||
@ -41,10 +41,14 @@ const createApp = () => {
|
||||
|
||||
// Serve static files
|
||||
app.use(express.static(frontendDirectoryPath));
|
||||
|
||||
app.use(express.json());
|
||||
app.use(jsonSyntaxErrorHandler);
|
||||
app.use(cookieParser());
|
||||
|
||||
// Middleware to set HTTP context
|
||||
app.use(httpContextMiddleware);
|
||||
|
||||
// Public API routes
|
||||
app.use(`${INTERNAL_CONFIG.API_BASE_PATH_V1}/docs`, (_req: Request, res: Response) =>
|
||||
res.sendFile(publicApiHtmlFilePath)
|
||||
|
||||
39
backend/src/services/http-context.service.ts
Normal file
39
backend/src/services/http-context.service.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { Request } from 'express';
|
||||
import { injectable } from 'inversify';
|
||||
import { SERVER_PORT } from '../environment.js';
|
||||
|
||||
@injectable()
|
||||
export class HttpContextService {
|
||||
private baseUrl: string;
|
||||
|
||||
constructor() {
|
||||
this.baseUrl = this.getDefaultBaseUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current HTTP context from the request
|
||||
*/
|
||||
setContext(req: Request): void {
|
||||
const protocol = req.protocol;
|
||||
const host = req.get('host');
|
||||
this.baseUrl = `${protocol}://${host}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base URL from the current context
|
||||
*/
|
||||
getBaseUrl(): string {
|
||||
return this.baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the current context
|
||||
*/
|
||||
clearContext(): void {
|
||||
this.baseUrl = this.getDefaultBaseUrl();
|
||||
}
|
||||
|
||||
private getDefaultBaseUrl(): string {
|
||||
return `http://localhost:${SERVER_PORT}`;
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ export * from './redis.service.js';
|
||||
export * from './distributed-event.service.js';
|
||||
export * from './mutex.service.js';
|
||||
export * from './task-scheduler.service.js';
|
||||
export * from './http-context.service.js';
|
||||
|
||||
export * from './storage/index.js';
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import {
|
||||
internalError,
|
||||
OpenViduMeetError
|
||||
} from '../models/error.model.js';
|
||||
import { chunkArray } from '../utils/array.utils.js';
|
||||
import { chunkArray } from '../utils/index.js';
|
||||
import { LoggerService } from './index.js';
|
||||
|
||||
@injectable()
|
||||
|
||||
@ -3,7 +3,6 @@ import { inject, injectable } from 'inversify';
|
||||
import ms from 'ms';
|
||||
import { Readable } from 'stream';
|
||||
import {
|
||||
getBaseUrl,
|
||||
MEET_INITIAL_ADMIN_PASSWORD,
|
||||
MEET_INITIAL_ADMIN_USER,
|
||||
MEET_INITIAL_API_KEY,
|
||||
@ -20,6 +19,7 @@ import {
|
||||
OpenViduMeetError,
|
||||
RedisKeyName
|
||||
} from '../../models/index.js';
|
||||
import { getBaseUrl } from '../../utils/index.js';
|
||||
import { LoggerService, MutexService, RedisService } from '../index.js';
|
||||
import { StorageFactory } from './storage.factory.js';
|
||||
import { StorageKeyBuilder, StorageProvider } from './storage.interface.js';
|
||||
|
||||
3
backend/src/utils/index.ts
Normal file
3
backend/src/utils/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './array.utils.js';
|
||||
export * from './cookie.utils.js';
|
||||
export * from './url.utils.js';
|
||||
21
backend/src/utils/url.utils.ts
Normal file
21
backend/src/utils/url.utils.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { container } from '../config/dependency-injector.config.js';
|
||||
import { MEET_BASE_URL } from '../environment.js';
|
||||
import { HttpContextService } from '../services/http-context.service.js';
|
||||
|
||||
/**
|
||||
* Returns the base URL for the application.
|
||||
*
|
||||
* If the global `MEET_BASE_URL` variable is defined, it returns its value,
|
||||
* ensuring there is no trailing slash. Otherwise, it retrieves the base URL
|
||||
* from the `HttpContextService` instance.
|
||||
*
|
||||
* @returns {string} The base URL as a string.
|
||||
*/
|
||||
export const getBaseUrl = (): string => {
|
||||
if (MEET_BASE_URL) {
|
||||
return MEET_BASE_URL.endsWith('/') ? MEET_BASE_URL.slice(0, -1) : MEET_BASE_URL;
|
||||
}
|
||||
|
||||
const httpContextService = container.get(HttpContextService);
|
||||
return httpContextService.getBaseUrl();
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user