⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nth_client.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 3 页
字号:
    return (errno = EINVAL), -1;  ta_start(ta, tag, value);  n = tl_tgets(ta_args(ta), TAG_END());  ta_end(ta);  return n;}static tp_name_t he_name[1] = { {"*", "*", "*", "*"} };static char const *const he_tports[] = {  "tcp", "tls", NULL};static char const *const he_no_tls_tports[] = { "tcp", NULL };static tp_stack_class_t http_client_class[1] = { {						  sizeof(http_client_class),						  he_recv_message,						  he_tp_error,						  he_msg_create}};/** Create transports for client engine */staticint he_create_tports(nth_engine_t * he, tagi_t *tags){  he->he_tports = tport_tcreate(he, http_client_class, he->he_root, TAG_END());  if (!he->he_tports)    return -1;  if (tport_tbind(he->he_tports, he_name, he_tports,		  TPTAG_SERVER(0), TAG_NEXT(tags)) >= 0)    return 0;  return tport_tbind(he->he_tports, he_name, he_no_tls_tports,		     TPTAG_SERVER(0), TAG_NEXT(tags));}/** Initialize engine timer. */staticint he_timer_init(nth_engine_t * he){  he->he_timer = su_timer_create(su_root_task(he->he_root), HE_TIMER);  return su_timer_set(he->he_timer, he_timer, he);}/** * Engine timer routine. */staticvoid he_timer(su_root_magic_t *rm, su_timer_t *timer, nth_engine_t * he){  unsigned i;  uint32_t now;  hc_htable_t *hct = he->he_clients;  now = su_time_ms(su_now());  now += now == 0;  he->he_now = now;  if (hct)    for (i = hct->hct_size; i > 0;)      if (hct->hct_table[--i])	hc_timer(he, hct->hct_table[i], now);  su_timer_set(timer, he_timer, he);  he->he_now = 0;}/** Get current timestamp in milliseconds */staticuint32_t he_now(nth_engine_t const *he){  if (he->he_now)    return he->he_now;  else    return su_time_ms(su_now());}staticvoid he_recv_message(nth_engine_t * he,		     tport_t * tport, msg_t *msg, void *arg, su_time_t now){  nth_client_t *hc, **hcp;  tp_name_t const *tpn;  for (hcp = hc_htable_hash(he->he_clients, (hash_value_t)(uintptr_t) tport);       (hc = *hcp); hcp = hc_htable_next(he->he_clients, hcp)) {    if (hc->hc_tport == tport) {      if (hc_recv(hc, msg, http_object(msg)) < 0)	msg_destroy(msg);      return;    }  }  /* Extra response? Framing error? */  tpn = tport_name(tport);  if (msg_size(msg))    SU_DEBUG_3(("nth client: received extra data ("MOD_ZU" bytes) "		"from %s/%s:%s\n",		(size_t)msg_size(msg), 		tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port));  else    SU_DEBUG_3(("nth client: received extra data from %s/%s:%s\n",		tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port));  msg_destroy(msg);  tport_shutdown(tport, 2);}/** Report error from transport */static void he_tp_error(nth_engine_t * he,			tport_t * tport, int errcode, char const *remote){  su_log("\nth: tport: %s%s%s\n",	 remote ? remote : "", remote ? ": " : "", su_strerror(errcode));}/** Create a new message. */msg_t *nth_engine_msg_create(nth_engine_t * he, int flags){  if (he == NULL) {    errno = EINVAL;    return NULL;  }  flags |= he->he_mflags;  if (he->he_streaming)    flags |= MSG_FLG_STREAMING;  else    flags &= ~MSG_FLG_STREAMING;  return msg_create(he->he_mclass, flags);}/** Create a new message for transport */staticmsg_t *he_msg_create(nth_engine_t * he, int flags,		     char const data[], usize_t dlen,		     tport_t const *tport, nth_client_t * hc){  flags |= he->he_mflags;  if (he->he_streaming)    flags |= MSG_FLG_STREAMING;  else    flags &= ~MSG_FLG_STREAMING;  if (hc == NULL) {    nth_client_t **slot;    for (slot = hc_htable_hash(he->he_clients, (hash_value_t)(uintptr_t) tport);	 (hc = *slot); slot = hc_htable_next(he->he_clients, slot))      if (hc->hc_tport == tport)	break;  }  if (hc) {    if (hc->hc_method == http_method_head) {      flags &= ~MSG_FLG_STREAMING;      flags |= HTTP_FLG_NO_BODY;    }  }  return msg_create(he->he_mclass, flags);}/** Get destination name from Host header and request URI. */staticint tpn_by_host(tp_name_t * tpn, http_host_t const *h, url_t const *url){  if (!h || !url)    return -1;  tpn->tpn_proto = url_tport_default(url->url_type);  tpn->tpn_canon = h->h_host;  tpn->tpn_host = h->h_host;  if (h->h_port)    tpn->tpn_port = h->h_port;  else    tpn->tpn_port = url_port_default(url->url_type);  return 0;}/* ---------------------------------------------------------------------- */nth_client_t *nth_client_tcreate(nth_engine_t * engine,				 nth_response_f * callback,				 nth_client_magic_t * magic,				 http_method_t method, char const *name,				 url_string_t const *uri,				 tag_type_t tag, tag_value_t value, ...){  nth_client_t *hc = NULL;  ta_list ta;  if (engine) {    void *none = &none;    msg_t *msg = none;    http_t *http;    char const *version = http_version_1_1;    nth_client_t const *template = NULL;    auth_client_t **auc = none;    unsigned expires = engine->he_expires;    int ok = 0;    ta_start(ta, tag, value);    tl_gets(ta_args(ta),	    NTHTAG_TEMPLATE_REF(template),	    NTHTAG_AUTHENTICATION_REF(auc),	    NTHTAG_MESSAGE_REF(msg),	    NTHTAG_EXPIRES_REF(expires),	    HTTPTAG_VERSION_REF(version), 	    TAG_END());    if (msg == none) {      if (template && template->hc_request)	msg = msg_copy(template->hc_request);      else	msg = msg_create(engine->he_mclass, engine->he_mflags);    }    http = http_object(msg);    if (template) {      if (callback == NULL)	callback = template->hc_callback;      if (magic == NULL)	magic = template->hc_magic;      if (name == NULL)	method = template->hc_method, name = template->hc_method_name;      if (uri == NULL)	uri = (url_string_t *) template->hc_url;      if (auc == none)	auc = template->hc_auc;    } else if (auc == none) {      auc = NULL;    }    hc = hc_create(engine, callback, magic, msg, ta_tags(ta));    if (hc)      hc->hc_expires = expires;    if (hc == NULL)      ;    else if (http_add_tl(msg, http, ta_tags(ta)) < 0)      ;    else if (!(uri = hc_request_complete(hc, msg, http,					 method, name, uri, version,					 nth_client_url(template))))      ;    else if (auc && hc_request_authenticate(hc, msg, http, uri, auc) <= 0)      ;    else if (hc_resolve_and_send(hc) < 0)      ;    else      ok = 1;    if (!ok) {      if (hc)	hc_free(hc);      else	msg_destroy(msg);      hc = NULL;    }    ta_end(ta);  }  return hc;}staticurl_string_t const *hc_request_complete(nth_client_t * hc,					msg_t *msg, http_t * http,					http_method_t method,					char const *name,					url_string_t const *uri,					char const *version,					url_t const *parent){  su_home_t *home = msg_home(msg);  http_host_t *host = http->http_host;  void *tbf = NULL;  url_t const *url;  url_t u[1];  if (uri == NULL && http->http_request)    uri = (url_string_t *) http->http_request->rq_url;  if (uri == NULL)    uri = (url_string_t *) parent;  url = url_string_p(uri) ? (tbf = url_hdup(NULL, uri->us_url)) : uri->us_url;  if (!url)    return NULL;  *u = *url;  if (u->url_type == url_unknown && u->url_path && !u->url_host) {    if (parent) {      *u = *parent;      u->url_path = url->url_path;	/* XXX - relative URLs! */      u->url_params = url->url_params;      u->url_headers = url->url_headers;	/* Query */    }  }  if (!hc->hc_route_url && u->url_type != url_http      && u->url_type != url_https)    hc->hc_route_url = (url_string_t *) u;  if (host &&      (host_cmp(host->h_host, u->url_host) ||       str0cmp(host->h_port, u->url_port)))    host = NULL;  if (host == NULL && u->url_host) {    host = http_host_create(home, u->url_host, u->url_port);    msg_header_insert(msg, http, (http_header_t *) host);  }  if (u->url_host || hc->hc_route_url || host)    hc->hc_url = url_hdup(home, u);  if (hc->hc_route_url == (url_string_t *) u)    hc->hc_route_url = (url_string_t *) hc->hc_url;  if (hc->hc_url) {    http_request_t *rq = http->http_request;    if (rq && !method && !name)      method = rq->rq_method, name = rq->rq_method_name;    else if (rq && method && method != rq->rq_method)      rq = NULL;    else if (rq && name && strcmp(name, rq->rq_method_name))      rq = NULL;    if (rq && version && strcasecmp(version, rq->rq_version))      rq = NULL;    if (!hc->hc_route_url) {      u->url_type = url_unknown, u->url_scheme = NULL;      u->url_user = NULL, u->url_password = NULL;      u->url_host = NULL, u->url_port = NULL;      u->url_root = '/';      if (!u->url_path)	u->url_path = "";      u->url_fragment = NULL;    }    if (rq && http_url_cmp(u, rq->rq_url))      rq = NULL;    if (!rq) {      if (http->http_request)	msg_header_remove(msg, http, (msg_header_t *) http->http_request);      http->http_request =	http_request_create(home, method, name, (url_string_t *) u, version);      if (!http->http_request)	uri = NULL;    }  } else {    uri = NULL;  }  if (http_message_complete(msg, http) < 0)    uri = NULL;  if (tbf)    su_free(NULL, tbf);  if (uri) {    hc->hc_method = http->http_request->rq_method;    hc->hc_method_name = http->http_request->rq_method_name;  }  return uri;}staticint hc_request_authenticate(nth_client_t * hc,			    msg_t *msg,			    http_t * http,			    url_string_t const *uri, auth_client_t **auc){  return auc_authorization(auc, msg, http,			   http->http_request->rq_method_name,			   uri->us_url, http->http_payload);}staticnth_client_t *hc_create(nth_engine_t * he,			nth_response_f * callback,			nth_client_magic_t * magic,			msg_t *msg, tag_type_t tag, tag_value_t value, ...){  nth_client_t *hc;  su_home_t *home = msg_home(msg);  if (!(hc = su_zalloc(he->he_home, sizeof(*hc))))    return NULL;  if (!callback)    callback = hc_default_cb;  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -