[SR-Users] OpenXcap always returns full resource list

Fabian Bernhard fbernhard at gmail.com
Tue May 1 07:49:33 CEST 2012


Hi Daniel

>>>> we are running Kamailio 3.2 together with the included OpenXcap server.
>>>>
>>> by the "included openxcap" server do you mean the xcap_server module?
>>>
>>>   * http://kamailio.org/docs/modules/stable/modules_k/xcap_server.html
>>>
>> Yes
>>
>>> Can you try with the master branch (which is upcoming 3.3.0, development
>>> being frozen already
>>> and we are in testing phase for it)? Just to be sure it is not a feature
>>> we added afterwards - I
>>> cannot look right now in the sources.
>>>
>> The issue still exists in 3.3.0: The function "w_xcaps_get()" in
>> xcap_server.c actually never evaluates an XPath expression.
>>
>> There is a function "xcaps_xpath_get()" in xcap_misc.c which is afaik
>> not used within Kamailio. To resolve my issue I have - to the best of
>> my knowledge - fixed that function and included a call to it in
>> "w_xcaps_get()", see attached diff.
>
>
> can you details a bit the changes you done to xcaps_xpath_get()? IIRC, it
> may be there as a generic function to get xpath nodes, but your patch
> removes lot of its content.
>

I have removed too much, indeed.

Please find attached a new patch that resolves my initial issue
without any changes to xcaps_xpath_get(). I don't fully understand why
xcaps_xpath_hack() is needed, but its done so in other parts of the
xcap_server code too, so I assume that there is a good reason for it.

The following in the patch might look suspicious:

xcaps_xpath_get(&body, &xuri.node, &body)

I'd say its ok because xcaps_xpath_get() does not read the input
buffer (first argument) after it started to write into the output
buffer (last argument).

Also attached, as requested, the full code of both functions involved.

Hope this helps!

Best regards

Fabian
-------------- next part --------------
int xcaps_xpath_get(str *inbuf, str *xpaths, str *outbuf)
{
	xmlDocPtr doc = NULL;
	xmlXPathContextPtr xpathCtx = NULL; 
	xmlXPathObjectPtr xpathObj = NULL; 
	xmlNodeSetPtr nodes;
	xmlChar *keyword;
	xmlBufferPtr psBuf;
	int size;
	int i;
	char *p;
	char *end;
	char *pos;

	doc = xmlParseMemory(inbuf->s, inbuf->len);
	if(doc == NULL)
		return -1;

	xpathCtx = xmlXPathNewContext(doc);
	if(xpathCtx == NULL)
	{
		LM_ERR("unable to create new XPath context\n");
		goto error;
	}
	
	/* Evaluate xpath expression */
	// xcaps_xpath_register_ns(xpathCtx);
	xpathObj = xmlXPathEvalExpression(
					(const xmlChar*)xpaths->s, xpathCtx);
	if(xpathObj == NULL)
	{
		LM_ERR("unable to evaluate xpath expression [%s]\n", xpaths->s);
		goto error;
	}
    nodes = xpathObj->nodesetval;
	if(nodes==NULL)
	{
		outbuf->len = 0;
		outbuf->s[outbuf->len] = '\0';
		goto done;
	}
	size = nodes->nodeNr;
    p = outbuf->s;
	end = outbuf->s + outbuf->len;
	for(i = 0; i < size; ++i)
	{
		if(nodes->nodeTab[i]==NULL)
			continue;
		if(i!=0)
		{
			if(p>=end)
			{
				LM_ERR("output buffer overflow\n");
				goto error;
			}
			*p = ',';
			p++;
		}
		if(nodes->nodeTab[i]->type == XML_ATTRIBUTE_NODE)
		{
			keyword = xmlNodeListGetString(doc,
				nodes->nodeTab[i]->children, 0);
			if(keyword != NULL)
			{
				pos = p + strlen((char*)keyword);
				if(pos>=end)
				{
					LM_ERR("output buffer overflow\n");
					goto error;
				}
				strcpy(p, (char*)keyword);
				p = pos;
				xmlFree(keyword);
				keyword = NULL;
			}
		} else {
			if(nodes->nodeTab[i]->content!=NULL)
			{
				pos = p + strlen((char*)nodes->nodeTab[i]->content);
				if(pos>=end)
				{
					LM_ERR("output buffer overflow\n");
					goto error;
				}
				strcpy(p, (char*)nodes->nodeTab[i]->content);
				p = pos;
			} else {
				psBuf = xmlBufferCreate();
				if(psBuf != NULL && xmlNodeDump(psBuf, doc,
						nodes->nodeTab[i], 0, 0)>0)
				{
					pos = p + strlen((char*)xmlBufferContent(psBuf));
					if(pos>=end)
					{
						LM_ERR("output buffer overflow\n");
						goto error;
					}
					strcpy(p, (char*)xmlBufferContent(psBuf));
					p = pos;
				}
				if(psBuf != NULL) xmlBufferFree(psBuf);
				psBuf = NULL;
			}
		}
	}
	outbuf->len = p - outbuf->s;
	outbuf->s[outbuf->len] = '\0';

done:
	if(xpathObj!=NULL) xmlXPathFreeObject(xpathObj);
	if(xpathCtx!=NULL) xmlXPathFreeContext(xpathCtx); 
	if(doc!=NULL) xmlFreeDoc(doc);
	xpathObj = NULL;
	xpathCtx = NULL; 
	doc = NULL; 
	return 0;

error:
	if(xpathObj!=NULL) xmlXPathFreeObject(xpathObj);
	if(xpathCtx!=NULL) xmlXPathFreeContext(xpathCtx); 
	if(doc!=NULL) xmlFreeDoc(doc);
	xpathObj = NULL;
	xpathCtx = NULL; 
	doc = NULL; 
	outbuf->len = 0;
	outbuf->s[outbuf->len] = '\0';
	return -1;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: xcap_server-20120501.diff
Type: application/octet-stream
Size: 779 bytes
Desc: not available
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20120501/9ba7867a/attachment.obj>
-------------- next part --------------
static int w_xcaps_get(sip_msg_t* msg, char* puri, char* ppath)
{
	struct sip_uri turi;
	str uri;
	str path;
	str etag;
	str body;
	int ret = 0;
	xcap_uri_t xuri;
	str *ctype;

	if(puri==0 || ppath==0)
	{
		LM_ERR("invalid parameters\n");
		return -1;
	}

	if(fixup_get_svalue(msg, (gparam_p)puri, &uri)!=0)
	{
		LM_ERR("unable to get uri\n");
		return -1;
	}
	if(uri.s==NULL || uri.len == 0)
	{
		LM_ERR("invalid uri parameter\n");
		return -1;
	}

	if(fixup_get_svalue(msg, (gparam_p)ppath, &path)!=0)
	{
		LM_ERR("unable to get path\n");
		return -1;
	}
	if(path.s==NULL || path.len == 0)
	{
		LM_ERR("invalid path parameter\n");
		return -1;
	}

	if(parse_uri(uri.s, uri.len, &turi)!=0)
	{
		LM_ERR("parsing uri parameter\n");
		goto error;
	}

	if(xcap_parse_uri(&path, &xcaps_root, &xuri)<0)
	{
		LM_ERR("cannot parse xcap uri [%.*s]\n",
				path.len, path.s);
		goto error;
	}

	if((ret=xcaps_get_db_etag(&turi.user, &turi.host, &xuri, &etag))<0)
	{ 
		LM_ERR("could not fetch etag for xcap document\n");
		goto error;
	}
	if (ret==1)
	{
		/* doc not found */
		xcaps_send_reply(msg, 404, &xcaps_str_notfound, &xcaps_str_empty,
				&xcaps_str_empty, &xcaps_str_empty);
		return 1;
	}
	
	if((ret=check_preconditions(msg, etag))==-1)
	{
		xcaps_send_reply(msg, 412, &xcaps_str_precon, &xcaps_str_empty,
				&xcaps_str_empty, &xcaps_str_empty);
		return -2;
	} else if (ret==-2) {
		xcaps_send_reply(msg, 304, &xcaps_str_notmod, &xcaps_str_empty,
				&xcaps_str_empty, &xcaps_str_empty);
		return -2;
	}

	if((ret=xcaps_get_db_doc(&turi.user, &turi.host, &xuri, &body))<0)
	{
		LM_ERR("could not fetch xcap document\n");
		goto error;
	}
	
	if (xuri.node.s != NULL) 
	{		
		if(xcaps_xpath_hack(&body, 0)<0)
		{
			LM_ERR("could not hack xcap document\n");
			goto error;
		}
		
		if(xcaps_xpath_get(&body, &xuri.node, &body)<0)
		{
			LM_ERR("could not filter xml document\n");
			goto error;
		}
		
		if(xcaps_xpath_hack(&body, 1)<0)
		{
			LM_ERR("could not hack xcap document\n");
			goto error;
		}
	} 
	
	if(ret==0)
	{
		/* doc found */
		ctype = &xcaps_str_appxml;
		if(xuri.type==RESOURCE_LIST)
			ctype = &xcaps_str_apprlxml;
		else if(xuri.type==PRES_RULES)
			ctype = &xcaps_str_appapxml;
		else if(xuri.type==RLS_SERVICE)
			ctype = &xcaps_str_apprsxml;
		else if(xuri.type==USER_PROFILE)
			ctype = &xcaps_str_appupxml;
		else if(xuri.type==PRES_CONTENT)
			ctype = &xcaps_str_apppcxml;
		else if(xuri.type==PIDF_MANIPULATION)
			ctype = &xcaps_str_apppdxml;
		xcaps_send_reply(msg, 200, &xcaps_str_ok, &etag,
				ctype, &body);
	} else {
		/* doc not found */
		xcaps_send_reply(msg, 404, &xcaps_str_notfound, &xcaps_str_empty,
				&xcaps_str_empty, &xcaps_str_empty);
	}
	return 1;

error:
	xcaps_send_reply(msg, 500, &xcaps_str_srverr, &xcaps_str_empty,
				&xcaps_str_empty, &xcaps_str_empty);
	return -1;
}


More information about the sr-users mailing list