package org.webpieces.http2client;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import javax.net.ssl.SSLEngine;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.webpieces.http2client.api.Http2Client;
import org.webpieces.http2client.api.Http2ClientFactory;
import org.webpieces.http2client.api.Http2Socket;
import org.webpieces.http2client.integ.ForTestSslClientEngineFactory;
import org.webpieces.http2client.mock.MockChanMgr;
import org.webpieces.http2client.mock.MockHttp2Channel;
import org.webpieces.http2client.mock.Preface;
import org.webpieces.http2client.util.Requests;
import org.webpieces.mock.time.MockTime;
import org.webpieces.util.threading.DirectExecutor;
import com.webpieces.http2engine.api.client.Http2Config;
import com.webpieces.http2engine.api.client.InjectionConfig;
import com.webpieces.http2engine.impl.shared.HeaderSettings;
import com.webpieces.http2parser.api.dto.lib.Http2Msg;
/**
* Test this section of rfc..
* http://httpwg.org/specs/rfc7540.html#starting
*/
public class TestC3InitialHttpsConnections {
private MockChanMgr mockChanMgr = new MockChanMgr();
private MockHttp2Channel mockChannel = new MockHttp2Channel();
private Http2Socket socket;
private HeaderSettings localSettings = Requests.createSomeSettings();
private MockTime mockTime = new MockTime(true);
@Before
public void setUp() throws InterruptedException, ExecutionException {
mockChannel.setIncomingFrameDefaultReturnValue(CompletableFuture.completedFuture(mockChannel));
Http2Config config = new Http2Config();
config.setInitialRemoteMaxConcurrent(1); //start with 1 max concurrent
config.setLocalSettings(localSettings);
InjectionConfig injConfig = new InjectionConfig(new DirectExecutor(), mockTime, config);
Http2Client client = Http2ClientFactory.createHttpClient(mockChanMgr, injConfig);
mockChanMgr.addSSLChannelToReturn(mockChannel);
InetSocketAddress addr = new InetSocketAddress("somehost.com", 555);
String host = addr.getHostName();
int port = addr.getPort();
ForTestSslClientEngineFactory ssl = new ForTestSslClientEngineFactory();
SSLEngine engine = ssl.createSslEngine(host, port);
socket = client.createHttpsSocket("simple", engine);
CompletableFuture<Http2Socket> connect = socket.connect(addr);
Assert.assertTrue(connect.isDone());
Assert.assertEquals(socket, connect.get());
//verify settings on connect were sent
//verify settings on connect were sent
List<Http2Msg> frames = mockChannel.getFramesAndClear();
Preface preface = (Preface) frames.get(0);
preface.verify();
Http2Msg settings1 = frames.get(1);
Assert.assertEquals(HeaderSettings.createSettingsFrame(localSettings), settings1);
}
/**
* Works with everyone but incurs a round trip overhead
*
* client sends PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n after TLS ALPN
*
* The first HTTP/2 frame sent by the server MUST be a server connection preface (Section 3.5)
* consisting of a SETTINGS frame (Section 6.5). Upon
* receiving the 101 response, the client MUST send a connection preface
* (Section 3.5), which includes a SETTINGS frame.
*/
@Test
public void testSection3_3WithH2andAlpn() {
}
/**
* Only will work with webpieces and jetty or webservers that support prior knowledge
*
* should send PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
* and server sends back it's preface...
* The server connection preface consists of a potentially empty SETTINGS
* frame (Section 6.5) that MUST be the first frame the server sends in the HTTP/2 connection.
*/
@Test
public void testSection3_3WithPriorKnowledge() {
//this is actually tested with the http version of this test
}
@Test
public void testSection3_3WithH2PriorKnowledgeFailsIfHttp1_1() {
//same as http version of this test
}
}