You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by lu...@apache.org on 2003/10/13 23:53:45 UTC
cvs commit: jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote Response.java
luehe 2003/10/13 14:53:45
Modified: coyote/src/java/org/apache/coyote Response.java
Log:
Fixed Bugtraq 4934442 ("Response Content-Type has no charset even
though setCharacterEncoding was called")
This fixes the problem where a response char setting via
response.setCharacterEncoding() or response.setLocale() is not
preserved by a call to response.setContentType() with a content type
that has no charset, ie., response.getContentType(), following this
sequence of calls:
response.setCharacterEncoding("Shift_Jis");
response.setContentType("text/html")
used to return "text/html" instead of "text/html;charset=Shift_Jis",
which violates the servlet spec.
Revision Changes Path
1.27 +59 -34 jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/Response.java
Index: Response.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/Response.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- Response.java 2 Sep 2003 21:34:38 -0000 1.26
+++ Response.java 13 Oct 2003 21:53:45 -0000 1.27
@@ -64,7 +64,6 @@
import java.util.Locale;
import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.http.ContentType;
import org.apache.tomcat.util.http.MimeHeaders;
/**
@@ -87,15 +86,18 @@
}
- // ----------------------------------------------------- Instance Variables
-
-
- /**
+ // ----------------------------------------------------- Class Variables
+
+ /**
* Default locale as mandated by the spec.
*/
private static Locale DEFAULT_LOCALE = Locale.getDefault();
-
-
+
+ private static final int BEGIN_CHARSET_VALUE = "charset=".length();
+
+
+ // ----------------------------------------------------- Instance Variables
+
/**
* Status code.
*/
@@ -471,44 +473,67 @@
return;
characterEncoding = charset;
-
- String type = this.contentType;
- if (type != null) {
- int start = type.indexOf("charset=");
- if ( start != -1 ) {
- int end = type.indexOf(';', start+8);
- if (end >= 0)
- type = type.substring(0,start+8)
- + charset + type.substring(end-1);
- else
- type = type.substring(0,start+8) + charset;
- this.contentType = type;
- } else {
- int end = type.indexOf(';');
- if (end >= 0) {
- type = type.substring(0, end) + ";charset=" + charset;
- } else {
- type = type + ";charset=" + charset;
- }
- }
- setContentType( type );
- }
}
public String getCharacterEncoding() {
return characterEncoding;
}
+ /**
+ * Sets the content type.
+ *
+ * @param contentType the content type
+ */
public void setContentType(String contentType) {
- this.contentType = contentType;
- String encoding = ContentType.getCharsetFromContentType(contentType);
- if (encoding != null) {
- characterEncoding = encoding;
+
+ if (contentType == 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 Content-Type (as its charset param) by getContentType();
+ */
+ int beginCharsetValue = BEGIN_CHARSET_VALUE;
+ int beginCharsetParam = contentType.indexOf(";charset=");
+ if (beginCharsetParam == -1) {
+ beginCharsetParam = contentType.indexOf("; charset=");
+ beginCharsetValue++;
+ }
+ if (beginCharsetParam == -1) {
+ // no charset
+ this.contentType = contentType;
+ return;
+ }
+
+ this.contentType = contentType.substring(0, beginCharsetParam);
+ String tail = contentType.substring(beginCharsetParam + 1);
+ int nextParam = tail.indexOf(';');
+ String charsetValue = null;
+ if (nextParam != -1) {
+ this.contentType += tail.substring(nextParam);
+ charsetValue = tail.substring(beginCharsetValue, nextParam);
+ } else {
+ charsetValue = tail.substring(beginCharsetValue);
+ }
+ // The charset value may be quoted, but must not contain any quotes.
+ charsetValue = charsetValue.replace('"', ' ');
+ this.characterEncoding = charsetValue.trim();
}
public String getContentType() {
- return contentType;
+
+ String ret = contentType;
+
+ if (ret != null && characterEncoding != null) {
+ ret += ";charset=";
+ ret += characterEncoding;
+ }
+
+ return ret;
}
public void setContentLength(int contentLength) {
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org
Re: cvs commit: jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote Response.java
Posted by Bill Barker <wb...@wilshire.com>.
> + /*
> + * 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 Content-Type (as its charset param) by
getContentType();
> + */
> + int beginCharsetValue = BEGIN_CHARSET_VALUE;
> + int beginCharsetParam = contentType.indexOf(";charset=");
> + if (beginCharsetParam == -1) {
> + beginCharsetParam = contentType.indexOf("; charset=");
> + beginCharsetValue++;
> + }
Of course, this doesn't work if I do setContentType("text/html;
charset=utf-8");.
> + if (beginCharsetParam == -1) {
> + // no charset
> + this.contentType = contentType;
> + return;
> + }