2014-08-15 16:47 GMT+04:00 <[email protected]>:
> Author: markt
> Date: Fri Aug 15 12:47:56 2014
> New Revision: 1618166
>
> URL: http://svn.apache.org/r1618166
> Log:
> Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56848
> Improve handling of <code>accept-language</code> headers.
>
> Added:
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/AcceptLanguage.java
> (with props)
>
> tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAcceptLanguage.java
> (with props)
> Modified:
> tomcat/trunk/java/org/apache/catalina/connector/Request.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/Authorization.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaType.java
> tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java
> tomcat/trunk/test/org/apache/catalina/connector/TesterRequest.java
> tomcat/trunk/webapps/docs/changelog.xml
>
> Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1618166&r1=1618165&r2=1618166&view=diff
> ==============================================================================
> --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
> +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Fri Aug 15
> 12:47:56 2014
> @@ -21,6 +21,7 @@ import java.io.BufferedReader;
> import java.io.File;
> import java.io.IOException;
> import java.io.InputStream;
> +import java.io.StringReader;
> import java.io.UnsupportedEncodingException;
> import java.lang.reflect.InvocationTargetException;
> import java.nio.charset.Charset;
> @@ -76,7 +77,6 @@ import org.apache.catalina.core.Applicat
> import org.apache.catalina.core.AsyncContextImpl;
> import org.apache.catalina.mapper.MappingData;
> import org.apache.catalina.util.ParameterMap;
> -import org.apache.catalina.util.StringParser;
> import org.apache.coyote.ActionCode;
> import org.apache.juli.logging.Log;
> import org.apache.juli.logging.LogFactory;
> @@ -95,6 +95,7 @@ import org.apache.tomcat.util.http.fileu
> import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
> import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
> import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
> +import org.apache.tomcat.util.http.parser.AcceptLanguage;
> import org.apache.tomcat.util.res.StringManager;
> import org.ietf.jgss.GSSCredential;
> import org.ietf.jgss.GSSException;
> @@ -367,12 +368,6 @@ public class Request
>
>
> /**
> - * The string parser we will use for parsing request lines.
> - */
> - private final StringParser parser = new StringParser();
As a result, the o.a.c.util.StringParser class is no longer used anywhere.
> -
> -
> - /**
> * Local port
> */
> protected int localPort = -1;
> @@ -3114,99 +3109,24 @@ public class Request
> */
> protected void parseLocalesHeader(String value, TreeMap<Double,
> ArrayList<Locale>> locales) {
>
> - // Preprocess the value to remove all whitespace
> - int white = value.indexOf(' ');
> - if (white < 0) {
> - white = value.indexOf('\t');
> - }
> - if (white >= 0) {
> - StringBuilder sb = new StringBuilder();
> - int len = value.length();
> - for (int i = 0; i < len; i++) {
> - char ch = value.charAt(i);
> - if ((ch != ' ') && (ch != '\t')) {
> - sb.append(ch);
> - }
> - }
> - parser.setString(sb.toString());
> - } else {
> - parser.setString(value);
> + List<AcceptLanguage> acceptLanguages;
> + try {
> + acceptLanguages = AcceptLanguage.parse(new StringReader(value));
> + } catch (IOException e) {
> + // Mal-formed headers are ignore. Do the same in the unlikely
> event
> + // of an IOException.
> + return;
> }
>
> - // Process each comma-delimited language specification
> - int length = parser.getLength();
> - while (true) {
> -
> - // Extract the next comma-delimited entry
> - int start = parser.getIndex();
> - if (start >= length) {
> - break;
> - }
> - int end = parser.findChar(',');
> - String entry = parser.extract(start, end).trim();
> - parser.advance(); // For the following entry
> -
> - // Extract the quality factor for this entry
> - double quality = 1.0;
> - int semi = entry.indexOf(";q=");
> - if (semi >= 0) {
> - try {
> - String strQuality = entry.substring(semi + 3);
> - if (strQuality.length() <= 5) {
> - quality = Double.parseDouble(strQuality);
> - } else {
> - quality = 0.0;
> - }
> - } catch (NumberFormatException e) {
> - quality = 0.0;
> - }
> - entry = entry.substring(0, semi);
> - }
> -
> - // Skip entries we are not going to keep track of
> - if (quality < 0.00005)
> - {
> - continue; // Zero (or effectively zero) quality factors
> - }
> - if ("*".equals(entry))
> - {
> - continue; // FIXME - "*" entries are not handled
> - }
> -
> - // Extract the language and country for this entry
> - String language = null;
> - String country = null;
> - String variant = null;
> - int dash = entry.indexOf('-');
> - if (dash < 0) {
> - language = entry;
> - country = "";
> - variant = "";
> - } else {
> - language = entry.substring(0, dash);
> - country = entry.substring(dash + 1);
> - int vDash = country.indexOf('-');
> - if (vDash > 0) {
> - String cTemp = country.substring(0, vDash);
> - variant = country.substring(vDash + 1);
> - country = cTemp;
> - } else {
> - variant = "";
> - }
> - }
> - if (!isAlpha(language) || !isAlpha(country) ||
> !isAlpha(variant)) {
> - continue;
> - }
> -
> + for (AcceptLanguage acceptLanguage : acceptLanguages) {
> // Add a new Locale to the list of Locales for this quality level
> - Locale locale = new Locale(language, country, variant);
> - Double key = new Double(-quality); // Reverse the order
> + Double key = new Double(-acceptLanguage.getQuality()); //
> Reverse the order
> ArrayList<Locale> values = locales.get(key);
> if (values == null) {
> values = new ArrayList<>();
> locales.put(key, values);
> }
> - values.add(locale);
> + values.add(acceptLanguage.getLocale());
> }
> }
>
>
> Added:
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/AcceptLanguage.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/AcceptLanguage.java?rev=1618166&view=auto
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/util/http/parser/AcceptLanguage.java
> (added)
> +++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/AcceptLanguage.java
> Fri Aug 15 12:47:56 2014
> @@ -0,0 +1,76 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.tomcat.util.http.parser;
> +
> +import java.io.IOException;
> +import java.io.StringReader;
> +import java.util.ArrayList;
> +import java.util.List;
> +import java.util.Locale;
> +
> +public class AcceptLanguage {
> +
> + private final Locale locale;
> + private final double quality;
> +
> + protected AcceptLanguage(Locale locale, double quality) {
> + this.locale = locale;
> + this.quality = quality;
> + }
> +
> + public Locale getLocale() {
> + return locale;
> + }
> +
> + public double getQuality() {
> + return quality;
> + }
> +
> +
> + public static List<AcceptLanguage> parse(StringReader input) throws
> IOException {
> +
> + List<AcceptLanguage> result = new ArrayList<>();
> +
> + do {
> + // Token is broader than what is permitted in a language tag
> + // (alphanumeric + '-') but any invalid values that slip through
> + // will be caught later
> + String languageTag = HttpParser.readToken(input);
> + if (languageTag == null) {
> + // Invalid tag, skip to the next one
> + HttpParser.skipUntil(input, 0, ',');
> + continue;
> + }
> +
> + if (languageTag.length() == 0) {
> + // No more data to read
> + break;
> + }
> +
> + // See if a quality has been provided
> + double quality = 1;
> + HttpParser.SkipResult lookForSemiColon =
> HttpParser.skipConstant(input, ";");
> + if (lookForSemiColon == HttpParser.SkipResult.FOUND) {
> + quality = HttpParser.readWeight(input, ',');
> + }
> +
If readWeight() above returns 0 (invalid weight value detected), it
would better to just skip the next line that creates an AcceptLanguage
object.
> + result.add(new
> AcceptLanguage(Locale.forLanguageTag(languageTag), quality));
> + } while (true);
> +
> + return result;
> + }
> +}
>
(...)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]