Author: markt Date: Wed May 13 10:51:46 2015 New Revision: 1679174 URL: http://svn.apache.org/r1679174 Log: Fix various i18n TODOs
Modified: tomcat/trunk/java/org/apache/coyote/http2/ConnectionSettings.java tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Modified: tomcat/trunk/java/org/apache/coyote/http2/ConnectionSettings.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/ConnectionSettings.java?rev=1679174&r1=1679173&r2=1679174&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/ConnectionSettings.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/ConnectionSettings.java Wed May 13 10:51:46 2015 @@ -82,8 +82,8 @@ public class ConnectionSettings { // Can't be less than zero since the result of the byte->long conversion // will never be negative if (enablePush > 1) { - // TODO i18n - throw new Http2Exception("", 0, Http2Exception.PROTOCOL_ERROR); + throw new Http2Exception(sm.getString("connectionSettings.enablePushInvalid", + Long.toString(enablePush)), 0, Http2Exception.PROTOCOL_ERROR); } this.enablePush = enablePush; } @@ -102,8 +102,9 @@ public class ConnectionSettings { } public void setInitialWindowSize(long initialWindowSize) throws IOException { if (initialWindowSize > MAX_WINDOW_SIZE) { - // TODO i18n - throw new Http2Exception("", 0, Http2Exception.PROTOCOL_ERROR); + throw new Http2Exception(sm.getString("connectionSettings.windowSizeTooBig", + Long.toString(initialWindowSize), Long.toString(MAX_WINDOW_SIZE)), + 0, Http2Exception.PROTOCOL_ERROR); } this.initialWindowSize = initialWindowSize; } @@ -114,8 +115,9 @@ public class ConnectionSettings { } public void setMaxFrameSize(long maxFrameSize) throws IOException { if (maxFrameSize < MIN_MAX_FRAME_SIZE || maxFrameSize > MAX_MAX_FRAME_SIZE) { - // TODO i18n - throw new Http2Exception("", 0, Http2Exception.PROTOCOL_ERROR); + throw new Http2Exception(sm.getString("connectionSettings.maxFrameSizeInvalid", + Long.toString(maxFrameSize), Long.toString(MIN_MAX_FRAME_SIZE), + Long.toString(MAX_MAX_FRAME_SIZE)), 0, Http2Exception.PROTOCOL_ERROR); } this.maxFrameSize = maxFrameSize; } Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1679174&r1=1679173&r2=1679174&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Wed May 13 10:51:46 2015 @@ -18,6 +18,7 @@ package org.apache.coyote.http2; import java.io.EOFException; import java.io.IOException; +import java.nio.charset.StandardCharsets; import javax.servlet.http.WebConnection; @@ -51,13 +52,13 @@ public class Http2UpgradeHandler impleme private static final byte[] SETTINGS_EMPTY = { 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 }; private static final byte[] SETTINGS_ACK = { 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00 }; + private static final byte[] GOAWAY = { 0x07, 0x00, 0x00, 0x00 }; private volatile SocketWrapperBase<?> socketWrapper; private volatile boolean initialized = false; private volatile ConnectionPrefaceParser connectionPrefaceParser = new ConnectionPrefaceParser(); private volatile boolean firstFrame = true; - private volatile boolean open = true; private final ConnectionSettings remoteSettings = new ConnectionSettings(); @@ -70,8 +71,7 @@ public class Http2UpgradeHandler impleme socketWrapper.write(true, SETTINGS_EMPTY, 0, SETTINGS_EMPTY.length); socketWrapper.flush(true); } catch (IOException ioe) { - // TODO i18n - throw new IllegalStateException("Failed to send preface to client", ioe); + throw new IllegalStateException(sm.getString("upgradeHandler.sendPrefaceFail"), ioe); } } @@ -96,6 +96,7 @@ public class Http2UpgradeHandler impleme if (connectionPrefaceParser != null) { if (!connectionPrefaceParser.parse(socketWrapper)) { if (connectionPrefaceParser.isError()) { + // Any errors will have already been logged. close(); return SocketState.CLOSED; } else { @@ -109,17 +110,25 @@ public class Http2UpgradeHandler impleme try { while (processFrame()) { } - // TODO Catch the Http2Exception and reset the stream / close - // the connection as appropriate + } catch (Http2Exception h2e) { + if (h2e.getStreamId() == 0) { + // Connection error + log.warn(sm.getString("upgradeHandler.connectionError"), h2e); + close(h2e); + return SocketState.CLOSED; + } else { + // Stream error + // TODO Reset stream + } } catch (IOException ioe) { - log.error("TODO: i18n - Frame processing error", ioe); - open = false; + if (log.isDebugEnabled()) { + log.debug("TODO: i18n - I/O error during frame processing", ioe); + } + close(); + return SocketState.CLOSED; } - if (open) { - return SocketState.LONG; - } - break; + return SocketState.LONG; case OPEN_WRITE: // TODO @@ -181,16 +190,16 @@ public class Http2UpgradeHandler impleme } // Validate the frame if (streamId != 0) { - // TODO i18n - throw new Http2Exception("", 0, Http2Exception.FRAME_SIZE_ERROR); + throw new Http2Exception(sm.getString("upgradeHandler.processFrameSettings.invalidStream", + Integer.toString(streamId)), 0, Http2Exception.FRAME_SIZE_ERROR); } if (payloadSize % 6 != 0) { - // TODO i18n - throw new Http2Exception("", 0, Http2Exception.FRAME_SIZE_ERROR); + throw new Http2Exception(sm.getString("upgradeHandler.processFrameSettings.invalidPayloadSize", + Integer.toString(payloadSize)), 0, Http2Exception.FRAME_SIZE_ERROR); } if (payloadSize > 0 && (flags & 0x1) != 0) { - // TODO i18n - throw new Http2Exception("", 0, Http2Exception.FRAME_SIZE_ERROR); + throw new Http2Exception(sm.getString("upgradeHandler.processFrameSettings.ackWithNonZeroPayload"), + 0, Http2Exception.FRAME_SIZE_ERROR); } if (payloadSize == 0) { @@ -206,8 +215,7 @@ public class Http2UpgradeHandler impleme while (read < 6) { int thisTime = socketWrapper.read(true, setting, read, setting.length - read); if (thisTime == -1) { - // TODO i18n - throw new EOFException(); + throw new EOFException(sm.getString("upgradeHandler.unexpectedEos")); } read += thisTime; } @@ -262,8 +270,7 @@ public class Http2UpgradeHandler impleme int read = socketWrapper.read(true, frameHeader, headerBytesRead, frameHeader.length - headerBytesRead); if (read == -1) { - // TODO i18n - throw new EOFException(); + throw new EOFException(sm.getString("upgradeHandler.unexpectedEos")); } } @@ -276,8 +283,8 @@ public class Http2UpgradeHandler impleme // Make sure the first frame is a settings frame if (firstFrame) { if (frameType != FRAME_SETTINGS) { - // TODO i18n - throw new Http2Exception("", 0, Http2Exception.PROTOCOL_ERROR); + throw new Http2Exception(sm.getString("upgradeHandler.receivePrefaceNotSettings"), + 0, Http2Exception.PROTOCOL_ERROR); } else { firstFrame = false; } @@ -301,8 +308,9 @@ public class Http2UpgradeHandler impleme if (payloadSize > remoteSettings.getMaxFrameSize()) { swallowPayload(payloadSize); - // TODO i18n - throw new Http2Exception("", streamId, Http2Exception.FRAME_SIZE_ERROR); + throw new Http2Exception(sm.getString("upgradeHandler.payloadTooBig", + Integer.toString(payloadSize), Long.toString(remoteSettings.getMaxFrameSize())), + streamId, Http2Exception.FRAME_SIZE_ERROR); } return payloadSize; @@ -315,6 +323,36 @@ public class Http2UpgradeHandler impleme } + private void close(Http2Exception h2e) { + // Write a GOAWAY frame. + byte[] payload = h2e.getMessage().getBytes(StandardCharsets.UTF_8); + byte[] payloadLength = getPayloadLength(payload); + + try { + socketWrapper.write(true, payloadLength, 0, payloadLength.length); + socketWrapper.write(true, GOAWAY, 0, GOAWAY.length); + socketWrapper.write(true, payload, 0, payload.length); + socketWrapper.flush(true); + } catch (IOException ioe) { + // Ignore. GOAWAY is sent on a best efforts basis and the original + // error has already been logged. + } + close(); + } + + + private byte[] getPayloadLength(byte[] payload) { + byte[] result = new byte[3]; + int len = payload.length; + result[2] = (byte) (len & 0xFF); + len = len >>> 8; + result[1] = (byte) (len & 0xFF); + len = len >>> 8; + result[0] = (byte) (len & 0xFF); + + return result; + } + private void close() { try { socketWrapper.close(); Modified: tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties?rev=1679174&r1=1679173&r2=1679174&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Wed May 13 10:51:46 2015 @@ -17,7 +17,10 @@ connectionPrefaceParser.eos=Unexpected e connectionPrefaceParser.ioError=Failed to read opening client preface byte sequence connectionPrefaceParser.mismatch=An unexpected byte sequence was received at the start of the client preface [{0}] +connectionSettings.enablePushInvalid=The requested value for enable push [{0}] is not one of the permitted values (zero or one) +connectionSettings.maxFrameSizeInvalid=The requested maximum frame size of [{0}] is ouside the permitted range of [{1}] to [{2}] connectionSettings.unknown=An unknown setting with identifier [{0}] and value [{1}] was ignored +connectionSettings.windowSizeTooBig=The requested window size of [{0}] is bigger than the maximum permitted value of [{1}] hpack.integerEncodedOverTooManyOctets=HPACK variable length integer encoded over too many octets, max is {0} @@ -25,6 +28,14 @@ hpackdecoder.zeroNotValidHeaderTableInde hpackhuffman.huffmanEncodedHpackValueDidNotEndWithEOS=Huffman encoded value in HPACK headers did not end with EOS padding +upgradeHandler.connectionError=An error occurred that requires the HTTP/2 connection to be closed. +upgradeHandler.payloadTooBig=The payload is [{0}] bytes long but the maximum frame size is [{1}] upgradeHandler.processFrameSettings=Processing settings frame for stream [{1}] with flags [{0}] and payload size [{2}] +upgradeHandler.processFrameSettings.ackWithNonZeroPayload=Settings frame received with the ACK flag set and payload present +upgradeHandler.processFrameSettings.invalidPayloadSize=Settings frame received with a payload size of [{0}] which is not a multiple of 6 +upgradeHandler.processFrameSettings.invalidStream=Settings frame received for stream [{0}] +upgradeHandler.receivePrefaceNotSettings=The first frame received from the client was not a settings frame +upgradeHandler.sendPrefaceFail=Failed to send preface to client upgradeHandler.socketCloseFailed=Error closing socket +upgradeHandler.unexpectedEos=Unexpected end of stream upgradeHandler.unexpectedStatus=An unexpected value of status ([{0}]) was passed to this method \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org