const http=require('node:http'); function postLoopback({port,route,token,body,signal,maxResponseBytes=2*1024*1024}){ if(!Number.isInteger(Number(port))||Number(port)<1||Number(port)>65535||!/^\/[a-z0-9/-]+$/i.test(route)||typeof token!=='string')return Promise.reject(Error('Local endpoint rejected')); const payload=Buffer.from(JSON.stringify(body)); return new Promise((resolve,reject)=>{ // Direct TCP avoids environment/global proxy routing of private content. const request=http.request({hostname:'127.0.0.1',port:Number(port),path:route,method:'POST',agent:false,signal, headers:{authorization:`Bearer ${token}`,'content-type':'application/json','content-length':payload.length}},response=>{ if(response.statusCode>=300&&response.statusCode<400){response.resume();reject(Error('Local redirects rejected'));return;} let size=0;const chunks=[];response.on('error',reject); response.on('data',chunk=>{size+=chunk.length;if(size>maxResponseBytes){response.destroy();request.destroy();reject(Error('Local response budget exceeded'));}else chunks.push(chunk);}); response.on('end',()=>{try{resolve({status:response.statusCode,body:JSON.parse(Buffer.concat(chunks).toString('utf8'))});}catch{reject(Error('Invalid local JSON response'));}}); }); request.on('error',reject);request.end(payload); }); } module.exports={postLoopback};