📄 wsp_headers.c
字号:
case WSP_HEADER_RETRY_AFTER: decoded = unpack_retry_after(context); break; case WSP_HEADER_WARNING: decoded = unpack_warning_value(context); break; case WSP_HEADER_CONTENT_DISPOSITION: decoded = unpack_disposition(context); break; case WSP_HEADER_ENCODING_VERSION: decoded = unpack_encoding_version(context); break; default: if (headername) { warning(0, "Did not expect value-length with " "'%s' header, skipping.", headername); } break; } if (headername && parse_octets_left(context) > 0) { warning(0, "WSP: %s: skipping %ld trailing octets.", headername, parse_octets_left(context)); } parse_skip_to_limit(context); parse_pop_limit(context); } else { panic(0, "Unknown field-value type %d.", ret); } if (ch == NULL && decoded != NULL) ch = octstr_get_cstr(decoded); if (ch == NULL) goto value_error; if (!headername) { warning(0, "Unknown header number 0x%02x.", field_type); goto value_error; } http_header_add(unpacked, headername, ch); octstr_destroy(decoded); return;value_error: warning(0, "Skipping faulty header."); octstr_destroy(decoded);}void wsp_unpack_app_header(List *unpacked, ParseContext *context){ Octstr *header = NULL; Octstr *value = NULL; header = parse_get_nul_string(context); value = parse_get_nul_string(context); if (header && value) { http_header_add(unpacked, octstr_get_cstr(header), octstr_get_cstr(value)); } if (parse_error(context)) warning(0, "Error parsing application-header."); octstr_destroy(header); octstr_destroy(value);}List *wsp_headers_unpack(Octstr *headers, int content_type_present){ ParseContext *context; int byte; List *unpacked; int code_page; unpacked = http_create_empty_headers(); context = parse_context_create(headers); if (octstr_len(headers) > 0) { debug("wsp", 0, "WSP: decoding headers:"); octstr_dump(headers, 0); } if (content_type_present) wsp_unpack_well_known_field(unpacked, WSP_HEADER_CONTENT_TYPE, context); code_page = 1; /* default */ while (parse_octets_left(context) > 0 && !parse_error(context)) { byte = parse_get_char(context); if (byte == 127 || (byte >= 1 && byte <= 31)) { if (byte == 127) code_page = parse_get_char(context); else code_page = byte; if (code_page == 1) info(0, "Returning to code page 1 (default)."); else { warning(0, "Shift to unknown code page %d.", code_page); warning(0, "Will try to skip headers until " "next known code page."); } } else if (byte >= 128) { /* well-known-header */ if (code_page == 1) wsp_unpack_well_known_field(unpacked, byte - 128, context); else { debug("wsp", 0, "Skipping field 0x%02x.", byte); wsp_skip_field_value(context); } } else if (byte > 31 && byte < 127) { /* Un-parse the character we just read */ parse_skip(context, -1); wsp_unpack_app_header(unpacked, context); } else { warning(0, "Unsupported token or header (start 0x%x)", byte); break; } } if (list_len(unpacked) > 0) { long i; debug("wsp", 0, "WSP: decoded headers:"); for (i = 0; i < list_len(unpacked); i++) { Octstr *header = list_get(unpacked, i); debug("wsp", 0, "%s", octstr_get_cstr(header)); } debug("wsp", 0, "WSP: End of decoded headers."); } parse_context_destroy(context); return unpacked;}/**********************************************************************//* Start of header packing code (HTTP to WSP) *//**********************************************************************/static int pack_accept(Octstr *packet, Octstr *value);static int pack_accept_charset(Octstr *packet, Octstr *value);static int pack_accept_encoding(Octstr *packet, Octstr *value);static int pack_accept_language(Octstr *packet, Octstr *value);static int pack_cache_control(Octstr *packet, Octstr *value);static int pack_challenge(Octstr *packet, Octstr *value);static int pack_connection(Octstr *packet, Octstr *value);static int pack_content_disposition(Octstr *packet, Octstr *value);static int pack_content_range(Octstr *packet, Octstr *value);static int pack_credentials(Octstr *packet, Octstr *value);static int pack_encoding(Octstr *packet, Octstr *value);static int pack_expires(Octstr *packet, Octstr *value);static int pack_field_name(Octstr *packet, Octstr *value);static int pack_if_range(Octstr *packet, Octstr *value);static int pack_language(Octstr *packet, Octstr *value);static int pack_md5(Octstr *packet, Octstr *value);static int pack_method(Octstr *packet, Octstr *value);static int pack_pragma(Octstr *packet, Octstr *value);static int pack_range(Octstr *packet, Octstr *value);static int pack_range_unit(Octstr *packet, Octstr *value);static int pack_transfer_encoding(Octstr *packet, Octstr *value);static int pack_uri(Octstr *packet, Octstr *value);static int pack_warning(Octstr *packet, Octstr *value);/* these are used in MMS encapsulation code too */struct headerinfo headerinfo[] = { { WSP_HEADER_ACCEPT, pack_accept, LIST }, { WSP_HEADER_ACCEPT_CHARSET, pack_accept_charset, LIST }, { WSP_HEADER_ACCEPT_ENCODING, pack_accept_encoding, LIST }, { WSP_HEADER_ACCEPT_LANGUAGE, pack_accept_language, LIST }, { WSP_HEADER_ACCEPT_RANGES, pack_range_unit, LIST }, { WSP_HEADER_AGE, wsp_pack_integer_string, 0 }, /* pack_method is slightly too general because Allow is only * supposed to encode well-known-methods. */ { WSP_HEADER_ALLOW, pack_method, LIST }, { WSP_HEADER_AUTHORIZATION, pack_credentials, BROKEN_LIST }, { WSP_HEADER_CACHE_CONTROL, pack_cache_control, LIST }, { WSP_HEADER_CACHE_CONTROL_V13, pack_cache_control, LIST }, { WSP_HEADER_CACHE_CONTROL_V14, pack_cache_control, LIST }, { WSP_HEADER_CONNECTION, pack_connection, LIST }, { WSP_HEADER_CONTENT_BASE, pack_uri, 0 }, { WSP_HEADER_CONTENT_ENCODING, pack_encoding, LIST }, { WSP_HEADER_CONTENT_LANGUAGE, pack_language, LIST }, { WSP_HEADER_CONTENT_LENGTH, wsp_pack_integer_string, 0 }, { WSP_HEADER_CONTENT_LOCATION, pack_uri, 0 }, { WSP_HEADER_CONTENT_MD5, pack_md5, 0 }, { WSP_HEADER_CONTENT_RANGE, pack_content_range, 0 }, { WSP_HEADER_CONTENT_TYPE, wsp_pack_content_type, 0 }, { WSP_HEADER_DATE, wsp_pack_date, 0 }, { WSP_HEADER_ETAG, wsp_pack_text, 0 }, { WSP_HEADER_EXPIRES, pack_expires, 0 }, { WSP_HEADER_FROM, wsp_pack_text, 0 }, { WSP_HEADER_HOST, wsp_pack_text, 0 }, { WSP_HEADER_IF_MODIFIED_SINCE, wsp_pack_date, 0 }, { WSP_HEADER_IF_MATCH, wsp_pack_text, 0 }, { WSP_HEADER_IF_NONE_MATCH, wsp_pack_text, 0 }, { WSP_HEADER_IF_RANGE, pack_if_range, 0 }, { WSP_HEADER_IF_UNMODIFIED_SINCE, wsp_pack_date, 0 }, { WSP_HEADER_LAST_MODIFIED, wsp_pack_date, 0 }, { WSP_HEADER_LOCATION, pack_uri, 0 }, { WSP_HEADER_MAX_FORWARDS, wsp_pack_integer_string, 0 }, { WSP_HEADER_PRAGMA, pack_pragma, LIST }, { WSP_HEADER_PROXY_AUTHENTICATE, pack_challenge, BROKEN_LIST }, { WSP_HEADER_PROXY_AUTHORIZATION, pack_credentials, BROKEN_LIST }, { WSP_HEADER_PUBLIC, pack_method, LIST }, { WSP_HEADER_RANGE, pack_range, 0 }, { WSP_HEADER_REFERER, pack_uri, 0 }, { WSP_HEADER_RETRY_AFTER, wsp_pack_retry_after, 0 }, { WSP_HEADER_SERVER, wsp_pack_text, 0 }, { WSP_HEADER_TRANSFER_ENCODING, pack_transfer_encoding, LIST }, { WSP_HEADER_UPGRADE, wsp_pack_text, LIST }, { WSP_HEADER_USER_AGENT, wsp_pack_text, 0 }, { WSP_HEADER_VARY, pack_field_name, LIST }, { WSP_HEADER_VIA, wsp_pack_text, LIST }, { WSP_HEADER_WARNING, pack_warning, LIST }, { WSP_HEADER_WWW_AUTHENTICATE, pack_challenge, BROKEN_LIST }, { WSP_HEADER_CONTENT_DISPOSITION, pack_content_disposition, 0 }, { WSP_HEADER_PUSH_FLAG, wsp_pack_integer_string, 0}, { WSP_HEADER_X_WAP_CONTENT_URI, pack_uri, 0}, { WSP_HEADER_X_WAP_INITIATOR_URI, pack_uri, 0}, { WSP_HEADER_X_WAP_APPLICATION_ID, wsp_pack_integer_string, 0}, { WSP_HEADER_CONTENT_ID, wsp_pack_text, 0}, { WSP_HEADER_ENCODING_VERSION, wsp_pack_version_value, 0 } // DAVI { WSP_HEADER_SET_COOKIE, pack_version_value, 0 } };static Parameter *parm_create(Octstr *key, Octstr *value){ Parameter *parm; parm = gw_malloc(sizeof(*parm)); parm->key = key; parm->value = value; return parm;}static void parm_destroy(Parameter *parm){ if (parm == NULL) return; octstr_destroy(parm->key); octstr_destroy(parm->value); gw_free(parm);}void parm_destroy_item(void *parm){ parm_destroy(parm);}static Parameter *parm_parse(Octstr *value){ long pos; Octstr *key, *val; pos = octstr_search_char(value, '=', 0); if (pos > 0) { key = octstr_copy(value, 0, pos); val = octstr_copy(value, pos + 1, octstr_len(value) - pos); octstr_strip_blanks(key); octstr_strip_blanks(val); } else { key = octstr_duplicate(value); val = NULL; } return parm_create(key, val);}/* Many HTTP field elements can take parameters in a standardized * form: parameters appear after the main value, each is introduced * by a semicolon (;), and consists of a key=value pair or just * a key, where the key is a token and the value is either a token * or a quoted-string. * The main value itself is a series of tokens, separators, and * quoted-strings. * * This function will take such a field element, and remove all * parameters from it. The parameters are returned as a List * of Parameter, where the value field is left NULL * if the parameter was just a key. * It returns NULL if there were no parameters. */List *wsp_strip_parameters(Octstr *value){ long pos; long len; int c; long end; List *parms; long firstparm; len = octstr_len(value); /* Find the start of the first parameter. */ for (pos = 0; pos < len; pos++) { c = octstr_get_char(value, pos); if (c == ';') break; else if (c == '"') pos += http_header_quoted_string_len(value, pos) - 1; } if (pos >= len) return NULL; /* no parameters */ parms = list_create(); firstparm = pos; for (pos++; pos > 0 && pos < len; pos++) { Octstr *key = NULL; Octstr *val = NULL; end = octstr_search_char(value, '=', pos); if (end < 0) end = octstr_search_char(value, ';', pos); if (end < 0) end = octstr_len(value); key = octstr_copy(value, pos, end - pos); octstr_strip_blanks(key); pos = end; if (octstr_get_char(value, pos) == '=') { pos++; while (isspace(octstr_get_char(value, pos))) pos++; if (octstr_get_char(value, pos) == '"') end = pos + http_header_quoted_string_len(value, pos); else end = octstr_search_char(value, ';', pos); if (end < 0) end = octstr_len(value); val = octstr_copy(value, pos, end - pos); octstr_strip_blanks(val); pos = end; pos = octstr_search_char(value, ';', pos); } list_append(parms, parm_create(key, val)); } octstr_delete(value, firstparm, octstr_len(value) - firstparm); octstr_strip_blanks(value); return parms;}int wsp_pack_text(Octstr *packed, Octstr *text){ /* This check catches 0-length strings as well, because * octstr_get_char will return -1. */ if (octstr_get_char(text, 0) >= 128 || octstr_get_char(text, 0) < 32) octstr_append_char(packed, WSP_QUOTE); octstr_append(packed, text); octstr_append_char(packed, 0); return 0;}/* Pack text as Quoted-string if it starts with a " character. * Pack it as Text-string otherwise. */static void pack_quoted_string(Octstr *packed, Octstr *text){ octstr_append(packed, text); if (octstr_get_char(text, octstr_len(text) - 1) == '"' && octstr_get_char(text, 0) == '"') octstr_delete(packed, octstr_len(packed) - 1, 1); octstr_append_char(packed, 0);}/* Is this char in the 'separators' set defined by HTTP? */static int is_separator_char(int c){ switch (c) { case '(': case ')': case '<': case '>': case '@': case ',': case ';': case ':': case '\\': case '"': case '/': case '[': case ']': case '?': case '=': case '{': case '}': case 32: /* SP */ case 9: /* HT */ return 1; default: return 0; }}/* Is this char part of a 'token' as defined by HTTP? */static int is_token_char(int c){ return c >= 32 && c < 127 && !is_separator_char(c);}/* Is this string a 'token' as defined by HTTP? */static int is_token(Octstr *token){ return octstr_len(token) > 0 && octstr_check_range(token, 0, octstr_len(token), is_token_char);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -