mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2026-07-04 19:11:47 +00:00
refactor
- remove Redis - handle proxing of non-success response
This commit is contained in:
+25
-1
@@ -19,6 +19,9 @@ const debug = require('debug')('jambonz:sbc-inbound');
|
||||
const MS_TEAMS_USER_AGENT = 'Microsoft.PSTNHub.SIPProxy';
|
||||
const MS_TEAMS_SIP_ENDPOINT = 'sip.pstnhub.microsoft.com';
|
||||
const IMMUTABLE_HEADERS = ['via', 'from', 'to', 'call-id', 'cseq', 'max-forwards', 'content-length'];
|
||||
const NONCOPYABLE_RESPONSE_HEADERS = [
|
||||
'via', 'from', 'to', 'call-id', 'cseq', 'contact', 'content-length', 'content-type'
|
||||
];
|
||||
|
||||
/**
|
||||
* this is to make sure the outgoing From has the number in the incoming From
|
||||
@@ -281,6 +284,7 @@ class CallSession extends Emitter {
|
||||
proxy,
|
||||
headers,
|
||||
responseHeaders,
|
||||
passFailure: false,
|
||||
proxyRequestHeaders: [
|
||||
'all',
|
||||
'-Authorization',
|
||||
@@ -355,12 +359,16 @@ class CallSession extends Emitter {
|
||||
this.stats.increment('sbc.terminations', tags);
|
||||
this.logger.info(`call failed to connect to feature server with ${err.status}`);
|
||||
|
||||
/* capture trace_id from the feature server's error response for the CDR */
|
||||
/* capture trace_id and application_sid from the feature server's error response for the CDR. */
|
||||
if (this.req.locals.cdr && err.res) {
|
||||
const trace_id = err.res.get('X-Trace-ID');
|
||||
if (trace_id) {
|
||||
this.req.locals.cdr.trace_id = trace_id;
|
||||
}
|
||||
const application_sid = err.res.get('X-Application-Sid');
|
||||
if (application_sid) {
|
||||
this.req.locals.cdr.application_sid = application_sid;
|
||||
}
|
||||
}
|
||||
|
||||
this.emit('failed');
|
||||
@@ -377,6 +385,22 @@ class CallSession extends Emitter {
|
||||
.catch((err) => this.logger.error(err, 'Error decrementing call counts'));
|
||||
|
||||
}
|
||||
|
||||
/* manually proxy the failure response to UAS so that the trace_id/application_sid capture above runs before
|
||||
res.end fires (which is what triggers the failure-CDR writer). */
|
||||
if (err.message !== 'call canceled' && !this.res.finalResponseSent) {
|
||||
if (err instanceof SipError && err.res) {
|
||||
const headers = {};
|
||||
Object.keys(err.res.headers || {}).forEach((h) => {
|
||||
if (!NONCOPYABLE_RESPONSE_HEADERS.includes(h)) headers[h] = err.res.headers[h];
|
||||
});
|
||||
this.res.send(err.status, err.reason, {headers});
|
||||
}
|
||||
else {
|
||||
this.res.send(err.status || 500, err.reason);
|
||||
}
|
||||
}
|
||||
|
||||
this.srf.endSession(this.req);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-27
@@ -31,7 +31,6 @@ module.exports = function(srf, logger) {
|
||||
queryCallLimits,
|
||||
} = srf.locals.dbHelpers;
|
||||
const {stats, writeCdrs, lookupAuthCarriersForAccountAndSP, getApplicationForDidAndCarrier} = srf.locals;
|
||||
const {retrieveKey} = srf.locals.realtimeDbHelpers;
|
||||
|
||||
const initLocals = (req, res, next) => {
|
||||
const callId = req.get('Call-ID');
|
||||
@@ -60,32 +59,16 @@ module.exports = function(srf, logger) {
|
||||
|
||||
/* write cdr for non-success response here */
|
||||
res.once('end', ({status}) => {
|
||||
if (req.locals.cdr && req.locals.cdr.account_sid && status > 200 && 401 !== status) {
|
||||
const writeCdr = () => {
|
||||
const trunk = ['trunk', 'teams'].includes(req.locals.originator) ?
|
||||
req.locals.carrier : req.locals.originator;
|
||||
writeCdrs({...req.locals.cdr,
|
||||
terminated_at: Date.now(),
|
||||
termination_reason: status === 487 === status ? 'caller abandoned' : 'failed',
|
||||
sip_status: status,
|
||||
trunk,
|
||||
...(req.locals.application_sid && {application_sid: req.locals.application_sid})
|
||||
}).catch((err) => logger.error({err}, 'Error writing cdr for call failure'));
|
||||
};
|
||||
|
||||
/* if trace_id is missing, look it up from Redis using the original Call-ID */
|
||||
if (!req.locals.cdr.trace_id) {
|
||||
retrieveKey(`callid:${callId}`)
|
||||
.then((trace_id) => {
|
||||
if (trace_id) req.locals.cdr.trace_id = trace_id;
|
||||
return;
|
||||
})
|
||||
.catch((err) => logger.debug({err, callId}, 'Error retrieving trace_id from Redis'))
|
||||
.finally(() => writeCdr())
|
||||
.catch(() => {});
|
||||
} else {
|
||||
writeCdr();
|
||||
}
|
||||
if (req.locals.cdr && req.locals.cdr.account_sid && status > 200 && 401 !== status) {
|
||||
const trunk = ['trunk', 'teams'].includes(req.locals.originator) ?
|
||||
req.locals.carrier : req.locals.originator;
|
||||
writeCdrs({...req.locals.cdr,
|
||||
terminated_at: Date.now(),
|
||||
termination_reason: status === 487 ? 'caller abandoned' : 'failed',
|
||||
sip_status: status,
|
||||
trunk,
|
||||
...(req.locals.application_sid && {application_sid: req.locals.application_sid})
|
||||
}).catch((err) => logger.error({err}, 'Error writing cdr for call failure'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user