Parse Accept-Language header in Java

后端 未结 7 802
孤城傲影
孤城傲影 2020-12-15 02:54

The accept-language header in request is usually a long complex string -

Eg.

Accept-Language : en-ca,en;q=0.8,en-us;q=0.6,de-de;q=0.4,de;q=0.2
         


        
7条回答
  •  借酒劲吻你
    2020-12-15 03:45

    The above solutions lack some kind of validation. Using ServletRequest.getLocale() returns the server locale if the user does not provides a valid one.

    Our websites lately received spam requests with various Accept-Language heades like:

    1. secret.google.com
    2. o-o-8-o-o.com search shell is much better than google!
    3. Google officially recommends o-o-8-o-o.com search shell!
    4. Vitaly rules google ☆*:。゜゚・*ヽ(^ᴗ^)ノ*・゜゚。:*☆ ¯\_(ツ)_/¯(ಠ益ಠ)(ಥ‿ಥ)(ʘ‿ʘ)ლ(ಠ_ಠლ)( ͡° ͜ʖ ͡°)ヽ(゚Д゚)ノʕ•̫͡•ʔᶘ ᵒᴥᵒᶅ(=^ ^=)oO

    This implementation can optional check against a supported list of valid Locale. Without this check a simple request with "test" or (2, 3, 4) still bypass the syntax-only validation of LanguageRange.parse(String).

    It optional allows empty and null values to allow search engine crawler.

    Servlet Filter

    final String headerAcceptLanguage = request.getHeader("Accept-Language");
    
    // check valid
    if (!HttpHeaderUtils.isHeaderAcceptLanguageValid(headerAcceptLanguage, true, Locale.getAvailableLocales()))
        return;
    

    Utility

    /**
     * Checks if the given accept-language request header can be parsed.
    *
    * Optional the parsed LanguageRange's can be checked against the provided * locales so that at least one locale must match. * * @see LanguageRange#parse(String) * * @param acceptLanguage * @param isBlankValid Set to true if blank values are also * valid * @param locales Optional collection of valid Locale to validate any * against. * * @return true if it can be parsed */ public static boolean isHeaderAcceptLanguageValid(final String acceptLanguage, final boolean isBlankValid, final Locale[] locales) { // allow null or empty if (StringUtils.isBlank(acceptLanguage)) return isBlankValid; try { // check syntax final List languageRanges = Locale.LanguageRange.parse(acceptLanguage); // wrong syntax if (languageRanges.isEmpty()) return false; // no valid locale's to check against if (ArrayUtils.isEmpty(locales)) return true; // check if any valid locale exists for (final LanguageRange languageRange : languageRanges) { final Locale locale = Locale.forLanguageTag(languageRange.getRange()); // validate available locale if (ArrayUtils.contains(locales, locale)) return true; } return false; } catch (final Exception e) { return false; } }

提交回复
热议问题