Skip to content

Commit

Permalink
Issue #5757 - cleanup logic around character encoding in Response
Browse files Browse the repository at this point in the history
Signed-off-by: Lachlan Roberts <[email protected]>
  • Loading branch information
lachlan-roberts committed Dec 9, 2020
1 parent 5490b3a commit f5fab09
Showing 1 changed file with 59 additions and 72 deletions.
131 changes: 59 additions & 72 deletions jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ private enum EncodingFrom
}

private static final EnumSet<EncodingFrom> __localeOverride = EnumSet.of(EncodingFrom.NOT_SET, EncodingFrom.INFERRED, EncodingFrom.SET_LOCALE);
private static final EnumSet<EncodingFrom> __explicitCharset = EnumSet.of(EncodingFrom.SET_LOCALE, EncodingFrom.SET_CHARACTER_ENCODING);
private static final EnumSet<EncodingFrom> __explicitCharset = EnumSet.of(EncodingFrom.SET_LOCALE, EncodingFrom.SET_CHARACTER_ENCODING, EncodingFrom.SET_CONTENT_TYPE);

public Response(HttpChannel channel, HttpOutput out)
{
Expand Down Expand Up @@ -778,26 +778,40 @@ public void setStatusWithReason(int sc, String message)
@Override
public String getCharacterEncoding()
{
if (_characterEncoding == null)
// First try explicit char encoding.
if (_characterEncoding != null)
return _characterEncoding;

String encoding;

// Try charset from mime type.
if (_mimeType != null && _mimeType.isCharsetAssumed())
return _mimeType.getCharsetString();

// Try charset assumed from content type.
encoding = MimeTypes.getCharsetAssumedFromContentType(_contentType);
if (encoding != null)
return encoding;

// Try char set inferred from content type.
encoding = MimeTypes.getCharsetInferredFromContentType(_contentType);
if (encoding != null)
{
String encoding = MimeTypes.getCharsetAssumedFromContentType(_contentType);
if (encoding != null)
return encoding;
setCharacterEncoding(encoding, EncodingFrom.INFERRED);
return encoding;
}

encoding = MimeTypes.getCharsetInferredFromContentType(_contentType);
// Try any default char encoding for the context.
Context context = _channel.getRequest().getContext();
if (context != null)
{
encoding = context.getResponseCharacterEncoding();
if (encoding != null)
return encoding;

Context context = _channel.getRequest().getContext();
if (context != null)
{
encoding = context.getResponseCharacterEncoding();
if (encoding != null)
return encoding;
}
return StringUtil.__ISO_8859_1;
}
return _characterEncoding;

// Fallback to last resort iso-8859-1.
return StringUtil.__ISO_8859_1;
}

@Override
Expand Down Expand Up @@ -838,44 +852,7 @@ public PrintWriter getWriter() throws IOException

if (_outputType == OutputType.NONE)
{
// First try explicit char encoding.
String encoding = _characterEncoding;

// Try charset from mime type.
if (encoding == null)
{
if (_mimeType != null && _mimeType.isCharsetAssumed())
encoding = _mimeType.getCharsetString();
}

// Try charset assumed from content type.
if (encoding == null)
{
encoding = MimeTypes.getCharsetAssumedFromContentType(_contentType);
}

// Try char set inferred from content type.
if (encoding == null)
{
encoding = MimeTypes.getCharsetInferredFromContentType(_contentType);
setCharacterEncoding(encoding, EncodingFrom.INFERRED);
}

// Try any default char encoding for the context.
if (encoding == null)
{
Context context = _channel.getRequest().getContext();
if (context != null)
encoding = context.getResponseCharacterEncoding();
}

// Fallback to last resort iso-8859-1.
if (encoding == null)
{
encoding = StringUtil.__ISO_8859_1;
setCharacterEncoding(encoding, EncodingFrom.INFERRED);
}

String encoding = getCharacterEncoding();
Locale locale = getLocale();
if (_writer != null && _writer.isFor(locale, encoding))
_writer.reopen();
Expand Down Expand Up @@ -1331,21 +1308,34 @@ public boolean isCommitted()
@Override
public void setLocale(Locale locale)
{
if (locale == null || isCommitted() || !isMutable())
if (isCommitted() || !isMutable())
return;

_locale = locale;
_fields.put(HttpHeader.CONTENT_LANGUAGE, StringUtil.replace(locale.toString(), '_', '-'));

if (_outputType != OutputType.NONE)
if (locale == null)
{
_locale = null;
_fields.remove(HttpHeader.CONTENT_LANGUAGE);
if (_encodingFrom == EncodingFrom.SET_LOCALE)
setCharacterEncoding(null, EncodingFrom.NOT_SET);
return;
}
else
{

if (_channel.getRequest().getContext() == null)
return;
_locale = locale;
_fields.put(HttpHeader.CONTENT_LANGUAGE, StringUtil.replace(locale.toString(), '_', '-'));

if (_outputType != OutputType.NONE)
return;

Context context = _channel.getRequest().getContext();
if (context == null)
return;

String charset = _channel.getRequest().getContext().getContextHandler().getLocaleEncoding(locale);
if (charset != null && charset.length() > 0 && __localeOverride.contains(_encodingFrom))
setCharacterEncoding(charset, EncodingFrom.SET_LOCALE);
String charset = context.getContextHandler().getLocaleEncoding(locale);
if (!StringUtil.isEmpty(charset) && __localeOverride.contains(_encodingFrom))
setCharacterEncoding(charset, EncodingFrom.SET_LOCALE);
}
}

@Override
Expand Down Expand Up @@ -1403,20 +1393,17 @@ else if (contentLength > NO_CONTENT_LENGTH)
HttpField ct = content.getContentType();
if (ct != null)
{
if (_characterEncoding != null &&
content.getCharacterEncoding() == null &&
content.getContentTypeValue() != null &&
__explicitCharset.contains(_encodingFrom))
{
setContentType(MimeTypes.getContentTypeWithoutCharset(content.getContentTypeValue()));
}
else
if (!__explicitCharset.contains(_encodingFrom))
{
_fields.put(ct);
_contentType = ct.getValue();
_characterEncoding = content.getCharacterEncoding();
_mimeType = content.getMimeType();
}
else
{
setContentType(content.getContentTypeValue());
}
}

HttpField ce = content.getContentEncoding();
Expand Down

0 comments on commit f5fab09

Please sign in to comment.