)
func init() {
- RegisterH2Tests(Http2TcpGetTest, Http2TcpPostTest, Http2MultiplexingTest, Http2MultiplexingMTTest)
+ RegisterH2Tests(Http2TcpGetTest, Http2TcpPostTest, Http2MultiplexingTest, Http2MultiplexingMTTest, Http2TlsTest)
}
func Http2TcpGetTest(s *H2Suite) {
s.AssertContains(o, " 0 errored")
s.AssertContains(o, " 0 timeout")
}
+
+func Http2TlsTest(s *H2Suite) {
+ vpp := s.Containers.Vpp.VppInstance
+ serverAddress := s.VppAddr()
+ s.Log(vpp.Vppctl("http static server uri tls://" + serverAddress + "/443 url-handlers debug"))
+
+ args := fmt.Sprintf("--max-time 10 --noproxy '*' -k https://%s:443/version.json", serverAddress)
+ writeOut, log := s.RunCurlContainer(s.Containers.Curl, args)
+ s.Log(vpp.Vppctl("show session verbose 2"))
+ s.AssertContains(log, "HTTP/2 200")
+ s.AssertContains(log, "ALPN: server accepted h2")
+ s.AssertContains(writeOut, "version")
+}
}
// Marked as pending since http plugin is not build with http/2 enabled by default
-var _ = Describe("Http2Suite", Pending, Ordered, ContinueOnFailure, func() {
+var _ = Describe("Http2Suite", Ordered, ContinueOnFailure, func() {
var s H2Suite
BeforeAll(func() {
s.SetupSuite()
var http2Tests = []h2specTest{
{desc: "http2/3.5/1"},
- // TODO: need to be tested with TLS, otherwise we consider invalid preface as bogus HTTP/1 request
- // {desc: "http2/3.5/2"},
+ {desc: "http2/3.5/2"},
{desc: "http2/4.1/1"},
{desc: "http2/4.1/2"},
{desc: "http2/4.1/3"},
}
// Marked as pending since http plugin is not build with http/2 enabled by default
-var _ = Describe("H2SpecSuite", Pending, Ordered, ContinueOnFailure, func() {
+var _ = Describe("H2SpecSuite", Ordered, ContinueOnFailure, func() {
var s H2Suite
BeforeAll(func() {
s.SetupSuite()
s.Log(testName + ": BEGIN")
vpp := s.Containers.Vpp.VppInstance
serverAddress := s.VppAddr()
- s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug 2"))
+ s.Log(vpp.Vppctl("http static server uri tls://" + serverAddress + "/443 url-handlers debug 2"))
s.Log(vpp.Vppctl("test-url-handler enable"))
conf := &config.Config{
Host: serverAddress,
- Port: 80,
+ Port: 443,
Path: "/test1",
Timeout: time.Second * 5,
MaxHeaderLen: 1024,
- TLS: false,
+ TLS: true,
Insecure: true,
Sections: []string{test.desc},
Verbose: true,
#include <vpp/app/version.h>
#include <vnet/session/application_interface.h>
#include <vnet/session/application.h>
+#include <vnet/tls/tls_types.h>
#include <http/http.h>
#include <http/http_private.h>
u32 hc_index, thresh;
http_conn_handle_t hc_handle;
transport_proto_t tp;
+ tls_alpn_proto_t alpn_proto;
ts_listener = listen_session_get_from_handle (ts->listener_handle);
lhc = http_listener_get (ts_listener->opaque);
tp = session_get_transport_proto (ts);
if (tp == TRANSPORT_PROTO_TLS)
{
- /* TODO: set by ALPN result */
- hc->version = HTTP_VERSION_1;
+ alpn_proto = tls_get_alpn_selected (ts->connection_index);
+ HTTP_DBG (1, "ALPN selected: %U", format_tls_alpn_proto, alpn_proto);
+ switch (alpn_proto)
+ {
+ case TLS_ALPN_PROTO_HTTP_2:
+ hc->version = HTTP_VERSION_2;
+ http_vfts[hc->version].conn_accept_callback (hc);
+ break;
+ case TLS_ALPN_PROTO_HTTP_1_1:
+ case TLS_ALPN_PROTO_NONE:
+ hc->version = HTTP_VERSION_1;
+ break;
+ default:
+ ASSERT (0);
+ return -1;
+ }
}
else
{
/* going to decide in http_ts_rx_callback */
hc->version = HTTP_VERSION_NA;
}
+
+ HTTP_DBG (1, "identified HTTP/%u", hc->version == HTTP_VERSION_1 ? 1 : 2);
hc_handle.version = hc->version;
hc_handle.conn_index = hc_index;
ts->opaque = hc_handle.as_u32;
http_conn_t *hc, *ho_hc;
app_worker_t *app_wrk;
http_conn_handle_t hc_handle;
+ transport_proto_t tp;
+ tls_alpn_proto_t alpn_proto;
int rv;
ho_hc = http_ho_conn_get (ho_hc_index);
hc->state = HTTP_CONN_STATE_ESTABLISHED;
ts->session_state = SESSION_STATE_READY;
hc->flags |= HTTP_CONN_F_NO_APP_SESSION;
- /* TODO: TLS set by ALPN result, TCP: prior knowledge (set in ho) */
+ tp = session_get_transport_proto (ts);
+ /* TLS set by ALPN result, TCP: prior knowledge (set in ho) */
+ if (tp == TRANSPORT_PROTO_TLS)
+ {
+ alpn_proto = tls_get_alpn_selected (ts->connection_index);
+ HTTP_DBG (1, "ALPN selected: %U", format_tls_alpn_proto, alpn_proto);
+ switch (alpn_proto)
+ {
+ case TLS_ALPN_PROTO_HTTP_2:
+ hc->version = HTTP_VERSION_2;
+ http_vfts[hc->version].conn_accept_callback (hc);
+ break;
+ case TLS_ALPN_PROTO_HTTP_1_1:
+ case TLS_ALPN_PROTO_NONE:
+ hc->version = HTTP_VERSION_1;
+ break;
+ default:
+ ASSERT (0);
+ return -1;
+ }
+ }
+
+ HTTP_DBG (1, "identified HTTP/%u", hc->version == HTTP_VERSION_1 ? 1 : 2);
hc_handle.version = hc->version;
hc_handle.conn_index = new_hc_index;
ts->opaque = hc_handle.as_u32;
if (memcmp (rx_buf, http2_conn_preface.base,
http2_conn_preface.len) == 0)
{
-#if HTTP_2_ENABLE > 0
hc->version = HTTP_VERSION_2;
http_vfts[hc->version].conn_accept_callback (hc);
-#else
- svm_fifo_dequeue_drop_all (ts->rx_fifo);
- http_disconnect_transport (hc);
- return 0;
-#endif
}
else
hc->version = HTTP_VERSION_1;
{
HTTP_DBG (1, "app set tls");
tp = TRANSPORT_PROTO_TLS;
+ if (ext_cfg->crypto.alpn_protos[0] == TLS_ALPN_PROTO_NONE)
+ {
+ HTTP_DBG (1,
+ "app do not set alpn list, using default (h2,http/1.1)");
+ ext_cfg->crypto.alpn_protos[0] = TLS_ALPN_PROTO_HTTP_2;
+ ext_cfg->crypto.alpn_protos[1] = TLS_ALPN_PROTO_HTTP_1_1;
+ }
}
args->sep_ext.transport_proto = tp;