Skip to content

Commit

Permalink
added gzip handler in middleware (#1290)
Browse files Browse the repository at this point in the history
* added gzip handler in middleware

* added gzip handler specific to request middleware

* refactored gzip handler
  • Loading branch information
nitish-egov authored Dec 19, 2024
1 parent b373ac4 commit b69ba14
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
2 changes: 1 addition & 1 deletion health-services/project-factory/src/server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class App {
extended: true,
})
);
this.app.use(bodyParser.json());
// this.app.use(bodyParser.json());
this.app.use(tracingMiddleware);
this.app.use(requestMiddleware);
this.app.use(errorLogger);
Expand Down
36 changes: 36 additions & 0 deletions health-services/project-factory/src/server/utils/gzipHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Request } from "express";
import * as zlib from "zlib";

export const handleGzipRequest = async (req: Request): Promise<void> => {
const buffers: Buffer[] = [];

// Collect data chunks from the request
await new Promise<void>((resolve, reject) => {
req.on("data", (chunk: any) => buffers.push(chunk));
req.on("end", resolve);
req.on("error", reject);
});

// Concatenate and decompress the data
const gzipBuffer = Buffer.concat(buffers);
try {
const decompressedData = await decompressGzip(gzipBuffer);
req.body = decompressedData; // Assign the parsed data to req.body
} catch (err: any) {
throw new Error(`Failed to process Gzip data: ${err.message}`);
}
};

// Helper function to decompress Gzip data
const decompressGzip = (gzipBuffer: Buffer): Promise<any> => {
return new Promise((resolve, reject) => {
zlib.gunzip(gzipBuffer, (err, result) => {
if (err) return reject(err);
try {
resolve(JSON.parse(result.toString()));
} catch (parseErr) {
reject(new Error("Invalid JSON format in decompressed data"));
}
});
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NextFunction, Request, Response } from "express"; // Importing necessar
const { object, string } = require("yup"); // Importing object and string from yup for schema validation
import { errorResponder } from "../genericUtils"; // Importing errorResponder function from genericUtils
import { logger } from "../logger";
import { handleGzipRequest } from "../gzipHandler";

// Defining the request schema using yup
const requestSchema = object({
Expand All @@ -13,18 +14,21 @@ const requestSchema = object({
});

// Middleware function to validate request payload
const requestMiddleware = (req: Request, res: Response, next: NextFunction) => {
const requestMiddleware = async (req: Request, res: Response, next: NextFunction) => {
try {
logger.info(`RECEIVED A HTTP REQUEST :: URI :: ${req.url}`);
// Check if the content type is 'application/json'
const contentType = req.headers['content-type'];
if (!contentType || !contentType.split(';').map(part => part.trim()).includes('application/json')) {
// If content type is not 'application/json', throw Unsupported Media Type error
let e: any = new Error("Unsupported Media Type: Content-Type should be 'application/json'");
if (!contentType || !contentType.split(';').map(part => part.trim()).includes('application/json') && !contentType.split(';').map(part => part.trim()).includes('application/gzip')) {
// If content type is not 'application/json' or 'application/gzip', throw Unsupported Media Type error
let e: any = new Error("Unsupported Media Type: Content-Type should be 'application/json' or 'application/gzip'");
e = Object.assign(e, { status: 415, code: "UNSUPPORTED_MEDIA_TYPE" });
errorResponder(e, req, res, 415)
return;
}
if (contentType === 'application/gzip') {
await handleGzipRequest(req);
}
// Check if tenantId is missing in RequestInfo.userInfo
if (!req?.body?.RequestInfo?.userInfo?.tenantId) {
// If tenantId is missing, throw Validation Error
Expand All @@ -37,10 +41,11 @@ const requestMiddleware = (req: Request, res: Response, next: NextFunction) => {
requestSchema.validateSync(req.body.RequestInfo);
// If validation succeeds, proceed to the next middleware
next();
} catch (error) {
}
catch (error) {
// If an error occurs during validation process, handle the error using errorResponder function
errorResponder(error, req, res);
}
};

export default requestMiddleware; // Exporting the requestMiddleware function for use in Express middleware chain
export default requestMiddleware; // Exporting the requestMiddleware function for use in Express middleware chain

0 comments on commit b69ba14

Please sign in to comment.