Issue #3207
updates after review Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
225760c2de
commit
8f06fa8083
|
@ -27,6 +27,7 @@ import java.nio.channels.WritePendingException;
|
|||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
@ -127,6 +128,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
}
|
||||
|
||||
private static Logger LOG = Log.getLogger(HttpOutput.class);
|
||||
private final static ThreadLocal<CharsetEncoder> _encoder = new ThreadLocal<>();
|
||||
|
||||
private final HttpChannel _channel;
|
||||
private final SharedBlockingCallback _writeBlocker;
|
||||
|
@ -138,7 +140,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
private int _bufferSize;
|
||||
private int _commitSize;
|
||||
private WriteListener _writeListener;
|
||||
private CharsetEncoder _encoder;
|
||||
private volatile Throwable _onError;
|
||||
/*
|
||||
ACTION OPEN ASYNC READY PENDING UNREADY CLOSED
|
||||
|
@ -699,16 +700,23 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
if (isClosed())
|
||||
throw new IOException("Closed");
|
||||
|
||||
// TODO would a Threadlocal pool be better?
|
||||
String charset = _channel.getResponse().getCharacterEncoding();
|
||||
if (_encoder==null || !_encoder.charset().name().equals(charset))
|
||||
_encoder = Charset.forName(charset).newEncoder();
|
||||
CharsetEncoder encoder = _encoder.get();
|
||||
if (encoder==null || !encoder.charset().name().equalsIgnoreCase(charset))
|
||||
{
|
||||
encoder = Charset.forName(charset).newEncoder();
|
||||
encoder.onMalformedInput(CodingErrorAction.REPLACE);
|
||||
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
|
||||
_encoder.set(encoder);
|
||||
}
|
||||
else
|
||||
_encoder.reset();
|
||||
{
|
||||
encoder.reset();
|
||||
}
|
||||
|
||||
CharBuffer in = CharBuffer.wrap(s);
|
||||
CharBuffer crlf = eoln?CharBuffer.wrap("\r\n"):null;
|
||||
ByteBuffer out = getHttpChannel().getByteBufferPool().acquire((int)(1+(s.length()+2)*_encoder.averageBytesPerChar()),false);
|
||||
ByteBuffer out = getHttpChannel().getByteBufferPool().acquire((int)(1+(s.length()+2)*encoder.averageBytesPerChar()),false);
|
||||
BufferUtil.flipToFill(out);
|
||||
|
||||
for(;;)
|
||||
|
@ -716,7 +724,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
CoderResult result;
|
||||
if (in.hasRemaining())
|
||||
{
|
||||
result = _encoder.encode(in, out, false);
|
||||
result = encoder.encode(in, out, crlf==null);
|
||||
if (result.isUnderflow())
|
||||
if (crlf==null)
|
||||
break;
|
||||
|
@ -725,10 +733,10 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
}
|
||||
else if (crlf.hasRemaining())
|
||||
{
|
||||
result = _encoder.encode(crlf, out, true);
|
||||
result = encoder.encode(crlf, out, true);
|
||||
if (result.isUnderflow())
|
||||
{
|
||||
if (!_encoder.flush(out).isUnderflow())
|
||||
if (!encoder.flush(out).isUnderflow())
|
||||
result.throwException();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -591,14 +591,24 @@ public class ResponseTest
|
|||
session_handler.start();
|
||||
request.setSessionHandler(session_handler);
|
||||
HttpSession session = request.getSession(true);
|
||||
response.setCharacterEncoding(UTF_8.name());
|
||||
|
||||
assertThat(session,not(nullValue()));
|
||||
assertTrue(session.isNew());
|
||||
|
||||
response.getOutputStream().println("ABC");
|
||||
String expected = "";
|
||||
response.getOutputStream().print("ABC");
|
||||
expected += "ABC";
|
||||
response.getOutputStream().println("XYZ");
|
||||
expected += "XYZ\r\n";
|
||||
String s="";
|
||||
for (int i=0; i<100; i++)
|
||||
s += "\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC";
|
||||
response.getOutputStream().println(s);
|
||||
expected += s +"\r\n";
|
||||
|
||||
response.getOutputStream().close();
|
||||
assertEquals("ABC\r\nXYZ\r\n",BufferUtil.toString(_content));
|
||||
assertEquals(expected,BufferUtil.toString(_content, UTF_8));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue