Browse code

modules_k/xcap_server: Added support for the org.openmobilealliance.xcap-directory auid

- Directory listing worked out on-the-fly based on DB contents

Peter Dunkley authored on 25/10/2012 16:33:46
Showing 3 changed files
... ...
@@ -40,24 +40,18 @@ extern str xcaps_root;
40 40
 
41 41
 static param_t *_xcaps_xpath_ns_root = NULL;
42 42
 
43
-typedef struct xcaps_auid_list {
44
-	str auid;  /* auid value */
45
-	char term; /* ending char (next one after auid) */
46
-	int type;  /* internaly type id for auid */
47
-} xcaps_auid_list_t;
48
-
49
-/* list of supported auid */
50
-static xcaps_auid_list_t _xcaps_auid_list[] = {
43
+/* list of supported auid  - ordered ascending by type */
44
+xcaps_auid_list_t xcaps_auid_list[] = {
51 45
 	{ { "pres-rules", 10 },
52 46
 			'/', PRES_RULES },
53 47
 	{ { "org.openmobilealliance.pres-rules", 33 },
54 48
 			'/', PRES_RULES },
49
+	{ { "resource-lists", 14 },
50
+			'/', RESOURCE_LIST },
55 51
 	{ { "rls-services", 12 },
56 52
 			'/', RLS_SERVICE },
57 53
 	{ { "pidf-manipulation", 17 },
58 54
 			'/', PIDF_MANIPULATION },
59
-	{ { "resource-lists", 14 },
60
-			'/', RESOURCE_LIST },
61 55
 	{ { "xcap-caps", 9 },
62 56
 			'/', XCAP_CAPS },
63 57
 	{ { "org.openmobilealliance.user-profile", 35},
... ...
@@ -66,6 +60,8 @@ static xcaps_auid_list_t _xcaps_auid_list[] = {
66 66
 			'/', PRES_CONTENT },
67 67
 	{ { "org.openmobilealliance.search", 29},
68 68
 			'?', SEARCH },
69
+	{ { "org.openmobilealliance.xcap-directory", 37},
70
+			'/', DIRECTORY },
69 71
 
70 72
 	{ { 0, 0 }, 0, 0 }
71 73
 };
... ...
@@ -73,18 +69,18 @@ static xcaps_auid_list_t _xcaps_auid_list[] = {
73 73
 static int xcaps_find_auid(str *s, xcap_uri_t *xuri)
74 74
 {
75 75
 	int i;
76
-	for(i=0; _xcaps_auid_list[i].auid.s!=NULL; i++)
76
+	for(i=0; xcaps_auid_list[i].auid.s!=NULL; i++)
77 77
 	{
78
-		if(s->len > _xcaps_auid_list[i].auid.len
79
-			&& s->s[_xcaps_auid_list[i].auid.len] == _xcaps_auid_list[i].term
80
-			&& strncmp(s->s, _xcaps_auid_list[i].auid.s,
81
-							_xcaps_auid_list[i].auid.len) == 0)
78
+		if(s->len > xcaps_auid_list[i].auid.len
79
+			&& s->s[xcaps_auid_list[i].auid.len] == xcaps_auid_list[i].term
80
+			&& strncmp(s->s, xcaps_auid_list[i].auid.s,
81
+							xcaps_auid_list[i].auid.len) == 0)
82 82
 		{
83
-			LM_DBG("matched %.*s\n", _xcaps_auid_list[i].auid.len,
84
-					_xcaps_auid_list[i].auid.s);
85
-			xuri->type = _xcaps_auid_list[i].type;
83
+			LM_DBG("matched %.*s\n", xcaps_auid_list[i].auid.len,
84
+					xcaps_auid_list[i].auid.s);
85
+			xuri->type = xcaps_auid_list[i].type;
86 86
 			xuri->auid.s = s->s;
87
-			xuri->auid.len = _xcaps_auid_list[i].auid.len;
87
+			xuri->auid.len = xcaps_auid_list[i].auid.len;
88 88
 			return 0;
89 89
 		}
90 90
 	}
... ...
@@ -50,6 +50,14 @@ typedef struct xcap_uri {
50 50
 	str domain;
51 51
 } xcap_uri_t;
52 52
 
53
+typedef struct xcaps_auid_list {
54
+	str auid;  /* auid value */
55
+	char term; /* ending char (next one after auid) */
56
+	int type;  /* internaly type id for auid */
57
+} xcaps_auid_list_t;
58
+
59
+extern xcaps_auid_list_t xcaps_auid_list[];
60
+
53 61
 int xcap_parse_uri(str *huri, str *xroot, xcap_uri_t *xuri);
54 62
 int xcaps_xpath_set(str *inbuf, str *xpaths, str *val, str *outbuf);
55 63
 int xcaps_xpath_get(str *inbuf, str *xpaths, str *outbuf);
... ...
@@ -85,8 +85,8 @@ static int xcaps_etag_counter = 1;
85 85
 str xcaps_root = str_init("/xcap-root/");
86 86
 
87 87
 static str xcaps_buf = {0, 8192};
88
-#define XCAPS_ETAG_SIZE	128
89
-static char xcaps_etag_buf[XCAPS_ETAG_SIZE];
88
+#define XCAPS_HDR_SIZE	128
89
+static char xcaps_hdr_buf[XCAPS_HDR_SIZE];
90 90
 
91 91
 static str str_id_col = str_init("id");
92 92
 static str str_source_col = str_init("source");
... ...
@@ -243,7 +243,7 @@ static int xcaps_send_reply(sip_msg_t *msg, int code, str *reason,
243 243
 {
244 244
 	str tbuf;
245 245
 
246
-	if(hdrs->len>0)
246
+	if(hdrs && hdrs->len>0)
247 247
 	{
248 248
 		if (add_lump_rpl(msg, hdrs->s, hdrs->len, LUMP_RPL_HDR) == 0)
249 249
 		{
... ...
@@ -252,7 +252,7 @@ static int xcaps_send_reply(sip_msg_t *msg, int code, str *reason,
252 252
 		}
253 253
 	}
254 254
 
255
-	if(ctype->len>0)
255
+	if(ctype && ctype->len>0)
256 256
 	{
257 257
 		/* add content-type */
258 258
 		tbuf.len=sizeof("Content-Type: ") - 1 + ctype->len + CRLF_LEN;
... ...
@@ -275,7 +275,7 @@ static int xcaps_send_reply(sip_msg_t *msg, int code, str *reason,
275 275
 		}
276 276
 		pkg_free(tbuf.s);
277 277
 	}
278
-	if(body->len>0)
278
+	if(body && body->len>0)
279 279
 	{
280 280
 		if (add_lump_rpl(msg, body->s, body->len, LUMP_RPL_BODY) < 0)
281 281
 		{
... ...
@@ -460,12 +460,13 @@ error:
460 460
 	return -1;
461 461
 }
462 462
 
463
-static str xcaps_str_empty	= {"", 0};
464 463
 static str xcaps_str_ok		= {"OK", 2};
465 464
 static str xcaps_str_srverr	= {"Server error", 12};
466 465
 static str xcaps_str_notfound	= {"Not found", 9};
467 466
 static str xcaps_str_precon	= {"Precondition Failed", 19};
468 467
 static str xcaps_str_notmod	= {"Not Modified", 12};
468
+static str xcaps_str_notallowed = {"Method Not Allowed", 18};
469
+static str xcaps_str_notimplemented = {"Not Implemented", 15};
469 470
 static str xcaps_str_appxml	= {"application/xml", 15};
470 471
 static str xcaps_str_apprlxml	= {"application/resource-lists+xml", 30};
471 472
 static str xcaps_str_apprsxml	= {"application/rls-services+xml", 28};
... ...
@@ -478,6 +479,7 @@ static str xcaps_str_appapxml	= {"application/auth-policy+xml", 27};
478 478
 static str xcaps_str_appupxml	= {"application/vnd.oma.user-profile+xml", 36}; 
479 479
 static str xcaps_str_apppcxml	= {"application/vnd.oma.pres-content+xml", 36};
480 480
 static str xcaps_str_apppdxml	= {"application/pidf+xml", 20};
481
+static str xcaps_str_appdrxml	= {"application/vnd.oma.xcap-directory+xml", 38};
481 482
 
482 483
 
483 484
 /**
... ...
@@ -494,6 +496,7 @@ static int w_xcaps_put(sip_msg_t* msg, char* puri, char* ppath,
494 494
 	str etag_hdr;
495 495
 	str tbuf;
496 496
 	str nbuf = {0, 0};
497
+	str allow = {0, 0};
497 498
 	pv_elem_t *xm;
498 499
 	xcap_uri_t xuri;
499 500
 
... ...
@@ -522,37 +525,14 @@ static int w_xcaps_put(sip_msg_t* msg, char* puri, char* ppath,
522 522
 	if(path.s==NULL || path.len == 0)
523 523
 	{
524 524
 		LM_ERR("invalid path parameter\n");
525
-		goto error;
526
-	}
527
-
528
-	xm = (pv_elem_t*)pbody;
529
-	body.len = xcaps_buf.len - 1;
530
-	if(pv_printf(msg, xm, xcaps_buf.s, &body.len)<0)
531
-	{
532
-		LM_ERR("unable to get body\n");
533
-		goto error;
534
-	}
535
-	if(body.len <= 0)
536
-	{
537
-		LM_ERR("invalid body parameter\n");
538
-		goto error;
539
-	}
540
-	body.s = (char*)pkg_malloc(body.len+1);
541
-	if(body.s==NULL)
542
-	{
543
-		LM_ERR("no more pkg\n");
544
-		goto error;
525
+		return -1;
545 526
 	}
546 527
 
547
-	memcpy(body.s, xcaps_buf.s, body.len);
548
-	body.s[body.len] = '\0';
549
-
550 528
 	if(parse_uri(uri.s, uri.len, &turi)!=0)
551 529
 	{
552 530
 		LM_ERR("parsing uri parameter\n");
553 531
 		goto error;
554 532
 	}
555
-	/* TODO: do xml parsing for validation */
556 533
 
557 534
 	if(xcap_parse_uri(&path, &xcaps_root, &xuri)<0)
558 535
 	{
... ...
@@ -561,72 +541,110 @@ static int w_xcaps_put(sip_msg_t* msg, char* puri, char* ppath,
561 561
 		goto error;
562 562
 	}
563 563
 
564
-	xcaps_get_db_etag(&turi.user, &turi.host, &xuri, &etag);
565
-	if(check_preconditions(msg, etag)!=1)
564
+	switch(xuri.type)
566 565
 	{
567
-		xcaps_send_reply(msg, 412, &xcaps_str_precon, &xcaps_str_empty,
568
-				&xcaps_str_empty, &xcaps_str_empty);
569
-
570
-		pkg_free(body.s);
571
-		return -2;
572
-	}
573
-
574
-	if(xuri.nss!=NULL && xuri.node.len>0)
575
-	{
576
-		/* partial document upload
577
-		 *   - fetch, update, delete and store
578
-		 */
579
-		if(xcaps_get_db_doc(&turi.user, &turi.host, &xuri, &tbuf) != 0)
566
+	case DIRECTORY:
567
+	case XCAP_CAPS:
568
+		allow.s = xcaps_hdr_buf;
569
+		allow.len = snprintf(allow.s, XCAPS_HDR_SIZE, "Allow: GET\r\n");
570
+		xcaps_send_reply(msg, 405, &xcaps_str_notallowed, &allow, NULL, NULL);
571
+		break;
572
+	case SEARCH:
573
+		allow.s = xcaps_hdr_buf;
574
+		allow.len = snprintf(allow.s, XCAPS_HDR_SIZE, "Allow: POST\r\n");
575
+		xcaps_send_reply(msg, 405, &xcaps_str_notallowed, &allow, NULL, NULL);
576
+		break;
577
+	default:
578
+		xm = (pv_elem_t*)pbody;
579
+		body.len = xcaps_buf.len - 1;
580
+		if(pv_printf(msg, xm, xcaps_buf.s, &body.len)<0)
580 581
 		{
581
-			LM_ERR("could not fetch xcap document\n");
582
+			LM_ERR("unable to get body\n");
582 583
 			goto error;
583 584
 		}
584
-		if(xcaps_xpath_hack(&tbuf, 0)<0)
585
+		if(body.len <= 0)
585 586
 		{
586
-			LM_ERR("could not hack xcap document\n");
587
+			LM_ERR("invalid body parameter\n");
587 588
 			goto error;
588 589
 		}
589
-		if(xcaps_xpath_set(&tbuf, &xuri.node, &body, &nbuf)<0)
590
+		body.s = (char*)pkg_malloc(body.len+1);
591
+		if(body.s==NULL)
590 592
 		{
591
-			LM_ERR("could not update xcap document\n");
593
+			LM_ERR("no more pkg\n");
592 594
 			goto error;
593 595
 		}
594
-		if(nbuf.len<=0)
596
+		memcpy(body.s, xcaps_buf.s, body.len);
597
+		body.s[body.len] = '\0';
598
+
599
+		xcaps_get_db_etag(&turi.user, &turi.host, &xuri, &etag);
600
+		if(check_preconditions(msg, etag)!=1)
601
+		{
602
+			xcaps_send_reply(msg, 412, &xcaps_str_precon, NULL, NULL, NULL);
603
+
604
+			pkg_free(body.s);
605
+			return -2;
606
+		}
607
+
608
+		if(xuri.nss!=NULL && xuri.node.len>0)
595 609
 		{
596
-			LM_ERR("no new content\n");
610
+			/* partial document upload
611
+			 *   - fetch, update, delete and store
612
+			 */
613
+			if(xcaps_get_db_doc(&turi.user, &turi.host, &xuri, &tbuf) != 0)
614
+			{
615
+				LM_ERR("could not fetch xcap document\n");
616
+				goto error;
617
+			}
618
+			if(xcaps_xpath_hack(&tbuf, 0)<0)
619
+			{
620
+				LM_ERR("could not hack xcap document\n");
621
+				goto error;
622
+			}
623
+			if(xcaps_xpath_set(&tbuf, &xuri.node, &body, &nbuf)<0)
624
+			{
625
+				LM_ERR("could not update xcap document\n");
626
+				goto error;
627
+			}
628
+			if(nbuf.len<=0)
629
+			{
630
+				LM_ERR("no new content\n");
631
+				goto error;
632
+			}
633
+			pkg_free(body.s);
634
+			body = nbuf;
635
+			if(xcaps_xpath_hack(&body, 1)<0)
636
+			{
637
+				LM_ERR("could not hack xcap document\n");
638
+				goto error;
639
+			}
640
+		}
641
+
642
+		if(xcaps_generate_etag_hdr(&etag_hdr)<0)
643
+		{
644
+			LM_ERR("could not generate etag\n");
597 645
 			goto error;
598 646
 		}
599
-		pkg_free(body.s);
600
-		body = nbuf;
601
-		if(xcaps_xpath_hack(&body, 1)<0)
647
+		etag.s = etag_hdr.s + 7; /* 'ETag: "' */
648
+		etag.len = etag_hdr.len - 10; /* 'ETag: "  "\r\n' */
649
+		if(xcaps_put_db(&turi.user, &turi.host,
650
+					&xuri, &etag, &body)<0)
602 651
 		{
603
-			LM_ERR("could not hack xcap document\n");
652
+			LM_ERR("could not store document\n");
604 653
 			goto error;
605 654
 		}
606
-	}
655
+		xcaps_send_reply(msg, 200, &xcaps_str_ok, &etag_hdr,
656
+					NULL, NULL);
607 657
 
608
-	if(xcaps_generate_etag_hdr(&etag_hdr)<0)
609
-	{
610
-		LM_ERR("could not generate etag\n");
611
-		goto error;
612
-	}
613
-	etag.s = etag_hdr.s + 7; /* 'ETag: "' */
614
-	etag.len = etag_hdr.len - 10; /* 'ETag: "  "\r\n' */
615
-	if(xcaps_put_db(&turi.user, &turi.host,
616
-				&xuri, &etag, &body)<0)
617
-	{
618
-		LM_ERR("could not store document\n");
619
-		goto error;
658
+		if(body.s!=NULL)
659
+			pkg_free(body.s);
660
+
661
+		break;
620 662
 	}
621
-	xcaps_send_reply(msg, 200, &xcaps_str_ok, &etag_hdr,
622
-				&xcaps_str_empty, &xcaps_str_empty);
623
-	if(body.s!=NULL)
624
-		pkg_free(body.s);
663
+
625 664
 	return 1;
626 665
 
627 666
 error:
628
-	xcaps_send_reply(msg, 500, &xcaps_str_srverr, &xcaps_str_empty,
629
-				&xcaps_str_empty, &xcaps_str_empty);
667
+	xcaps_send_reply(msg, 500, &xcaps_str_srverr, NULL, NULL, NULL);
630 668
 	if(body.s!=NULL)
631 669
 		pkg_free(body.s);
632 670
 	return -1;
... ...
@@ -820,20 +838,20 @@ static int xcaps_get_db_etag(str* user, str *domain, xcap_uri_t *xuri, str *etag
820 820
 		LM_ERR("no etag in db record\n");
821 821
 		goto error;
822 822
 	}
823
-	etag->len = snprintf(xcaps_etag_buf, XCAPS_ETAG_SIZE,
823
+	etag->len = snprintf(xcaps_hdr_buf, XCAPS_HDR_SIZE,
824 824
 			"ETag: \"%.*s\"\r\n", s.len, s.s);
825 825
 	if(etag->len < 0)
826 826
 	{
827 827
 		LM_ERR("error printing etag hdr\n ");
828 828
 		goto error;
829 829
 	}
830
-	if(etag->len >= XCAPS_ETAG_SIZE)
830
+	if(etag->len >= XCAPS_HDR_SIZE)
831 831
 	{
832 832
 		LM_ERR("etag buffer overflow\n");
833 833
 		goto error;
834 834
 	}
835 835
 
836
-	etag->s = xcaps_etag_buf;
836
+	etag->s = xcaps_hdr_buf;
837 837
 	etag->s[etag->len] = '\0';
838 838
 
839 839
 	xcaps_dbf.free_result(xcaps_db, db_res);
... ...
@@ -849,6 +867,136 @@ error:
849 849
 	return -1;
850 850
 }
851 851
 
852
+static int xcaps_get_directory(struct sip_msg *msg, str *user, str *domain, str *directory)
853
+{
854
+	db_key_t qcols[2];
855
+	db_val_t qvals[2], *values;
856
+	db_key_t rcols[3];
857
+	db_row_t *rows;
858
+	db1_res_t* db_res = NULL;
859
+	int n_qcols = 0, n_rcols = 0;
860
+	int i, cur_type = 0, cur_pos = 0;
861
+	int doc_type_col, doc_uri_col, etag_col;
862
+	str auid_string = {0, 0};
863
+	struct hdr_field *hdr = msg->headers;
864
+	str server_name = {0, 0};
865
+
866
+	qcols[n_qcols] = &str_username_col;
867
+	qvals[n_qcols].type = DB1_STR;
868
+	qvals[n_qcols].nul = 0;
869
+	qvals[n_qcols].val.str_val = *user;
870
+	n_qcols++;
871
+	
872
+	qcols[n_qcols] = &str_domain_col;
873
+	qvals[n_qcols].type = DB1_STR;
874
+	qvals[n_qcols].nul = 0;
875
+	qvals[n_qcols].val.str_val = *domain;
876
+	n_qcols++;
877
+
878
+	rcols[doc_type_col = n_rcols++] = &str_doc_type_col;
879
+	rcols[doc_uri_col = n_rcols++] = &str_doc_uri_col;
880
+	rcols[etag_col = n_rcols++] = &str_etag_col;
881
+
882
+	if (xcaps_dbf.use_table(xcaps_db, &xcaps_db_table) < 0) 
883
+	{
884
+		LM_ERR("in use_table-[table]= %.*s\n", xcaps_db_table.len,
885
+				xcaps_db_table.s);
886
+		goto error;
887
+	}
888
+
889
+	if (xcaps_dbf.query(xcaps_db, qcols, 0, qvals, rcols, n_qcols,
890
+				n_rcols, &str_doc_type_col, &db_res) < 0)
891
+	{
892
+		LM_ERR("in sql query\n");
893
+		goto error;
894
+
895
+	}
896
+
897
+	if (db_res == NULL)
898
+		goto error;
899
+
900
+	while (hdr != NULL)
901
+	{
902
+		LM_ERR("Found header: %.*s\n", hdr->name.len, hdr->name.s);
903
+		if (cmp_hdrname_strzn(&hdr->name, "Host", 4) == 0)
904
+		{
905
+			LM_ERR("Found %.*s\n", hdr->body.len, hdr->body.s);
906
+			server_name = hdr->body;
907
+			break;
908
+		}
909
+		hdr = hdr->next;
910
+	}
911
+
912
+	directory->s = xcaps_buf.s;
913
+	directory->len = 0;
914
+
915
+	directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len,
916
+		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
917
+		"<xcap-directory xmlns=\"urn:oma:xml:xdm:xcap-directory\">\r\n");
918
+
919
+	rows = RES_ROWS(db_res);
920
+	for (i = 0; i < RES_ROW_N(db_res); i++)
921
+	{
922
+		values = ROW_VALUES(&rows[i]);
923
+
924
+		if (cur_type != VAL_INT(&values[doc_type_col]))
925
+		{
926
+			if (cur_type != 0)
927
+			{
928
+				directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len,
929
+		"</folder>\r\n");
930
+			}
931
+			cur_type = VAL_INT(&values[doc_type_col]);
932
+
933
+			memset(&auid_string, 0, sizeof(str));
934
+			while(xcaps_auid_list[cur_pos].auid.s != NULL)
935
+			{
936
+				if (xcaps_auid_list[cur_pos].type == cur_type)
937
+				{
938
+					auid_string.s = xcaps_auid_list[cur_pos].auid.s;
939
+					auid_string.len = xcaps_auid_list[cur_pos].auid.len;
940
+					break;
941
+				}
942
+				cur_pos++;
943
+			}
944
+
945
+			if (auid_string.s == NULL)
946
+			{
947
+				goto error;
948
+			}
949
+
950
+			directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len,
951
+		"<folder auid=\"%.*s\">\r\n",
952
+						auid_string.len, auid_string.s);
953
+		}
954
+
955
+		directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len,
956
+		"<entry uri=\"%s%.*s%s\" etag=\"%s\"/>\r\n",
957
+					server_name.len ? (msg->rcv.proto == PROTO_TLS ? "https://" : "http://") : "",
958
+					server_name.len, server_name.len ? server_name.s : "",
959
+					VAL_STRING(&values[doc_uri_col]),
960
+					VAL_STRING(&values[etag_col]));
961
+	}
962
+
963
+	if (cur_type != 0)
964
+	{
965
+		directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len,
966
+		"</folder>\r\n");
967
+	}
968
+	directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len,
969
+		"</xcap-directory>");
970
+
971
+	if (db_res != NULL)
972
+		xcaps_dbf.free_result(xcaps_db, db_res);
973
+
974
+	return 0;
975
+
976
+error:
977
+	if (db_res != NULL)
978
+		xcaps_dbf.free_result(xcaps_db, db_res);
979
+	return -1;
980
+}
981
+
852 982
 /**
853 983
  *
854 984
  */
... ...
@@ -862,6 +1010,7 @@ static int w_xcaps_get(sip_msg_t* msg, char* puri, char* ppath)
862 862
 	int ret = 0;
863 863
 	xcap_uri_t xuri;
864 864
 	str *ctype;
865
+	str allow;
865 866
 
866 867
 	if(puri==0 || ppath==0)
867 868
 	{
... ...
@@ -904,63 +1053,92 @@ static int w_xcaps_get(sip_msg_t* msg, char* puri, char* ppath)
904 904
 		goto error;
905 905
 	}
906 906
 
907
-	if((ret=xcaps_get_db_etag(&turi.user, &turi.host, &xuri, &etag))<0)
908
-	{ 
909
-		LM_ERR("could not fetch etag for xcap document\n");
910
-		goto error;
911
-	}
912
-	if (ret==1)
907
+	switch(xuri.type)
913 908
 	{
914
-		/* doc not found */
915
-		xcaps_send_reply(msg, 404, &xcaps_str_notfound, &xcaps_str_empty,
916
-				&xcaps_str_empty, &xcaps_str_empty);
917
-		return 1;
918
-	}
909
+	case DIRECTORY:
910
+		if (strncmp(xuri.file.s, "directory.xml", xuri.file.len) == 0)
911
+		{
912
+			if (xcaps_get_directory(msg, &turi.user, &turi.host, &body) < 0)
913
+				goto error;
914
+
915
+			xcaps_send_reply(msg, 200, &xcaps_str_ok, NULL, &xcaps_str_appdrxml, &body);
916
+		}
917
+		else
918
+		{
919
+			xcaps_send_reply(msg, 404, &xcaps_str_notfound, NULL, NULL, NULL);
920
+		}
921
+		break;
922
+	case XCAP_CAPS:
923
+		xcaps_send_reply(msg, 501, &xcaps_str_notimplemented, NULL, NULL, NULL);
924
+		break;
925
+	case SEARCH:
926
+		allow.s = xcaps_hdr_buf;
927
+		allow.len = snprintf(allow.s, XCAPS_HDR_SIZE, "Allow: POST\r\n");
928
+		xcaps_send_reply(msg, 405, &xcaps_str_notallowed, &allow, NULL, NULL);
929
+		break;
930
+	default:
931
+		if((ret=xcaps_get_db_etag(&turi.user, &turi.host, &xuri, &etag))<0)
932
+		{ 
933
+			LM_ERR("could not fetch etag for xcap document\n");
934
+			goto error;
935
+		}
936
+		if (ret==1)
937
+		{
938
+			/* doc not found */
939
+			xcaps_send_reply(msg, 404, &xcaps_str_notfound, NULL,
940
+					NULL, NULL);
941
+			return 1;
942
+		}
919 943
 	
920
-	if((ret=check_preconditions(msg, etag))==-1)
921
-	{
922
-		xcaps_send_reply(msg, 412, &xcaps_str_precon, &xcaps_str_empty,
923
-				&xcaps_str_empty, &xcaps_str_empty);
924
-		return -2;
925
-	} else if (ret==-2) {
926
-		xcaps_send_reply(msg, 304, &xcaps_str_notmod, &xcaps_str_empty,
927
-				&xcaps_str_empty, &xcaps_str_empty);
928
-		return -2;
929
-	}
944
+		if((ret=check_preconditions(msg, etag))==-1)
945
+		{
946
+			xcaps_send_reply(msg, 412, &xcaps_str_precon, NULL,
947
+					NULL, NULL);
948
+			return -2;
949
+		} else if (ret==-2) {
950
+			xcaps_send_reply(msg, 304, &xcaps_str_notmod, NULL,
951
+					NULL, NULL);
952
+			return -2;
953
+		}
930 954
 
931
-	if((ret=xcaps_get_db_doc(&turi.user, &turi.host, &xuri, &body))<0)
932
-	{
933
-		LM_ERR("could not fetch xcap document\n");
934
-		goto error;
935
-	}
936
-	if(ret==0)
937
-	{
938
-		/* doc found */
939
-		ctype = &xcaps_str_appxml;
940
-		if(xuri.type==RESOURCE_LIST)
941
-			ctype = &xcaps_str_apprlxml;
942
-		else if(xuri.type==PRES_RULES)
943
-			ctype = &xcaps_str_appapxml;
944
-		else if(xuri.type==RLS_SERVICE)
945
-			ctype = &xcaps_str_apprsxml;
946
-		else if(xuri.type==USER_PROFILE)
947
-			ctype = &xcaps_str_appupxml;
948
-		else if(xuri.type==PRES_CONTENT)
949
-			ctype = &xcaps_str_apppcxml;
950
-		else if(xuri.type==PIDF_MANIPULATION)
951
-			ctype = &xcaps_str_apppdxml;
952
-		xcaps_send_reply(msg, 200, &xcaps_str_ok, &etag,
953
-				ctype, &body);
954
-	} else {
955
-		/* doc not found */
956
-		xcaps_send_reply(msg, 404, &xcaps_str_notfound, &xcaps_str_empty,
957
-				&xcaps_str_empty, &xcaps_str_empty);
955
+		if((ret=xcaps_get_db_doc(&turi.user, &turi.host, &xuri, &body))<0)
956
+		{
957
+			LM_ERR("could not fetch xcap document\n");
958
+			goto error;
959
+		}
960
+
961
+		if(ret==0)
962
+		{
963
+			/* doc found */
964
+			ctype = &xcaps_str_appxml;
965
+			if(xuri.type==RESOURCE_LIST)
966
+				ctype = &xcaps_str_apprlxml;
967
+			else if(xuri.type==PRES_RULES)
968
+				ctype = &xcaps_str_appapxml;
969
+			else if(xuri.type==RLS_SERVICE)
970
+				ctype = &xcaps_str_apprsxml;
971
+			else if(xuri.type==USER_PROFILE)
972
+				ctype = &xcaps_str_appupxml;
973
+			else if(xuri.type==PRES_CONTENT)
974
+				ctype = &xcaps_str_apppcxml;
975
+			else if(xuri.type==PIDF_MANIPULATION)
976
+				ctype = &xcaps_str_apppdxml;
977
+			xcaps_send_reply(msg, 200, &xcaps_str_ok, &etag,
978
+					ctype, &body);
979
+		} else {
980
+			/* doc not found */
981
+			xcaps_send_reply(msg, 404, &xcaps_str_notfound, NULL,
982
+					NULL, NULL);
983
+		}
984
+
985
+		break;
958 986
 	}
987
+
959 988
 	return 1;
960 989
 
961 990
 error:
962
-	xcaps_send_reply(msg, 500, &xcaps_str_srverr, &xcaps_str_empty,
963
-				&xcaps_str_empty, &xcaps_str_empty);
991
+	xcaps_send_reply(msg, 500, &xcaps_str_srverr, NULL,
992
+				NULL, NULL);
964 993
 	return -1;
965 994
 }
966 995
 
... ...
@@ -1025,6 +1203,7 @@ static int w_xcaps_del(sip_msg_t* msg, char* puri, char* ppath)
1025 1025
 	str etag_hdr = {0, 0};
1026 1026
 	str etag = {0, 0};
1027 1027
 	str tbuf;
1028
+	str allow = {0, 0};
1028 1029
 
1029 1030
 	if(puri==0 || ppath==0)
1030 1031
 	{
... ...
@@ -1067,80 +1246,97 @@ static int w_xcaps_del(sip_msg_t* msg, char* puri, char* ppath)
1067 1067
 		goto error;
1068 1068
 	}
1069 1069
 
1070
-	if(xcaps_get_db_etag(&turi.user, &turi.host, &xuri, &etag)!=0)
1071
-	{ 
1072
-		LM_ERR("could not fetch etag for xcap document\n");
1073
-		goto error;
1074
-	}
1075
-
1076
-	if(check_preconditions(msg, etag)!=1)
1077
-	{
1078
-		xcaps_send_reply(msg, 412, &xcaps_str_precon, &xcaps_str_empty,
1079
-				&xcaps_str_empty, &xcaps_str_empty);
1080
-		return -2;
1081
-	}
1082
-
1083
-	if(xuri.nss==NULL)
1070
+	switch(xuri.type)
1084 1071
 	{
1085
-		/* delete document */
1086
-		if(xcaps_del_db(&turi.user, &turi.host, &xuri)<0)
1087
-		{
1088
-			LM_ERR("could not delete document\n");
1089
-			goto error;
1090
-		}
1091
-		xcaps_send_reply(msg, 200, &xcaps_str_ok, &xcaps_str_empty,
1092
-				&xcaps_str_empty, &xcaps_str_empty);
1093
-	} else {
1094
-		/* delete element */
1095
-		if(xcaps_get_db_doc(&turi.user, &turi.host, &xuri, &tbuf) != 0)
1096
-		{
1097
-			LM_ERR("could not fetch xcap document\n");
1098
-			goto error;
1099
-		}
1100
-		if(xcaps_xpath_hack(&tbuf, 0)<0)
1101
-		{
1102
-			LM_ERR("could not hack xcap document\n");
1103
-			goto error;
1104
-		}
1105
-		if(xcaps_xpath_set(&tbuf, &xuri.node, NULL, &body)<0)
1106
-		{
1107
-			LM_ERR("could not update xcap document\n");
1108
-			goto error;
1109
-		}
1110
-		if(body.len<=0)
1111
-		{
1112
-			LM_ERR("no new content\n");
1113
-			goto error;
1114
-		}
1115
-		if(xcaps_xpath_hack(&body, 1)<0)
1116
-		{
1117
-			LM_ERR("could not hack xcap document\n");
1072
+	case DIRECTORY:
1073
+	case XCAP_CAPS:
1074
+		allow.s = xcaps_hdr_buf;
1075
+		allow.len = snprintf(allow.s, XCAPS_HDR_SIZE, "Allow: GET\r\n");
1076
+		xcaps_send_reply(msg, 405, &xcaps_str_notallowed, &allow, NULL, NULL);
1077
+		break;
1078
+	case SEARCH:
1079
+		allow.s = xcaps_hdr_buf;
1080
+		allow.len = snprintf(allow.s, XCAPS_HDR_SIZE, "Allow: POST\r\n");
1081
+		xcaps_send_reply(msg, 405, &xcaps_str_notallowed, &allow, NULL, NULL);
1082
+		break;
1083
+	default:
1084
+		if(xcaps_get_db_etag(&turi.user, &turi.host, &xuri, &etag)!=0)
1085
+		{ 
1086
+			LM_ERR("could not fetch etag for xcap document\n");
1118 1087
 			goto error;
1119 1088
 		}
1120
-		if(xcaps_generate_etag_hdr(&etag_hdr)<0)
1089
+
1090
+		if(check_preconditions(msg, etag)!=1)
1121 1091
 		{
1122
-			LM_ERR("could not generate etag\n");
1123
-			goto error;
1092
+			xcaps_send_reply(msg, 412, &xcaps_str_precon, NULL,
1093
+					NULL, NULL);
1094
+			return -2;
1124 1095
 		}
1125
-		etag.s = etag_hdr.s + 7; /* 'ETag: "' */
1126
-		etag.len = etag_hdr.len - 10; /* 'ETag: "  "\r\n' */
1127
-		if(xcaps_put_db(&turi.user, &turi.host,
1128
-				&xuri, &etag, &body)<0)
1096
+
1097
+		if(xuri.nss==NULL)
1129 1098
 		{
1130
-			LM_ERR("could not store document\n");
1131
-			goto error;
1099
+			/* delete document */
1100
+			if(xcaps_del_db(&turi.user, &turi.host, &xuri)<0)
1101
+			{
1102
+				LM_ERR("could not delete document\n");
1103
+				goto error;
1104
+			}
1105
+			xcaps_send_reply(msg, 200, &xcaps_str_ok, NULL,
1106
+					NULL, NULL);
1107
+		} else {
1108
+			/* delete element */
1109
+			if(xcaps_get_db_doc(&turi.user, &turi.host, &xuri, &tbuf) != 0)
1110
+			{
1111
+				LM_ERR("could not fetch xcap document\n");
1112
+				goto error;
1113
+			}
1114
+			if(xcaps_xpath_hack(&tbuf, 0)<0)
1115
+			{
1116
+				LM_ERR("could not hack xcap document\n");
1117
+				goto error;
1118
+			}
1119
+			if(xcaps_xpath_set(&tbuf, &xuri.node, NULL, &body)<0)
1120
+			{
1121
+				LM_ERR("could not update xcap document\n");
1122
+				goto error;
1123
+			}
1124
+			if(body.len<=0)
1125
+			{
1126
+				LM_ERR("no new content\n");
1127
+				goto error;
1128
+			}
1129
+			if(xcaps_xpath_hack(&body, 1)<0)
1130
+			{
1131
+				LM_ERR("could not hack xcap document\n");
1132
+				goto error;
1133
+			}
1134
+			if(xcaps_generate_etag_hdr(&etag_hdr)<0)
1135
+			{
1136
+				LM_ERR("could not generate etag\n");
1137
+				goto error;
1138
+			}
1139
+			etag.s = etag_hdr.s + 7; /* 'ETag: "' */
1140
+			etag.len = etag_hdr.len - 10; /* 'ETag: "  "\r\n' */
1141
+			if(xcaps_put_db(&turi.user, &turi.host,
1142
+					&xuri, &etag, &body)<0)
1143
+			{
1144
+				LM_ERR("could not store document\n");
1145
+				goto error;
1146
+			}
1147
+			xcaps_send_reply(msg, 200, &xcaps_str_ok, &etag_hdr,
1148
+					NULL, NULL);
1149
+			if(body.s!=NULL)
1150
+				pkg_free(body.s);
1132 1151
 		}
1133
-		xcaps_send_reply(msg, 200, &xcaps_str_ok, &etag_hdr,
1134
-				&xcaps_str_empty, &xcaps_str_empty);
1135
-		if(body.s!=NULL)
1136
-			pkg_free(body.s);
1137
-		return 1;
1152
+
1153
+		break;
1138 1154
 	}
1155
+
1139 1156
 	return 1;
1140 1157
 
1141 1158
 error:
1142
-	xcaps_send_reply(msg, 500, &xcaps_str_srverr, &xcaps_str_empty,
1143
-				&xcaps_str_empty, &xcaps_str_empty);
1159
+	xcaps_send_reply(msg, 500, &xcaps_str_srverr, NULL,
1160
+				NULL, NULL);
1144 1161
 	if(body.s!=NULL)
1145 1162
 		pkg_free(body.s);
1146 1163
 	return -1;
... ...
@@ -1246,7 +1442,7 @@ done:
1246 1246
  */
1247 1247
 int xcaps_generate_etag_hdr(str *etag)
1248 1248
 {
1249
-	etag->len = snprintf(xcaps_etag_buf, XCAPS_ETAG_SIZE,
1249
+	etag->len = snprintf(xcaps_hdr_buf, XCAPS_HDR_SIZE,
1250 1250
 			"ETag: \"sr-%d-%d-%d\"\r\n", xcaps_init_time, my_pid(),
1251 1251
 			xcaps_etag_counter++);
1252 1252
 	if(etag->len <0)
... ...
@@ -1254,13 +1450,13 @@ int xcaps_generate_etag_hdr(str *etag)
1254 1254
 		LM_ERR("error printing etag\n ");
1255 1255
 		return -1;
1256 1256
 	}
1257
-	if(etag->len >= XCAPS_ETAG_SIZE)
1257
+	if(etag->len >= XCAPS_HDR_SIZE)
1258 1258
 	{
1259 1259
 		LM_ERR("etag buffer overflow\n");
1260 1260
 		return -1;
1261 1261
 	}
1262 1262
 
1263
-	etag->s = xcaps_etag_buf;
1263
+	etag->s = xcaps_hdr_buf;
1264 1264
 	etag->s[etag->len] = '\0';
1265 1265
 	return 0;
1266 1266
 }