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

📄 nth_client.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE nth_client.c * @brief HTTP Client implementhtion *  * Copyright (c) 2002 Nokia Research Center.  All rights reserved. *  * This source file has been divided into following sections: * 1) engine * 2) tport handling * 3) client transactions *  * @author Pekka Pessi <Pekka.Pessi@nokia.com> *  * @date Created: Tue Jun 13 02:57:51 2000 ppessi */#include "config.h"#include <stddef.h>#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <assert.h>#include <errno.h>#include <sofia-sip/string0.h>/** @internal SU message argument structure type */#define SU_MSG_ARG_T   union sm_arg_u/** @internal SU timer argument pointer type */#define SU_TIMER_ARG_T struct nth_engine_s#define MSG_HDR_T union http_header_u#define MSG_PUB_T struct http_s#include "sofia-sip/nth.h"#include <sofia-sip/http_header.h>#include <sofia-sip/http_tag.h>#include <sofia-sip/http_status.h>#include <sofia-sip/hostdomain.h>#include <sofia-sip/msg_addr.h>#include <sofia-sip/su_tagarg.h>#include <sofia-sip/auth_client.h>/* We are customer of tport_t */#define TP_STACK_T   nth_engine_t#define TP_MAGIC_T   void#define TP_CLIENT_T  nth_client_t#ifndef TPORT_H#include <sofia-sip/tport.h>#endif#include <sofia-sip/htable.h>#define HE_TIMER HE_TIMERenum { HE_TIMER = 1000 };/** @c http_flag telling that this message is internally generated. */#define NTH_INTERNAL_MSG (1<<16)HTABLE_DECLARE_WITH(hc_htable, hct, nth_client_t, uintptr_t, size_t);struct nth_engine_s {  su_home_t he_home[1];  su_root_t *he_root;  su_timer_t *he_timer;  int he_mflags;			/**< Message flags */  msg_mclass_t const *he_mclass;  tport_t *he_tports;  url_t *he_default_proxy;  unsigned he_now;  unsigned he_expires;  /* Attributes */  unsigned he_streaming:1;		/**< Enable streaming */  unsigned he_error_msg:1;  unsigned:0;  /* Statistics */  struct {    uint32_t st_requests;		/**< Sent requests */    uint32_t st_1xxresponses;		/**< Received 1XX responses */    uint32_t st_responses;		/**< Received responses */    uint32_t st_tp_errors;		/**< Transport errors */    uint32_t st_timeouts;		/**< Timeouts */    uint32_t st_bad;			/**< Bad responses*/  } he_stats[1];  /** Table for client transactions */  hc_htable_t he_clients[1];};struct nth_client_s {  nth_engine_t *hc_engine;  nth_response_f *hc_callback;  nth_client_magic_t *hc_magic;  http_method_t hc_method;  char const *hc_method_name;  url_t const *hc_url;			/**< Original RequestURI  */  unsigned hc_timeout;		        /**< Client timeout */  unsigned hc_expires;		        /**< Client expires */  /* Request state */  unsigned short hc_status;  unsigned hc_destroyed:1;  unsigned hc_completed:1;  unsigned hc_inserted:1;  unsigned hc_is_streaming:1;		/**< Currently streaming response */  /* Attributes */  unsigned hc_streaming:1;		/**< Enable streaming */  unsigned hc_error_msg:1;  unsigned /* pad */:0;				  url_string_t const *hc_route_url;  tp_name_t hc_tpn[1];			/**< Where to send requests */  tport_t *hc_tport;  int hc_pending;			/**< Request is pending in tport */  tagi_t *hc_tags;			/**< Transport tags */  auth_client_t **hc_auc;		/**< List of authenticators */  msg_t *hc_request;  msg_t *hc_response;};/* ====================================================================== *//* Debug log settings */#define SU_LOG   nth_client_log#ifdef SU_DEBUG_H#error <su_debug.h> included directly.#endif#include <sofia-sip/su_debug.h>/**@var NTH_DEBUG * * Environment variable determining the debug log level for @b nth * module. * * The NTH_DEBUG environment variable is used to determine the debug * logging level for @b nth module. The default level is 1. * * @sa <sofia-sip/su_debug.h>, nth_client_log, #SOFIA_DEBUG */extern char const NTH_DEBUG[];#ifndef SU_DEBUG#define SU_DEBUG 1#endif/**Debug log for @b nth module. * * The nth_client_log is the log object used by @b nth client. The level of * #nth_client_log is set using #NTH_DEBUG environment variable. */su_log_t nth_client_log[] = { SU_LOG_INIT("nth", "NTH_DEBUG", SU_DEBUG) };#if HAVE_FUNC#elif HAVE_FUNCTION#define __func__ __FUNCTION__#elsestatic char const __func__[] = "nth";#endif/* ====================================================================== *//* Internal message passing */union sm_arg_u {  struct hc_recv_s {    nth_client_t *hc;    msg_t *msg;    http_t *http;  } hc_recv[1];};/* ====================================================================== *//* Internal prototypes */tagi_t nth_client_tags[] = {  {nthtag_mclass, 0},  {nthtag_message, 0},  {nthtag_mflags, 0},  {nthtag_proxy, 0},  {nthtag_error_msg, 0},  {nthtag_template, 0},  {nthtag_authentication, 0},  {TAG_NEXT(tport_tags)}};/* ====================================================================== *//* Internal prototypes */static int he_create_tports(nth_engine_t * he, tagi_t *tags);static int he_timer_init(nth_engine_t * he);static void he_timer(su_root_magic_t *, su_timer_t *, nth_engine_t * he);static void hc_timer(nth_engine_t * he, nth_client_t * hc, uint32_t now);static uint32_t he_now(nth_engine_t const *he);static void he_recv_message(nth_engine_t * he, tport_t * tport,			    msg_t *msg, void *arg, su_time_t now);static msg_t *he_msg_create(nth_engine_t * he, int flags,			    char const data[], usize_t dlen,			    tport_t const *tport, nth_client_t * hc);static void he_tp_error(nth_engine_t * he,			tport_t * tport, int errcode, char const *remote);static int hc_recv(nth_client_t * hc, msg_t *msg, http_t * http);HTABLE_PROTOS_WITH(hc_htable, hct, nth_client_t, uintptr_t, size_t);#define HTABLE_HASH_CLIENT(hc) ((uintptr_t)(hc)->hc_tport)HTABLE_BODIES_WITH(hc_htable, hct, nth_client_t, HTABLE_HASH_CLIENT,		   uintptr_t, size_t);static url_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 *url,					       char const *version,					       url_t const *parent);staticint hc_request_authenticate(nth_client_t * hc,			    msg_t *msg, http_t * http,			    url_string_t const *uri, auth_client_t **auc);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, ...);static int hc_resolve_and_send(nth_client_t * hc);static nth_client_t *hc_send(nth_client_t * hc);static void hc_insert(nth_engine_t * he, nth_client_t * hc);static void hc_free(nth_client_t * hc);static void hc_tport_error(nth_engine_t *, nth_client_t * hc,			   tport_t * tp, msg_t *msg, int error);static int hc_reply(nth_client_t * hc, int status, char const *phrase);static int hc_default_cb(nth_client_magic_t * magic,			 nth_client_t * request, http_t const *http);/* ---------------------------------------------------------------------- */char const *nth_engine_version(void){  return "sofia-http-client/" NTH_CLIENT_VERSION;}/* ---------------------------------------------------------------------- */nth_engine_t *nth_engine_create(su_root_t *root,				tag_type_t tag, tag_value_t value, ...){  nth_engine_t *he;  ta_list ta;  if ((he = su_home_new(sizeof(*he)))) {    he->he_root = root;    he->he_mflags = MSG_DO_CANONIC;    he->he_mclass = http_default_mclass();    he->he_expires = 32000;    ta_start(ta, tag, value);    if (hc_htable_resize(he->he_home, he->he_clients, 0) < 0 ||	he_create_tports(he, ta_args(ta)) < 0 ||	he_timer_init(he) < 0 || nth_engine_set_params(he, ta_tags(ta)) < 0) {      nth_engine_destroy(he), he = NULL;    }    ta_end(ta);  }  return he;}void nth_engine_destroy(nth_engine_t * he){  if (he) {    size_t i;    hc_htable_t *hct = he->he_clients;    for (i = 0; i < hct->hct_size; i++)      hc_free(hct->hct_table[i]);    tport_destroy(he->he_tports);    su_timer_destroy(he->he_timer), he->he_timer = NULL;    su_home_unref(he->he_home);  }}int nth_engine_set_params(nth_engine_t * he,			  tag_type_t tag, tag_value_t value, ...){  int n;  ta_list ta;  unsigned expires;  int error_msg;  msg_mclass_t const *mclass;  int mflags;  int streaming;  url_string_t const *proxy;  if (he == NULL)    return (errno = EINVAL), -1;  ta_start(ta, tag, value);  expires = he->he_expires;  error_msg = he->he_error_msg;  mclass = he->he_mclass;  mflags = he->he_mflags;  streaming = he->he_streaming;  proxy = (void *) he->he_default_proxy;  n = tl_gets(ta_args(ta),	      NTHTAG_EXPIRES_REF(expires),	      NTHTAG_ERROR_MSG_REF(error_msg),	      NTHTAG_MCLASS_REF(mclass),	      NTHTAG_MFLAGS_REF(mflags),	      NTHTAG_STREAMING_REF(streaming),	      NTHTAG_PROXY_REF(proxy), TAG_END());  if (n > 0) {    if (proxy->us_url != he->he_default_proxy) {      url_t *copy = url_hdup(he->he_home, proxy->us_url);      if (proxy && !copy) {	n = -1;      } else {	su_free(he->he_home, (void *) he->he_default_proxy);	he->he_default_proxy = copy;      }    }  }  if (n > 0) {    he->he_expires = expires;    he->he_error_msg = error_msg != 0;    if (mclass)      he->he_mclass = mclass;    else      he->he_mclass = http_default_mclass();    he->he_mflags = mflags;    he->he_streaming = streaming != 0;  }  ta_end(ta);  return n;}int nth_engine_get_params(nth_engine_t const *he,			  tag_type_t tag, tag_value_t value, ...){  int n;  ta_list ta;  msg_mclass_t const *mclass;  if (he == NULL)    return (errno = EINVAL), -1;  if (he->he_mclass != http_default_mclass())    mclass = he->he_mclass;  else    mclass = NULL;  ta_start(ta, tag, value);  n = tl_tgets(ta_args(ta),	       NTHTAG_ERROR_MSG(he->he_error_msg),	       NTHTAG_MCLASS(mclass),	       NTHTAG_MFLAGS(he->he_mflags),	       NTHTAG_EXPIRES(he->he_expires),	       NTHTAG_STREAMING(he->he_streaming),	       NTHTAG_PROXY((url_string_t *) he->he_default_proxy),	       TAG_END());  ta_end(ta);  return n;}int nth_engine_get_stats(nth_engine_t const *he,			 tag_type_t tag, tag_value_t value, ...){  int n;  ta_list ta;  if (he == NULL)

⌨️ 快捷键说明

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