Skip to content
Permalink
Browse files

Make optional the reason phrase when reply-ing

Take the reason phrase corresponding with the cause code if none is given as parameter.
If non is given as parameter and no corresponding reason phrase exist, take '  ' (double space) as reason phrase.
- Yes, more than one server will complain. Let's see.
  • Loading branch information
jmillan committed Nov 23, 2012
1 parent 025b381 commit 35e5874e5c0e8e14aa8082bf8cc690c90a060dc0
Showing with 122 additions and 102 deletions.
  1. +4 −4 src/Dialogs.js
  2. +4 −4 src/Message.js
  3. +9 −4 src/SIPMessage.js
  4. +7 −7 src/SanityCheck.js
  5. +11 −11 src/Session.js
  6. +3 −3 src/Transactions.js
  7. +7 −7 src/UA.js
  8. +77 −62 src/constants.js
@@ -139,7 +139,7 @@ JsSIP.Dialog.prototype = {
} else if(request.method !== JsSIP.c.INVITE && request.cseq < this.remote_seqnum) {
//Do not try to reply to an ACK request.
if (request.method !== JsSIP.c.ACK) {
request.reply(500, JsSIP.c.REASON_500);
request.reply(500);
}
return false;
} else if(request.cseq > this.remote_seqnum) {
@@ -152,17 +152,17 @@ JsSIP.Dialog.prototype = {
if(request.cseq < this.remote_seqnum) {
if(this.state === JsSIP.c.DIALOG_EARLY) {
var retryAfter = (Math.random() * 10 | 0) + 1;
request.reply(500, JsSIP.c.REASON_500, [
request.reply(500, JsSIP.c.REASON_PHRASE[500], [
'Retry-After:'+ retryAfter
]);
} else {
request.reply(500, JsSIP.c.REASON_500);
request.reply(500);
}
return false;
}
// RFC3261 14.2
if(this.state === JsSIP.c.DIALOG_EARLY) {
request.reply(491, JsSIP.c.REASON_491);
request.reply(491);
return false;
}
// RFC3261 12.2.2 Replace the dialog`s remote target URI
@@ -167,14 +167,14 @@ JsSIP.Message.prototype.init_incoming = function(request) {
this.remote_identity = request.s('from').uri;

this.accept = function() {
request.reply(200, JsSIP.c.REASON_200);
request.reply(200);
};

this.reject = function(status_code, reason_phrase) {
if (status_code && reason_phrase) {
request.reply(status_code, reason_phrase);
} else {
request.reply(480, JsSIP.c.REASON_480);
request.reply(480);
}
};

@@ -188,9 +188,9 @@ JsSIP.Message.prototype.init_incoming = function(request) {
transaction = this.ua.transactions.nist[request.via_branch];

if (transaction && (transaction.state === JsSIP.c.TRANSACTION_TRYING || transaction.state === JsSIP.c.TRANSACTION_PROCEEDING)) {
request.reply(200, JsSIP.c.REASON_200);
request.reply(200);
}
} else {
request.reply(415, JsSIP.c.REASON_415, ["Accept: text/plain, text/html"]);
request.reply(415, JsSIP.c.REASON_PHRASE[415], ["Accept: text/plain, text/html"]);

This comment has been minimized.

Copy link
@ibc

ibc Nov 24, 2012

Member

Is it valid this?:

request.reply(415, null, ["Accept: text/plain, text/html"]);

This comment has been minimized.

Copy link
@jmillan

jmillan Nov 26, 2012

Author Member

Yes, it is valid.

In fact, there is no sense on specifying the reason phrase if it does match the status code.., I'll update it.

Thanks

This comment has been minimized.

Copy link
@jmillan

jmillan Nov 26, 2012

Author Member

Done in 73e4dcb

}
};
@@ -343,14 +343,16 @@ JsSIP.IncomingRequest.prototype = new JsSIP.IncomingMessage();
* @param {Function} [onFailure] onFailure callback
*/
JsSIP.IncomingRequest.prototype.reply = function(code, reason, extraHeaders, body, onSuccess, onFailure) {
var rr, vias, header, length, idx,
response = 'SIP/2.0 ' + code + ' ' + reason + '\r\n',
var rr, vias, header, length, idx, response,
to = this.getHeader('To'),
r = 0,
v = 0;

reason = reason || JsSIP.c.REASON_PHRASE[code] || ' ';
extraHeaders = extraHeaders || [];

response = 'SIP/2.0 ' + code + ' ' + reason + '\r\n';

if(this.method === JsSIP.c.INVITE && code > 100 && code <= 200) {
rr = this.countHeader('record-route');

@@ -401,10 +403,13 @@ JsSIP.IncomingRequest.prototype.reply = function(code, reason, extraHeaders, bod
* @param {String} reason reason phrase
*/
JsSIP.IncomingRequest.prototype.reply_sl = function(code, reason) {
var to,
response = 'SIP/2.0 ' + code + ' ' + reason + '\r\n',
var to, response,
vias = this.countHeader('via');

reason = reason || JsSIP.c.REASON_PHRASE[code] || ' ';

response = 'SIP/2.0 ' + code + ' ' + reason + '\r\n';

for(var v = 0; v < vias; v++) {
response += 'Via: ' + this.getHeader('via', v) + '\r\n';
}
@@ -37,15 +37,15 @@ JsSIP.sanityCheck = (function() {
// Sanity Check functions for requests
function rfc3261_8_2_2_1() {
if(message.s('to').scheme !== 'sip') {
reply(416, JsSIP.c.REASON_416);
reply(416);
return false;
}
}

function rfc3261_16_3_4() {
if(!message.to_tag) {
if(message.call_id.substr(0, 5) === ua.configuration.jssip_id) {
reply(482, JsSIP.c.REASON_482);
reply(482);
return false;
}
}
@@ -56,7 +56,7 @@ JsSIP.sanityCheck = (function() {
contentLength = message.getHeader('content-length');

if(len < contentLength) {
reply(400, JsSIP.c.REASON_400);
reply(400);
return false;
}
}
@@ -76,7 +76,7 @@ JsSIP.sanityCheck = (function() {
for(idx in ua.transactions.ist) {
tr = ua.transactions.ist[idx];
if(tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) {
reply(482, JsSIP.c.REASON_482);
reply(482);
return false;
}
}
@@ -89,7 +89,7 @@ JsSIP.sanityCheck = (function() {
for(idx in ua.transactions.nist) {
tr = ua.transactions.nist[idx];
if(tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) {
reply(482, JsSIP.c.REASON_482);
reply(482);
return false;
}
}
@@ -136,9 +136,9 @@ JsSIP.sanityCheck = (function() {
}

// Reply
function reply(status_code, reason_phrase) {
function reply(status_code) {
var to,
response = "SIP/2.0 " + status_code + " " + reason_phrase + "\r\n",
response = "SIP/2.0 " + status_code + " " + JsSIP.c.REASON_PHRASE[status_code] + "\r\n",
via_length = message.countHeader('via'),
idx = 0;

@@ -310,7 +310,7 @@ JsSIP.Session.prototype.receiveRequest = function(request) {
// Transaction layer already responded 487 to the initial request.

// Reply 200 to CANCEL
request.reply(200, JsSIP.c.REASON_200);
request.reply(200);

/*
* Terminate the whole session in case the user didn't accept nor reject the
@@ -332,7 +332,7 @@ JsSIP.Session.prototype.receiveRequest = function(request) {
break;
case JsSIP.c.BYE:
if(this.status === JsSIP.c.SESSION_CONFIRMED) {
request.reply(200, JsSIP.c.REASON_200);
request.reply(200);
this.ended('remote', request, JsSIP.c.causes.BYE);
}
break;
@@ -408,7 +408,7 @@ JsSIP.Session.prototype.receiveInitialRequest = function(ua, request) {
return;
}

request.reply(200, JsSIP.c.REASON_200, [
request.reply(200, JsSIP.c.REASON_PHRASE[200], [
'Contact: <' + session.contact + '>'],
sdp,
// onSuccess
@@ -437,7 +437,7 @@ JsSIP.Session.prototype.receiveInitialRequest = function(ua, request) {

onMediaFailure = function(e) {
// Unable to get User Media
request.reply(486, JsSIP.c.REASON_486);
request.reply(486);
session.failed('local', null, JsSIP.c.causes.USER_DENIED_MEDIA_ACCESS);
};

@@ -446,7 +446,7 @@ JsSIP.Session.prototype.receiveInitialRequest = function(ua, request) {
* peerConnection.setRemoteDescription throws an exception
*/
console.log(JsSIP.c.LOG_SERVER_INVITE_SESSION +'PeerConnection Creation Failed: --'+e+'--');
request.reply(488, JsSIP.c.REASON_488);
request.reply(488);
session.failed('remote', request, JsSIP.c.causes.BAD_MEDIA_DESCRIPTION);
};

@@ -461,7 +461,7 @@ JsSIP.Session.prototype.receiveInitialRequest = function(ua, request) {
*/
this.reject = function() {
if (this.status === JsSIP.c.SESSION_WAITING_FOR_ANSWER) {
request.reply(486, JsSIP.c.REASON_486);
request.reply(486);

this.failed('local', null, JsSIP.c.causes.REJECTED);
}
@@ -474,12 +474,12 @@ JsSIP.Session.prototype.receiveInitialRequest = function(ua, request) {
if (this.status !== JsSIP.c.SESSION_TERMINATED) {
this.progress('local');

request.reply(180, JsSIP.c.REASON_180, [
request.reply(180, JsSIP.c.REASON_PHRASE[180], [
'Contact: <' + this.contact + '>'
]);
}
} else {
request.reply(415, JsSIP.c.REASON_415);
request.reply(415);
}
};

@@ -639,7 +639,7 @@ JsSIP.Session.prototype.ackTimeout = function() {
*/
JsSIP.Session.prototype.expiresTimeout = function(request) {
if(this.status === JsSIP.c.SESSION_WAITING_FOR_ANSWER) {
request.reply(487, JsSIP.c.REASON_487);
request.reply(487);

this.failed('system', null, JsSIP.c.causes.EXPIRES);
}
@@ -660,7 +660,7 @@ JsSIP.Session.prototype.invite2xxRetransmission = function(retransmissions, requ
if((retransmissions * JsSIP.Timers.T1) <= JsSIP.Timers.T2) {
retransmissions += 1;

request.reply(200, JsSIP.c.REASON_200, [
request.reply(200, JsSIP.c.REASON_PHRASE[200], [
'Contact: <' + this.contact + '>'],
body);

@@ -678,7 +678,7 @@ JsSIP.Session.prototype.invite2xxRetransmission = function(retransmissions, requ
* @private
*/
JsSIP.Session.prototype.userNoAnswerTimeout = function(request) {
request.reply(408, JsSIP.c.REASON_408);
request.reply(408);

this.failed('local',null, JsSIP.c.causes.NO_ANSWER);
};
@@ -552,7 +552,7 @@ JsSIP.Transactions.InviteServerTransaction = function(request, ua) {

this.reliableProvisionalTimer = null;

request.reply(100, JsSIP.c.REASON_100);
request.reply(100);
};
JsSIP.Transactions.InviteServerTransaction.prototype = new InviteServerTransactionPrototype();

@@ -622,13 +622,13 @@ JsSIP.Transactions.checkTransaction = function(ua, request) {
tr = ua.transactions.ist[request.via_branch];
if(tr) {
if(tr.state === JsSIP.c.TRANSACTION_PROCEEDING) {
tr.request.reply(487, JsSIP.c.REASON_487);
tr.request.reply(487);
return false;
} else {
return true;
}
} else {
request.reply_sl(481, JsSIP.c.REASON_481);
request.reply_sl(481);
return true;
}
break;
@@ -362,7 +362,7 @@ JsSIP.UA.prototype.receiveRequest = function(request) {
//Check that Ruri points to us
if(request.ruri.user !== this.configuration.user) {
console.log(JsSIP.c.LOG_UA +'Request URI does not point to us');
request.reply_sl(404, JsSIP.c.REASON_404);
request.reply_sl(404);
return;
}

@@ -384,13 +384,13 @@ JsSIP.UA.prototype.receiveRequest = function(request) {
* They are processed as if they had been received outside the dialog.
*/
if(method === JsSIP.c.OPTIONS) {
request.reply(200, JsSIP.c.REASON_200, [
request.reply(200, JsSIP.c.REASON_PHRASE[200], [
'Allow: '+ JsSIP.utils.getAllowedMethods(this),
'Accept: '+ JsSIP.c.ACCEPTED_BODY_TYPES
]);
} else if (method === JsSIP.c.MESSAGE) {
if (!this.checkEvent('newMessage') || this.listeners('newMessage').length === 0) {
request.reply(405, JsSIP.c.REASON_405, ['Allow: '+ JsSIP.utils.getAllowedMethods(this)]);
request.reply(405, JsSIP.c.REASON_PHRASE[405], ['Allow: '+ JsSIP.utils.getAllowedMethods(this)]);
return;
}
message = new JsSIP.Message(this);
@@ -401,7 +401,7 @@ JsSIP.UA.prototype.receiveRequest = function(request) {
if(!request.to_tag) {
if(!this.registrator || (this.registrator && !this.registrator.registered)) {
// High user does not want to be contacted
request.reply(410, JsSIP.c.REASON_410);
request.reply(410);
return;
}

@@ -416,7 +416,7 @@ JsSIP.UA.prototype.receiveRequest = function(request) {
break;
case JsSIP.c.BYE:
// Out of dialog BYE received
request.reply(481, JsSIP.c.REASON_481);
request.reply(481);
break;
case JsSIP.c.CANCEL:
session = this.findSession(request);
@@ -433,7 +433,7 @@ JsSIP.UA.prototype.receiveRequest = function(request) {
*/
break;
default:
request.reply(405, JsSIP.c.REASON_405);
request.reply(405);
break;
}
}
@@ -459,7 +459,7 @@ JsSIP.UA.prototype.receiveRequest = function(request) {
*/
else {
if(method !== JsSIP.c.ACK) {
request.reply(481, JsSIP.c.REASON_481);
request.reply(481);
}
}
}

2 comments on commit 35e5874

@saghul

This comment has been minimized.

Copy link
Contributor

saghul replied Nov 23, 2012

Why not simply add "Unknown" and avoid possible problems? This is asking for trouble.

@jmillan

This comment has been minimized.

Copy link
Member Author

jmillan replied Nov 23, 2012

You are right, and that's bad. I should be free to respond with a two spaced reason phrase.

I got carried away by the moment :-)

Please sign in to comment.
You can’t perform that action at this time.