Esempio n. 1
0
static inline int create_headers(struct watcher* _w, str *dst, str *content_type)
{
    dstring_t buf;
    time_t t;
    int err = 0;

    dstr_init(&buf, 256);
    str_clear(dst);

    /* required by RFC 3261 */
    dstr_append_zt(&buf, "Max-Forwards: 70\r\n");

    /* Event header */

    dstr_append_zt(&buf, "Event: ");
    dstr_append_zt(&buf, event_package2str(_w->event_package));
    dstr_append_zt(&buf, "\r\n");

    /* Content-Type header */

    /* content types can have dynamical parameters (multipart/related)
     * => don't generate them "staticaly"; use values created in the
     * time of document creation */
    if (!is_str_empty(content_type)) { /* documents without body doesn't need it */
        dstr_append_zt(&buf, "Content-Type: ");
        dstr_append_str(&buf, content_type);
        dstr_append_zt(&buf, "\r\n");
    }

    /* Contact header */

    if (is_str_empty(&_w->server_contact)) {
        LOG(L_WARN, "add_contact_hf(): Can't add empty contact to NOTIFY.\n");
    }
    else {
        dstr_append_zt(&buf, "Contact: ");
        dstr_append_str(&buf, &_w->server_contact);
        dstr_append_zt(&buf, "\r\n");
    }

    /* Subscription-State header */

    if (_w->expires) t = _w->expires - time(0);
    else t = 0;

    if (add_subs_state_hf(&buf, _w->status, t) < 0) {
        LOG(L_ERR, "create_headers(): Error while adding Subscription-State\n");
        dstr_destroy(&buf);
        return -3;
    }

    err = dstr_get_str(&buf, dst);
    dstr_destroy(&buf);

    return err;
}
Esempio n. 2
0
char *xcap_uri_for_rls_resource(const str_t *xcap_root, const str_t *uri)
{
	dstring_t s;
	int l;
	str_t c_uri;
	char *dst = NULL;

	if (!xcap_root) return NULL;
	dstr_init(&s, 2 * xcap_root->len + 32);
	dstr_append_str(&s, xcap_root);
	if (xcap_root->s[xcap_root->len - 1] != '/') dstr_append(&s, "/", 1);
	dstr_append_zt(&s, "rls-services/global/index/~~/rls-services/service[@uri=%22");
	canonicalize_uri(uri, &c_uri);
	dstr_append_str(&s, &c_uri);
	if (c_uri.s) cds_free(c_uri.s);
	
	dstr_append_zt(&s, "%22]");
	l = dstr_get_data_length(&s);
	if (l > 0) {
		dst = (char *)cds_malloc(l + 1);
		if (dst) {
			dstr_get_data(&s, dst);
			dst[l] = 0;
		}
	}
	dstr_destroy(&s);
	return dst;
}
Esempio n. 3
0
int create_lpidf_document(presentity_info_t *p, str_t *dst, str_t *dst_content_type)
{
	dstring_t buf;
	int err;
	
	if (!dst) return -1;
	
	str_clear(dst);
	if (dst_content_type) str_clear(dst_content_type);

	if (!p) return -1;
	
	if (dst_content_type) {
		if (str_dup_zt(dst_content_type, "text/lpidf") < 0) {
			return -1;
		}
	}

/*	if (!p->first_tuple) return 0;*/	/* no tuples => nothing to say */ 
	
	dstr_init(&buf, 2048);
	
	doc_add_presentity(&buf, p);
	
	err = dstr_get_str(&buf, dst);
	dstr_destroy(&buf);
	
	if (err != 0) {
		str_free_content(dst);
		if (dst_content_type) str_free_content(dst_content_type);
	}
	
	return err;
}
Esempio n. 4
0
char *xcap_uri_for_rls_services(const str_t *xcap_root)
{
	dstring_t s;
	int l;
	char *dst = NULL;

	if (!xcap_root) return NULL;
	dstr_init(&s, 2 * xcap_root->len + 32);
	dstr_append_str(&s, xcap_root);
	if (xcap_root->s[xcap_root->len - 1] != '/') dstr_append(&s, "/", 1);
	dstr_append_zt(&s, "rls-services/global/index");
	
	l = dstr_get_data_length(&s);
	if (l > 0) {
		dst = (char *)cds_malloc(l + 1);
		if (dst) {
			dstr_get_data(&s, dst);
			dst[l] = 0;
		}
	}
	dstr_destroy(&s);
	return dst;
}
Esempio n. 5
0
static int rls_generate_notify_ext(rl_subscription_t *s, int full_info)
{
	/* !!! the main mutex must be locked here !!! */
	int res;
	str doc;
	dstring_t dstr;
	str headers, content_type;
	static str method = STR_STATIC_INIT(METHOD_NOTIFY);
	dlg_t *dlg;
	int exp_time = 0;
	char expiration[32];
	str body = STR_STATIC_INIT("");
	int removed = 0;

	dlg = s->u.external.dialog;
	if (!dlg) return -1;

	DEBUG("generating external notify\n");
	
	str_clear(&doc);
	str_clear(&content_type);
	if (sm_subscription_pending(&s->u.external) != 0) {
		/* create the document only for non-pending subscriptions */
		if (create_rlmi_document(&doc, &content_type, s, full_info) != 0) {
			return -1;
		}
	}
	
	exp_time = sm_subscription_expires_in(rls_manager, &s->u.external);
	sprintf(expiration, ";expires=%d\r\n", exp_time);
		
	dstr_init(&dstr, 256);
	dstr_append_zt(&dstr, "Subscription-State: ");
	switch (s->u.external.status) {
		case subscription_active: 
				dstr_append_zt(&dstr, "active");
				dstr_append_zt(&dstr, expiration);
				break;
		case subscription_pending: 
				dstr_append_zt(&dstr, "pending");
				dstr_append_zt(&dstr, expiration);
				break;
		case subscription_terminated_pending: 
		case subscription_terminated: 
				dstr_append_zt(&dstr, "terminated\r\n");
				break;
		case subscription_terminated_pending_to: 
		case subscription_terminated_to: 
				dstr_append_zt(&dstr, 
					"terminated;reason=timeout\r\n");
				break;
		case subscription_uninitialized: 
				dstr_append_zt(&dstr, "pending\r\n");
				/* this is an error ! */
				LOG(L_ERR, "sending NOTIFY for an unitialized subscription!\n");
				break;
	}
	dstr_append_str(&dstr, &s->u.external.contact);
	
	/* required by RFC 3261 */
	dstr_append_zt(&dstr, "Max-Forwards: 70\r\n"); 
	dstr_append_zt(&dstr, "Event: ");
	dstr_append_str(&dstr, rls_get_package(s));
	dstr_append_zt(&dstr, "\r\n");
	dstr_append_zt(&dstr, "Require: eventlist\r\nContent-Type: ");
	dstr_append_str(&dstr, &content_type);
	dstr_append_zt(&dstr, "\r\n");

	res = dstr_get_str(&dstr, &headers);
	dstr_destroy(&dstr);

	if (res >= 0) {
		/* DEBUG("sending NOTIFY message to %.*s (subscription %p)\n",  
				dlg->rem_uri.len, 
				ZSW(dlg->rem_uri.s), s); */
		
		if (!is_str_empty(&doc)) body = doc;
		
		if (sm_subscription_terminated(&s->u.external) == 0) {
			/* doesn't matter if delivered or not, it will be freed otherwise !!! */
			res = tmb.t_request_within(&method, &headers, &body, dlg, 0, 0);
			if (res >= 0) clear_change_flags(s);
		}
		else {
			rls_notify_cb_param_t *cbd = create_notify_cb_param(s);
			if (!cbd) {
				ERR("Can't create notify cb data! Freeing RL subscription.\n");
				rls_remove(s); /* ?????? */
				removed = 1;
				res = -13;
			}
			else {
				/* the subscritpion will be destroyed if NOTIFY delivery problems */
				/* rls_unlock();  the callback locks this mutex ! */
				
				/* !!!! FIXME: callbacks can't be safely used (may be called or not,
				 * may free memory automaticaly or not) !!! */
				res = tmb.t_request_within(&method, &headers, &body, dlg, rls_notify_cb, cbd);
				
		/*		res = tmb.t_request_within(&method, &headers, &body, dlg, rls_notify_cb, s); */
				/* rls_lock(); the callback locks this mutex ! */
				if (res < 0) {
					/* does this mean, that the callback was not called ??? */
					ERR("t_request_within FAILED: %d! Freeing RL subscription.\n", res);
					rls_remove(s); /* ?????? */
					removed = 1;
				}
				else clear_change_flags(s);
			}
		}
	}
	
	if (doc.s) cds_free(doc.s);
	if (content_type.s) cds_free(content_type.s);
	if (headers.s) cds_free(headers.s);
	
	if ((!removed) && use_db) rls_db_update(s);
	
	if (res < 0) DEBUG("external notify NOT generated\n");
	else DEBUG("external notify generated\n");
	
	return res;
}
int xcap_query_impl(const char *uri, xcap_query_params_t *params, char **buf, int *bsize)
{
    CURLcode res = -1;
    static CURL *handle = NULL;
    dstring_t data;
    char *auth = NULL;
    int i;
    long auth_methods;

    if (!uri) {
        ERR("BUG: no uri given\n");
        return -1;
    }
    if (!buf) {
        ERR("BUG: no buf given\n");
        return -1;
    }

    i = 0;
    if (params) {
        i += params->auth_user.len;
        i += params->auth_pass.len;
    }
    if (i > 0) {
        /* do authentication */
        auth = (char *)cds_malloc_pkg(i + 2);
        if (!auth) return -1;
        sprintf(auth, "%.*s:%.*s", FMT_STR(params->auth_user),
                FMT_STR(params->auth_pass));
    }

    auth_methods = CURLAUTH_BASIC | CURLAUTH_DIGEST;

    dstr_init(&data, 512);

    if (!handle) handle = curl_easy_init();
    if (handle) {
        curl_easy_setopt(handle, CURLOPT_URL, uri);
        /* TRACE_LOG("uri: %s\n", uri ? uri : "<null>"); */

        /* do not store data into a file - store them in memory */
        curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data_func);
        curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);

        /* be quiet */
#ifdef CURLOPT_MUTE
        curl_easy_setopt(handle, CURLOPT_MUTE, 1);
#endif /* CURLOPT_MUTE */

        /* non-2xx => error */
        curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1);

        /* auth */
        curl_easy_setopt(handle, CURLOPT_HTTPAUTH, auth_methods); /* TODO possibility of selection */
        curl_easy_setopt(handle, CURLOPT_NETRC, CURL_NETRC_IGNORED);
        curl_easy_setopt(handle, CURLOPT_USERPWD, auth);

        /* SSL */
        if (params) {
            if (params->enable_unverified_ssl_peer) {
                curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
                curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0);
            }
        }

        /* follow redirects (needed for apache mod_speling - case insesitive names) */
        curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);

        /*	curl_easy_setopt(handle, CURLOPT_TCP_NODELAY, 1);
        	curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 10);*/

        /* Accept headers */

        res = curl_easy_perform(handle);
        /* curl_easy_cleanup(handle); */ /* FIXME: experimental */
    }
    else ERROR_LOG("can't initialize curl handle\n");
    if (res == 0) {
        *bsize = dstr_get_data_length(&data);
        if (*bsize) {
            *buf = (char*)cds_malloc(*bsize);
            if (!*buf) {
                ERROR_LOG("can't allocate %d bytes\n", *bsize);
                res = -1;
                *bsize = 0;
            }
            else dstr_get_data(&data, *buf);
        }
    }
    else DBG("curl error: %d\n", res); /* see curl/curl.h for possible values*/
    dstr_destroy(&data);
    if (auth) cds_free_pkg(auth);
    return res;
}
Esempio n. 7
0
void destroy_sstream(sstream_t *ss)
{
	if (ss->type == sstream_out) dstr_destroy(&ss->out);
}