Author: markt Date: Sat Dec 7 21:18:55 2013 New Revision: 1548971 URL: http://svn.apache.org/r1548971 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=52811 Correctly parse values passed to HttpServletResponse.setContentType() to extract the character encoding
Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java - copied, changed from r1548680, tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/ - copied from r1548680, tomcat/trunk/java/org/apache/tomcat/util/http/parser/ Modified: tomcat/tc6.0.x/trunk/STATUS.txt tomcat/tc6.0.x/trunk/java/org/apache/coyote/Response.java tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Modified: tomcat/tc6.0.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1548971&r1=1548970&r2=1548971&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/STATUS.txt (original) +++ tomcat/tc6.0.x/trunk/STATUS.txt Sat Dec 7 21:18:55 2013 @@ -55,20 +55,6 @@ PATCHES PROPOSED TO BACKPORT: +1: markt, schultz, kkolinko -1: -* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=52811 - Correctly parse values passed to HttpServletResponse.setContentType() to - extract the character encoding - Note: The original proposal that used a parser generated by javacc did not - gather enough support for back-port. - https://issues.apache.org/bugzilla/show_bug.cgi?id=52811 - svn cp https://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/tomcat/util/http/parser/ \ - https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/ - svn cp https://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java \ - https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java - http://people.apache.org/~markt/patches/2013-07-31-bug52811-tc6.patch - +1: markt, schultz, kkolinko - -1: - * Fix issue with Manager app and other apps that use i18n in the UI when a request that specifies an Accept-Language of English ahead of French, Spanish or Japanese. Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/Response.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/Response.java?rev=1548971&r1=1548970&r2=1548971&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/coyote/Response.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/Response.java Sat Dec 7 21:18:55 2013 @@ -18,10 +18,13 @@ package org.apache.coyote; import java.io.IOException; +import java.io.StringReader; import java.util.Locale; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.http.MimeHeaders; +import org.apache.tomcat.util.http.parser.HttpParser; +import org.apache.tomcat.util.http.parser.MediaType; /** * Response object. @@ -455,64 +458,31 @@ public final class Response { */ public void setContentType(String type) { - int semicolonIndex = -1; - if (type == null) { this.contentType = null; return; } - /* - * Remove the charset param (if any) from the Content-Type, and use it - * to set the response encoding. - * The most recent response encoding setting will be appended to the - * response's Content-Type (as its charset param) by getContentType(); - */ - boolean hasCharset = false; - int len = type.length(); - int index = type.indexOf(';'); - while (index != -1) { - semicolonIndex = index; - index++; - while (index < len && Character.isSpace(type.charAt(index))) { - index++; - } - if (index+8 < len - && type.charAt(index) == 'c' - && type.charAt(index+1) == 'h' - && type.charAt(index+2) == 'a' - && type.charAt(index+3) == 'r' - && type.charAt(index+4) == 's' - && type.charAt(index+5) == 'e' - && type.charAt(index+6) == 't' - && type.charAt(index+7) == '=') { - hasCharset = true; - break; - } - index = type.indexOf(';', index); - } - - if (!hasCharset) { + MediaType m = null; + try { + m = HttpParser.parseMediaType(new StringReader(type)); + } catch (IOException e) { + // Ignore - null test below handles this + } + if (m == null) { + // Invalid - Assume no charset and just pass through whatever + // the user provided. this.contentType = type; return; } - this.contentType = type.substring(0, semicolonIndex); - String tail = type.substring(index+8); - int nextParam = tail.indexOf(';'); - String charsetValue = null; - if (nextParam != -1) { - this.contentType += tail.substring(nextParam); - charsetValue = tail.substring(0, nextParam); - } else { - charsetValue = tail; - } + this.contentType = m.toStringNoCharset(); + + String charsetValue = m.getCharset().trim(); - // The charset value may be quoted, but must not contain any quotes. if (charsetValue != null && charsetValue.length() > 0) { - charsetSet=true; - charsetValue = charsetValue.replace('"', ' '); - this.characterEncoding = charsetValue.trim(); + charsetSet = true; + this.characterEncoding = charsetValue; } } Copied: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java (from r1548680, tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java) URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java?p2=tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java&p1=tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java&r1=1548680&r2=1548971&rev=1548971&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java Sat Dec 7 21:18:55 2013 @@ -30,8 +30,8 @@ public final class ConcurrentCache<K,V> public ConcurrentCache(int size) { this.size = size; - this.eden = new ConcurrentHashMap<>(size); - this.longterm = new WeakHashMap<>(size); + this.eden = new ConcurrentHashMap<K,V>(size); + this.longterm = new WeakHashMap<K,V>(size); } public V get(K k) { Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java?rev=1548971&r1=1548680&r2=1548971&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java Sat Dec 7 21:18:55 2013 @@ -50,7 +50,8 @@ public class HttpParser { private static final Integer FIELD_TYPE_LHEX = Integer.valueOf(3); private static final Integer FIELD_TYPE_QUOTED_TOKEN = Integer.valueOf(4); - private static final Map<String,Integer> fieldTypes = new HashMap<>(); + private static final Map<String,Integer> fieldTypes = + new HashMap<String, Integer>(); // Arrays used by isToken(), isHex() private static final boolean isToken[] = new boolean[128]; @@ -116,7 +117,7 @@ public class HttpParser { public static Map<String,String> parseAuthorizationDigest ( StringReader input) throws IllegalArgumentException, IOException { - Map<String,String> result = new HashMap<>(); + Map<String,String> result = new HashMap<String, String>(); if (skipConstant(input, "Digest") != SkipConstantResult.FOUND) { return null; @@ -199,7 +200,8 @@ public class HttpParser { return null; } - LinkedHashMap<String,String> parameters = new LinkedHashMap<>(); + LinkedHashMap<String,String> parameters = + new LinkedHashMap<String, String>(); SkipConstantResult lookForSemiColon = skipConstant(input, ";"); if (lookForSemiColon == SkipConstantResult.NOT_FOUND) { Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java?rev=1548971&r1=1548680&r2=1548971&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java Sat Dec 7 21:18:55 2013 @@ -29,7 +29,7 @@ public class MediaTypeCache { private final ConcurrentCache<String,String[]> cache; public MediaTypeCache(int size) { - cache = new ConcurrentCache<>(size); + cache = new ConcurrentCache<String, String[]>(size); } /** Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1548971&r1=1548970&r2=1548971&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Sat Dec 7 21:18:55 2013 @@ -69,6 +69,11 @@ <subsection name="Coyote"> <changelog> <fix> + <bug>52811</bug>: Fix parsing of Content-Type header in + <code>HttpServletResponse.setContentType()</code>. Introduces a new HTTP + header parser that follows RFC2616. (markt) + </fix> + <fix> <bug>54691</bug>: Add configuration attribute "sslEnabledProtocols" to HTTP connector and document it. (Internally this attribute has been already implemented but not documented, under names "protocols" --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org