int sip_add_make(msg_t *msg, sip_t *sip, msg_hclass_t *hc, char const *s) { return msg_header_add_make(msg, sip, hc, s); }
/** Add duplicates of headers from taglist to the TST message. */ int tst_add_tl(msg_t *msg, msg_test_t *tst, tag_type_t tag, tag_value_t value, ...) { tagi_t const *t; ta_list ta; ta_start(ta, tag, value); for (t = ta_args(ta); t; t = tl_next(t)) { if (!(tag = t->t_tag) || !(value = t->t_value)) continue; if (TSTTAG_P(tag)) { msg_hclass_t *hc = (msg_hclass_t *)tag->tt_magic; msg_header_t *h = (msg_header_t *)value, **hh; if (h == NULL) ; else if (h == MSG_HEADER_NONE) { /* Remove header */ hh = msg_hclass_offset(msg_mclass(msg), (msg_pub_t *)tst, hc); while (hh && *hh) msg_header_remove(msg, (msg_pub_t *)tst, *hh); } else if (msg_header_add_dup_as(msg, (msg_pub_t *)tst, hc, h) < 0) break; } else if (TSTTAG_STR_P(tag)) { msg_hclass_t *hc = (msg_hclass_t *)tag->tt_magic; char const *s = (char const *)value; if (s && msg_header_add_make(msg, (msg_pub_t *)tst, hc, s) < 0) break; } else if (tag == tsttag_header_str) { if (msg_header_add_str(msg, (msg_pub_t *)tst, (char const *)value) < 0) break; } } ta_end(ta); return t ? -1 : 0; }
static int nua_notify_client_request(nua_client_request_t *cr, msg_t *msg, sip_t *sip, tagi_t const *tags) { nua_dialog_usage_t *du = cr->cr_usage; struct notifier_usage *nu = nua_dialog_usage_private(du); su_home_t *home = msg_home(msg); sip_time_t now = sip_now(); sip_subscription_state_t *ss = sip->sip_subscription_state; char const *expires; if (du == NULL) /* Subscription has been terminated */ return nua_client_return(cr, SIP_481_NO_TRANSACTION, msg); assert(du && nu); if (du && nua_client_bind(cr, du) < 0) return -1; if (nu->nu_requested) nu->nu_expires = nu->nu_requested; nu->nu_requested = 0; if (nu->nu_expires <= now || du->du_shutdown) { nu->nu_substate = nua_substate_terminated; expires = "expires=0"; } else { expires = su_sprintf(home, "expires=%lu", nu->nu_expires - now); } if (ss == NULL || nua_substate_make(ss->ss_substate) != nu->nu_substate) { if (nu->nu_substate == nua_substate_terminated) expires = nu->nu_expires > now ? "reason=noresource" : "reason=timeout"; ss = sip_subscription_state_format(home, "%s;%s", nua_substate_name(nu->nu_substate), expires); msg_header_insert(msg, (void *)sip, (void *)ss); } else if (nu->nu_substate != nua_substate_terminated) { msg_header_replace_param(home, ss->ss_common, expires); } #if SU_HAVE_EXPERIMENTAL if (nu->nu_tag && !sip->sip_etag) msg_header_add_make(msg, (void *)sip, sip_etag_class, nu->nu_tag); if (nu->nu_no_body) { nu->nu_no_body = 0; msg_header_remove(msg, (void *)sip, (void *)sip->sip_payload); msg_header_remove(msg, (void *)sip, (void *)sip->sip_content_length); } #endif if (nu->nu_substate == nua_substate_terminated) nua_client_set_terminating(cr, 1); if (cr->cr_terminating) { nua_server_request_t *sr; for (sr = du->du_dialog->ds_sr; sr; sr = sr->sr_next) { if (sr->sr_usage == du) { /* If subscribe has not been responded, don't terminate usage by NOTIFY */ sr->sr_terminating = 1; nua_client_set_terminating(cr, 0); break; } } } if (du->du_event && !sip->sip_event) sip_add_dup(cr->cr_msg, sip, (sip_header_t *)du->du_event); return nua_base_client_request(cr, msg, sip, tags); }
static tport_t *tport_http_connect(tport_primary_t *pri, su_addrinfo_t *ai, tp_name_t const *tpn) { tport_http_connect_t *thc = (tport_http_connect_t *)pri; tport_http_connect_instance_t *thci; tport_master_t *mr = pri->pri_master; msg_t *msg, *response; char hostport[TPORT_HOSTPORTSIZE]; tport_t *tport; http_request_t *rq; msg = msg_create(http_default_mclass(), 0); if (!msg) return NULL; tport_hostport(hostport, sizeof hostport, (void *)ai->ai_addr, 1); rq = http_request_format(msg_home(msg), "CONNECT %s HTTP/1.1", hostport); if (msg_header_insert(msg, NULL, (void *)rq) < 0 || msg_header_add_str(msg, NULL, "User-Agent: Sofia-SIP/" VERSION "\n") < 0 || msg_header_add_str(msg, NULL, "Proxy-Connection: keepalive\n") < 0 || msg_header_add_make(msg, NULL, http_host_class, hostport) < 0 || msg_header_add_make(msg, NULL, http_separator_class, "\r\n") < 0 || msg_serialize(msg, NULL) < 0 || msg_prepare(msg) < 0) return (void)msg_destroy(msg), NULL; /* * Create a response message that ignores the body * if there is no Content-Length */ response = msg_create(http_default_mclass(), mr->mr_log | MSG_FLG_MAILBOX); tport = tport_base_connect(pri, thc->thc_proxy, ai, tpn); if (!tport) { msg_destroy(msg); msg_destroy(response); return tport; } thci = (tport_http_connect_instance_t*)tport; thci->thci_response = response; tport->tp_msg = response; msg_set_next(response, thci->thci_stackmsg = tport_msg_alloc(tport, 512)); if (tport_send_msg(tport, msg, tpn, NULL) < 0) { SU_DEBUG_9(("tport_send_msg failed in tpot_http_connect\n" VA_NONE)); msg_destroy(msg); tport_zap_secondary(tport); return NULL; } tport_set_secondary_timer(tport); return tport; }