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

📄 wsp_headers.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* We represent qvalues as integers from 0 through 1000, rather than * as floating values. */static int parse_qvalue(Octstr *value){    int qvalue;    if (value == NULL)        return -1;    if (!isdigit(octstr_get_char(value, 0)))        return -1;    qvalue = (octstr_get_char(value, 0) - '0') * 1000;    if (octstr_get_char(value, 1) != '.')        goto gotvalue;    if (!isdigit(octstr_get_char(value, 2)))        goto gotvalue;    qvalue += (octstr_get_char(value, 2) - '0') * 100;    if (!isdigit(octstr_get_char(value, 3)))        goto gotvalue;    qvalue += (octstr_get_char(value, 3) - '0') * 10;    if (!isdigit(octstr_get_char(value, 4)))        goto gotvalue;    qvalue += (octstr_get_char(value, 4) - '0');gotvalue:    if (qvalue < 0 || qvalue > 1000)        return -1;    return qvalue;}static int get_qvalue(List *parms, int default_qvalue){    long i;    Parameter *parm;    int qvalue;    for (i = 0; i < list_len(parms); i++) {        parm = list_get(parms, i);        if (octstr_str_compare(parm->key, "q") == 0 ||            octstr_str_compare(parm->key, "Q") == 0) {            qvalue = parse_qvalue(parm->value);            if (qvalue >= 0)                return qvalue;        }    }    return default_qvalue;}static int pack_qvalue(Octstr *packed, int qvalue){    /* "Quality factor 1 is the default value and shall never     * be sent." */    if (qvalue == 1000)        return -1;    /* Remember that our qvalues are already multiplied by 1000. */    if (qvalue % 10 == 0)        qvalue = qvalue / 10 + 1;    else        qvalue = qvalue + 100;    octstr_append_uintvar(packed, qvalue);    return 0;}/* Pack value as a Value-length followed by the encoded value. */void wsp_pack_value(Octstr *packed, Octstr *encoded){    long len;    len = octstr_len(encoded);    if (len <= 30)        octstr_append_char(packed, len);    else {        octstr_append_char(packed, 31);        octstr_append_uintvar(packed, len);    }    octstr_append(packed, encoded);}void wsp_pack_long_integer(Octstr *packed, unsigned long integer){    long oldlen = octstr_len(packed);    unsigned char octet;    long len;    if (integer == 0) {	/* The Multi-octet-integer has to be at least 1 octet long. */	octstr_append_char(packed, 1); /* length */	octstr_append_char(packed, 0); /* value */	return;    }    /* Encode it back-to-front, by repeatedly inserting     * at the same position, because that's easier. */    for (len = 0; integer != 0; integer >>= 8, len++) {        octet = integer & 0xff;        octstr_insert_data(packed, oldlen, &octet, 1);    }    octet = len;    octstr_insert_data(packed, oldlen, &octet, 1);}void wsp_pack_short_integer(Octstr *packed, unsigned long integer){    gw_assert(integer <= MAX_SHORT_INTEGER);    octstr_append_char(packed, integer + 0x80);}void wsp_pack_integer_value(Octstr *packed, unsigned long integer){    if (integer <= MAX_SHORT_INTEGER)        wsp_pack_short_integer(packed, integer);    else        wsp_pack_long_integer(packed, integer);}int wsp_pack_integer_string(Octstr *packed, Octstr *value){    unsigned long integer;    long pos;    int c;    int digit;    integer = 0;    for (pos = 0; pos < octstr_len(value); pos++) {        c = octstr_get_char(value, pos);        if (!isdigit(c))            break;        digit = c - '0';        if (integer > ULONG_MAX / 10)            goto overflow;        integer *= 10;        if (integer > ULONG_MAX - digit)            goto overflow;        integer += digit;    }    wsp_pack_integer_value(packed, integer);    return 0;overflow:    warning(0, "WSP: Number too large to handle: '%s'.",            octstr_get_cstr(value));    return -1;}int wsp_pack_version_value(Octstr *packed, Octstr *version){    long major, minor;    long pos;    pos = octstr_parse_long(&major, version, 0, 10);    if (pos < 0 || major < 1 || major > 7)        goto usetext;    if (pos == octstr_len(version))        minor = 15;    else {        if (octstr_get_char(version, pos) != '.')            goto usetext;        pos = octstr_parse_long(&minor, version, pos + 1, 10);        if (pos != octstr_len(version) || minor < 0 || minor > 14)            goto usetext;    }    wsp_pack_short_integer(packed, major << 4 | minor);    return 0;usetext:    wsp_pack_text(packed, version);    return 0;}int wsp_pack_constrained_value(Octstr *packed, Octstr *text, long value){    if (value >= 0)        wsp_pack_short_integer(packed, value);    else        wsp_pack_text(packed, text);    return 0;}static void pack_parameter(Octstr *packed, Parameter *parm){    long keytoken;    long tmp;    long start;    start = octstr_len(packed);    /* Parameter = Typed-parameter | Untyped-parameter */    /* keytoken = wsp_string_to_parameter(parm->key); */    /* XXX this should obey what kind of WSP Encoding-Version the client is using */    keytoken = wsp_string_to_versioned_parameter(parm->key, WSP_1_2);       if (keytoken >= 0) {        /* Typed-parameter = Well-known-parameter-token Typed-value */        /* Well-known-parameter-token = Integer-value */        wsp_pack_integer_value(packed, keytoken);        /* Typed-value = Compact-value | Text-value */        /* First try to pack as Compact-value or No-value.         * If that fails, pack as Text-value. */        if (parm->value == NULL) {            octstr_append_char(packed, 0);  /* No-value */            return;        } else switch (keytoken) {            case 0:   /* q */                tmp = parse_qvalue(parm->value);                if (tmp >= 0) {                    if (pack_qvalue(packed, tmp) < 0)                        octstr_delete(packed, start,                                      octstr_len(packed) - start);                    return;                }                break;            case 1:  /* charset */                tmp = wsp_string_to_charset(parm->value);                if (tmp >= 0) {                    wsp_pack_integer_value(packed, tmp);                    return;                }                break;            case 2:  /* level */                wsp_pack_version_value(packed, parm->value);                return;            case 3:  /* type */                if (octstr_check_range(parm->value, 0,                                       octstr_len(parm->value), 				       gw_isdigit) &&                    wsp_pack_integer_string(packed, parm->value) >= 0)                    return;                break;            case 5:  /* name */            case 6:  /* filename */                break;            case 7:  /* differences */                if (pack_field_name(packed, parm->value) >= 0)                    return;                break;            case 8:  /* padding */                if (octstr_parse_long(&tmp, parm->value, 0, 10)                    == octstr_len(parm->value) &&                    tmp >= 0 && tmp <= MAX_SHORT_INTEGER) {                    wsp_pack_short_integer(packed, tmp);                    return;                }                break;            }        pack_quoted_string(packed, parm->value);    } else {        /* Untyped-parameter = Token-text Untyped-value */        wsp_pack_text(packed, parm->key);        /* Untyped-value = Integer-value | Text-value */        if (parm->value == NULL) {            octstr_append_char(packed, 0);  /* No-value */            return;        }        /* If we can pack as integer, do so. */        if (octstr_parse_long(&tmp, parm->value, 0, 10)            == octstr_len(parm->value)) {            wsp_pack_integer_value(packed, tmp);        } else {            pack_quoted_string(packed, parm->value);        }    }}void wsp_pack_parameters(Octstr *packed, List *parms){    long i;    Parameter *parm;    for (i = 0; i < list_len(parms); i++) {        parm = list_get(parms, i);        pack_parameter(packed, parm);    }}static int pack_uri(Octstr *packed, Octstr *value){    wsp_pack_text(packed, value);    return 0;}static int pack_md5(Octstr *packed, Octstr *value){    Octstr *binary;    binary = octstr_duplicate(value);    octstr_base64_to_binary(binary);    if (octstr_len(binary) != 16) {        error(0, "WSP: MD5 value not 128 bits.");        return -1;    }    octstr_append_char(packed, 16);    octstr_append(packed, binary);    octstr_destroy(binary);    return 0;}/* Actually packs a "Value-length Challenge" *//* Relies on http_split_auth_value to have converted the entry to * the normal HTTP parameter format rather than the comma-separated * one used by challenge and credentials. */static int pack_challenge(Octstr *packed, Octstr *value){    Octstr *encoding = NULL;    Octstr *scheme = NULL;    Octstr *basic = octstr_imm("Basic");    Octstr *realm = octstr_imm("realm");    Octstr *parmstring = NULL;    List *parms = NULL;    Parameter *realmparm = NULL;    long realmpos = -1;    Octstr *realmval = NULL;    long pos;    encoding = octstr_create("");    /* Get authentication scheme */    for (pos = 0; pos < octstr_len(value); pos++) {        if (!is_token_char(octstr_get_char(value, pos)))            break;    }    scheme = octstr_copy(value, 0, pos);    octstr_strip_blanks(scheme);    /* Skip whitespace */    while (isspace(octstr_get_char(value, pos)))        pos++;    if (octstr_case_compare(scheme, basic) == 0) {        parmstring = octstr_copy(value, pos, octstr_len(value) - pos);        realmparm = parm_parse(parmstring);        octstr_append_char(encoding, BASIC_AUTHENTICATION);        realmpos = octstr_len(encoding);    } else {        long i;        wsp_pack_text(encoding, scheme);        realmpos = octstr_len(encoding);        /* Find the realm parameter and exclude it */        parms = wsp_strip_parameters(value);        for (i = 0; i < list_len(parms); i++) {            Parameter *parm = list_get(parms, i);            if (octstr_case_compare(realm, parm->key) == 0) {                realmparm = parm;                list_delete(parms, i, 1);                break;            }        }        wsp_pack_parameters(encoding, parms);    }    /*     * In the WSP encoding we have to put the realm value first, but     * with non-Basic challenges we don't know if it will come first     * in the HTTP header.  So we just start parsing parameters, and     * go back and insert the realm value later.  The same technique     * is used for Basic authentication to simplify the code.     */    if (realmparm == NULL ||        octstr_case_compare(realmparm->key, realm) != 0 ||        realmparm->value == NULL)        goto error;    /* Zap quote marks */    if (octstr_get_char(realmparm->value, 0) == '"' &&        octstr_get_char(realmparm->value, octstr_len(realmparm->value) - 1) == '"') {        octstr_delete(realmparm->value, 0, 1);        octstr_delete(realmparm->value, octstr_len(realmparm->value) - 1, 1);    }    gw_assert(realmpos >= 0);    realmval = octstr_create("");    wsp_pack_text(realmval, realmparm->value);    octstr_insert(encoding, realmval, realmpos);    wsp_pack_value(packed, encoding);    octstr_destroy(encoding);    octstr_destroy(scheme);    octstr_destroy(parmstring);    parm_destroy(realmparm);    list_destroy(parms, parm_destroy_item);    octstr_destroy(realmval);    return 0;error:    warning(0, "WSP: Cannot parse challenge.");    octstr_destroy(encoding);    octstr_destroy(scheme);    octstr_destroy(parmstring);    parm_destr

⌨️ 快捷键说明

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