tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Konstantin Kolinko <knst.koli...@gmail.com>
Subject Re: svn commit: r1374073 - in /tomcat/trunk: java/org/apache/catalina/connector/Response.java java/org/apache/coyote/Response.java java/org/apache/tomcat/util/http/ResponseUtil.java webapps/docs/changelog.xml
Date Fri, 17 Aug 2012 20:05:17 GMT
2012/8/17  <markt@apache.org>:
> Author: markt
> Date: Thu Aug 16 21:50:44 2012
> New Revision: 1374073
>
> URL: http://svn.apache.org/viewvc?rev=1374073&view=rev
> Log:
> FindBugs: Fix unused code by implementing the TODO associated with it
>
> Added:
>     tomcat/trunk/java/org/apache/tomcat/util/http/ResponseUtil.java   (with props)
> Modified:
>     tomcat/trunk/java/org/apache/catalina/connector/Response.java
>     tomcat/trunk/java/org/apache/coyote/Response.java
>     tomcat/trunk/webapps/docs/changelog.xml
>
> Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java
> URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=1374073&r1=1374072&r2=1374073&view=diff
> ==============================================================================
> --- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original)
> +++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Thu Aug 16 21:50:44
2012
> @@ -51,6 +51,7 @@ import org.apache.tomcat.util.buf.CharCh
>  import org.apache.tomcat.util.buf.UEncoder;
>  import org.apache.tomcat.util.http.FastHttpDateFormat;
>  import org.apache.tomcat.util.http.MimeHeaders;
> +import org.apache.tomcat.util.http.ResponseUtil;
>  import org.apache.tomcat.util.http.ServerCookie;
>  import org.apache.tomcat.util.http.parser.AstMediaType;
>  import org.apache.tomcat.util.http.parser.HttpParser;
> @@ -1023,8 +1024,8 @@ public class Response
>      /**
>       * An extended version of this exists in {@link org.apache.coyote.Response}.
>       * This check is required here to ensure that the usingWriter checks in
> -     * {@link #setContentType(String)} are applied since usingWriter is not
> -     * visible to {@link org.apache.coyote.Response}
> +     * {@link #setContentType(String)} and {@link #setLocale(Locale) are applied
> +     * since usingWriter is not visible to {@link org.apache.coyote.Response}
>       *
>       * Called from set/addHeader.
>       * Return true if the header is special, no need to set the header.
> @@ -1034,6 +1035,15 @@ public class Response
>              setContentType(value);
>              return true;
>          }
> +        if (name.equalsIgnoreCase("Content-Language")) {
> +            Locale locale = ResponseUtil.getLocaleFromLanguageHeader(value);
> +            if (locale == null) {
> +                return false;
> +            } else {
> +                setLocale(locale);
> +                return true;
> +            }
> +        }
>          return false;
>      }
>
>
> Modified: tomcat/trunk/java/org/apache/coyote/Response.java
> URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Response.java?rev=1374073&r1=1374072&r2=1374073&view=diff
> ==============================================================================
> --- tomcat/trunk/java/org/apache/coyote/Response.java (original)
> +++ tomcat/trunk/java/org/apache/coyote/Response.java Thu Aug 16 21:50:44 2012
> @@ -26,6 +26,7 @@ import javax.servlet.WriteListener;
>  import org.apache.coyote.http11.AbstractOutputBuffer;
>  import org.apache.tomcat.util.buf.ByteChunk;
>  import org.apache.tomcat.util.http.MimeHeaders;
> +import org.apache.tomcat.util.http.ResponseUtil;
>  import org.apache.tomcat.util.http.parser.AstMediaType;
>  import org.apache.tomcat.util.http.parser.HttpParser;
>  import org.apache.tomcat.util.http.parser.ParseException;
> @@ -342,8 +343,14 @@ public final class Response {
>                  return false;
>              }
>          }
> -        if( name.equalsIgnoreCase( "Content-Language" ) ) {
> -            // XXX XXX Need to construct Locale or something else
> +        if (name.equalsIgnoreCase("Content-Language")) {
> +            Locale locale = ResponseUtil.getLocaleFromLanguageHeader(value);
> +            if (locale == null) {
> +                return false;
> +            } else {
> +                setLocale(locale);
> +                return true;
> +            }
>          }
>          return false;
>      }
>
> Added: tomcat/trunk/java/org/apache/tomcat/util/http/ResponseUtil.java
> URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/ResponseUtil.java?rev=1374073&view=auto
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/util/http/ResponseUtil.java (added)
> +++ tomcat/trunk/java/org/apache/tomcat/util/http/ResponseUtil.java Thu Aug 16 21:50:44
2012
> @@ -0,0 +1,60 @@
> +/*
> + * 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;
> +
> +import java.util.Locale;
> +
> +public class ResponseUtil {
> +
> +    private ResponseUtil() {
> +        // Hide default constructor as this is a utility class
> +    }
> +
> +    public static Locale getLocaleFromLanguageHeader(String header) {
> +        if (header == null) {
> +            return null;
> +        }
> +
> +        if (header.indexOf(',') > -1) {
> +            // Multiple values. RFC 2616 does not define a priority.
> +            // No way to select a Locale
> +            return null;
> +        }
> +
> +        String tags[] = header.split("-");
> +        String primaryTag = tags[0];
> +
> +        if (primaryTag.length() != 2) {
> +            // Not an ISO-639 language abbreviation. No way to determine Locale
> +            return null;
> +        }
> +
> +        String firstSubTag = null;
> +        if (tags.length > 1) {
> +            if (tags[1].length() == 2) {
> +                // Hopefully an ISO-3166 country code
> +                firstSubTag = tags[1];
> +            }
> +        }
> +
> +        if (firstSubTag == null) {
> +            return new Locale(primaryTag);
> +        } else {
> +            return new Locale(primaryTag, firstSubTag);
> +        }
> +    }
> +}
>
> Propchange: tomcat/trunk/java/org/apache/tomcat/util/http/ResponseUtil.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
>
> Modified: tomcat/trunk/webapps/docs/changelog.xml
> URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1374073&r1=1374072&r2=1374073&view=diff
> ==============================================================================
> --- tomcat/trunk/webapps/docs/changelog.xml (original)
> +++ tomcat/trunk/webapps/docs/changelog.xml Thu Aug 16 21:50:44 2012
> @@ -92,6 +92,12 @@
>          Service. This removes the need to maintain two copies of the mappings
>          for Servlets and Filters. (markt)
>        </scode>
> +      <add>
> +        If the <code>Content-Language</code> HTTP header is set directly,
> +        attempt to determine the Locale from the header value and call
> +        <code>ServletResponse.setLocale()</code> with the derived Locale.
> +        (markt)
> +      </add>
>      </changelog>
>    </subsection>
>    <subsection name="Coyote">


I do not like it.

My concerns are that
================
1) It contradicts the specification of ServletResponse.getLocale().

The Javadoc for ServletResponse.getLocale() in Servlet 3.0 spec is the
same as in Tomcat source code and says that the method returns the
value set by setLocale() and is the container's default locale
otherwise.

Effectively this commit changes the value returned by getLocale() so
that the default locale is no longer returned.

It seems reasonable to expect an explicit call to setLocale(), so not
to bother with creation of Locale object.

2) This implementation may change the value of Content-Language header

It relies on roundtrip of header -> Locale -> header, but this
roundtrip may change the value of the header (explained below).  I
think that if the header has been set explicitly, it would be better
to preserve it as is.


Regarding the roundtrip:
===================
- When any of those "checkSpecialHeader()" methods return true, it
means that the header will not be set.
- Later in AbstractHttpProcessor#prepareResponse() Tomcat will create
the header from Locale.
- The Locale class constructor converts language to lowercase and also
maps some "old" codes to other ones.
- There is a problem with ResponseUtil.getLocaleFromLanguageHeader():

It checks "if (tags.length > 1)". If the purpose of the method is to
reconstruct a locale, it is OK.  But if the purpose is to get exact
match then it should check "if (tags.length == 2)", because only 2
components are used to create a Locale. According to RFC2616 ch 3.10
there may be an arbitrary count of subtags.

        language-tag  = primary-tag *( "-" subtag )


One more bug in ResponseUtil.getLocaleFromLanguageHeader():
===================================
"if (primaryTag.length() != 2)"
should be "if (primaryTag.length() != 2 && primaryTag.length() != 3)"

RFC2616 ch 3.10 says that language codes are 2 characters, but this
information is outdated. The language codes can be 3 characters as
well.

The IANA registry is defined by RFC 5646 and can be seen here: Look for "aaa".

http://www.iana.org/protocols/
http://www.iana.org/assignments/language-subtag-registry/

The Locale(String,String) constructor in JDK 7u05 says "An ISO 639
alpha-2 or alpha-3 language code".

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message