First commit merge
This commit is contained in:
142
middleware/requestProcessor.js
Normal file
142
middleware/requestProcessor.js
Normal file
@@ -0,0 +1,142 @@
|
||||
const logger = require('../utils/logger');
|
||||
const RequestValidator = require('./validation');
|
||||
const UserAgentFilter = require('./userAgentFilter');
|
||||
|
||||
/**
|
||||
* Request Processing Pipeline - Equivalent to Kamailio's main request_route
|
||||
* This is the primary entry point for all SIP requests received by Drachtio
|
||||
*/
|
||||
class RequestProcessor {
|
||||
constructor(srf) {
|
||||
this.srf = srf;
|
||||
this.validator = new RequestValidator();
|
||||
this.uaFilter = new UserAgentFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle OPTIONS requests (equivalent to kamailio.cfg:297-301)
|
||||
*/
|
||||
handleOptions(req, res) {
|
||||
logger.info('[OPTIONS] Options request from %s:%s | Call-ID: %s',
|
||||
req.source_address, req.source_port, req.get('Call-ID'));
|
||||
res.send(200, 'OK');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle CANCEL requests (equivalent to kamailio.cfg:196-201)
|
||||
*/
|
||||
handleCancel(req, res) {
|
||||
const callId = req.get('Call-ID');
|
||||
logger.info('[CANCEL] CANCEL: Call-ID: %s', callId);
|
||||
|
||||
// Check if transaction exists
|
||||
if (this.srf.hasUacTransaction(callId)) {
|
||||
// Relay the CANCEL to the appropriate destination
|
||||
this.srf.createUacRequest('CANCEL', req.uri, {
|
||||
headers: {
|
||||
'Call-ID': callId,
|
||||
'CSeq': req.get('CSeq'),
|
||||
'From': req.get('From'),
|
||||
'To': req.get('To'),
|
||||
'Via': req.get('Via'),
|
||||
'Route': req.get('Route'),
|
||||
'Max-Forwards': req.get('Max-Forwards')
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
res.send(200, 'OK');
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error('[CANCEL] Failed to relay CANCEL: %s', err.message);
|
||||
res.send(500, 'Server Error');
|
||||
});
|
||||
} else {
|
||||
res.send(481, 'Transaction Does Not Exist');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle in-dialog requests (equivalent to kamailio.cfg:239-241)
|
||||
*/
|
||||
handleInDialog(req, res, next) {
|
||||
if (req.has('To') && req.getParsedHeader('to').params.tag && req.method !== 'INVITE') {
|
||||
logger.info('[WITHINDLG] %s request | Call-ID: %s', req.method, req.get('Call-ID'));
|
||||
// Pass to in-dialog handler
|
||||
next();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle presence-related requests (equivalent to kamailio.cfg:304)
|
||||
*/
|
||||
handlePresence(req, res) {
|
||||
if (req.method === 'PUBLISH' || req.method === 'SUBSCRIBE') {
|
||||
logger.info('[PRESENCE] %s request from %s:%s | Call-ID: %s',
|
||||
req.method, req.source_address, req.source_port, req.get('Call-ID'));
|
||||
res.send(404, 'Not here');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle requests that don't match specific routes (equivalent to kamailio.cfg:312-315)
|
||||
*/
|
||||
handleUnmatchedRequest(req, res) {
|
||||
logger.warn('[MAIN_ROUTE] No specific route found for method: %s to %s | Call-ID: %s',
|
||||
req.method, req.uri.user, req.get('Call-ID'));
|
||||
res.send(501, 'Not Implemented - No action found for destination or method');
|
||||
}
|
||||
|
||||
/**
|
||||
* Main request processing pipeline
|
||||
*/
|
||||
processRequest() {
|
||||
return (req, res, next) => {
|
||||
logger.debug('[REQUEST_PROCESSOR] Processing %s request from %s:%s',
|
||||
req.method, req.source_address, req.source_port);
|
||||
|
||||
// Apply validation middleware
|
||||
this.validator.middleware()(req, res, () => {
|
||||
// Apply User-Agent filtering
|
||||
this.uaFilter.middleware()(req, res, () => {
|
||||
// Handle specific method types
|
||||
switch (req.method) {
|
||||
case 'OPTIONS':
|
||||
this.handleOptions(req, res);
|
||||
break;
|
||||
|
||||
case 'CANCEL':
|
||||
this.handleCancel(req, res);
|
||||
break;
|
||||
|
||||
case 'REGISTER':
|
||||
// Pass to registration handler
|
||||
next();
|
||||
break;
|
||||
|
||||
case 'INVITE':
|
||||
// Pass to INVITE handler
|
||||
next();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Handle in-dialog requests
|
||||
this.handleInDialog(req, res, () => {
|
||||
// Check for presence requests
|
||||
if (!this.handlePresence(req, res)) {
|
||||
// If no specific handler, return error
|
||||
this.handleUnmatchedRequest(req, res);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RequestProcessor;
|
||||
Reference in New Issue
Block a user