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

📄 wap-appl.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 4 页
字号:
             * Note: if request is HEAD, body is empty and we still need to adapt             * content-type but we don't need to convert a 0 bytes body              */            if (allow_empty && octstr_len(content->body) == 0)                 return 1;            new_body = converters[i].convert(content);            if (new_body != NULL) {                long s = octstr_len(content->body);                octstr_destroy(content->body);                octstr_destroy(content->type);                content->body = new_body;                content->type = octstr_create(converters[i].result_type);                debug("wap.convert",0,"WSP: Content-type is "                      "now <%s>, size %ld bytes (before: %ld bytes), content body is:",                       converters[i].result_type, octstr_len(new_body), s);                octstr_dump(new_body, 0);                return 1;            }            debug("wap.convert",0,"WSP: Content convertion failed!");            failed = 1;        }    }        return (failed ? -1 : 0);}/*  * Tries to deconvert or decompile a specific content-type to * it's complementing one. * Returns 1 if an deconvertion has been successfull, * -1 if an deconvertion failed and 0 if no deconvertion routine * was maching this content-type */static int deconvert_content(struct content *content) {    Octstr *new_body;    int failed = 0;    int i;    debug("wap.deconvert",0,"WSP deconvert: Trying to deconvert:");     octstr_dump(content->body, 0);    for (i = 0; i < NUM_DECONVERTERS; i++) {        if (octstr_str_compare(content->type, deconverters[i].type) == 0) {            debug("wap.deconvert",0,"WSP: Deconverting from <%s> to <%s>",                   octstr_get_cstr(content->type),             deconverters[i].result_type);            new_body = deconverters[i].deconvert(content);            if (new_body != NULL) {                long s = octstr_len(content->body);                octstr_destroy(content->body);                octstr_destroy(content->type);                content->body = new_body;                content->type = octstr_create(deconverters[i].result_type);                debug("wap.convert",0,"WSP: Content-type is "                      "now <%s>, size %ld bytes (before: %ld bytes), content body is:",                 deconverters[i].result_type, octstr_len(new_body), s);                octstr_dump(new_body, 0);                return 1;            }            debug("wap.deconvert",0,"WSP: Content convertion failed!");            failed = 1;        }    }        return (failed ? -1 : 0);}/* Add a header identifying our gateway version */static void add_kannel_version(List *headers) {    http_header_add(headers, "X-WAP-Gateway", GW_NAME "/" GW_VERSION);}/* Add Accept-Charset: headers for stuff the WML compiler can * convert to UTF-8. *//* XXX This is not really correct, since we will not be able * to handle those charsets for all content types, just WML/XHTML. */static void add_charset_headers(List *headers) {    long i, len;        gw_assert(charsets != NULL);    len = list_len(charsets);    for (i = 0; i < len; i++) {        unsigned char *charset = octstr_get_cstr(list_get(charsets, i));        if (!http_charset_accepted(headers, charset))            http_header_add(headers, "Accept-Charset", charset);    }}/* Add Accept: headers for stuff we can convert for the phone */static void add_accept_headers(List *headers) {    int i;        for (i = 0; i < NUM_CONVERTERS; i++) {        if (http_type_accepted(headers, "*/*") || (            http_type_accepted(headers, converters[i].result_type)            && !http_type_accepted(headers, converters[i].type))) {            http_header_add(headers, "Accept", converters[i].type);        }    }}/* Add X-WAP-Network-Client-IP: header to proxy client IP to HTTP server */static void add_network_info(List *headers, WAPAddrTuple *addr_tuple) {    if (octstr_len(addr_tuple->remote->address) > 0) {        http_header_add(headers, "X-WAP-Network-Client-IP",                         octstr_get_cstr(addr_tuple->remote->address));    }}/* Add X-WAP-Session-ID: header to request */static void add_session_id(List *headers, long session_id) {    if (session_id != -1) {        char buf[40];        sprintf(buf, "%ld", session_id);        http_header_add(headers, "X-WAP-Session-ID", buf);    }}/* Add X-WAP-Client-SDU-Size: to provide information on client capabilities */static void add_client_sdu_size(List *headers, long sdu_size) {    if (sdu_size > 0) {        Octstr *buf;	        buf = octstr_format("%ld", sdu_size);        http_header_add(headers, "X-WAP-Client-SDU-Size", octstr_get_cstr(buf));        octstr_destroy(buf);    }}/* Add proxy Via: header to request with our Kannel version */static void add_via(List *headers) {    Octstr *os;    Octstr *version;        version = http_header_value(headers, octstr_imm("Encoding-Version"));    os = octstr_format("WAP/%s %S (" GW_NAME "/%s)",                        (version ? octstr_get_cstr(version) : "1.1"),                       get_official_name(), GW_VERSION);    http_header_add(headers, "Via", octstr_get_cstr(os));    octstr_destroy(os);    octstr_destroy(version);}/* * Add an X-WAP.TOD header to the response headers.  It is defined in * the "WAP Caching Model" specification. * We generate it in textual form and let WSP header packing convert it * to binary form. */static void add_x_wap_tod(List *headers) {    Octstr *gateway_time;        gateway_time = date_format_http(time(NULL));    if (gateway_time == NULL) {        warning(0, "Could not add X-WAP.TOD response header.");        return;    }        http_header_add(headers, "X-WAP.TOD", octstr_get_cstr(gateway_time));    octstr_destroy(gateway_time);}/* Add MSISDN provisioning information to HTTP header */static void add_msisdn(List *headers, WAPAddrTuple *addr_tuple,                        Octstr *send_msisdn_header) {    Octstr *msisdn = NULL;    Octstr *value = NULL;    if (send_msisdn_header == NULL || octstr_len(send_msisdn_header) == 0)        return;    /*      * Security considerations. If there are headers with the header name we     * use to pass on the MSISDN number, then remove them.     */    if ((value = http_header_value(headers, send_msisdn_header)) != NULL) {        warning(0, "MSISDN header <%s> already present on request, "                   "header value=<%s>", octstr_get_cstr(send_msisdn_header),                   octstr_get_cstr(value));        http_header_remove_all(headers, octstr_get_cstr(send_msisdn_header));    }    /*      * XXX Add generic msisdn provisioning cleanly in here!     * See revision 1.89 for Bruno's try.     */    /* We do not accept NULL values to be added to the HTTP header */    if ((msisdn = radius_acct_get_msisdn(addr_tuple->remote->address)) != NULL) {        http_header_add(headers, octstr_get_cstr(send_msisdn_header), octstr_get_cstr(msisdn));    }    octstr_destroy(value);    octstr_destroy(msisdn);}/* XXX DAVI: Disabled in cvs revision 1.81 for Opengroup testsstatic void add_referer_url(List *headers, Octstr *url) {    if (octstr_len(url) > 0) {	   http_header_add(headers, "Referer", octstr_get_cstr(url));    }}*/static void set_referer_url(Octstr *url, WSPMachine *sm){	gw_assert(url != NULL);	gw_assert(sm != NULL);    octstr_destroy(sm->referer_url);    sm->referer_url = octstr_duplicate(url);}static Octstr *get_referer_url(const WSPMachine *sm){    return sm ? sm->referer_url : NULL;}/* * Return the reply from an HTTP request to the phone via a WSP session. */static void return_session_reply(long server_transaction_id, long status,    	    	    	    	 List *headers, Octstr *body, long session_id){    WAPEvent *e;        e = wap_event_create(S_MethodResult_Req);    e->u.S_MethodResult_Req.server_transaction_id = server_transaction_id;    e->u.S_MethodResult_Req.status = status;    e->u.S_MethodResult_Req.response_headers = headers;    e->u.S_MethodResult_Req.response_body = body;    e->u.S_MethodResult_Req.session_id = session_id;    wsp_session_dispatch_event(e);}/* * Return the reply from an HTTP request to the phone via connectionless * WSP. */static void return_unit_reply(WAPAddrTuple *tuple, long transaction_id,    	    	    	      long status, List *headers, Octstr *body){    WAPEvent *e;    e = wap_event_create(S_Unit_MethodResult_Req);    e->u.S_Unit_MethodResult_Req.addr_tuple =     	wap_addr_tuple_duplicate(tuple);    e->u.S_Unit_MethodResult_Req.transaction_id = transaction_id;    e->u.S_Unit_MethodResult_Req.status = status;    e->u.S_Unit_MethodResult_Req.response_headers = headers;    e->u.S_Unit_MethodResult_Req.response_body = body;    wsp_unit_dispatch_event(e);}/* * Return an HTTP reply back to the phone. */static void return_reply(int status, Octstr *content_body, List *headers,    	    	    	 long sdu_size, WAPEvent *orig_event, long session_id,                          Octstr *method, Octstr *url, int x_wap_tod,                         List *request_headers){    struct content content;    int converted;    WSPMachine *sm;    List *device_headers;    WAPAddrTuple *addr_tuple;    Octstr *ua, *server;    content.url = url;    content.body = content_body;    content.version = content.type = content.charset = NULL;    server = ua = NULL;    /* Get session machine for this session. If this was a connection-less     * request be obviously will not find any session machine entry. */    sm = find_session_machine_by_id(session_id);    /* ensure we pass only the original headers to the convertion routine */    device_headers = (orig_event->type == S_MethodInvoke_Ind) ?        orig_event->u.S_MethodInvoke_Ind.request_headers :        orig_event->u.S_Unit_MethodInvoke_Ind.request_headers;    if (device_headers == NULL)        device_headers = list_create();    /*      * We are acting as a proxy. Hence ensure we log a correct HTTP response     * code to our access-log file to allow identification of failed proxying     * requests in the main accesss-log.     */    /* get client IP and User-Agent identifier */    addr_tuple = (orig_event->type == S_MethodInvoke_Ind) ?        orig_event->u.S_MethodInvoke_Ind.addr_tuple :         orig_event->u.S_Unit_MethodInvoke_Ind.addr_tuple;    ua = http_header_value(request_headers, octstr_imm("User-Agent"));    if (headers != NULL) {        /* get response content type and Server identifier */        http_header_get_content_type(headers, &content.type, &content.charset);        server = http_header_value(headers, octstr_imm("Server"));    }    /* log the access */    /* XXX make this configurable in the future */    alog("%s %s <%s> (%s, charset='%s') %ld %d <%s> <%s>",          octstr_get_cstr(addr_tuple->remote->address),          octstr_get_cstr(method), octstr_get_cstr(url),          content.type ? octstr_get_cstr(content.type) : "",          content.charset ? octstr_get_cstr(content.charset) : "",         octstr_len(content.body), status < 0 ? HTTP_BAD_GATEWAY : status,         ua ? octstr_get_cstr(ua) : "",         server ? octstr_get_cstr(server) : "");    octstr_destroy(ua);    octstr_destroy(server);        if (status < 0) {        error(0, "WSP: HTTP lookup failed, oops.");        /* smart WSP error messaging?! */        if (wsp_smart_errors) {            Octstr *referer_url;            status = HTTP_OK;            content.type = octstr_create("text/vnd.wap.wml");            content.charset = octstr_create("");            /*             * check if a referer for this URL exists and              * get back to the previous page in this case             */            if ((referer_url = get_referer_url(find_session_machine_by_id(session_id)))) {                content.body = error_requesting_back(url, referer_url);                debug("wap.wsp",0,"WSP: returning smart error WML deck for referer URL");            }             /*             * if there is no referer to retun to, check if we have a             * device-home defined and return to that, otherwise simply             * drop an error wml deck.             */            else if (device_home != NULL) {                content.body = error_requesting_back(url, device_home);                debug("wap.wsp",0,"WSP: returning smart error WML deck for device-home URL");            } else {                content.body = error_requesting(url);                debug("wap.wsp",0,"WSP: returning smart error WML deck");            }            /*              * if we did not connect at all there is no content in              * the headers list, so create for the upcoming transformation             */            if (headers == NULL)                headers = http_create_empty_headers();            converted = convert_content(&content, device_headers, 0);            if (converted == 1)                http_header_mark_transformation(headers, content.body, content.type);        } else {            /* no WSP smart error messaging */            status = HTTP_BAD_GATEWAY;            content.type = octstr_create("text/plain");            content.charset = octstr_create("");            content.body = octstr_create("");        }    } else {        /* received response by HTTP server */ #ifdef ENABLE_COOKIES        if (session_id != -1)            /* DAVI if (get_cookies(url, headers, find_session_machine_by_id(session_id)) == -1) */            if (get_cookies(headers, find_session_machine_by_id(session_id)) == -1)                error(0, "WSP: Failed to extract cookies");#endif        /*          * XXX why do we transcode charsets on the content body here?!         * Why is this not in the scope of the HTTP server, rather         * then doing this inside Kannel?! st.          */        /*          * Adapts content body's charset to device.         * If device doesn't support body's charset but supports UTF-8, this          * block tries to convert body to UTF-8.          * (This is required for Sharp GX20 for example)         */        if (octstr_search(content.type, octstr_imm("text/vnd.wap.wml"), 0) >= 0 ||             octstr_search(content.type, octstr_imm("application/xhtml+xml"), 0) >= 0 ||            octstr_search(content.type, octstr_imm("application/vnd.wap.xhtml+xml"), 0) >= 0) {            Octstr *charset;                        /* get charset used in content body, default to utf-8 if not present */            if ((charset = find_charset_encoding(content.body)) == NULL)                charset = octstr_imm("UTF-8");             /* convert to utf-8 if original charset is not utf-8              * and device supports it */            if (octstr_case_compare(charset, octstr_imm("UTF-8")) < 0 &&                !http_charset_accepted(device_headers, octstr_get_cstr(charset))) {                if (!http_charset_accepted(device_headers, "UTF-8")) {

⌨️ 快捷键说明

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