Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added gzip handler in middleware #1290

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
63 changes: 63 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,63 @@
import zlib from "zlib";
import { Request, Response, NextFunction } from "express";
const { object, string } = require("yup"); // Importing object and string from yup for schema validation
import { logger } from "./logger";
import { errorResponder } from "./genericUtils";


const requestSchema = object({
apiId: string().nullable(), // Nullable string field for API ID
action: string().nullable(), // Nullable string field for action
msgId: string().required(), // Required string field for message ID
authToken: string().nullable(), // Nullable string field for authentication token
userInfo: object().nonNullable() // Non-nullable object field for user information
});

export const handleGzipRequest = (
req: Request,
res: Response,
next: NextFunction
) => {
const buffers: Buffer[] = [];

req.on("data", (chunk) => buffers.push(chunk));
req.on("end", () => {
try {
const gzipBuffer = Buffer.concat(buffers);
logger.info("Gzip buffer size:", gzipBuffer.length);

// Decompress the Gzip data
zlib.gunzip(gzipBuffer, (err, decompressedBuffer) => {
if (err) {
logger.error("Error decompressing Gzip file:", err);
res.status(500).send("Invalid Gzip file");
return;
}

try {
// Convert the decompressed buffer to string and parse as JSON
const jsonData = decompressedBuffer.toString().trim();
logger.info("Decompressed JSON data:", jsonData);
const parsedData = JSON.parse(jsonData);
req.body = parsedData;
// Validation 1: Check if tenantId is present
if (!req?.body?.RequestInfo?.userInfo?.tenantId) {
let e: any = new Error("RequestInfo.userInfo.tenantId is missing");
e = Object.assign(e, { status: 400, code: "VALIDATION_ERROR" });
return errorResponder(e, req, res, 400); // Return error response if tenantId is missing
}

// Validation 2: Validate the request payload against the defined schema
requestSchema.validateSync(req.body.RequestInfo); // Assuming validateSync is synchronous
next(); // Proceed to next middleware or controller if valid
} catch (parseError) {
logger.error("Error parsing JSON data:", parseError);
res.status(500).send("Invalid JSON in Gzip content");
}
});
} catch (err) {
logger.error("Error processing Gzip content:", err);
res.status(500).send("Invalid Gzip content");
}
});
};
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 @@ -18,29 +19,33 @@ const requestMiddleware = (req: Request, res: Response, next: NextFunction) => {
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;
}
// Check if tenantId is missing in RequestInfo.userInfo
if (!req?.body?.RequestInfo?.userInfo?.tenantId) {
// If tenantId is missing, throw Validation Error
let e: any = new Error("RequestInfo.userInfo.tenantId is missing");
e = Object.assign(e, { status: 400, code: "VALIDATION_ERROR" });
errorResponder(e, req, res, 400)
return;
if (contentType === 'application/gzip') {
return handleGzipRequest(req, res, next);
jagankumar-egov marked this conversation as resolved.
Show resolved Hide resolved
} else {
// Check if tenantId is missing in RequestInfo.userInfo
if (!req?.body?.RequestInfo?.userInfo?.tenantId) {
// If tenantId is missing, throw Validation Error
let e: any = new Error("RequestInfo.userInfo.tenantId is missing");
e = Object.assign(e, { status: 400, code: "VALIDATION_ERROR" });
errorResponder(e, req, res, 400)
return;
}
// Validate request payload against the defined schema
requestSchema.validateSync(req.body.RequestInfo);
// If validation succeeds, proceed to the next middleware
next();
}
// Validate request payload against the defined schema
requestSchema.validateSync(req.body.RequestInfo);
// If validation succeeds, proceed to the next middleware
next();
} 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
Loading