[asterisk-commits] dvossel: branch 1.4 r283960 - /branches/1.4/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Aug 27 17:17:32 CDT 2010
Author: dvossel
Date: Fri Aug 27 17:17:26 2010
New Revision: 283960
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=283960
Log:
Parse all "Accept" headers for SIP SUBSCRIBE requests.
(closes issue #17758)
Reported by: ibc
Patches:
multiple_accept_headers_1.4.diff uploaded by dvossel (license 671)
Modified:
branches/1.4/channels/chan_sip.c
Modified: branches/1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/channels/chan_sip.c?view=diff&rev=283960&r1=283959&r2=283960
==============================================================================
--- branches/1.4/channels/chan_sip.c (original)
+++ branches/1.4/channels/chan_sip.c Fri Aug 27 17:17:26 2010
@@ -16155,7 +16155,6 @@
int firststate = AST_EXTENSION_REMOVED;
struct sip_peer *authpeer = NULL;
const char *eventheader = get_header(req, "Event"); /* Get Event package name */
- const char *accept = get_header(req, "Accept");
int resubscribe = (p->subscribed != NONE);
char *temp, *event;
@@ -16282,56 +16281,96 @@
if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
unsigned int pidf_xml;
+ const char *accept;
+ int start = 0;
+ enum subscriptiontype subscribed = NONE;
+ const char *unknown_acceptheader = NULL;
if (authpeer) /* No need for authpeer here */
ASTOBJ_UNREF(authpeer, sip_destroy_peer);
/* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
-
- pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0;
-
- /* Older versions of Polycom firmware will claim pidf+xml, but really
- * they only support xpidf+xml. */
- if (pidf_xml && strstr(p->useragent, "Polycom")) {
- p->subscribed = XPIDF_XML;
- } else if (pidf_xml) {
- p->subscribed = PIDF_XML; /* RFC 3863 format */
- } else if (strstr(accept, "application/dialog-info+xml")) {
- p->subscribed = DIALOG_INFO_XML;
- /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
- } else if (strstr(accept, "application/cpim-pidf+xml")) {
- p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
- } else if (strstr(accept, "application/xpidf+xml")) {
- p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
- } else if (ast_strlen_zero(accept)) {
+ accept = __get_header(req, "Accept", &start);
+ while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
+ pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0;
+
+ /* Older versions of Polycom firmware will claim pidf+xml, but really
+ * they only support xpidf+xml. */
+ if (pidf_xml && strstr(p->useragent, "Polycom")) {
+ subscribed = XPIDF_XML;
+ } else if (pidf_xml) {
+ subscribed = PIDF_XML; /* RFC 3863 format */
+ } else if (strstr(accept, "application/dialog-info+xml")) {
+ subscribed = DIALOG_INFO_XML;
+ /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
+ } else if (strstr(accept, "application/cpim-pidf+xml")) {
+ subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
+ } else if (strstr(accept, "application/xpidf+xml")) {
+ subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
+ } else {
+ unknown_acceptheader = accept;
+ }
+ /* check to see if there is another Accept header present */
+ accept = __get_header(req, "Accept", &start);
+ }
+
+ if (!start) {
if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
transmit_response(p, "489 Bad Event", req);
-
- ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
- p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: "
+ "stateid: %d, laststate: %d, dialogver: %d, subscribecont: "
+ "'%s', subscribeuri: '%s'\n",
+ p->stateid,
+ p->laststate,
+ p->dialogver,
+ p->subscribecontext,
+ p->subscribeuri);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
return 0;
}
/* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
- } else {
+ } else if (subscribed == NONE) {
/* Can't find a format for events that we know about */
char mybuf[200];
- snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept);
+ if (!ast_strlen_zero(unknown_acceptheader)) {
+ snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", unknown_acceptheader);
+ } else {
+ snprintf(mybuf, sizeof(mybuf), "489 Bad Event");
+ }
transmit_response(p, mybuf, req);
-
- ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
- accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format:"
+ "'%s' pvt: subscribed: %d, stateid: %d, laststate: %d,"
+ "dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
+ unknown_acceptheader,
+ (int)p->subscribed,
+ p->stateid,
+ p->laststate,
+ p->dialogver,
+ p->subscribecontext,
+ p->subscribeuri);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
return 0;
- }
- } else if (!strcmp(event, "message-summary")) {
- if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) {
+ } else {
+ p->subscribed = subscribed;
+ }
+ } else if (!strcmp(event, "message-summary")) {
+ int start = 0;
+ int found_supported = 0;
+ const char *acceptheader;
+
+ acceptheader = __get_header(req, "Accept", &start);
+ while (!found_supported && !ast_strlen_zero(acceptheader)) {
+ found_supported = strcmp(acceptheader, "application/simple-message-summary") ? 0 : 1;
+ if (!found_supported && (option_debug > 2)) {
+ ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
+ }
+ acceptheader = __get_header(req, "Accept", &start);
+ }
+ if (start && !found_supported) {
/* Format requested that we do not support */
transmit_response(p, "406 Not Acceptable", req);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
if (authpeer) /* No need for authpeer here */
ASTOBJ_UNREF(authpeer, sip_destroy_peer);
return 0;
More information about the asterisk-commits
mailing list