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

📄 tport_type_connect.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2006 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 tport_type_connect.c Transport using HTTP CONNECT. * * See tport.docs for more detailed description of tport interface. * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * @author Martti Mela <Martti.Mela@nokia.com> * * @date Created: Fri Mar 24 08:45:49 EET 2006 ppessi */#include "config.h"#include "tport_internal.h"#include <stdlib.h>#include <time.h>#include <assert.h>#include <errno.h>#include <limits.h>/* ---------------------------------------------------------------------- *//* TCP using HTTP CONNECT */#include <sofia-sip/http.h>#include <sofia-sip/http_header.h>static int tport_http_connect_init_primary(tport_primary_t *,					   tp_name_t tpn[1], 					   su_addrinfo_t *, 					   tagi_t const *,					   char const **return_culprit);static void tport_http_connect_deinit_primary(tport_primary_t *);static tport_t *tport_http_connect(tport_primary_t *pri, su_addrinfo_t *ai, 				   tp_name_t const *tpn);static void tport_http_deliver(tport_t *self, msg_t *msg, su_time_t now);typedef struct{  tport_primary_t thc_primary[1];  su_addrinfo_t  *thc_proxy;} tport_http_connect_t;typedef struct{  tport_t thci_tport[1];  msg_t *thci_response;  msg_t *thci_stackmsg;} tport_http_connect_instance_t;tport_vtable_t const tport_http_connect_vtable ={  "TCP", tport_type_connect,  sizeof (tport_http_connect_t),  tport_http_connect_init_primary,  tport_http_connect_deinit_primary,  NULL,  tport_http_connect,  sizeof (tport_http_connect_instance_t),  NULL,  NULL,  NULL,  NULL,  NULL,  tport_recv_stream,  tport_send_stream,  tport_http_deliver,};static int tport_http_connect_init_primary(tport_primary_t *pri,					   tp_name_t tpn[1], 					   su_addrinfo_t *ai, 					   tagi_t const *tags,					   char const **return_culprit){  tport_http_connect_t *thc = (tport_http_connect_t *)pri;  char const *http_connect = NULL;  url_t *http_proxy;  int error;  char const *host, *port;  su_addrinfo_t hints[1];  tl_gets(tags,	  TPTAG_HTTP_CONNECT_REF(http_connect),	  TAG_END());  if (!http_connect)    return *return_culprit = "missing proxy url", -1;  http_proxy = url_hdup(pri->pri_home, URL_STRING_MAKE(http_connect)->us_url);  if (!http_proxy || !http_proxy->url_host)    return *return_culprit = "invalid proxy url", -1;  host = http_proxy->url_host;  port = http_proxy->url_port;  if (!port || !port[0])    port = "8080";  memcpy(hints, ai, sizeof hints);    hints->ai_flags = 0;  hints->ai_addr = NULL;  hints->ai_addrlen = 0;  hints->ai_next = NULL;  hints->ai_canonname = NULL;    error = su_getaddrinfo(host, port, hints, &thc->thc_proxy);  if (error)    return *return_culprit = "su_getaddrinfo", -1;  return tport_tcp_init_client(pri, tpn, ai, tags, return_culprit);}static void tport_http_connect_deinit_primary(tport_primary_t *pri){  tport_http_connect_t *thc = (tport_http_connect_t *)pri;    su_freeaddrinfo(thc->thc_proxy), thc->thc_proxy = NULL;}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"));    msg_destroy(msg);     tport_zap_secondary(tport);    return NULL;  }    tport_set_secondary_timer(tport);  return tport;}#include <sofia-sip/msg_buffer.h>static void tport_http_deliver(tport_t *self, msg_t *msg, su_time_t now){  tport_http_connect_instance_t *thci = (tport_http_connect_instance_t*)self;  if (msg && thci->thci_response == msg) {    tport_http_connect_t *thc = (tport_http_connect_t *)self->tp_pri;    http_t *http = http_object(msg);    if (http && http->http_status) {      SU_DEBUG_0(("tport_http_connect: %u %s\n", 		  http->http_status->st_status,		  http->http_status->st_phrase));      if (http->http_status->st_status < 300) {	msg_buf_move(thci->thci_stackmsg, msg);	thci->thci_response = NULL;	thci->thci_stackmsg = NULL;	return;      }    }    msg_destroy(msg);    thci->thci_response = NULL;    tport_error_report(self, EPROTO, (void *)thc->thc_proxy->ai_addr);    tport_close(self);    return;  }  tport_base_deliver(self, msg, now);}

⌨️ 快捷键说明

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