-
Notifications
You must be signed in to change notification settings - Fork 868
Open
Labels
Description
Checks
- I understand project setup issues should be asked on StackOverflow or in GitHub Discussions.
- I updated to latest
http-proxy-middleware
.
Describe the bug (be clear and concise)
I don't know why but we we use route as path like /forestfire/socket.io it will throw invalid header in some of my socket.io microservice but not other why i am not sure?
server.ts
import express, { Application, NextFunction, Request, Response } from 'express'
import { createProxyMiddleware } from 'http-proxy-middleware'
import cors from 'cors'
import cookieParser from 'cookie-parser'
import setHeaders from 'libs/set-headers'
import { PORT } from 'config/config'
import { ClientRequest, IncomingMessage, Server } from 'http'
import routes from 'config/routes'
import accessConfig, { verifyToken } from 'libs/access-config'
import EventEmitter from 'events'
// default is 12 is not enough for this project cause we use a lot of proxy
EventEmitter.defaultMaxListeners = 20
const proxyReq = (openAccess: boolean | Array<string> | undefined) => (proxyReq: ClientRequest, req: Request, res: Response) => {
// accessConfig(openAccess)(req, res) // check if user has access to the route
if(openAccess === true) return;
if(Array.isArray(openAccess)){
if(openAccess.includes(req.path)) return;
}
// check auth token;
const token = req.cookies.alert_token
if(token){
const data = verifyToken(token)
if(data) proxyReq.setHeader('data', JSON.stringify({ user: data}))
}
}
const proxyRes = (proxyRes: IncomingMessage, req: Request, res: Response) => {
// for(let oldKey in proxyRes.headers){
// if(oldKey === 'data') continue;
// let newkey = oldKey.replace(/((?:^|-)[a-z])/g, function(val) { return val.toUpperCase() });
// newkey = newkey.replace(/(-Os-)/g, function (val) { return val.toUpperCase() });
// proxyRes.headers[newkey] = proxyRes.headers[oldKey];
// delete proxyRes.headers[oldKey];
// }
}
const start = (): Promise<Server> => {
return new Promise((resolve, reject) => {
const app: Application = express();
app.use(cors({
origin: ['http://localhost:3000', 'http://localhost:3001', 'http://192.168.4.161:3000'],
credentials: true,
}))
app.use(cookieParser())
app.use(setHeaders)
routes.forEach(({ route, target, pathRewrite, openAccess }) => {
let rewrite_path: Record<string, string> | undefined = undefined
// HPM (HTTP PROXY MIDDLEWARE)
if(!target) return console.log(`[HPM] Proxy target not found for route: ${route} -> ${target}`)
// add logs for each proxy
console.log(`[HPM] Proxy created: ${route} -> ${target}`)
if(pathRewrite) {
const [key, value] = pathRewrite
rewrite_path = { [key]: value }
// console.log(`[HPM] Proxy rewrite rule created: "${key}" ~> "${value}"`)
}
// if(route === '/'){
// // use this / routes for the main frontend app if we not use like this it will thorow Invalid frame header
// app.use(route, createProxyMiddleware({ target, changeOrigin: true, logger: console, ws: false, on: { proxyReq: proxyReq(openAccess), proxyRes } }))
// return;
// }
const proxyMiddleware = createProxyMiddleware({
target: target,
pathFilter: route,
changeOrigin: true,
pathRewrite: rewrite_path,
// timeout: 1000 * 60, // 1 minute
// proxyTimeout: 1000 * 60 * 2, // default 2 minute
ws: route === '/' ? true : true, // for websocket proxy
logger: console,
on: {
proxyReq: proxyReq(openAccess),
proxyRes
}
})
app.use(proxyMiddleware)
})
const server = app.listen(PORT, () => resolve(server))
})
}
export { start }
routes.ts
import services from 'config/services'
const authNotAllow = [
'/auth/login', '/auth/create', '/auth/verify-recaptcha', '/auth/user-access',
'/auth/forgot-password', '/auth/change-password', "/auth/update-user", "/auth/refresh-page",
"/auth/socket.io"
]
const helperAuthNotAllow = [
'/helper/location',
'/helper/test', '/helper/wsm-date', '/helper/basin', '/helper/district', '/helper/province', '/helper/municipality', '/helper/nepal-boundary', '/helper/seiscomp-station', '/helper/earthquake-event',
'/helper/wms-forecast', '/helper/wms-forecast2', '/helper/wms-satellite',
'/helper/river_layer', '/helper/boundaries/province', '/helper/boundaries/district', '/helper/boundaries/municipality', '/helper/geoglows/get-comid', '/helper/geoglows/comid-list'
]
const _createTuple = (key: string, value: string): [string, string] => [key, value]
interface Routes {
service: string,
route: string,
target?: string
pathRewrite?: [string, string],
openAccess?: boolean | string[],
// ws?: boolean
}
const routes: Routes[] = [
// { service: 'meroalert', route: '/mero-alert', target: services.meroalert, pathRewrite: _createTuple('/mero_alert', ''), openAccess: true },
// { service: 'meteoblue', route: '/meteoblue', target: services.meteoblue, openAccess: true },
// { service: 'wrf-forecast', route: '/wrf-forecast', target: services.wrfForecast, pathRewrite: _createTuple('/wrf-forecast', ''), openAccess: true },
// { service: 'geoserver', route: '/geoserver', target: services.geoserver, openAccess: true },
// { service: 'seiscomp-history', route: '/seiscomp-history', target: services.seiscomp_history, openAccess: true},
// { service: "seiscomp-xml", route: "/seiscomp-xml", target: services.seiscomp_xml, openAccess: true, pathRewrite: _createTuple('/seiscomp-xml', '') },
// { service: 'seiscomp', route: '/seiscomp/socket.io', target: services.seiscomp, openAccess: true },
// { service: 'lightning-threats', route: '/lightning-threats/socket.io', target: services.lightning_threats, openAccess: true },
// { service: 'lightning', route: '/lightning/socket.io', target: services.lightning, openAccess: true },
{ service: 'helper', route: '/helper', target: services.helper, pathRewrite: _createTuple('/helper', ''), openAccess: helperAuthNotAllow},
{ service: 'personal-alert', route: '/personal-alert', target: services.personal_alert, openAccess: false },
// { service: 'forestfire', route: '/forestfire/socket.io', target: services.forestfire, openAccess: true },
// { service: 'cap', route: '/cap/socket.io', target: services.cap, openAccess: true },
// { service: 'auth', route: '/auth/socket.io', target: services.auth, openAccess: true },
{ service: 'auth', route: '/auth/google', target: services.auth, openAccess: true },
{ service: 'auth', route: '/auth', target: services.auth, openAccess: authNotAllow },
{ service: 'personal-dashboard', route: '/personal-dashboard', target: services.personal_dashbarod, pathRewrite: _createTuple('/personal_dashboard', ''), openAccess: true },
{ service: 'aws_dashboard', route: '/aws_dashboard', target: services.aws_dashboard, pathRewrite: _createTuple("/aws_dashboard", ''), openAccess: true },
{ service: 'hs_dashboard', route: '/hs_dashboard', target: services.hs_dashboard, pathRewrite: _createTuple("/hs_dashboard", ''), openAccess: true },
{ service: 'watershed_dashboard', route: '/watershed_dashboard', target: services.watershed_dashboard, pathRewrite: _createTuple("/watershed_dashboard", ''), openAccess: true },
{ service: 'alertnepal', route: '/', target: services.alertnepal, openAccess: true },
]
export default routes;
this is my code
when i disable websocket in / path it, the invalid headers error resolved but i like to tell you this why its happening i don't know please review once
or tell me the if i am doing somthing wrong
its happen to /auth/socket.io only i don't know why but in /auth microservice credentials is true.
but when i directly connect that invalid header error is not coming
Step-by-step reproduction instructions
1. use the following code which is provided in decription.
2. ...
Expected behavior (be clear and concise)
http proxy is worked fine & other socket.io microservice is working also good but, which /auth/socket.io it will throw warning when you enable ws in / routes
How is http-proxy-middleware used in your project?
i have personal project which have more then 12 microservices so i used for centralized the services.
What http-proxy-middleware configuration are you using?
latest http-proxy-middleware (V3)
const proxyMiddleware = createProxyMiddleware({
target: target,
pathFilter: route,
changeOrigin: true,
pathRewrite: rewrite_path,
// timeout: 1000 * 60, // 1 minute
// proxyTimeout: 1000 * 60 * 2, // default 2 minute
ws: route === '/' ? true : true, // for websocket proxy
logger: console,
on: {
proxyReq: proxyReq(openAccess),
proxyRes
}
})
What OS/version and node/version are you seeing the problem?
Ubuntu 24.04.2 LTS x86_64 & node 23
Additional context (optional)
No response