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

📄 wsp_headers.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 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.   */ /* * wsp_headers.c - Implement WSP PDU headers *  * References: *   WSP specification version 1.1 *   RFC 2068, Hypertext Transfer Protocol HTTP/1.1 *   RFC 2616, Hypertext Transfer Protocol HTTP/1.1 * *   For push headers, WSP specification, June 2000 conformance release * * This file has two parts.  The first part decodes the request's headers * from WSP to HTTP.  The second part encodes the response's headers from * HTTP to WSP. * * Note that push header encoding and decoding are divided two parts: * first decoding and encoding numeric values and then packing these values * into WSP format and unpacking them from WSP format. This module contains * only packing and unpacking parts. * * Some functions are declared non-static to provide them for external use, * ie. the MMS encapsulation encoding and decoding routines implemented in  * other files. * * Richard Braakman * Stipe Tolj <tolj@wapme-systems.de> */#include <string.h>#include <limits.h>#include <ctype.h>#include "gwlib/gwlib.h"#include "wsp.h"#include "wsp_headers.h"#include "wsp_strings.h"/* * get field value and return its type as predefined data types * There are three kinds of field encodings: *   WSP_FIELD_VALUE_NUL_STRING: 0-terminated string *   WSP_FIELD_VALUE_ENCODED: short integer, range 0-127 *   WSP_FIELD_VALUE_DATA: octet string defined by length * The function will return one of those values, and modify the parse context * to make it easy to get the field data. *   WSP_FIELD_VALUE_NUL_STRING: Leave parsing position at start of string *   WSP_FIELD_VALUE_ENCODED: Put value in *well_known_value, leave *        parsing position after field value. *   WSP_FIELD_VALUE_DATA: Leave parsing position at start of data, and set *        a parse limit at the end of data. */int wsp_field_value(ParseContext *context, int *well_known_value){    int val;    unsigned long len;    val = parse_get_char(context);    if (val >= 0 && val < 31) {        *well_known_value = -1;        parse_limit(context, val);        return WSP_FIELD_VALUE_DATA;    } else if (val == 31) {        *well_known_value = -1;        len = parse_get_uintvar(context);        parse_limit(context, len);        return WSP_FIELD_VALUE_DATA;    } else if (val > 127) {        *well_known_value = val - 128;        return WSP_FIELD_VALUE_ENCODED;    } else if (val == WSP_QUOTE) {  /* 127 */        *well_known_value = -1;        /* We already consumed the Quote */        return WSP_FIELD_VALUE_NUL_STRING;    } else {        *well_known_value = -1;        /* Un-parse the character we just read */        parse_skip(context, -1);        return WSP_FIELD_VALUE_NUL_STRING;    }}/* Skip over a field_value as defined above. */void wsp_skip_field_value(ParseContext *context){    int val;    int ret;    ret = wsp_field_value(context, &val);    if (ret == WSP_FIELD_VALUE_DATA) {        parse_skip_to_limit(context);        parse_pop_limit(context);    }}/* Multi-octet-integer is defined in 8.4.2.1 */static long unpack_multi_octet_integer(ParseContext *context, long len){    long val = 0;    if (len > (long) sizeof(val) || len < 0)        return -1;    while (len > 0) {        val = val * 256 + parse_get_char(context);        len--;    }    if (parse_error(context))        return -1;    return val;}/* This function is similar to field_value, but it is used at various * places in the grammar where we expect either an Integer-value * or some kind of NUL-terminated text. *  * Return values are just like field_value except that WSP_FIELD_VALUE_DATA * will not be returned. * * As a special case, we parse a 0-length Long-integer as an * WSP_FIELD_VALUE_NONE, so that we can distinguish between No-value * and an Integer-value of 0.  (A real integer 0 would be encoded as * a Short-integer; the definition of Long-integer seems to allow * 0-length integers, but the definition of Multi-octet-integer does * not, so this is an unclear area of the specification.) */int wsp_secondary_field_value(ParseContext *context, long *result){    int val;    long length;    val = parse_get_char(context);    if (val == 0) {        *result = 0;        return WSP_FIELD_VALUE_NONE;    } else if (val > 0 && val < 31) {        *result = unpack_multi_octet_integer(context, val);        return WSP_FIELD_VALUE_ENCODED;    } else if (val == 31) {        length = parse_get_uintvar(context);        *result = unpack_multi_octet_integer(context, length);        return WSP_FIELD_VALUE_ENCODED;    } else if (val > 127) {        *result = val - 128;        return WSP_FIELD_VALUE_ENCODED;    } else if (val == WSP_QUOTE) {  /* 127 */        *result = -1;        return WSP_FIELD_VALUE_NUL_STRING;    } else {        *result = -1;        /* Un-parse the character we just read */        parse_skip(context, -1);        return WSP_FIELD_VALUE_NUL_STRING;    }}/* Integer-value is defined in 8.4.2.3 */Octstr *wsp_unpack_integer_value(ParseContext *context){    Octstr *decoded;    unsigned long value;    int val;    val = parse_get_char(context);    if (val < 31) {        value = unpack_multi_octet_integer(context, val);    } else if (val > 127) {        value = val - 128;    } else {        warning(0, "WSP headers: bad integer-value.");        return NULL;    }    decoded = octstr_create("");    octstr_append_decimal(decoded, value);    return decoded;}/* Q-value is defined in 8.4.2.3 */static Octstr *convert_q_value(int q){    Octstr *result = NULL;    /* When quality factor 0 and quality factors with one or two     * decimal digits are encoded, they shall be multiplied by 100     * and incremented by one, so that they encode as a one-octet     * value in range 1-100. */    if (q >= 1 && q <= 100) {        q = q - 1;        result = octstr_create("0.");        octstr_append_char(result, (q / 10) + '0');        if (q % 10 > 0)            octstr_append_char(result, (q % 10) + '0');        return result;    }    /* Three decimal quality factors shall be multiplied with 1000     * and incremented by 100. */    if (q > 100 && q <= 1000) {        q = q - 100;        result = octstr_create("0.");        octstr_append_char(result, (q / 100) + '0');        if (q % 100 > 0)            octstr_append_char(result, (q / 10 % 10) + '0');        if (q % 10 > 0)            octstr_append_char(result, (q % 10) + '0');        return result;    }    return NULL;}/* Q-value is defined in 8.4.2.3 */static Octstr *unpack_q_value(ParseContext *context){    int c, c2;    c = parse_get_char(context);    if (c < 0)        return NULL;    if (c & 0x80) {        c2 = parse_get_char(context);        if (c2 < 0 || (c2 & 0x80))            return NULL;        c = ((c & 0x7f) << 8) + c2;    }    return convert_q_value(c);}/* Version-value is defined in 8.4.2.3. Encoding-Version uses coding * defined in this chapter, see 8.4.2.70.  */Octstr *wsp_unpack_version_value(long value){    Octstr *result;    int major, minor;    major = ((value >> 4) & 0x7);    minor = (value & 0xf);    result = octstr_create("");    octstr_append_char(result, major + '0');    if (minor != 15) {        octstr_append_char(result, '.');        octstr_append_decimal(result, minor);    }    return result;}static Octstr *unpack_encoding_version(ParseContext *context){    int ch;    ch = parse_get_char(context);    if (ch < 128) {        warning(0, "WSP: bad Encoding-Version value");        return NULL;    }    return wsp_unpack_version_value(((long) ch) - 128);}/* Called with the parse limit set to the end of the parameter data, * and decoded containing the unpacked header line so far. * Parameter is defined in 8.4.2.4. */static int unpack_parameter(ParseContext *context, Octstr *decoded){    Octstr *parm = NULL;    Octstr *value = NULL;    int ret;    long type;    long val;    ret = wsp_secondary_field_value(context, &type);    if (parse_error(context) || ret == WSP_FIELD_VALUE_NONE) {        warning(0, "bad parameter");        goto error;    }    if (ret == WSP_FIELD_VALUE_ENCODED) {        /* Typed-parameter */        parm = wsp_parameter_to_string(type);        if (!parm)            warning(0, "Unknown parameter %02lx.", type);    } else if (ret == WSP_FIELD_VALUE_NUL_STRING) {        /* Untyped-parameter */        parm = parse_get_nul_string(context);        if (!parm)            warning(0, "Format error in parameter.");        type = -1;        /* We treat Untyped-value as a special type.  Its format         * Integer-value | Text-value is pretty similar to most         * typed formats. */    } else {        panic(0, "Unknown secondary field value type %d.", ret);    }    if (type == 0x00) /* q */        value = unpack_q_value(context);    else {        ret = wsp_secondary_field_value(context, &val);        if (parse_error(context)) {            warning(0, "bad parameter value");            goto error;        }        if (ret == WSP_FIELD_VALUE_ENCODED) {            switch (type) {            case -1:  /* untyped: Integer-value */            case 3:  /* type: Integer-value */            case 8:  /* padding: Short-integer */                value = octstr_create("");                octstr_append_decimal(value, val);                break;            case 0:  /* q, already handled above */                gw_assert(0);                break;            case 1:  /* charset: Well-known-charset */                value = wsp_charset_to_string(val);                if (!value)                    warning(0, "Unknown charset %04lx.", val);                break;            case 2:  /* level: Version-value */                value = wsp_unpack_version_value(val);                break;            case 5:  /* name: Text-string */            case 6:  /* filename: Text-string */                warning(0, "Text-string parameter with integer encoding");                break;            case 7:  /* differences: Field-name */                value = wsp_header_to_string(val);                if (!value)                    warning(0, "Unknown differences header %02lx.", val);                break;            default:                warning(0, "Unknown parameter encoding %02lx.",                        type);                break;            }        } else if (ret == WSP_FIELD_VALUE_NONE) {            value = octstr_create("");        } else {            gw_assert(ret == WSP_FIELD_VALUE_NUL_STRING);            /* Text-value = No-value | Token-text | Quoted-string */            value = parse_get_nul_string(context);            if (!value)                warning(0, "Format error in parameter value.");            else {                if (octstr_get_char(value, 0) == '"') {                    /* Quoted-string */                    octstr_append_char(value, '"');                } else { /* DAVI! */                    octstr_insert(value, octstr_imm("\""), 0);                    octstr_append_char(value, '"');                }            }        }    }

⌨️ 快捷键说明

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