📄 wsp_headers.c
字号:
warning(0, "Bad cache-directive 0x%02x.", val); goto error; } octstr_append_char(decoded, '='); switch (val) { case WSP_CACHE_CONTROL_NO_CACHE: case WSP_CACHE_CONTROL_PRIVATE: if (parse_octets_left(context) == 0) { warning(0, "Too short cache-directive"); goto error; } octstr_append_char(decoded, '"'); do { Octstr *fieldname = unpack_field_name(context); if (!fieldname) { warning(0, "Bad field name in cache directive"); goto error; } octstr_append(decoded, fieldname); octstr_destroy(fieldname); if (parse_octets_left(context) > 0) { octstr_append_char(decoded, ','); octstr_append_char(decoded, ' '); } } while (parse_octets_left(context) > 0 && !parse_error(context)); octstr_append_char(decoded, '"'); break; case WSP_CACHE_CONTROL_MAX_AGE: case WSP_CACHE_CONTROL_MAX_STALE: case WSP_CACHE_CONTROL_MIN_FRESH: { Octstr *seconds; seconds = wsp_unpack_integer_value(context); if (!seconds) { warning(0, "Bad integer value in cache directive"); goto error; } octstr_append(decoded, seconds); octstr_destroy(seconds); } break; default: warning(0, "Unexpected value 0x%02x in cache directive.", val); break; } } else if (ret == WSP_FIELD_VALUE_NUL_STRING) { /* XXX: WSP grammar seems wrong here. It works out * to Token-text followed by Parameter. But the * grammar in RFC2616 works out to a key = value * pair, i.e. only a Parameter. */ decoded = parse_get_nul_string(context); if (!decoded) { warning(0, "Format error in cache-control."); return NULL; } /* Yes, the grammar allows only one */ unpack_parameter(context, decoded); } else { panic(0, "Unknown field value type %d.", ret); } return decoded;error: octstr_destroy(decoded); return NULL;}/* Retry-after is defined in 8.4.2.44 */static Octstr *unpack_retry_after(ParseContext *context){ int selector; selector = parse_get_char(context); if (selector == ABSOLUTE_TIME) { return wsp_unpack_date_value(context); } else if (selector == RELATIVE_TIME) { return wsp_unpack_integer_value(context); } else { warning(0, "Cannot parse retry-after value."); return NULL; }}/* Disposition is defined in 8.4.2.53 */static Octstr *unpack_disposition(ParseContext *context){ Octstr *decoded = NULL; int selector; selector = parse_get_char(context) - 128; decoded = wsp_disposition_to_string(selector); if (!decoded) { warning(0, "Cannot parse content-disposition value."); return NULL; } wsp_unpack_all_parameters(context, decoded); return decoded;}/* Range-value is defined in 8.4.2.42 */static Octstr *unpack_range_value(ParseContext *context){ Octstr *decoded = NULL; int selector; unsigned long first_byte_pos, last_byte_pos, suffix_length; selector = parse_get_char(context); if (selector == BYTE_RANGE) { first_byte_pos = parse_get_uintvar(context); if (parse_error(context)) goto error; decoded = octstr_create("bytes = "); octstr_append_decimal(decoded, first_byte_pos); octstr_append_char(decoded, '-'); last_byte_pos = parse_get_uintvar(context); if (parse_error(context)) { /* last_byte_pos is optional */ parse_clear_error(context); } else { octstr_append_decimal(decoded, last_byte_pos); } } else if (selector == SUFFIX_BYTE_RANGE) { suffix_length = parse_get_uintvar(context); if (parse_error(context)) goto error; decoded = octstr_create("bytes = -"); octstr_append_decimal(decoded, suffix_length); } else { goto error; } return decoded;error: warning(0, "Bad format for range-value."); octstr_destroy(decoded); return NULL;}/* Warning-value is defined in 8.4.2.51 */static Octstr *unpack_warning_value(ParseContext *context){ Octstr *decoded = NULL; Octstr *warn_code = NULL; Octstr *warn_agent = NULL; Octstr *warn_text = NULL; unsigned char quote = '"'; warn_code = wsp_unpack_integer_value(context); warn_agent = parse_get_nul_string(context); if (warn_agent && octstr_get_char(warn_agent, 0) == WSP_QUOTE) octstr_delete(warn_agent, 0, 1); warn_text = parse_get_nul_string(context); if (warn_text && octstr_get_char(warn_text, 0) == WSP_QUOTE) octstr_delete(warn_text, 0, 1); if (octstr_get_char(warn_text, 0) != quote) octstr_insert_data(warn_text, 0, "e, 1); if (octstr_get_char(warn_text, octstr_len(warn_text) - 1) != quote) octstr_append_char(warn_text, quote); if (parse_error(context) || !warn_agent || !warn_text) goto error; decoded = octstr_create(""); octstr_append(decoded, warn_code); octstr_append_char(decoded, ' '); octstr_append(decoded, warn_agent); octstr_append_char(decoded, ' '); octstr_append(decoded, warn_text); octstr_destroy(warn_agent); octstr_destroy(warn_code); octstr_destroy(warn_text); return decoded;error: warning(0, "Bad format for warning-value."); octstr_destroy(warn_agent); octstr_destroy(warn_code); octstr_destroy(warn_text); octstr_destroy(decoded); return NULL;}void wsp_unpack_well_known_field(List *unpacked, int field_type, ParseContext *context){ int val, ret; unsigned char *headername = NULL; unsigned char *ch = NULL; Octstr *decoded = NULL; ret = wsp_field_value(context, &val); if (parse_error(context)) { warning(0, "Faulty header, skipping remaining headers."); parse_skip_to_limit(context); return; } headername = wsp_header_to_cstr(field_type); /* headername can still be NULL. This is checked after parsing * the field value. We want to parse the value before exiting, * so that we are ready for the next header. */ /* The following code must set "ch" or "decoded" to a non-NULL * value if the header is valid. */ if (ret == WSP_FIELD_VALUE_NUL_STRING) { /* We allow any header to have a text value, even if that * is not defined in the grammar. Be generous in what * you accept, etc. */ /* This covers Text-string, Token-Text, and Uri-value rules */ decoded = parse_get_nul_string(context); } else if (ret == WSP_FIELD_VALUE_ENCODED) { switch (field_type) { case WSP_HEADER_ACCEPT: case WSP_HEADER_CONTENT_TYPE: ch = wsp_content_type_to_cstr(val); if (!ch) warning(0, "Unknown content type 0x%02x.", val); break; case WSP_HEADER_ACCEPT_CHARSET: ch = wsp_charset_to_cstr(val); if (!ch) warning(0, "Unknown charset 0x%02x.", val); break; case WSP_HEADER_ACCEPT_ENCODING: case WSP_HEADER_CONTENT_ENCODING: ch = wsp_encoding_to_cstr(val); if (!ch) warning(0, "Unknown encoding 0x%02x.", val); break; case WSP_HEADER_ACCEPT_LANGUAGE: case WSP_HEADER_CONTENT_LANGUAGE: ch = wsp_language_to_cstr(val); if (!ch) warning(0, "Unknown language 0x%02x.", val); break; case WSP_HEADER_ACCEPT_RANGES: ch = wsp_ranges_to_cstr(val); if (!ch) warning(0, "Unknown ranges value 0x%02x.", val); break; case WSP_HEADER_AGE: case WSP_HEADER_CONTENT_LENGTH: case WSP_HEADER_MAX_FORWARDS: /* Short-integer version of Integer-value */ decoded = octstr_create(""); octstr_append_decimal(decoded, val); break; case WSP_HEADER_ALLOW: case WSP_HEADER_PUBLIC: ch = wsp_method_to_cstr(val); if (!ch) { /* FIXME Support extended methods */ warning(0, "Unknown method 0x%02x.", val); } break; case WSP_HEADER_CACHE_CONTROL: case WSP_HEADER_CACHE_CONTROL_V13: case WSP_HEADER_CACHE_CONTROL_V14: ch = wsp_cache_control_to_cstr(val); if (!ch) warning(0, "Unknown cache-control value 0x%02x.", val); break; case WSP_HEADER_CONNECTION: ch = wsp_connection_to_cstr(val); if (!ch) warning(0, "Unknown connection value 0x%02x.", val); break; case WSP_HEADER_PRAGMA: if (val == 0) ch = "no-cache"; else warning(0, "Unknown pragma value 0x%02x.", val); break; case WSP_HEADER_TRANSFER_ENCODING: ch = wsp_transfer_encoding_to_cstr(val); if (!ch) warning(0, "Unknown transfer encoding value 0x%02x.", val); break; case WSP_HEADER_VARY: ch = wsp_header_to_cstr(val); if (!ch) warning(0, "Unknown Vary field name 0x%02x.", val); break; case WSP_HEADER_WARNING: decoded = octstr_create(""); octstr_append_decimal(decoded, val); break; case WSP_HEADER_BEARER_INDICATION: ch = wsp_bearer_indication_to_cstr(val); if (!ch) warning(0, "Unknown Bearer-Indication field name 0x%02x.", val); break; case WSP_HEADER_ACCEPT_APPLICATION: ch = wsp_application_id_to_cstr(val); if (!ch) warning(0, "Unknown Accept-Application field name 0x%02x.", val); break; default: if (headername) { warning(0, "Did not expect short-integer with " "'%s' header, skipping.", headername); } break; } } else if (ret == WSP_FIELD_VALUE_DATA) { switch (field_type) { case WSP_HEADER_ACCEPT: case WSP_HEADER_CONTENT_TYPE: /* Content-general-form and Accept-general-form * are defined separately in WSP, but their * definitions are equivalent. */ decoded = wsp_unpack_accept_general_form(context); break; case WSP_HEADER_ACCEPT_CHARSET: decoded = wsp_unpack_accept_charset_general_form(context); break; case WSP_HEADER_ACCEPT_LANGUAGE: decoded = unpack_accept_language_general_form(context); break; case WSP_HEADER_AGE: case WSP_HEADER_CONTENT_LENGTH: case WSP_HEADER_MAX_FORWARDS: case WSP_HEADER_BEARER_INDICATION: case WSP_HEADER_ACCEPT_APPLICATION: /* Long-integer version of Integer-value */ { long l = unpack_multi_octet_integer(context, parse_octets_left(context)); decoded = octstr_create(""); octstr_append_decimal(decoded, l); } break; case WSP_HEADER_AUTHORIZATION: decoded = unpack_credentials(context); break; case WSP_HEADER_PROXY_AUTHORIZATION: decoded = proxy_unpack_credentials(context); break; case WSP_HEADER_CACHE_CONTROL: decoded = unpack_cache_directive(context); break; case WSP_HEADER_CONTENT_MD5: decoded = parse_get_octets(context, parse_octets_left(context)); octstr_binary_to_base64(decoded); /* Zap the CR LF sequence at the end */ octstr_delete(decoded, octstr_len(decoded) - 2, 2); break; case WSP_HEADER_CONTENT_RANGE: decoded = unpack_content_range(context); break; case WSP_HEADER_DATE: case WSP_HEADER_EXPIRES: case WSP_HEADER_IF_MODIFIED_SINCE: case WSP_HEADER_IF_RANGE: case WSP_HEADER_IF_UNMODIFIED_SINCE: case WSP_HEADER_LAST_MODIFIED: /* Back up to get the length byte again */ parse_skip(context, -1); decoded = wsp_unpack_date_value(context); break; case WSP_HEADER_PRAGMA: /* The value is a bare Parameter, without a preceding * header body. unpack_parameter wasn't really * designed for this. We work around it here. */ decoded = octstr_create(""); if (unpack_parameter(context, decoded) < 0) { octstr_destroy(decoded); decoded = NULL; } else { /* Remove the leading "; " */ octstr_delete(decoded, 0, 2); } break; case WSP_HEADER_PROXY_AUTHENTICATE: case WSP_HEADER_WWW_AUTHENTICATE: decoded = unpack_challenge(context); break; case WSP_HEADER_RANGE: decoded = unpack_range_value(context); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -