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; str allow; 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; } switch(xuri.type) { case DIRECTORY: if (strncmp(xuri.file.s, "directory.xml", xuri.file.len) == 0) { if (xcaps_get_directory(msg, &turi.user, &turi.host, &body) < 0) goto error; xcaps_send_reply(msg, 200, &xcaps_str_ok, NULL, &xcaps_str_appdrxml, &body); } else { xcaps_send_reply(msg, 404, &xcaps_str_notfound, NULL, NULL, NULL); } break; case XCAP_CAPS: xcaps_send_reply(msg, 501, &xcaps_str_notimplemented, NULL, NULL, NULL); break; case SEARCH: allow.s = xcaps_hdr_buf; allow.len = snprintf(allow.s, XCAPS_HDR_SIZE, "Allow: POST\r\n"); xcaps_send_reply(msg, 405, &xcaps_str_notallowed, &allow, NULL, NULL); break; default: 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, NULL, NULL, NULL); return 1; } if((ret=check_preconditions(msg, etag))==-1) { xcaps_send_reply(msg, 412, &xcaps_str_precon, NULL, NULL, NULL); return -2; } else if (ret==-2) { xcaps_send_reply(msg, 304, &xcaps_str_notmod, NULL, NULL, NULL); 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(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, NULL, NULL, NULL); } break; } return 1; error: xcaps_send_reply(msg, 500, &xcaps_str_srverr, NULL, NULL, NULL); return -1; }
static int ki_xcaps_get(sip_msg_t* msg, str* uri, str* path) { struct sip_uri turi; str etag = {0, 0}; str body = {0, 0}; str new_body = {0, 0}; int ret = 0; xcap_uri_t xuri; str *ctype; str allow; if(uri->s==NULL || uri->len == 0) { LM_ERR("invalid uri parameter\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 [%.*s]\n", uri->len, uri->s); 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; } switch(xuri.type) { case DIRECTORY: if (strncmp(xuri.file.s, "directory.xml", xuri.file.len) == 0) { if (xcaps_get_directory(msg, &turi.user, &turi.host, &body) < 0) goto error; xcaps_send_reply(msg, 200, &xcaps_str_ok, NULL, &xcaps_str_appdrxml, &body); } else { xcaps_send_reply(msg, 404, &xcaps_str_notfound, NULL, NULL, NULL); } break; case XCAP_CAPS: xcaps_send_reply(msg, 501, &xcaps_str_notimplemented, NULL, NULL, NULL); break; case SEARCH: allow.s = xcaps_hdr_buf; allow.len = snprintf(allow.s, XCAPS_HDR_SIZE, "Allow: POST\r\n"); xcaps_send_reply(msg, 405, &xcaps_str_notallowed, &allow, NULL, NULL); break; default: 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, NULL, NULL, NULL); return 1; } if((ret=check_preconditions(msg, etag))==-1) { xcaps_send_reply(msg, 412, &xcaps_str_precon, NULL, NULL, NULL); return -2; } else if (ret==-2) { xcaps_send_reply(msg, 304, &xcaps_str_notmod, NULL, NULL, NULL); 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(ret!=0) { /* doc not found */ xcaps_send_reply(msg, 404, &xcaps_str_notfound, NULL, NULL, NULL); break; } if(xuri.nss!=NULL && xuri.node.len>0) { if((new_body.s = pkg_malloc(body.len))==NULL) { LM_ERR("allocating package memory\n"); goto error; } new_body.len = body.len; if(xcaps_xpath_hack(&body, 0)<0) { LM_ERR("could not hack xcap document\n"); goto error; } if(xcaps_xpath_get(&body, &xuri.node, &new_body)<0) { LM_ERR("could not retrieve element from xcap document\n"); goto error; } if(new_body.len<=0) { /* element not found */ xcaps_send_reply(msg, 404, &xcaps_str_notfound, NULL, NULL, NULL); pkg_free(new_body.s); new_body.s = NULL; break; } if(xcaps_xpath_hack(&new_body, 1)<0) { LM_ERR("could not hack xcap document\n"); goto error; } memcpy(body.s, new_body.s, new_body.len); body.len = new_body.len; pkg_free(new_body.s); new_body.s = NULL; } /* doc or element 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); break; } return 1; error: if (new_body.s) pkg_free(new_body.s); xcaps_send_reply(msg, 500, &xcaps_str_srverr, NULL, NULL, NULL); return -1; }