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

📄 smsc_http.c

📁 WAP gateway, Linux source
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2007 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * smsc_http.c - interface to various HTTP based content/SMS gateways * * HTTP based "SMSC Connection" is meant for gateway connections, * and has following features: * * o Kannel listens to certain (HTTP server) port for MO SMS messages. *   The exact format of these HTTP calls are defined by type of HTTP based *   connection. Kannel replies to these messages as ACK, but does not *   support immediate reply. Thus, if Kannel is linked to another Kannel, *   only 'max-messages = 0' services are practically supported - any *   replies must be done with SMS PUSH (sendsms) * * o For MT messages, Kannel does HTTP GET or POST to given address, in format *   defined by type of HTTP based protocol * * The 'type' of requests and replies are defined by 'system-type' variable. * The only type of HTTP requests currently supported are basic Kannel. * If new support is added, smsc_http_create is modified accordingly and new * functions added. * * * KANNEL->KANNEL linking: (UDH not supported in MO messages) * ***** * FOR CLIENT/END-POINT KANNEL: * *  group = smsc *  smsc = http *  system-type = kannel *  port = NNN *  smsc-username = XXX *  smsc-password = YYY *  send-url = "server.host:PORT" * ***** * FOR SERVER/RELAY KANNEL: * *  group = smsbox *  sendsms-port = PORT *  ... *  *  group = sms-service *  keyword = ... *  url = "client.host:NNN/sms?user=XXX&pass=YYY&from=%p&to=%P&text=%a" *  max-messages = 0 * *  group = send-sms *  username = XXX *  password = YYY *   * Kalle Marjola for Project Kannel 2001 * Stipe Tolj <st@tolj.org> * Alexander Malysh <amalysh at kannel.org> * Tobias Weber <weber@wapme.de> */#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <errno.h>#include <time.h>#include <limits.h>#include "gwlib/gwlib.h"#include "smscconn.h"#include "smscconn_p.h"#include "bb_smscconn_cb.h"#include "msg.h"#include "sms.h"#include "dlr.h"#include "urltrans.h"typedef struct conndata {    HTTPCaller *http_ref;    long receive_thread;    long send_cb_thread;    int shutdown;    int	port;   /* port for receiving SMS'es */    Octstr *allow_ip;    Octstr *send_url;    Octstr *dlr_url;    /* our own DLR MO URL */    long open_sends;    Octstr *username;   /* if needed */    Octstr *password;   /* as said */    Octstr *system_id;	/* api id for clickatell */    int no_sender;      /* ditto */    int no_coding;      /* this, too */    int no_sep;         /* not to mention this */    Octstr *proxy;      /* proxy a constant string */    /* The following are compiled regex for the 'generic' type for handling      * success, permanent failure and temporary failure. For types that use     * simple HTTP body parsing, these may be used also for other types,     * ie. for our own Kannel reply parsing. */    regex_t *success_regex;       regex_t *permfail_regex;    regex_t *tempfail_regex;    /* callback functions set by HTTP-SMSC type */    void (*send_sms) (SMSCConn *conn, Msg *msg);    void (*parse_reply) (SMSCConn *conn, Msg *msg, int status,                         List *headers, Octstr *body);    void (*receive_sms) (SMSCConn *conn, HTTPClient *client,                         List *headers, Octstr *body, List *cgivars);} ConnData;static void conndata_destroy(ConnData *conndata){    if (conndata == NULL)        return;    if (conndata->http_ref)        http_caller_destroy(conndata->http_ref);    if (conndata->success_regex)        gw_regex_destroy(conndata->success_regex);    if (conndata->permfail_regex)        gw_regex_destroy(conndata->permfail_regex);    if (conndata->tempfail_regex)        gw_regex_destroy(conndata->tempfail_regex);    octstr_destroy(conndata->allow_ip);    octstr_destroy(conndata->send_url);    octstr_destroy(conndata->dlr_url);    octstr_destroy(conndata->username);    octstr_destroy(conndata->password);    octstr_destroy(conndata->proxy);    octstr_destroy(conndata->system_id);    gw_free(conndata);}/* * Thread to listen to HTTP requests from SMSC entity */static void httpsmsc_receiver(void *arg){    SMSCConn *conn = arg;    ConnData *conndata = conn->data;    HTTPClient *client;    Octstr *ip, *url, *body;    List *headers, *cgivars;    ip = url = body = NULL;    headers = cgivars = NULL;    /* Make sure we log into our own log-file if defined */    log_thread_to(conn->log_idx);     while (conndata->shutdown == 0) {        /* XXX if conn->is_stopped, do not receive new messages.. */	        client = http_accept_request(conndata->port, &ip, &url,                                     &headers, &body, &cgivars);        if (client == NULL)            break;        debug("smsc.http", 0, "HTTP[%s]: Got request `%s'",               octstr_get_cstr(conn->id), octstr_get_cstr(url));        if (connect_denied(conndata->allow_ip, ip)) {            info(0, "HTTP[%s]: Connection `%s' tried from denied "                    "host %s, ignored", octstr_get_cstr(conn->id),                    octstr_get_cstr(url), octstr_get_cstr(ip));            http_close_client(client);        } else            conndata->receive_sms(conn, client, headers, body, cgivars);        debug("smsc.http", 0, "HTTP[%s]: Destroying client information",              octstr_get_cstr(conn->id));        octstr_destroy(url);        octstr_destroy(ip);        octstr_destroy(body);        http_destroy_headers(headers);        http_destroy_cgiargs(cgivars);    }    debug("smsc.http", 0, "HTTP[%s]: httpsmsc_receiver dying",          octstr_get_cstr(conn->id));    conndata->shutdown = 1;    http_close_port(conndata->port);        /* unblock http_receive_result() if there are no open sends */    if (conndata->open_sends == 0)        http_caller_signal_shutdown(conndata->http_ref);}/* * Thread to handle finished sendings */static void httpsmsc_send_cb(void *arg){    SMSCConn *conn = arg;    ConnData *conndata = conn->data;    Msg *msg;    int status;    List *headers;    Octstr *final_url, *body;    /* Make sure we log into our own log-file if defined */    log_thread_to(conn->log_idx);    while (conndata->shutdown == 0 || conndata->open_sends) {        msg = http_receive_result(conndata->http_ref, &status,                                  &final_url, &headers, &body);        if (msg == NULL)            break;  /* they told us to die, by unlocking */        /* Handle various states here. */        /* request failed and we are not in shutdown mode */        if (status == -1 && conndata->shutdown == 0) {             error(0, "HTTP[%s]: Couldn't connect to SMS center "                     "(retrying in %ld seconds).",                     octstr_get_cstr(conn->id), conn->reconnect_delay);            conn->status = SMSCCONN_RECONNECTING;             gwthread_sleep(conn->reconnect_delay);            debug("smsc.http.kannel", 0, "HTTP[%s]: Re-sending request",                  octstr_get_cstr(conn->id));            conndata->send_sms(conn, msg);            continue;         }         /* request failed and we *are* in shutdown mode, drop the message */         else if (status == -1 && conndata->shutdown == 1) {        }        /* request succeeded */            else {            /* we received a response, so this link is considered online again */            if (status && conn->status != SMSCCONN_ACTIVE) {                conn->status = SMSCCONN_ACTIVE;                time(&conn->connect_time);            }            conndata->parse_reply(conn, msg, status, headers, body);        }           conndata->open_sends--;        http_destroy_headers(headers);        octstr_destroy(final_url);        octstr_destroy(body);    }    debug("smsc.http", 0, "HTTP[%s]: httpsmsc_send_cb dying",          octstr_get_cstr(conn->id));    conndata->shutdown = 1;    if (conndata->open_sends) {        warning(0, "HTTP[%s]: Shutdown while <%ld> requests are pending.",                octstr_get_cstr(conn->id), conndata->open_sends);    }    gwthread_join(conndata->receive_thread);    conn->data = NULL;    conndata_destroy(conndata);    conn->status = SMSCCONN_DEAD;    bb_smscconn_killed();}/*---------------------------------------------------------------- * SMSC-type specific functions * * 3 functions are needed for each: * *   1) send SMS *   2) parse send SMS result *   3) receive SMS (and send reply) * *   These functions do not return anything and do not destroy *   arguments. They must handle everything that happens therein *   and must call appropriate bb_smscconn functions *//*---------------------------------------------------------------- * Kannel *  * This type allows concatenation of Kannel instances, ie: *  *  <smsc>--<bearerbox2><smsbox2>--HTTP--<smsc_http><bearerbox1><smsbox1> *  * Where MT messages are injected via the sendsms HTTP interface at smsbox1, * forwarded to bearerbo1 and routed via the SMSC HTTP type kannel to  * sendsms HTTP interface of smsbox2 and further on. *  * This allows chaining of Kannel instances for MO and MT traffic. *  * DLR handling: * For DLR handling we have the usual effect that the "last" smsbox instance

⌨️ 快捷键说明

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