Skip to content
Commits on Source (4)
......@@ -25,12 +25,12 @@
<parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-parent</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
</parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-benchmarks</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
<name>Undertow Benchmarks</name>
......
......@@ -25,12 +25,12 @@
<parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-parent</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
</parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
<name>Undertow Core</name>
......
......@@ -401,9 +401,9 @@ public interface UndertowLogger extends BasicLogger {
@Message(id = 5086, value = "Failed to accept SSL request")
void failedToAcceptSSLRequest(@Cause Exception e);
@LogMessage(level = ERROR)
@Message(id = 5087, value = "Failed to use the server order")
void failedToUseServerOrder(@Cause ReflectiveOperationException e);
// @LogMessage(level = ERROR)
// @Message(id = 5087, value = "Failed to use the server order")
// void failedToUseServerOrder(@Cause ReflectiveOperationException e);
@LogMessage(level = ERROR)
@Message(id = 5088, value = "Failed to execute ServletOutputStream.closeAsync() on IO thread")
......
......@@ -169,7 +169,7 @@ public class AjpClientChannel extends AbstractFramedChannel<AjpClientChannel, Ab
return lastFrameSent;
}
protected void lastDataRead() {
protected synchronized void lastDataRead() {
if(!lastFrameSent) {
markReadsBroken(new ClosedChannelException());
markWritesBroken(new ClosedChannelException());
......
......@@ -587,18 +587,23 @@ public class Http2Channel extends AbstractFramedChannel<Http2Channel, AbstractHt
}
protected void lastDataRead() {
final boolean peerGoneAway;
synchronized (this) {
lastDataRead = true;
if(!peerGoneAway) {
//we just close the connection, as the peer has performed an unclean close
IoUtils.safeClose(this);
} else {
peerGoneAway = true;
peerGoneAway = this.peerGoneAway;
if(peerGoneAway) {
if(!thisGoneAway) {
//we send a goaway message, and then close
sendGoAway(ERROR_CONNECT_ERROR);
}
}
}
if (!peerGoneAway) {
//we just close the connection, as the peer has performed an unclean close
IoUtils.safeClose(this);
}
}
@Override
protected boolean isLastFrameReceived() {
......
......@@ -38,8 +38,6 @@ import org.xnio.channels.AcceptingChannel;
import org.xnio.ssl.SslConnection;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
......@@ -59,18 +57,6 @@ import javax.net.ssl.SSLParameters;
*/
class UndertowAcceptingSslChannel implements AcceptingChannel<SslConnection> {
static final Method USE_CIPHER_SUITES_METHOD;
static {
Method method = null;
try {
method = SSLParameters.class.getDeclaredMethod("setUseCipherSuitesOrder", boolean.class);
method.setAccessible(true);
} catch (NoSuchMethodException e) {
}
USE_CIPHER_SUITES_METHOD = method;
}
private final UndertowXnioSsl ssl;
private final AcceptingChannel<? extends StreamConnection> tcpServer;
......@@ -158,14 +144,10 @@ class UndertowAcceptingSslChannel implements AcceptingChannel<SslConnection> {
final InetSocketAddress peerAddress = tcpConnection.getPeerAddress(InetSocketAddress.class);
final SSLEngine engine = ssl.getSslContext().createSSLEngine(getHostNameNoResolve(peerAddress), peerAddress.getPort());
if(USE_CIPHER_SUITES_METHOD != null && useCipherSuitesOrder) {
if(useCipherSuitesOrder) {
SSLParameters sslParameters = engine.getSSLParameters();
try {
USE_CIPHER_SUITES_METHOD.invoke(sslParameters, true);
sslParameters.setUseCipherSuitesOrder(true);
engine.setSSLParameters(sslParameters);
} catch (IllegalAccessException | InvocationTargetException e) {
UndertowLogger.ROOT_LOGGER.failedToUseServerOrder(e);
}
}
final boolean clientMode = useClientMode != 0;
engine.setUseClientMode(clientMode);
......
......@@ -21,8 +21,6 @@ package io.undertow.protocols.ssl;
import static org.xnio.IoUtils.safeClose;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
......@@ -42,7 +40,6 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import io.undertow.UndertowLogger;
import io.undertow.UndertowOptions;
import org.xnio.ChannelListener;
import org.xnio.ChannelListeners;
......@@ -82,18 +79,6 @@ public class UndertowXnioSsl extends XnioSsl {
private final ByteBufferPool bufferPool;
private volatile SSLContext sslContext;
private static final Method USE_CIPHER_SUITES_METHOD;
static {
Method method = null;
try {
method = SSLParameters.class.getDeclaredMethod("setUseCipherSuitesOrder", boolean.class);
method.setAccessible(true);
} catch (NoSuchMethodException e) {
}
USE_CIPHER_SUITES_METHOD = method;
}
/**
* Construct a new instance.
*
......@@ -298,14 +283,10 @@ public class UndertowXnioSsl extends XnioSsl {
}
}
boolean useCipherSuitesOrder = optionMap.get(UndertowOptions.SSL_USER_CIPHER_SUITES_ORDER, false);
if (USE_CIPHER_SUITES_METHOD != null && useCipherSuitesOrder) {
if (useCipherSuitesOrder) {
SSLParameters sslParameters = engine.getSSLParameters();
try {
USE_CIPHER_SUITES_METHOD.invoke(sslParameters, true);
sslParameters.setUseCipherSuitesOrder(true);
engine.setSSLParameters(sslParameters);
} catch (IllegalAccessException | InvocationTargetException e) {
UndertowLogger.ROOT_LOGGER.failedToUseServerOrder(e);
}
}
final String endpointIdentificationAlgorithm = optionMap.get(UndertowOptions.ENDPOINT_IDENTIFICATION_ALGORITHM, null);
if (endpointIdentificationAlgorithm != null) {
......
......@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import org.xnio.conduits.StreamSourceConduit;
import io.undertow.conduits.GzipStreamSourceConduit;
import io.undertow.conduits.InflatingStreamSourceConduit;
import io.undertow.server.ConduitWrapper;
import io.undertow.server.HandlerWrapper;
......@@ -108,6 +109,7 @@ public class RequestEncodingHandler implements HttpHandler {
@Override
public HttpHandler wrap(HttpHandler handler) {
return new RequestEncodingHandler(handler)
.addEncoding("gzip", GzipStreamSourceConduit.WRAPPER)
.addEncoding("deflate", InflatingStreamSourceConduit.WRAPPER);
}
};
......
......@@ -139,8 +139,9 @@ public abstract class AbstractFramedChannel<C extends AbstractFramedChannel<C, R
private final Runnable taskRunQueueRunnable = new Runnable() {
@Override
public void run() {
while (!taskRunQueue.isEmpty()) {
taskRunQueue.poll().run();
Runnable runnable;
while ((runnable = taskRunQueue.poll()) != null) {
runnable.run();
}
}
};
......@@ -341,7 +342,11 @@ public abstract class AbstractFramedChannel<C extends AbstractFramedChannel<C, R
* existing source channels. In general if you suspend receives or don't have some other way
* of calling this method then it can prevent frame channels for being fully consumed.
*/
public synchronized R receive() throws IOException {
public R receive() throws IOException {
// store in a local variable to prevent invoking lastDataRead twice
boolean receivedMinusOne = false;
try {
synchronized (this) {
if (readChannelDone && receiver == null) {
//we have received the last frame, we just shut down and return
//it would probably make more sense to have the last channel responsible for this
......@@ -387,8 +392,7 @@ public abstract class AbstractFramedChannel<C extends AbstractFramedChannel<C, R
return null;
} else if (read == -1 && !hasData) {
forceFree = true;
readChannelDone = true;
lastDataRead();
receivedMinusOne = readChannelDone = true;
return null;
} else if(isLastFrameReceived() && frameDataRemaining == 0) {
//we got data, although we should have received the last frame
......@@ -511,6 +515,15 @@ public abstract class AbstractFramedChannel<C extends AbstractFramedChannel<C, R
}
}
}
} finally {
// read receivedMinusOne, and not readChannelDone
// to prevent lastDataRead being invoked twice in case of
// two concurrent receive invocations
if (receivedMinusOne) {
lastDataRead();
}
}
}
/**
* Called when the last frame has been received (note that their may still be data from the last frame than needs to be read)
......@@ -596,8 +609,8 @@ public abstract class AbstractFramedChannel<C extends AbstractFramedChannel<C, R
flushingSenders = true;
try {
int toSend = 0;
while (!newFrames.isEmpty()) {
S frame = newFrames.poll();
S frame;
while ((frame = newFrames.poll()) != null) {
frame.preWrite();
if (framePriority.insertFrame(frame, pendingFrames)) {
if (!heldFrames.isEmpty()) {
......@@ -813,6 +826,7 @@ public abstract class AbstractFramedChannel<C extends AbstractFramedChannel<C, R
*/
@Override
public void close() throws IOException {
synchronized (this) {
if (UndertowLogger.REQUEST_IO_LOGGER.isTraceEnabled()) {
UndertowLogger.REQUEST_IO_LOGGER.tracef(new ClosedChannelException(), "Channel %s is being closed", this);
}
......@@ -821,6 +835,7 @@ public abstract class AbstractFramedChannel<C extends AbstractFramedChannel<C, R
readData.close();
readData = null;
}
}
closeSubChannels();
}
......@@ -933,8 +948,9 @@ public abstract class AbstractFramedChannel<C extends AbstractFramedChannel<C, R
@Override
public void handleEvent(final StreamSourceChannel channel) {
//clear the task queue before reading
while (!taskRunQueue.isEmpty()) {
taskRunQueue.poll().run();
Runnable runnable;
while ((runnable = taskRunQueue.poll()) != null) {
runnable.run();
}
final R receiver = AbstractFramedChannel.this.receiver;
......
......@@ -108,6 +108,8 @@ public abstract class AbstractFramedStreamSinkChannel<C extends AbstractFramedCh
private volatile boolean writesResumed;
@SuppressWarnings("unused")
private volatile int inListenerLoop;
/* keep track of successful writes to properly prevent a loop UNDERTOW-1624 */
private volatile boolean writeSucceeded;
private static final AtomicIntegerFieldUpdater<AbstractFramedStreamSinkChannel> inListenerLoopUpdater = AtomicIntegerFieldUpdater.newUpdater(AbstractFramedStreamSinkChannel.class, "inListenerLoop");
......@@ -196,6 +198,8 @@ public abstract class AbstractFramedStreamSinkChannel<C extends AbstractFramedCh
if (inListenerLoopUpdater.compareAndSet(this, 0, 1)) {
getChannel().runInIoThread(new Runnable() {
// loopCount keeps track of runnable being invoked in a
// loop without any successful write operation
int loopCount = 0;
@Override
......@@ -205,7 +209,11 @@ public abstract class AbstractFramedStreamSinkChannel<C extends AbstractFramedCh
if (listener == null || !isWriteResumed()) {
return;
}
if (loopCount++ == 100) {
if (writeSucceeded) {
// reset write succeeded and loopCount
writeSucceeded = false;
loopCount = 0;
} else if (loopCount++ == 100) {
//should never happen
UndertowLogger.ROOT_LOGGER.listenerNotProgressing();
IoUtils.safeClose(AbstractFramedStreamSinkChannel.this);
......@@ -387,6 +395,7 @@ public abstract class AbstractFramedStreamSinkChannel<C extends AbstractFramedCh
if(!buffer.hasRemaining()) {
handleBufferFull();
}
writeSucceeded = writeSucceeded || copied > 0;
return copied;
}
......@@ -408,6 +417,7 @@ public abstract class AbstractFramedStreamSinkChannel<C extends AbstractFramedCh
if(!buffer.hasRemaining()) {
handleBufferFull();
}
writeSucceeded = writeSucceeded || copied > 0;
return copied;
}
......@@ -433,6 +443,7 @@ public abstract class AbstractFramedStreamSinkChannel<C extends AbstractFramedCh
protected boolean sendInternal(PooledByteBuffer pooled) throws IOException {
if (safeToSend()) {
this.body = pooled;
writeSucceeded = true;
return true;
}
return false;
......@@ -516,7 +527,7 @@ public abstract class AbstractFramedStreamSinkChannel<C extends AbstractFramedCh
}
@Override
public void close() throws IOException {
public synchronized void close() throws IOException {
if(fullyFlushed || anyAreSet(state, STATE_CLOSED)) {
return;
}
......
......@@ -49,6 +49,7 @@ import io.undertow.UndertowMessages;
* Source channel, used to receive framed messages.
*
* @author Stuart Douglas
* @author Flavia Rainone
*/
public abstract class AbstractFramedStreamSourceChannel<C extends AbstractFramedChannel<C, R, S>, R extends AbstractFramedStreamSourceChannel<C, R, S>, S extends AbstractFramedStreamSinkChannel<C, R, S>> implements StreamSourceChannel {
......@@ -62,13 +63,13 @@ public abstract class AbstractFramedStreamSourceChannel<C extends AbstractFramed
private static final int STATE_DONE = 1 << 1;
private static final int STATE_READS_RESUMED = 1 << 2;
private static final int STATE_CLOSED = 1 << 3;
private static final int STATE_LAST_FRAME = 1 << 4;
private static final int STATE_IN_LISTENER_LOOP = 1 << 5;
private static final int STATE_STREAM_BROKEN = 1 << 6;
private static final int STATE_RETURNED_MINUS_ONE = 1 << 7;
private static final int STATE_WAITNG_MINUS_ONE = 1 << 8;
private static final int STATE_READS_AWAKEN = 1 << 3;
private static final int STATE_CLOSED = 1 << 4;
private static final int STATE_LAST_FRAME = 1 << 5;
private static final int STATE_IN_LISTENER_LOOP = 1 << 6;
private static final int STATE_STREAM_BROKEN = 1 << 7;
private static final int STATE_RETURNED_MINUS_ONE = 1 << 8;
private static final int STATE_WAITNG_MINUS_ONE = 1 << 9;
/**
* The backing data for the current frame.
......@@ -215,7 +216,7 @@ public abstract class AbstractFramedStreamSourceChannel<C extends AbstractFramed
@Override
public void suspendReads() {
synchronized (lock) {
state &= ~STATE_READS_RESUMED;
state &= ~(STATE_READS_RESUMED | STATE_READS_AWAKEN);
}
}
......@@ -263,9 +264,13 @@ public abstract class AbstractFramedStreamSourceChannel<C extends AbstractFramed
*/
void resumeReadsInternal(boolean wakeup) {
synchronized (lock) {
boolean alreadyResumed = anyAreSet(state, STATE_READS_RESUMED);
state |= STATE_READS_RESUMED;
if (!alreadyResumed || wakeup) {
// mark state awaken if wakeup is true
if (wakeup)
state |= STATE_READS_AWAKEN;
// if not waked && not resumed, return
else if (!anyAreSet(state, STATE_READS_RESUMED))
return;
if (!anyAreSet(state, STATE_IN_LISTENER_LOOP)) {
state |= STATE_IN_LISTENER_LOOP;
getFramedChannel().runInIoThread(new Runnable() {
......@@ -273,8 +278,11 @@ public abstract class AbstractFramedStreamSourceChannel<C extends AbstractFramed
@Override
public void run() {
try {
boolean moreData;
boolean readAgain;
do {
synchronized(lock) {
state &= ~STATE_READS_AWAKEN;
}
ChannelListener<? super R> listener = getReadListener();
if (listener == null || !isReadResumed()) {
return;
......@@ -283,15 +291,24 @@ public abstract class AbstractFramedStreamSourceChannel<C extends AbstractFramed
//if writes are shutdown or we become active then we stop looping
//we stop when writes are shutdown because we can't flush until we are active
//although we may be flushed as part of a batch
moreData = (frameDataRemaining > 0 && data != null) || !pendingFrameData.isEmpty() || anyAreSet(state, STATE_WAITNG_MINUS_ONE);
final boolean moreData = (frameDataRemaining > 0 && data != null) || !pendingFrameData.isEmpty() || anyAreSet(state, STATE_WAITNG_MINUS_ONE);
synchronized (lock) {
// keep running if either reads are resumed and there is more data to read, or if reads are awaken
readAgain =((isReadResumed() && moreData) || allAreSet(state, STATE_READS_AWAKEN))
// as long as channel is not closed and there is no stream broken
&& allAreClear(state,STATE_CLOSED | STATE_STREAM_BROKEN);
if (!readAgain)
state &= ~STATE_IN_LISTENER_LOOP;
}
while (allAreSet(state, STATE_READS_RESUMED) && allAreClear(state, STATE_CLOSED | STATE_STREAM_BROKEN) && moreData);
} finally {
} while (readAgain);
} catch (RuntimeException | Error e) {
synchronized (lock) {
state &= ~STATE_IN_LISTENER_LOOP;
}
}
});
}
});
}
}
}
......@@ -311,7 +328,9 @@ public abstract class AbstractFramedStreamSourceChannel<C extends AbstractFramed
}
waitingForFrame = false;
if(data == null && pendingFrameData.isEmpty() && frameDataRemaining == 0) {
synchronized (lock) {
state |= STATE_DONE | STATE_CLOSED;
}
getFramedChannel().notifyFrameReadComplete(this);
IoUtils.safeClose(this);
}
......@@ -603,7 +622,7 @@ public abstract class AbstractFramedStreamSourceChannel<C extends AbstractFramed
}
@Override
public void close() {
public synchronized void close() {
if(anyAreSet(state, STATE_CLOSED)) {
return;
}
......
......@@ -147,7 +147,7 @@ public abstract class WebSocketChannel extends AbstractFramedChannel<WebSocketCh
}
@Override
protected void lastDataRead() {
protected synchronized void lastDataRead() {
if(!closeFrameReceived && !closeFrameSent) {
//the peer has likely already gone away, but try and send a close frame anyway
//this will likely just result in the write() failing an immediate connection termination
......
......@@ -25,6 +25,7 @@ io.undertow.server.handlers.PathSeparatorHandler$Builder
io.undertow.server.handlers.IPAddressAccessControlHandler$Builder
io.undertow.server.handlers.ByteRangeHandler$Builder
io.undertow.server.handlers.encoding.EncodingHandler$Builder
io.undertow.server.handlers.encoding.RequestEncodingHandler$Builder
io.undertow.server.handlers.LearningPushHandler$Builder
io.undertow.server.handlers.SetHeaderHandler$Builder
io.undertow.predicate.PredicatesHandler$DoneHandlerBuilder
......
......@@ -104,7 +104,7 @@ public class RangeRequestTestCase {
HttpResponse result = client.execute(get);
Assert.assertEquals(StatusCodes.PARTIAL_CONTENT, result.getStatusLine().getStatusCode());
String response = EntityUtils.toString(result.getEntity());
Assert.assertEquals("89\n2:012345", response);
Assert.assertEquals("89#2:012345", response);
Assert.assertEquals( "bytes 10-20/1034", result.getFirstHeader(Headers.CONTENT_RANGE_STRING).getValue());
get = new HttpGet(DefaultServer.getDefaultServerURL() + path);
......@@ -112,7 +112,7 @@ public class RangeRequestTestCase {
result = client.execute(get);
Assert.assertEquals(StatusCodes.PARTIAL_CONTENT, result.getStatusLine().getStatusCode());
response = EntityUtils.toString(result.getEntity());
Assert.assertEquals("3:0123456789\n74:012345678", response);
Assert.assertEquals("3:0123456789#74:012345678", response);
Assert.assertEquals( "bytes 1000-1024/1034", result.getFirstHeader(Headers.CONTENT_RANGE_STRING).getValue());
get = new HttpGet(DefaultServer.getDefaultServerURL() + path);
......@@ -120,7 +120,7 @@ public class RangeRequestTestCase {
result = client.execute(get);
Assert.assertEquals(StatusCodes.PARTIAL_CONTENT, result.getStatusLine().getStatusCode());
response = EntityUtils.toString(result.getEntity());
Assert.assertEquals(":0123456789\n74:012345678", response);
Assert.assertEquals(":0123456789#74:012345678", response);
Assert.assertEquals( "bytes 1001-1024/1034", result.getFirstHeader(Headers.CONTENT_RANGE_STRING).getValue());
get = new HttpGet(DefaultServer.getDefaultServerURL() + path);
......
1:0123456789
2:0123456789
3:0123456789
4:0123456789
5:0123456789
6:0123456789
7:0123456789
8:0123456789
9:0123456789
10:0123456789
11:0123456789
12:0123456789
13:0123456789
14:0123456789
15:0123456789
16:0123456789
17:0123456789
18:0123456789
19:0123456789
20:0123456789
21:0123456789
22:0123456789
23:0123456789
24:0123456789
25:0123456789
26:0123456789
27:0123456789
28:0123456789
29:0123456789
30:0123456789
31:0123456789
32:0123456789
33:0123456789
34:0123456789
35:0123456789
36:0123456789
37:0123456789
38:0123456789
39:0123456789
40:0123456789
41:0123456789
42:0123456789
43:0123456789
44:0123456789
45:0123456789
46:0123456789
47:0123456789
48:0123456789
49:0123456789
50:0123456789
51:0123456789
52:0123456789
53:0123456789
54:0123456789
55:0123456789
56:0123456789
57:0123456789
58:0123456789
59:0123456789
60:0123456789
61:0123456789
62:0123456789
63:0123456789
64:0123456789
65:0123456789
66:0123456789
67:0123456789
68:0123456789
69:0123456789
70:0123456789
71:0123456789
72:0123456789
73:0123456789
74:0123456789abcdefg
1:0123456789#2:0123456789#3:0123456789#4:0123456789#5:0123456789#6:0123456789#7:0123456789#8:0123456789#9:0123456789#10:0123456789#11:0123456789#12:0123456789#13:0123456789#14:0123456789#15:0123456789#16:0123456789#17:0123456789#18:0123456789#19:0123456789#20:0123456789#21:0123456789#22:0123456789#23:0123456789#24:0123456789#25:0123456789#26:0123456789#27:0123456789#28:0123456789#29:0123456789#30:0123456789#31:0123456789#32:0123456789#33:0123456789#34:0123456789#35:0123456789#36:0123456789#37:0123456789#38:0123456789#39:0123456789#40:0123456789#41:0123456789#42:0123456789#43:0123456789#44:0123456789#45:0123456789#46:0123456789#47:0123456789#48:0123456789#49:0123456789#50:0123456789#51:0123456789#52:0123456789#53:0123456789#54:0123456789#55:0123456789#56:0123456789#57:0123456789#58:0123456789#59:0123456789#60:0123456789#61:0123456789#62:0123456789#63:0123456789#64:0123456789#65:0123456789#66:0123456789#67:0123456789#68:0123456789#69:0123456789#70:0123456789#71:0123456789#72:0123456789#73:0123456789#74:0123456789abcdefg#
\ No newline at end of file
......@@ -3,7 +3,7 @@
<parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-parent</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
</parent>
<artifactId>undertow-coverage-report</artifactId>
<name>Undertow Test Coverage Report</name>
......
undertow (2.0.29-1) unstable; urgency=medium
* New upstream version 2.0.29.
-- Markus Koschany <apo@debian.org> Wed, 08 Jan 2020 22:54:07 +0100
undertow (2.0.28-1) unstable; urgency=medium
* New upstream version 2.0.28.
......
......@@ -5,11 +5,11 @@ Files-Excluded:
*.class
Files: *
Copyright: 2012-2019, Redhat Inc.
Copyright: 2012-2020, Redhat Inc.
License: Apache-2.0
Files: debian/*
Copyright: 2015-2019, Markus Koschany <apo@debian.org>
Copyright: 2015-2020, Markus Koschany <apo@debian.org>
License: Apache-2.0
Files: debian/patches/ALPN.patch
......
......@@ -25,12 +25,12 @@
<parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-parent</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
</parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-dist</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
<name>Undertow: Distribution</name>
......
......@@ -25,12 +25,12 @@
<parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-parent</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
</parent>
<groupId>io.undertow</groupId>
<artifactId>undertow-examples</artifactId>
<version>2.0.28.Final</version>
<version>2.0.29.Final</version>
<name>Undertow Examples</name>
......