Merge pull request #2475 from eclipse/jetty-9.4.x-2474-http2_client_invalid_server

Issue #2474 - HTTP/2 client not handling invalid servers correctly.
This commit is contained in:
Simone Bordet 2018-04-24 10:44:27 +02:00 committed by GitHub
commit 525579a395
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 6 deletions

View File

@ -129,11 +129,12 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
@Override
public void succeeded()
{
super.onOpen();
promise.succeeded(getSession());
// Only start reading from server after we have sent the client preface,
// otherwise we risk to read the server preface (a SETTINGS frame) and
// reply to that before we have the chance to send the client preface.
super.onOpen();
promise.succeeded(getSession());
produce();
}
@Override

View File

@ -0,0 +1,76 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.client;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.util.Promise;
import org.junit.Assert;
import org.junit.Test;
public class InvalidServerTest extends AbstractTest
{
@Test
public void testInvalidPreface() throws Exception
{
try (ServerSocket server = new ServerSocket(0))
{
prepareClient();
client.start();
CountDownLatch failureLatch = new CountDownLatch(1);
Promise.Completable<Session> promise = new Promise.Completable<>();
InetSocketAddress address = new InetSocketAddress("localhost", server.getLocalPort());
client.connect(address, new Session.Listener.Adapter()
{
@Override
public void onFailure(Session session, Throwable failure)
{
failureLatch.countDown();
}
}, promise);
Socket socket = server.accept();
OutputStream output = socket.getOutputStream();
output.write("enough_junk_bytes".getBytes(StandardCharsets.UTF_8));
Session session = promise.get(5, TimeUnit.SECONDS);
Assert.assertNotNull(session);
Assert.assertTrue(failureLatch.await(5, TimeUnit.SECONDS));
// Verify that the client closed the socket.
InputStream input = socket.getInputStream();
while (true)
{
int read = input.read();
if (read < 0)
break;
}
}
}
}

View File

@ -101,7 +101,6 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
if (LOG.isDebugEnabled())
LOG.debug("HTTP2 Open {} ", this);
super.onOpen();
strategy.produce();
}
@Override
@ -119,7 +118,7 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
{
if (LOG.isDebugEnabled())
LOG.debug("HTTP2 onFillable {} ", this);
strategy.produce();
produce();
}
private int fill(EndPoint endPoint, ByteBuffer buffer)
@ -154,9 +153,23 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
{
offerTask(task);
if (dispatch)
strategy.dispatch();
dispatch();
else
strategy.produce();
produce();
}
protected void produce()
{
if (LOG.isDebugEnabled())
LOG.debug("HTTP2 produce {} ", this);
strategy.produce();
}
protected void dispatch()
{
if (LOG.isDebugEnabled())
LOG.debug("HTTP2 dispatch {} ", this);
strategy.dispatch();
}
@Override

View File

@ -145,6 +145,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
for (Frame frame : upgradeFrames)
getSession().onFrame(frame);
super.onOpen();
produce();
}
private void notifyAccept(ISession session)