瀏覽代碼

improved handling presence documents in PA
- added generating of cpim-pidf+xml (draft version 07)
- improved parsing Accept header fields
- clarified work with document types

Vaclav Kubart 20 年之前
父節點
當前提交
8e4e4fcb66
共有 4 個文件被更改,包括 118 次插入11 次删除
  1. 57 9
      lib/presence/pidf.c
  2. 3 2
      lib/presence/pidf.h
  3. 56 0
      parser/parse_content.c
  4. 2 0
      parser/parse_content.h

+ 57 - 9
lib/presence/pidf.c

@@ -44,7 +44,7 @@ static void doc_add_tuple(dstring_t *buf, presentity_info_t *p, presence_tuple_i
 	
 	
 	if (t->status == presence_tuple_open) dstr_append_zt(buf, "\t\t<status><basic>open</basic></status>\r\n");
 	if (t->status == presence_tuple_open) dstr_append_zt(buf, "\t\t<status><basic>open</basic></status>\r\n");
 	else dstr_append_zt(buf, "\t\t<status><basic>closed</basic></status>\r\n");
 	else dstr_append_zt(buf, "\t\t<status><basic>closed</basic></status>\r\n");
-	
+
 	dstr_append_zt(buf, "\t\t<contact priority=\"");
 	dstr_append_zt(buf, "\t\t<contact priority=\"");
 	sprintf(tmp, "%1.2f", t->priority);
 	sprintf(tmp, "%1.2f", t->priority);
 	dstr_append_zt(buf, tmp);
 	dstr_append_zt(buf, tmp);
@@ -70,14 +70,40 @@ static void doc_add_note(dstring_t *buf, presentity_info_t *p, presence_note_t *
 	dstr_append_zt(buf, "</note>\r\n");
 	dstr_append_zt(buf, "</note>\r\n");
 }
 }
 
 
-static void doc_add_presentity(dstring_t *buf, presentity_info_t *p)
+static void dstr_put_pres_uri(dstring_t *buf, str_t *uri)
+{
+	char *c;
+	int len = 0;
+	
+	if (!uri) return;
+	
+	c = str_strchr(uri, ':');
+	if (c) {
+		len = uri->len - (c - uri->s) - 1;
+		if (len > 0) c++;
+	}
+	else {
+		c = uri->s;
+		len = uri->len;
+	}
+	if (len > 0) {
+		dstr_append_zt(buf, "pres:");
+		dstr_append(buf, c, len);
+	}
+}
+
+static void doc_add_presentity(dstring_t *buf, presentity_info_t *p, int use_cpim_pidf_ns)
 {
 {
 	presence_tuple_info_t *t;
 	presence_tuple_info_t *t;
 	presence_note_t *n;
 	presence_note_t *n;
 
 
 	DEBUG_LOG("doc_add_presentity()\n");
 	DEBUG_LOG("doc_add_presentity()\n");
-	dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"");
-	dstr_append_str(buf, &p->presentity);
+	if (use_cpim_pidf_ns)
+		dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:cpim-pidf\" entity=\"");
+	else 
+		dstr_append_zt(buf, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"");
+	/* !!! there SHOULD be pres URI of presentity !!! */
+	dstr_put_pres_uri(buf, &p->presentity);
 	dstr_append_zt(buf, "\">\r\n");
 	dstr_append_zt(buf, "\">\r\n");
 	
 	
 	DEBUG_LOG("doc_add_presentity(): adding tuples\n");
 	DEBUG_LOG("doc_add_presentity(): adding tuples\n");
@@ -97,8 +123,7 @@ static void doc_add_presentity(dstring_t *buf, presentity_info_t *p)
 	dstr_append_zt(buf, "</presence>");
 	dstr_append_zt(buf, "</presence>");
 }
 }
 
 
-		
-int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type)
+int create_pidf_document_ex(presentity_info_t *p, str_t *dst, str_t *dst_content_type, int use_cpim_pidf_ns)
 {
 {
 	dstring_t buf;
 	dstring_t buf;
 	
 	
@@ -117,7 +142,7 @@ int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_ty
 	dstr_init(&buf, 2048);
 	dstr_init(&buf, 2048);
 	
 	
 	dstr_append_zt(&buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
 	dstr_append_zt(&buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
-	doc_add_presentity(&buf, p);
+	doc_add_presentity(&buf, p, use_cpim_pidf_ns);
 	
 	
 	dst->len = dstr_get_data_length(&buf);
 	dst->len = dstr_get_data_length(&buf);
 	dst->s = cds_malloc(dst->len);
 	dst->s = cds_malloc(dst->len);
@@ -128,6 +153,11 @@ int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_ty
 	return 0;
 	return 0;
 }
 }
 
 
+int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type)
+{
+	return create_pidf_document_ex(p, dst, dst_content_type, 0);
+}
+
 /* ------------------------------ PIDF document parsing ------------------------------ */
 /* ------------------------------ PIDF document parsing ------------------------------ */
 
 
 static char *pidf_ns = "urn:ietf:params:xml:ns:pidf";
 static char *pidf_ns = "urn:ietf:params:xml:ns:pidf";
@@ -272,8 +302,8 @@ static int read_presentity(xmlNode *root, presentity_info_t **dst, int ignore_ns
 	return res;
 	return res;
 }
 }
 
 
-/* libxml2 must be initialized before calling this function ! */
-int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len, int ignore_ns)
+/* ignore ns added for cpim-pidf+xml, draft version 07 (differs only in ns) */
+int parse_pidf_document_ex(presentity_info_t **dst, const char *data, int data_len, int ignore_ns)
 {
 {
 	int res = 0;
 	int res = 0;
 	xmlDocPtr doc;
 	xmlDocPtr doc;
@@ -299,3 +329,21 @@ int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len,
 	return res;
 	return res;
 }
 }
 
 
+/* libxml2 must be initialized before calling this function ! */
+int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len)
+{
+	return parse_pidf_document_ex(dst, data, data_len, 0);
+}
+
+/* --------------- CPIM_PIDF document creation/parsing ---------------- */
+
+int parse_cpim_pidf_document(presentity_info_t **dst, const char *data, int data_len)
+{
+	return parse_pidf_document_ex(dst, data, data_len, 1);
+}
+
+int create_cpim_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type)
+{
+	return create_pidf_document_ex(p, dst, dst_content_type, 1);
+}
+

+ 3 - 2
lib/presence/pidf.h

@@ -30,8 +30,9 @@
 #include <presence/pres_doc.h>
 #include <presence/pres_doc.h>
 
 
 int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type);
 int create_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type);
+int create_cpim_pidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type);
 
 
-/* ignore ns added for cpim-pidf+xml, draft version 07 (differs only in ns) */
-int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len, int ignore_ns);
+int parse_pidf_document(presentity_info_t **dst, const char *data, int data_len);
+int parse_cpim_pidf_document(presentity_info_t **dst, const char *data, int data_len);
 
 
 #endif
 #endif

+ 56 - 0
parser/parse_content.c

@@ -405,7 +405,63 @@ error:
 	return -1;
 	return -1;
 }
 }
 
 
+int parse_accept_body(struct hdr_field *hdr)
+{
+	static unsigned int mimes[MAX_MIMES_NR];
+	int nr_mimes;
+	unsigned int mime;
+	char *end;
+	char *ret;
+
+	if (!hdr) return -1;
+	
+	/* maybe the header is already parsed! */
+	if (hdr->parsed!=0) return 1;
+	
+	/* it seams we have to parse it! :-( */
+	ret = hdr->body.s;
+	end = ret + hdr->body.len;
+	nr_mimes = 0;
+	while (1){
+		ret = decode_mime_type(ret, end , &mime);
+		if (ret==0)
+			goto error;
+		/* a new mime was found  -> put it into array */
+		if (nr_mimes==MAX_MIMES_NR) {
+			LOG(L_ERR,"ERROR:parse_accept_hdr: Accept hdr contains more than"
+				" %d mime type -> buffer overflow!!\n",MAX_MIMES_NR);
+			goto error;
+		}
+		mimes[nr_mimes++] = mime;
+		/* is another mime following? */
+		if (ret==end )
+			break;
+		/* parse the mime separator ',' */
+		if (*ret!=',' || ret+1==end) {
+			LOG(L_ERR,"ERROR:parse_accept_hdr: parse error between mimes at "
+				"char <%x> (offset=%d) in <%.*s>!\n",
+				*ret, (int)(ret-hdr->body.s),
+				hdr->body.len, hdr->body.s);
+			goto error;
+		}
+		/* skip the ',' */
+		ret++;
+	}
+
+	/* copy and link the mime buffer into the message */
+	hdr->parsed = (void*)pkg_malloc((nr_mimes+1)*sizeof(int));
+	if (hdr->parsed==0) {
+		LOG(L_ERR,"ERROR:parse_accept: no more pkg memory\n");
+		goto error;
+	}
+	memcpy(hdr->parsed,mimes,nr_mimes*sizeof(int));
+	/* make the buffer null terminated */
+	((int*)hdr->parsed)[nr_mimes] = 0;
 
 
+	return 1;
+error:
+	return -1;
+}
 
 
 /* returns: > 0 ok
 /* returns: > 0 ok
  *          = 0 hdr not found
  *          = 0 hdr not found

+ 2 - 0
parser/parse_content.h

@@ -98,6 +98,8 @@ struct mime_type {
  */
  */
 int parse_content_type_hdr( struct sip_msg *msg);
 int parse_content_type_hdr( struct sip_msg *msg);
 
 
+int parse_accept_body(struct hdr_field *hdr);
+
 /*
 /*
  * parse the the body of the Accept header. It's values are also converted
  * parse the the body of the Accept header. It's values are also converted
  * as an null-terminated array of ints.
  * as an null-terminated array of ints.