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

📄 wap-appl.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 4 页
字号:
                    warning(0, "WSP: Device doesn't support charset <%s> neither UTF-8",                                 octstr_get_cstr(charset));                } else {                    /* convert to utf-8 */                    debug("wsp",0,"Converting wml/xhtml from charset <%s> to UTF-8",                           octstr_get_cstr(charset));                    if (charset_convert(content.body,                                         octstr_get_cstr(charset), "UTF-8") >= 0) {                        octstr_destroy(content.charset);                        content.charset = octstr_create("UTF-8");                        /* XXX it might be good idea to change <?xml...encoding?> */                    }                 }            }             /* convert to iso-8859-1 if original charset is not iso              * and device supports it */            else if (octstr_case_compare(charset, octstr_imm("ISO-8859-1")) < 0 &&                    !http_charset_accepted(device_headers, octstr_get_cstr(charset))) {                if (!http_charset_accepted(device_headers, "ISO-8859-1")) {                    warning(0, "WSP: Device doesn't support charset <%s> neither ISO-8859-1",                             octstr_get_cstr(charset));                } else {                    /* convert to iso-latin1 */                    debug("wsp",0,"Converting wml/xhtml from charset <%s> to ISO-8859-1",                           octstr_get_cstr(charset));                    if (charset_convert(content.body,                                         octstr_get_cstr(charset), "ISO-8859-1") >= 0) {                        octstr_destroy(content.charset);                        content.charset = octstr_create("ISO-8859-1");                        /* XXX it might be good idea to change <?xml...encoding?> */                    }                }            }            octstr_destroy(charset);        }        /* set WBXML Encoding-Version for wml->wmlc conversion */        if (sm != NULL) {            content.version = http_header_value(sm->http_headers,                                                 octstr_imm("Encoding-Version"));        } else {            content.version = NULL;        }        /* convert content-type by our own converter table */        converted = convert_content(&content, device_headers,                                     octstr_compare(method, octstr_imm("HEAD")) == 0);        if (converted < 0) {            warning(0, "WSP: All converters for `%s' at `%s' failed.",                    octstr_get_cstr(content.type), octstr_get_cstr(url));            /*              * Don't change status; just send the client what we did get.             * Or if smart error messages are configured, send a wmlc deck             * with accurate information.             */            if (wsp_smart_errors) {                octstr_destroy(content.body);                octstr_destroy(content.charset);                content.body = error_converting(url, content.type);                content.charset = octstr_create("UTF-8");                                debug("wap.wsp",0,"WSP: returning smart error WML deck for failed converters");                converted = convert_content(&content, device_headers, 0);                if (converted == 1)                    http_header_mark_transformation(headers, content.body, content.type);            }        }        else if (converted == 1) {            http_header_mark_transformation(headers, content.body, content.type);            /*              * set referer URL to WSPMachine, but only if this was a converted             * content-type, like .wml             */            if (session_id != -1) {                debug("wap.wsp.http",0,"WSP: Setting Referer URL to <%s>",                       octstr_get_cstr(url));                if ((sm = find_session_machine_by_id(session_id)) != NULL) {                    set_referer_url(url, sm);                } else {                    error(0,"WSP: Failed to find session machine for ID %ld",                          session_id);                }            }        }        /* if converted == 0 then we pass the content wihtout modification */    }    if (headers == NULL)        headers = http_create_empty_headers();    http_remove_hop_headers(headers);    http_header_remove_all(headers, "X-WAP.TOD");    if (x_wap_tod)        add_x_wap_tod(headers);    if (content.body == NULL)        content.body = octstr_create("");       /*     * Deal with otherwise wap-aware servers that return text/html error     * messages if they report an error.     * (Normally we leave the content type alone even if the client doesn't     * claim to accept it, because the server might know better than the     * gateway.)     */    if (http_status_class(status) != HTTP_STATUS_SUCCESSFUL &&        !http_type_accepted(request_headers, octstr_get_cstr(content.type))) {        warning(0, "WSP: Content type <%s> not supported by client,"                   " deleting body.", octstr_get_cstr(content.type));        octstr_destroy(content.body);        content.body = octstr_create("");        octstr_destroy(content.type);        content.type = octstr_create("text/plain");        http_header_mark_transformation(headers, content.body, content.type);    }    /* remove body if request method was HEAD, we act strictly here */    else if (octstr_compare(method, octstr_imm("HEAD")) == 0) {        octstr_destroy(content.body);        content.body = octstr_create("");        /* change to text/plain if received content-type is not accepted */        if (!http_type_accepted(request_headers, "*/*") &&            !http_type_accepted(request_headers, octstr_get_cstr(content.type))) {            octstr_destroy(content.type);            content.type = octstr_create("text/plain");        }        debug("wsp",0,"WSP: HEAD request, removing body, content-type is now <%s>",               octstr_get_cstr(content.type));        http_header_mark_transformation(headers, content.body, content.type);    }#ifdef ENABLE_NOT_ACCEPTED     /* Returns HTTP response 406 if content-type is not supported by device */    else if (request_headers && content.type &&             !http_type_accepted(request_headers, octstr_get_cstr(content.type)) &&             !http_type_accepted(request_headers, "*/*")) {        warning(0, "WSP: content-type <%s> not supported",                 octstr_get_cstr(content.type));        status = HTTP_NOT_ACCEPTABLE;        octstr_destroy(content.type);        content.type = octstr_create("text/plain");        octstr_destroy(content.charset);        octstr_destroy(content.body);        content.charset = octstr_create("");        content.body = octstr_create("");        http_header_mark_transformation(headers, content.body, content.type);    }#endif    /*     * If the response is too large to be sent to the client,     * suppress it and inform the client.     */    if (octstr_len(content.body) > sdu_size && sdu_size > 0) {        /*         * Only change the status if it indicated success.         * If it indicated an error, then that information is         * more useful to the client than our "Bad Gateway" would be.         * The too-large body is probably an error page in html.         */        /* XXX add WSP smart messaging here too */        if (http_status_class(status) == HTTP_STATUS_SUCCESSFUL)            status = HTTP_BAD_GATEWAY;        warning(0, "WSP: Entity at %s too large (size %ld B, limit %lu B)",                octstr_get_cstr(url), octstr_len(content.body), sdu_size);        octstr_destroy(content.body);        content.body = octstr_create("");        http_header_mark_transformation(headers, content.body, content.type);    }    if (orig_event->type == S_MethodInvoke_Ind) {        return_session_reply(orig_event->u.S_MethodInvoke_Ind.server_transaction_id,                             status, headers, content.body, session_id);    } else {        return_unit_reply(orig_event->u.S_Unit_MethodInvoke_Ind.addr_tuple,                          orig_event->u.S_Unit_MethodInvoke_Ind.transaction_id,                          status, headers, content.body);    }    octstr_destroy(content.version); /* body was re-used above */    octstr_destroy(content.type); /* body was re-used above */    octstr_destroy(content.charset);    octstr_destroy(url);          /* same as content.url */    counter_decrease(fetches);}/* * This thread receives replies from HTTP layer and sends them back to * the phone. */static void return_replies_thread(void *arg){    Octstr *body;    struct request_data *p;    int status;    Octstr *final_url;    List *headers;    while (run_status == running) {        p = http_receive_result(caller, &status, &final_url, &headers, &body);        if (p == NULL)            break;        return_reply(status, body, headers, p->client_SDU_size,                     p->event, p->session_id, p->method, p->url, p->x_wap_tod,                     p->request_headers);        wap_event_destroy(p->event);        http_destroy_headers(p->request_headers);        gw_free(p);        octstr_destroy(final_url);    }}/* * This WML deck is returned when the user asks for the magic  * URL "kannel:alive". */#define HEALTH_DECK \    "<?xml version=\"1.0\"?>" \    "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD 1.1//EN\" " \    "\"http://www.wapforum.org/DTD/wml_1.1.xml\">" \    "<wml><card id=\"health\"><p>Ok</p></card></wml>"static void start_fetch(WAPEvent *event) {    int ret;    long client_SDU_size; /* 0 means no limit */    Octstr *url;    List *session_headers;    List *request_headers;    List *actual_headers;    List *resp_headers;    WAPAddrTuple *addr_tuple;    long session_id;    Octstr *content_body;    Octstr *method;	    /* type of request, normally a get or a post */    Octstr *request_body;    int x_wap_tod;          /* X-WAP.TOD header was present in request */    Octstr *magic_url;    struct request_data *p;    Octstr *send_msisdn_query, *send_msisdn_header, *send_msisdn_format;    int accept_cookies;        counter_increase(fetches);        if (event->type == S_MethodInvoke_Ind) {        struct S_MethodInvoke_Ind *p;            /* WSP, connection orientated */        p = &event->u.S_MethodInvoke_Ind;        session_headers = p->session_headers;        request_headers = p->request_headers;        url = octstr_duplicate(p->request_uri);        addr_tuple = p->addr_tuple;        session_id = p->session_id;        client_SDU_size = p->client_SDU_size;        request_body = octstr_duplicate(p->request_body);        method = p->method;    } else {        struct S_Unit_MethodInvoke_Ind *p;	        /* WDP, non orientated */        p = &event->u.S_Unit_MethodInvoke_Ind;        session_headers = NULL;        request_headers = p->request_headers;        url = octstr_duplicate(p->request_uri);        addr_tuple = p->addr_tuple;        session_id = -1;        client_SDU_size = 0; /* No limit */        request_body = octstr_duplicate(p->request_body);        method = p->method;    }    info(0, "Fetching <%s>", octstr_get_cstr(url));    /*      * XXX this URL mapping needs to be rebuild! st.      */    /* try to rewrite URL */    wap_map_url(&url, &send_msisdn_query, &send_msisdn_header,                &send_msisdn_format, &accept_cookies);    /* if no mapping found, then use our RADIUS acct proxy header */    if (send_msisdn_header == NULL)        send_msisdn_header = octstr_create("X-WAP-Network-Client-MSISDN");    actual_headers = list_create();        if (session_headers != NULL)        http_header_combine(actual_headers, session_headers);    if (request_headers != NULL)        http_header_combine(actual_headers, request_headers);        x_wap_tod = http_header_remove_all(actual_headers, "X-WAP.TOD");    add_accept_headers(actual_headers);    add_charset_headers(actual_headers);    add_network_info(actual_headers, addr_tuple);    add_client_sdu_size(actual_headers, client_SDU_size);    add_via(actual_headers);#ifdef ENABLE_COOKIES    /* DAVI: to finish - accept_cookies -1,      * use global accept-cookies, 0 = no, 1 = yes ? */    if (accept_cookies != 0 && (session_id != -1) &&          /* DAVI (set_cookies(url, actual_headers,                              find_session_machine_by_id(session_id)) == -1)) */        (set_cookies(actual_headers, find_session_machine_by_id(session_id)) == -1))         error(0, "WSP: Failed to add cookies");#endif    /* set referer URL to HTTP header from WSPMachine */    /*      * XXX This makes Open Group's test suite wml/events/tasks/go/5 failing,      * which requires that device is *not* sending referer, but Kannel drops     * it in. We have to remove this for now.     */    /*    if (session_id != -1) {        if ((referer_url = get_referer_url(find_session_machine_by_id(session_id))) != NULL) {            add_referer_url(actual_headers, referer_url);        }    }    */        add_kannel_version(actual_headers);    add_session_id(actual_headers, session_id);    add_msisdn(actual_headers, addr_tuple, send_msisdn_header);    octstr_destroy(send_msisdn_query);    octstr_destroy(send_msisdn_header);    octstr_destroy(send_msisdn_format);        http_remove_hop_headers(actual_headers);    http_header_pack(actual_headers);        magic_url = octstr_imm("kannel:alive");    /* check if this request is a call for our magic URL */    if (octstr_str_compare(method, "GET")  == 0 &&         octstr_compare(url, magic_url) == 0) {        ret = HTTP_OK;        resp_headers = list_create();        http_header_add(resp_headers, "Content-Type", "text/vnd.wap.wml");        content_body = octstr_create(HEALTH_DECK);        octstr_destroy(request_body);        return_reply(ret, content_body, resp_headers, client_SDU_size,                     event, session_id, method, url, x_wap_tod, actual_headers);        wap_event_destroy(event);        http_destroy_headers(actual_headers);    }     /* otherwise it should be a GET, POST or HEAD request type */    else if (octstr_str_compare(method, "GET") == 0 ||             octstr_str_compare(method, "POST") == 0 ||             octstr_str_compare(method, "HEAD") == 0) {        /* we don't allow a body within a GET or HEAD request */        if (request_body != NULL && (octstr_str_compare(method, "GET") == 0 ||                                     octstr_str_compare(method, "HEAD") == 0)) {            octstr_destroy(request_body);            request_body = NULL;        }        /*          * Call deconvert_content() here for transformations of binary         * encoded POST requests from the client into plain text decoded         * POST requests for the HTTP server.         * Mainly this is used for multipart/form-data transmissions,         * including MMS on-the-fly message decoding.         * When we are doing mms, the phone POSTs contents and acknowled-         * gements. In this case, we dont do not deconvert anything.         */        if (octstr_str_compare(method, "POST") == 0 && request_body &&             octstr_len(request_body)) {            struct content content;            int converted;            http_header_get_content_type(actual_headers, &content.type,                                          &content.charset);            content.body = request_body;            converted = deconvert_content(&content);             if (converted == 1)                 http_header_mark_transformation(actual_headers, content.body,                                                 content.type);            request_body = content.body;            octstr_destroy(content.type);            octstr_destroy(content.charset);        }        /* struct that is used for the HTTP response identifier */        p = gw_malloc(sizeof(*p));        p->client_SDU_size = client_SDU_size;        p->event = event;        p->session_id = session_id;        p->method = method;        p->url = url;        p->x_wap_tod = x_wap_tod;        p->request_headers = actual_headers;        /* issue the request to the HTTP server */        http_start_request(caller, http_name2method(method), url, actual_headers,                            request_body, 0, p, NULL);        octstr_destroy(request_body);    }     /* we don't support the WSP/HTTP method the client asked us */    else {        error(0, "WSP: Method %s not supported.", octstr_get_cstr(method));        content_body = octstr_create("");        resp_headers = http_create_empty_headers();        ret = HTTP_NOT_IMPLEMENTED;        octstr_destroy(request_body);        return_reply(ret, content_body, resp_headers, client_SDU_size,                     event, session_id, method, url, x_wap_tod, actual_headers);        wap_event_destroy(event);        http_destroy_headers(actual_headers);    }}                

⌨️ 快捷键说明

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