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

📄 wap_push_pap_mime.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 2 页
字号:
 * Control entity headers must contain Content-Type: application/xml headers. * Rfc 2045, Appendix A does not specify the order of entity headers and states * that all rfc 822 headers having a string "Content" in their field-name must * be accepted. Rfc 822 grammar is capitulated in appendix D. * Message starts after the first null line, so only something after it can be * an extension header (or any header). */static int check_control_headers(Octstr **body_part){    if (check_control_content_type_header(body_part, octstr_imm("\r\n\r\n")) == 0)        return 0;    if (drop_optional_header(body_part, "Content-Transfer-Encoding:",            octstr_imm("\r\n\r\n")) == 0)        return 0;    if (drop_optional_header(body_part, "Content-ID:", octstr_imm("\r\n\r\n")) == 0)        return 0;    if (drop_optional_header(body_part, "Content-Description:", octstr_imm("\r\n\r\n")) == 0)        return 0;    if (drop_extension_headers(body_part, octstr_imm("\r\n\r\n")) == 0)        return 0;    return 1;}static int check_control_content_type_header(Octstr **body_part, Octstr *boundary){    long content_pos;    long message_start_pos;    message_start_pos = octstr_search(*body_part, boundary, 0);    if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm("Content-Type:"), 0,            message_start_pos)) < 0 ||             octstr_case_search(*body_part, octstr_imm("application/xml"), 0) < 0) {        return 0;    }    if (drop_header_true(body_part, content_pos) < 0)        return 0;        return 1;}/* * This function actually removes a header (deletes corresponding part from * the octet string body_part), in addition of all stuff prepending it. So * deleting start from the octet 0. Content_pos tells where the header starts. */static int drop_header_true(Octstr **body_part, long content_pos) {    long next_header_pos;    next_header_pos = -1;    if ((next_header_pos = parse_field_value(*body_part, content_pos)) == 0)        return 0;    if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) == 0)        return 0;    octstr_delete(*body_part, 0, next_header_pos);    return 1;}static int drop_optional_header(Octstr **body_part, char *name, Octstr *boundary){    long content_pos;    long message_start_pos;             content_pos = -1;    message_start_pos = octstr_search(*body_part, boundary, 0);    if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm(name), 0, message_start_pos)) < 0)        return 1;        if (drop_header_true(body_part, content_pos) < 0)        return 0;    return 1;}/* * Extension headers are defined in rfc 822, Appendix D, as fields. We must * parse all rfc 822 headers containing a string "Content". These headers  * are optional, too. For general definition of message parts see chapter 4.1. * Specifically: "everything after first null line is message body". */static int drop_extension_headers(Octstr **body_part, Octstr *boundary){    long content_pos,         next_header_pos;      long next_content_part_pos;    next_content_part_pos = octstr_case_search(*body_part, boundary, 0);    do {        if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm("Content"), 0,                next_content_part_pos)) < 0)            return 1;        if ((next_header_pos = parse_field_name(*body_part, content_pos)) < 0)            return 0;        if ((next_header_pos = parse_field_value(*body_part,                  next_header_pos)) < 0)	    return 0;        if ((next_header_pos = parse_terminator(*body_part,                  next_header_pos)) == 0)            return 0;    } while (islwspchar(octstr_get_char(*body_part, next_header_pos)));    octstr_delete(*body_part, content_pos, next_header_pos - content_pos);       return 1;}static long parse_field_value(Octstr *pap_content, long pos){    int c;    while (!is_cr(c = octstr_get_char(pap_content, pos)) &&	     pos < octstr_len(pap_content)) {         ++pos;    }     if (is_lf(c)) {        if (is_lf(octstr_get_char(pap_content, pos))) {	    ++pos;        } else {	    return -1;        }    }    if (pos == octstr_len(pap_content)) {        return -1;    }    return pos;}static long parse_field_name(Octstr *content, long pos){    while (octstr_get_char(content, pos) != ':' &&                pos < octstr_len(content))           ++pos;    if (pos == octstr_len(content))        return -1;    return pos;}/* * Transfer entity headers of a body part (it is, from the content entity)  * to a header list. Push Message, chapter 6.2.1.10 states that Content-Type * header is mandatory.  * Message proper starts after first empty line. We search only to it, and * remove the line here. * Return 0 when error, 1 otherwise. In addition, return the modified body * part and content headers. */static int pass_data_headers(Octstr **body_part, List **data_headers){    *data_headers = http_create_empty_headers();    if (check_data_content_type_header(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0) {        warning(0, "MIME: pass_data_headers: Content-Type header missing");         return 0;    }            if (pass_optional_header(body_part, "Content-Transfer-Encoding", data_headers,            octstr_imm("\r\n\r\n")) < 0)        goto operror;    if (pass_optional_header(body_part, "Content-ID", data_headers, octstr_imm("\r\n\r\n")) < 0)        goto operror;    if (pass_optional_header(body_part, "Content-Description", data_headers,             octstr_imm("\r\n\r\n")) < 0)        goto operror;    if (pass_extension_headers(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0)        goto operror;       octstr_delete(*body_part, 0, octstr_len(octstr_imm("\r\n")));       return 1;operror:    warning(0, "MIME: pass_data_headers: an unparsable optional header");    return 0;}/* * Checks if body_part contains a Content-Type header. Tranfers this header to * a list content_headers. (Only part before 'boundary'). * Return 1, when Content-Type headers was found, 0 otherwise */static int check_data_content_type_header(Octstr **body_part, List **content_headers,                                          Octstr *boundary){    long header_pos,         next_header_pos;    Octstr *content_header;    long message_start_pos;    header_pos = next_header_pos = -1;    content_header = octstr_create("Content-Type");    message_start_pos = octstr_search(*body_part, boundary, 0);        if ((header_pos = octstr_case_nsearch(*body_part, content_header, 0,             message_start_pos)) < 0) {        goto error;    }    if ((next_header_pos = pass_field_value(body_part, &content_header, 	    header_pos + octstr_len(content_header))) < 0) {        goto error;    }    if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) < 0) {        goto error;    }    octstr_delete(*body_part, header_pos, next_header_pos - header_pos);    list_append(*content_headers, octstr_duplicate(content_header));    octstr_destroy(content_header);    return 1;error:    octstr_destroy(content_header);    return 0;}/* * We try to find an optional header, so a failure to find one is not an  * error. Return -1 when error, 0 when header name not found, 1 otherwise. * Search only until 'boundary'. */static int pass_optional_header(Octstr **body_part, char *name, List **content_headers,                                Octstr *boundary){    long content_pos,         next_header_pos;    Octstr *osname,           *osvalue;    long message_start_pos;    content_pos = next_header_pos = -1;    osname = octstr_create(name);    osvalue = octstr_create("");    message_start_pos = octstr_search(*body_part, boundary, 0);    if ((content_pos = octstr_case_nsearch(*body_part, osname, 0, message_start_pos)) < 0)         goto noheader;    if ((next_header_pos = pass_field_value(body_part, &osvalue, 	     content_pos + octstr_len(osname))) < 0)        goto error;       if ((next_header_pos = 	     parse_terminator(*body_part, next_header_pos)) == 0)        goto error;    drop_separator(&osvalue, &next_header_pos);    http_header_add(*content_headers, name, octstr_get_cstr(osvalue));    octstr_delete(*body_part, content_pos, next_header_pos - content_pos);    octstr_destroy(osname);    octstr_destroy(osvalue);    return 1;error:    octstr_destroy(osvalue);    octstr_destroy(osname);    return -1;noheader:    octstr_destroy(osvalue);    octstr_destroy(osname);    return 0;}/* * Remove ':' plus spaces from the header value */static void drop_separator(Octstr **header_value, long *pos){   long count;   octstr_delete(*header_value, 0, 1);            /* remove :*/   count = octstr_drop_leading_blanks(header_value);   pos = pos - 1 - count;} /* * Return number of spaces dropped. */static long octstr_drop_leading_blanks(Octstr **header_value){    long count;    count = 0;    while (octstr_get_char(*header_value, 0) == ' ') {        octstr_delete(*header_value, 0, 1);        ++count;    }    return count;}/* * Extension headers are optional, see Push Message, chapter 6.2. Field struc- * ture is defined in rfc 822, chapter 3.2. Extension headers are defined in  * rfc 2045, chapter 9, grammar in appendix A. (Only to the next null line). * Return 0 when error, 1 otherwise. */static int pass_extension_headers(Octstr **body_part, List **content_headers, Octstr *boundary){    long next_field_part_pos,         count;      Octstr *header_name,           *header_value;     long next_content_part_pos;    header_name = octstr_create("");    header_value = octstr_create("");    count = 0;    next_field_part_pos = 0;    next_content_part_pos = octstr_search(*body_part, boundary, 0);    do {        if ((octstr_case_nsearch(*body_part, octstr_imm("Content"), 0,                next_content_part_pos)) < 0)            goto end;         if ((next_field_part_pos = pass_field_name(body_part, &header_name,                 next_field_part_pos)) < 0)            goto error;        if ((next_field_part_pos = pass_field_value(body_part, &header_value,                  next_field_part_pos)) < 0)            goto error;        if ((next_field_part_pos = parse_terminator(*body_part,                  next_field_part_pos)) == 0)            goto error;        drop_separator(&header_value, &next_field_part_pos);        http_header_add(*content_headers, octstr_get_cstr(header_name),             octstr_get_cstr(header_value));    } while (islwspchar(octstr_get_char(*body_part, next_field_part_pos)));    octstr_delete(*body_part, 0, next_field_part_pos);/* * An intentional fall-through. We must eventually use a function for memory * cleaning. */end:    octstr_destroy(header_name);    octstr_destroy(header_value);    return 1;error:    octstr_destroy(header_name);    octstr_destroy(header_value);    return 0;}static long pass_field_value(Octstr **body_part, Octstr **header,                              long pos){    int c;    long start;    Octstr *field = NULL;    start = pos;    while (!is_cr(c = octstr_get_char(*body_part, pos)) &&             pos < octstr_len(*body_part)) {        ++pos;    }     if (pos == octstr_len(*body_part)) {        return -1;    }    field = octstr_copy(*body_part, start, pos - start);    octstr_append(*header, field);    octstr_destroy(field);    return pos;}static long pass_field_name(Octstr **body_part, Octstr **field_part,                             long pos){    int c;    long start;    Octstr *name = NULL;    start = pos;    while (((c = octstr_get_char(*body_part, pos)) != ':') &&            pos < octstr_len(*body_part)) {        ++pos;    }    if (pos == octstr_len(*body_part)) {        return -1;    }    name = octstr_copy(*body_part, start, pos - start);    octstr_append(*field_part, name);    octstr_destroy(name);    return pos;}/* This is actually CRLF epilogue. */static int parse_epilogue(Octstr **mime_content){    long pos;    if (octstr_len(*mime_content) == 0)        return 0;        if ((pos = parse_terminator(*mime_content, 0)) < 0)        return -1;    octstr_delete(*mime_content, 0, octstr_len(*mime_content));    return 0;}

⌨️ 快捷键说明

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