diff --git a/finagle/h2/src/test/scala/io/buoyant/test/h2/StreamTestUtils.scala b/finagle/h2/src/test/scala/io/buoyant/test/h2/StreamTestUtils.scala index de2f4ce062..ac8c6fbd0b 100644 --- a/finagle/h2/src/test/scala/io/buoyant/test/h2/StreamTestUtils.scala +++ b/finagle/h2/src/test/scala/io/buoyant/test/h2/StreamTestUtils.scala @@ -1,7 +1,6 @@ package io.buoyant.test.h2 import com.twitter.finagle.buoyant.h2.{Frame, Stream} -import com.twitter.io.Buf import com.twitter.util.Future object StreamTestUtils { @@ -26,25 +25,6 @@ object StreamTestUtils { } } - def readDataStream(stream: Stream): Future[Buf] = { - stream.read().flatMap { - case frame: Frame.Data if frame.isEnd => - val buf = frame.buf - val _ = frame.release() - Future.value(buf) - case frame: Frame.Data => - val buf = frame.buf - val _ = frame.release() - readDataStream(stream).map(buf.concat) - case frame: Frame.Trailers => - val _ = frame.release() - Future.value(Buf.Empty) - } - } - - def readDataString(stream: Stream): Future[String] = - readDataStream(stream).map(Buf.Utf8.unapply).map(_.get) - /** * Enhances a [[Stream]] by providing the [[readToEnd()]] function in the * method position @@ -53,7 +33,6 @@ object StreamTestUtils { */ implicit class ReadAllStream(val stream: Stream) extends AnyVal { @inline def readToEnd: Future[Unit] = StreamTestUtils.readToEnd(stream) - @inline def readDataString: Future[String] = StreamTestUtils.readDataString(stream) } } diff --git a/linkerd/protocol/h2/src/e2e/scala/io/buoyant/linkerd/protocol/h2/H2EndToEndTest.scala b/linkerd/protocol/h2/src/e2e/scala/io/buoyant/linkerd/protocol/h2/H2EndToEndTest.scala index 9f05a3e518..03f215e07d 100644 --- a/linkerd/protocol/h2/src/e2e/scala/io/buoyant/linkerd/protocol/h2/H2EndToEndTest.scala +++ b/linkerd/protocol/h2/src/e2e/scala/io/buoyant/linkerd/protocol/h2/H2EndToEndTest.scala @@ -1,16 +1,85 @@ package io.buoyant.linkerd.protocol.h2 import com.twitter.concurrent.AsyncQueue +import com.twitter.finagle.buoyant.H2 import com.twitter.finagle.buoyant.h2._ -import com.twitter.finagle.stats.InMemoryStatsReceiver -import com.twitter.finagle.param.Stats +import com.twitter.finagle.stats.{InMemoryStatsReceiver, NullStatsReceiver} +import com.twitter.finagle.tracing.NullTracer +import com.twitter.finagle.{param => fparam, Status => _, _} +import com.twitter.io.Buf +import com.twitter.logging.Level +import com.twitter.util.{Future, Promise, Var} import io.buoyant.linkerd.Linker import io.buoyant.linkerd.protocol.H2Initializer import io.buoyant.test.FunSuite -import io.buoyant.test.h2.StreamTestUtils._ +import java.net.InetSocketAddress +import scala.collection.mutable class H2EndToEndTest extends FunSuite { + case class Downstream(name: String, server: ListeningServer) { + val address = server.boundAddress.asInstanceOf[InetSocketAddress] + val port = address.getPort + val dentry = Dentry( + Path.read(s"/svs/$name"), + NameTree.read(s"/$$/inet/127.1/$port") + ) + } + + object Downstream { + def mk(name: String)(f: Request=>Future[Response]): Downstream = { + val service = Service.mk { req: Request => f(req) } + val server = H2.server + .configured(fparam.Label(name)) + .configured(fparam.Tracer(NullTracer)) + .serve(":*", service) + Downstream(name, server) + } + + def const(name: String, value: String, status: Status = Status.Ok): Downstream = + mk(name) { _ => + Future.value(Response(status, Stream.const(value))) + } + + def promise(name: String): (Downstream, mutable.Seq[Promise[Response]]) = { + val ps = mutable.MutableList[Promise[Response]]() + val svc = mk(name) { _ => + val p = new Promise[Response]() + ps += p + p + } + (svc, ps) + } + } + + def upstream(server: ListeningServer) = { + val address = Address(server.boundAddress.asInstanceOf[InetSocketAddress]) + val name = Name.Bound(Var.value(Addr.Bound(address)), address) + H2.client + .configured(fparam.Stats(NullStatsReceiver)) + .configured(fparam.Tracer(NullTracer)) + .newClient(name, "upstream").toService + } + + def readDataStream(stream: Stream): Future[Buf] = { + stream.read().flatMap { + case frame: Frame.Data if frame.isEnd => + val buf = frame.buf + val _ = frame.release() + Future.value(buf) + case frame: Frame.Data => + val buf = frame.buf + val _ = frame.release() + readDataStream(stream).map(buf.concat) + case frame: Frame.Trailers => + val _ = frame.release() + Future.value(Buf.Empty) + } + } + + def readDataString(stream: Stream): Future[String] = + readDataStream(stream).map(Buf.Utf8.unapply).map(_.get) + test("single request") { val stats = new InMemoryStatsReceiver @@ -28,11 +97,11 @@ class H2EndToEndTest extends FunSuite { |""".stripMargin val linker = Linker.Initializers(Seq(H2Initializer)).load(config) - .configured(Stats(stats)) + .configured(fparam.Stats(stats)) val router = linker.routers.head.initialize() val server = router.servers.head.serve() - val client = Upstream.mk(server) + val client = upstream(server) def get(host: String, path: String = "/")(f: Response => Unit) = { val req = Request("http", Method.Get, host, path, Stream.empty()) val rsp = await(client(req)) @@ -41,7 +110,7 @@ class H2EndToEndTest extends FunSuite { get("dog") { rsp => assert(rsp.status == Status.Ok) - assert(await(rsp.stream.readDataString) == "woof") + assert(await(readDataString(rsp.stream)) == "woof") () } assert(stats.counters(Seq("rt", "h2", "client", s"$$/inet/127.1/${dog.port}", "connects")) == 1) @@ -67,11 +136,11 @@ class H2EndToEndTest extends FunSuite { |""".stripMargin val linker = Linker.Initializers(Seq(H2Initializer)).load(config) - .configured(Stats(stats)) + .configured(fparam.Stats(stats)) val router = linker.routers.head.initialize() val server = router.servers.head.serve() - val client = Upstream.mk(server) + val client = upstream(server) val req0 = Request("http", Method.Get, "dog", "/", Stream.empty()) @@ -90,11 +159,11 @@ class H2EndToEndTest extends FunSuite { rsps(1).setValue(Response(Status.Ok, Stream.const("bow"))) val rsp1 = await(fRsp1) - assert(await(rsp1.stream.readDataString) == "bow") + assert(await(readDataString(rsp1.stream)) == "bow") rsps(0).setValue(Response(Status.Ok, Stream.const("wow"))) val rsp0 = await(fRsp0) - assert(await(rsp0.stream.readDataString) == "wow") + assert(await(readDataString(rsp0.stream)) == "wow") // should multiplex over a single connection assert(stats.counters(Seq("rt", "h2", "client", s"$$/inet/127.1/${dog.port}", "connects")) == 1) @@ -120,11 +189,11 @@ class H2EndToEndTest extends FunSuite { |""".stripMargin val linker = Linker.Initializers(Seq(H2Initializer)).load(config) - .configured(Stats(stats)) + .configured(fparam.Stats(stats)) val router = linker.routers.head.initialize() val server = router.servers.head.serve() - val client = Upstream.mk(server) + val client = upstream(server) val req = Request("http", Method.Get, "dog", "/", Stream.empty()) val fRsp = client(req) @@ -143,7 +212,7 @@ class H2EndToEndTest extends FunSuite { val rsp = await(fRsp) - assert(await(rsp.stream.readDataString) == "bowwow") + assert(await(readDataString(rsp.stream)) == "bowwow") await(client.close()) await(server.close()) diff --git a/linkerd/protocol/h2/src/integration/scala/io/buoyant/linkerd/protocol/h2/ForwardClientCertTest.scala b/linkerd/protocol/h2/src/integration/scala/io/buoyant/linkerd/protocol/h2/ForwardClientCertTest.scala deleted file mode 100644 index 0a3174da33..0000000000 --- a/linkerd/protocol/h2/src/integration/scala/io/buoyant/linkerd/protocol/h2/ForwardClientCertTest.scala +++ /dev/null @@ -1,69 +0,0 @@ -package io.buoyant.linkerd.protocol.h2 - -import com.twitter.finagle.buoyant.h2.{Method, Request, Response, Status, Stream} -import com.twitter.util.Future -import io.buoyant.linkerd.Linker -import io.buoyant.linkerd.tls.TlsUtils.withCerts -import io.buoyant.test.FunSuite -import io.buoyant.test.h2.StreamTestUtils._ -import java.io.FileInputStream -import java.security.MessageDigest -import java.security.cert.CertificateFactory -import javax.xml.bind.DatatypeConverter.printHexBinary - -class ForwardClientCertTest extends FunSuite { - - test("forward client certificate") { - withCerts("upstream", "linkerd") { certs => - var downstreamRequest: Request = null - val dog = Downstream.mk("dogs") { req => - downstreamRequest = req - Future.value(Response(Status.Ok, Stream.const("woof"))) - } - - val linkerConfig = - s""" - |routers: - |- protocol: h2 - | experimental: true - | dtab: | - | /p/dog => /$$/inet/127.1/${dog.port} ; - | /svc/clifford => /p/dog ; - | servers: - | - port: 0 - | tls: - | certPath: ${certs.serviceCerts("linkerd").cert.getPath} - | keyPath: ${certs.serviceCerts("linkerd").key.getPath} - | caCertPath: ${certs.caCert.getPath} - | requireClientAuth: true - | client: - | kind: io.l5d.global - | forwardClientCert: true - |""".stripMargin - val linker = Linker.load(linkerConfig) - val router = linker.routers.head.initialize() - val server = router.servers.head.serve() - - val upstreamServiceCert = certs.serviceCerts("upstream") - val client = Upstream.mkTls(server, "linkerd", certs.caCert, Some(upstreamServiceCert)) - - try { - val rsp = await(client(Request("http", Method.Get, "clifford", "/", Stream.empty()))) - - assert(await(rsp.stream.readDataString) == "woof") - assert(downstreamRequest.headers.get("x-forwarded-client-cert") == { - val cf = CertificateFactory.getInstance("X.509") - val cert = cf.generateCertificate(new FileInputStream(upstreamServiceCert.cert)) - val digest = MessageDigest.getInstance("SHA-256") - Some(s"""Hash=${printHexBinary(digest.digest(cert.getEncoded))};SAN=https://buoyant.io;Subject="C=US,CN=upstream"""") - }) - () - } finally { - await(client.close()) - await(server.close()) - await(router.close()) - await(dog.server.close()) - } - } - } -} diff --git a/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/H2Config.scala b/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/H2Config.scala index c29c53537d..2b72faa975 100644 --- a/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/H2Config.scala +++ b/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/H2Config.scala @@ -7,9 +7,9 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer, JsonNode} import com.twitter.conversions.storage._ import com.twitter.conversions.time._ +import com.twitter.finagle.buoyant.h2.{param => h2Param, _} import com.twitter.finagle.buoyant.h2.param._ import com.twitter.finagle.buoyant.h2.service.H2Classifier -import com.twitter.finagle.buoyant.h2.{param => h2Param, _} import com.twitter.finagle.buoyant.{ParamsMaybeWith, PathMatcher} import com.twitter.finagle.client.StackClient import com.twitter.finagle.filter.DtabStatsFilter @@ -21,7 +21,6 @@ import io.buoyant.config.PolymorphicConfig import io.buoyant.linkerd.protocol.h2.{H2ClassifierConfig, H2RequestAuthorizerConfig} import io.buoyant.router.h2.ClassifiedRetries.{BufferSize, ClassificationTimeout} import io.buoyant.router.h2.{ClassifiedRetryFilter, DupRequest} -import io.buoyant.router.http.ForwardClientCertFilter import io.buoyant.router.{ClassifiedRetries, H2, RoutingFactory} import io.netty.handler.ssl.ApplicationProtocolNames import scala.collection.JavaConverters._ @@ -154,12 +153,10 @@ class H2StaticClient(val configs: Seq[H2PrefixConfig]) extends H2Client with Sta class H2PrefixConfig(prefix: PathMatcher) extends PrefixConfig(prefix) with H2ClientConfig trait H2ClientConfig extends ClientConfig with H2EndpointConfig { - var forwardClientCert: Option[Boolean] = None @JsonIgnore override def params(vars: Map[String, String]): Stack.Params = withEndpointParams(super.params(vars)) - .maybeWith(forwardClientCert.map(ForwardClientCertFilter.Enabled)) } @JsonTypeInfo( @@ -234,7 +231,6 @@ case class RetryBufferSize( class H2ServerConfig extends ServerConfig with H2EndpointConfig { var maxConcurrentStreamsPerConnection: Option[Int] = None - val forwardClientCert: Option[Boolean] = None @JsonIgnore override val alpnProtocols: Option[Seq[String]] = @@ -245,7 +241,6 @@ class H2ServerConfig extends ServerConfig with H2EndpointConfig { override def withEndpointParams(params: Stack.Params): Stack.Params = super.withEndpointParams(params) .maybeWith(maxConcurrentStreamsPerConnection.map(c => Settings.MaxConcurrentStreams(Some(c.toLong)))) - .maybeWith(forwardClientCert.map(ForwardClientCertFilter.Enabled)) @JsonIgnore override def serverParams = withEndpointParams(super.serverParams) diff --git a/linkerd/protocol/h2/src/test/scala/io/buoyant/linkerd/protocol/h2/Downstream.scala b/linkerd/protocol/h2/src/test/scala/io/buoyant/linkerd/protocol/h2/Downstream.scala deleted file mode 100644 index 2c7e0c02b2..0000000000 --- a/linkerd/protocol/h2/src/test/scala/io/buoyant/linkerd/protocol/h2/Downstream.scala +++ /dev/null @@ -1,44 +0,0 @@ -package io.buoyant.linkerd.protocol.h2 - -import com.twitter.finagle.buoyant.H2 -import com.twitter.finagle.buoyant.h2.{Request, Response, Status, Stream} -import com.twitter.finagle.tracing.NullTracer -import com.twitter.finagle.{param => fparam, _} -import com.twitter.util.{Future, Promise} -import java.net.InetSocketAddress -import scala.collection.mutable - -case class Downstream(name: String, server: ListeningServer) { - val address = server.boundAddress.asInstanceOf[InetSocketAddress] - val port = address.getPort - val dentry = Dentry( - Path.read(s"/svs/$name"), - NameTree.read(s"/$$/inet/127.1/$port") - ) -} - -object Downstream { - def mk(name: String)(f: Request=>Future[Response]): Downstream = { - val service = Service.mk { req: Request => f(req) } - val server = H2.server - .configured(fparam.Label(name)) - .configured(fparam.Tracer(NullTracer)) - .serve(":*", service) - Downstream(name, server) - } - - def const(name: String, value: String, status: Status = Status.Ok): Downstream = - mk(name) { _ => - Future.value(Response(status, Stream.const(value))) - } - - def promise(name: String): (Downstream, mutable.Seq[Promise[Response]]) = { - val ps = mutable.MutableList[Promise[Response]]() - val svc = mk(name) { _ => - val p = new Promise[Response]() - ps += p - p - } - (svc, ps) - } -} diff --git a/linkerd/protocol/h2/src/test/scala/io/buoyant/linkerd/protocol/h2/Upstream.scala b/linkerd/protocol/h2/src/test/scala/io/buoyant/linkerd/protocol/h2/Upstream.scala deleted file mode 100644 index 1a93c5f7c1..0000000000 --- a/linkerd/protocol/h2/src/test/scala/io/buoyant/linkerd/protocol/h2/Upstream.scala +++ /dev/null @@ -1,41 +0,0 @@ -package io.buoyant.linkerd.protocol.h2 - -import com.twitter.finagle.buoyant.H2 -import com.twitter.finagle.ssl.KeyCredentials.Unspecified -import com.twitter.finagle.ssl.client.SslClientConfiguration -import com.twitter.finagle.ssl.{KeyCredentials, TrustCredentials} -import com.twitter.finagle.stats.NullStatsReceiver -import com.twitter.finagle.tracing.NullTracer -import com.twitter.finagle.transport.Transport -import com.twitter.finagle.{Addr, Address, ListeningServer, Name, param => fparam} -import com.twitter.util.Var -import io.buoyant.linkerd.tls.TlsUtils.ServiceCert -import java.io.File -import java.net.InetSocketAddress - -object Upstream { - def mk(server: ListeningServer) = { - val address = Address(server.boundAddress.asInstanceOf[InetSocketAddress]) - val name = Name.Bound(Var.value(Addr.Bound(address)), address) - H2.client - .configured(fparam.Stats(NullStatsReceiver)) - .configured(fparam.Tracer(NullTracer)) - .newClient(name, "upstream").toService - } - - def mkTls(server: ListeningServer, tlsName: String, caCert: File, certAndKey: Option[ServiceCert] = None) = { - val address = Address(server.boundAddress.asInstanceOf[InetSocketAddress]) - val name = Name.Bound(Var.value(Addr.Bound(address)), address) - H2.client - .configured(fparam.Stats(NullStatsReceiver)) - .configured(fparam.Tracer(NullTracer)) - .configured( - Transport.ClientSsl(Some(SslClientConfiguration( - hostname = Some(tlsName), - keyCredentials = certAndKey.map(c => KeyCredentials.CertAndKey(c.cert, c.key)).getOrElse(Unspecified), - trustCredentials = TrustCredentials.CertCollection(caCert) - ))) - ) - .newClient(name, "upstream").toService - } -} diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/ClientAuthTest.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/ClientAuthTest.scala index 1834ca8959..556cb746bc 100644 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/ClientAuthTest.scala +++ b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/ClientAuthTest.scala @@ -2,7 +2,7 @@ package io.buoyant.linkerd.protocol import com.twitter.finagle.http.{Request, Status} import io.buoyant.linkerd.Linker -import io.buoyant.linkerd.tls.TlsUtils +import io.buoyant.linkerd.protocol.TlsUtils.Downstream import io.buoyant.test.FunSuite import java.net.InetSocketAddress @@ -54,7 +54,7 @@ class ClientAuthTest extends FunSuite { val clientRouter = clientLinker.routers.head.initialize() val clientServer = clientRouter.servers.head.serve() - val upstream = Upstream.mk(clientServer) + val upstream = TlsUtils.upstream(clientServer) try { val req = Request() @@ -116,7 +116,7 @@ class ClientAuthTest extends FunSuite { val clientRouter = clientLinker.routers.head.initialize() val clientServer = clientRouter.servers.head.serve() - val upstream = Upstream.mk(clientServer) + val upstream = TlsUtils.upstream(clientServer) try { val req = Request() diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/Downstream.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/Downstream.scala deleted file mode 100644 index b2448ea1b6..0000000000 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/Downstream.scala +++ /dev/null @@ -1,65 +0,0 @@ -package io.buoyant.linkerd.protocol - -import com.twitter.finagle.http.{Request, Response} -import com.twitter.finagle.ssl.KeyCredentials -import com.twitter.finagle.ssl.server.SslServerConfiguration -import com.twitter.finagle.tracing.NullTracer -import com.twitter.finagle.transport.Transport -import com.twitter.finagle.{Http => FinagleHttp, _} -import com.twitter.util.Future -import java.io.File -import java.net.InetSocketAddress - -case class Downstream(name: String, server: ListeningServer) { - val address = server.boundAddress.asInstanceOf[InetSocketAddress] - val port = address.getPort - val dentry = Dentry( - Path.read(s"/svc/$name"), - NameTree.read(s"/$$/inet/127.1/$port") - ) -} - -object Downstream { - def mk(name: String)(f: Request => Response): Downstream = { - val service = Service.mk { req: Request => Future(f(req)) } - val server = FinagleHttp.server - .configured(param.Label(name)) - .configured(param.Tracer(NullTracer)) - .serve(":*", service) - Downstream(name, server) - } - - def mkTls(name: String, cert: File, key: File) - (f: Request => Response): Downstream = { - val service = Service.mk { req: Request => Future(f(req)) } - val server = FinagleHttp.server - .configured(param.Label(name)) - .configured(param.Tracer(NullTracer)) - .configured( - Transport.ServerSsl(Some(SslServerConfiguration( - keyCredentials = KeyCredentials.CertAndKey(cert, key) - ))) - ) - .serve(":*", service) - Downstream(name, server) - } - - def const(name: String, value: String): Downstream = - mk(name) { _ => - val rsp = Response() - rsp.contentString = value - rsp - } - - def constTls( - name: String, - value: String, - cert: File, - key: File - ): Downstream = - mkTls(name, cert, key) { _ => - val rsp = Response() - rsp.contentString = value - rsp - } -} diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/ForwardClientCertTest.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/ForwardClientCertTest.scala deleted file mode 100644 index fb81a69d33..0000000000 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/ForwardClientCertTest.scala +++ /dev/null @@ -1,72 +0,0 @@ -package io.buoyant.linkerd.protocol - -import com.twitter.finagle.http.{Request, Response} -import io.buoyant.linkerd.Linker -import io.buoyant.linkerd.tls.TlsUtils.withCerts -import io.buoyant.test.FunSuite -import java.io.FileInputStream -import java.security.MessageDigest -import java.security.cert.CertificateFactory -import javax.xml.bind.DatatypeConverter.printHexBinary - -class ForwardClientCertTest extends FunSuite { - - test("forward client certificate") { - withCerts("upstream", "linkerd") { certs => - var downstreamRequest: Request = null - val dog = Downstream.mk("dogs") { req => - downstreamRequest = req - val rsp = Response() - rsp.contentString = "woof" - rsp - } - - val linkerConfig = - s""" - |routers: - |- protocol: http - | dtab: | - | /p/dog => /$$/inet/127.1/${dog.port} ; - | /svc/clifford => /p/dog ; - | servers: - | - port: 0 - | tls: - | certPath: ${certs.serviceCerts("linkerd").cert.getPath} - | keyPath: ${certs.serviceCerts("linkerd").key.getPath} - | caCertPath: ${certs.caCert.getPath} - | requireClientAuth: true - | client: - | kind: io.l5d.global - | forwardClientCert: true - |""".stripMargin - val linker = Linker.load(linkerConfig) - val router = linker.routers.head.initialize() - val server = router.servers.head.serve() - - val upstreamServiceCert = certs.serviceCerts("upstream") - val client = Upstream.mkTls(server, "linkerd", certs.caCert, Some(upstreamServiceCert)) - - try { - val rsp = { - val req = Request() - req.host = "clifford" - await(client(req)) - } - - assert(rsp.contentString == "woof") - assert(downstreamRequest.headerMap("x-forwarded-client-cert") == { - val cf = CertificateFactory.getInstance("X.509") - val cert = cf.generateCertificate(new FileInputStream(upstreamServiceCert.cert)) - val digest = MessageDigest.getInstance("SHA-256") - s"""Hash=${printHexBinary(digest.digest(cert.getEncoded))};SAN=https://buoyant.io;Subject="C=US,CN=upstream"""" - }) - () - } finally { - await(client.close()) - await(server.close()) - await(router.close()) - await(dog.server.close()) - } - } - } -} diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsBoundPathTest.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsBoundPathTest.scala index c275d4f210..89ec1ef874 100644 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsBoundPathTest.scala +++ b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsBoundPathTest.scala @@ -4,7 +4,7 @@ package protocol import com.twitter.conversions.time._ import com.twitter.finagle.http.{Status, Request, Response} import com.twitter.finagle.{Failure, Service} -import io.buoyant.linkerd.tls.TlsUtils._ +import io.buoyant.linkerd.protocol.TlsUtils._ import io.buoyant.namer.fs.FsInitializer import io.buoyant.test.Awaits import java.io.File @@ -303,7 +303,7 @@ class TlsBoundPathTest extends FunSuite with Awaits { try { val server = router.servers.head.serve() try { - val client = Upstream.mk(server) + val client = upstream(server) try { f(client) } finally await(client.close()) diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsCertReloadingTest.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsCertReloadingTest.scala index 95801b9210..a7c01de5df 100644 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsCertReloadingTest.scala +++ b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsCertReloadingTest.scala @@ -2,7 +2,6 @@ package io.buoyant.linkerd.protocol import com.twitter.finagle.http.{Request, Status} import io.buoyant.linkerd.Linker -import io.buoyant.linkerd.tls.TlsUtils import io.buoyant.test.{Awaits, FunSuite} import java.net.InetSocketAddress @@ -10,7 +9,7 @@ class TlsCertReloadingTest extends FunSuite with Awaits { test("cert reloading") { TlsUtils.withCerts("foo", "bar") { certs => - val downstream = Downstream.const("foo", "foo") + val downstream = TlsUtils.Downstream.const("foo", "foo") val fooCerts = certs.serviceCerts("foo") val barCerts = certs.serviceCerts("bar") @@ -53,7 +52,7 @@ class TlsCertReloadingTest extends FunSuite with Awaits { val outgoingRouter = outgoingLinker.routers.head.initialize() val outgoingServer = outgoingRouter.servers.head.serve() - val upstream = Upstream.mk(outgoingServer) + val upstream = TlsUtils.upstream(outgoingServer) try { // build request diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsNoValidationTest.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsNoValidationTest.scala index 22f95cb1b4..9a497c6f1d 100644 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsNoValidationTest.scala +++ b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsNoValidationTest.scala @@ -3,7 +3,7 @@ package protocol import com.twitter.conversions.time._ import com.twitter.finagle.http.Request -import io.buoyant.linkerd.tls.TlsUtils._ +import io.buoyant.linkerd.protocol.TlsUtils._ import io.buoyant.test.Awaits import org.scalatest.FunSuite @@ -35,7 +35,7 @@ class TlsNoValidationTest extends FunSuite with Awaits { try { val server = router.servers.head.serve() try { - val client = Upstream.mk(server) + val client = upstream(server) try { val rsp = { val req = Request() diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsStaticValidationTest.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsStaticValidationTest.scala index ff0ee49c9d..f570696509 100644 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsStaticValidationTest.scala +++ b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsStaticValidationTest.scala @@ -4,7 +4,7 @@ package protocol import com.twitter.conversions.time._ import com.twitter.finagle.Failure import com.twitter.finagle.http.{Status, Request} -import io.buoyant.linkerd.tls.TlsUtils._ +import io.buoyant.linkerd.protocol.TlsUtils._ import io.buoyant.test.Awaits import org.scalatest.FunSuite @@ -39,7 +39,7 @@ class TlsStaticValidationTest extends FunSuite with Awaits { try { val server = router.servers.head.serve() try { - val client = Upstream.mk(server) + val client = upstream(server) try { val rsp = { val req = Request() @@ -86,7 +86,7 @@ class TlsStaticValidationTest extends FunSuite with Awaits { try { val server = router.servers.head.serve() try { - val client = Upstream.mk(server) + val client = upstream(server) try { val rsp = { val req = Request() diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsTerminationTest.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsTerminationTest.scala index 0df200e1eb..7c551dc972 100644 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsTerminationTest.scala +++ b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsTerminationTest.scala @@ -3,13 +3,13 @@ package protocol import com.twitter.conversions.time._ import com.twitter.finagle.http.Request -import io.buoyant.linkerd.tls.TlsUtils._ +import io.buoyant.linkerd.protocol.TlsUtils._ import io.buoyant.test.Awaits import org.scalatest.FunSuite class TlsTerminationTest extends FunSuite with Awaits { - test("tls server + plain backend") { + test("netty3 tls server + plain backend") { withCerts("linkerd") { certs => val dog = Downstream.const("dogs", "woof") try { @@ -32,7 +32,46 @@ class TlsTerminationTest extends FunSuite with Awaits { try { val server = router.servers.head.serve() try { - val client = Upstream.mkTls(server, "linkerd", certs.caCert) + val client = upstreamTls(server, "linkerd", certs.caCert) + try { + val rsp = { + val req = Request() + req.host = "clifford" + await(client(req)) + } + assert(rsp.contentString == "woof") + () + } finally await(client.close()) + } finally await(server.close()) + } finally await(router.close()) + } finally await(dog.server.close()) + } + } + + test("netty4 tls server + plain backend") { + withCerts("linkerd") { certs => + val dog = Downstream.const("dogs", "woof") + try { + val linkerConfig = + s""" + |routers: + |- protocol: http + | dtab: | + | /p/dog => /$$/inet/127.1/${dog.port} ; + | /svc/clifford => /p/dog ; + | servers: + | - port: 0 + | tls: + | certPath: ${certs.serviceCerts("linkerd").cert.getPath} + | keyPath: ${certs.serviceCerts("linkerd").key.getPath} + |""".stripMargin + val linker = Linker.Initializers(Seq(HttpInitializer)).load(linkerConfig) + + val router = linker.routers.head.initialize() + try { + val server = router.servers.head.serve() + try { + val client = upstreamTls(server, "linkerd", certs.caCert) try { val rsp = { val req = Request() diff --git a/linkerd/tls/src/main/scala/io/buoyant/linkerd/tls/TlsUtils.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsUtils.scala similarity index 54% rename from linkerd/tls/src/main/scala/io/buoyant/linkerd/tls/TlsUtils.scala rename to linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsUtils.scala index 480d81c4b5..2fe7b42691 100644 --- a/linkerd/tls/src/main/scala/io/buoyant/linkerd/tls/TlsUtils.scala +++ b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/TlsUtils.scala @@ -1,6 +1,18 @@ -package io.buoyant.linkerd.tls - -import java.io.File +package io.buoyant.linkerd.protocol + +import com.twitter.finagle.http.{Request, Response, TlsFilter} +import com.twitter.finagle.{Http => FinagleHttp, _} +import com.twitter.finagle.ssl.server.SslServerConfiguration +import com.twitter.finagle.ssl.KeyCredentials +import com.twitter.finagle.stats.NullStatsReceiver +import com.twitter.finagle.tracing.NullTracer +import com.twitter.finagle.transport.Transport +import com.twitter.util.{Future, Var} +import java.io.{File, FileInputStream} +import java.net.{InetSocketAddress} +import java.security.KeyStore +import java.security.cert.CertificateFactory +import javax.net.ssl.{SSLContext, TrustManagerFactory} import scala.sys.process._ object TlsUtils { @@ -55,6 +67,95 @@ object TlsUtils { def assertOk(cmd: ProcessBuilder): Unit = assert(run(cmd) == 0, s"`$cmd` failed") + def upstreamTls(server: ListeningServer, tlsName: String, caCert: File) = { + val address = Address(server.boundAddress.asInstanceOf[InetSocketAddress]) + + // Establish an SSL context that uses our generated certificate. + // Cribbed from http://stackoverflow.com/questions/18513792 + val cf = CertificateFactory.getInstance("X.509"); + val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm) + val ks = KeyStore.getInstance(KeyStore.getDefaultType()) + ks.load(null) + ks.setCertificateEntry("caCert", cf.generateCertificate(new FileInputStream(caCert))) + tmf.init(ks) + val ctx = SSLContext.getInstance("TLS") + ctx.init(null, tmf.getTrustManagers(), null) + + val name = Name.Bound(Var.value(Addr.Bound(address)), address) + FinagleHttp.client + .configured(param.Stats(NullStatsReceiver)) + .configured(param.Tracer(NullTracer)) + .withTransport.tls(ctx, tlsName) + .transformed(_.remove(TlsFilter.role)) // do NOT rewrite Host headers using tlsName + .newClient(name, "upstream").toService + } + + def upstream(server: ListeningServer) = { + val address = Address(server.boundAddress.asInstanceOf[InetSocketAddress]) + + val name = Name.Bound(Var.value(Addr.Bound(address)), address) + FinagleHttp.client + .configured(param.Stats(NullStatsReceiver)) + .configured(param.Tracer(NullTracer)) + .transformed(_.remove(TlsFilter.role)) // do NOT rewrite Host headers using tlsName + .newClient(name, "upstream").toService + } + + case class Downstream(name: String, server: ListeningServer) { + val address = server.boundAddress.asInstanceOf[InetSocketAddress] + val port = address.getPort + val dentry = Dentry( + Path.read(s"/svc/$name"), + NameTree.read(s"/$$/inet/127.1/$port") + ) + } + + object Downstream { + def mk(name: String)(f: Request => Response): Downstream = { + val service = Service.mk { req: Request => Future(f(req)) } + val server = FinagleHttp.server + .configured(param.Label(name)) + .configured(param.Tracer(NullTracer)) + .serve(":*", service) + Downstream(name, server) + } + + def mkTls(name: String, cert: File, key: File) + (f: Request => Response): Downstream = { + val service = Service.mk { req: Request => Future(f(req)) } + val server = FinagleHttp.server + .configured(param.Label(name)) + .configured(param.Tracer(NullTracer)) + .configured( + Transport.ServerSsl(Some(SslServerConfiguration( + keyCredentials = KeyCredentials.CertAndKey(cert, key) + ))) + ) + .serve(":*", service) + Downstream(name, server) + } + + def const(name: String, value: String): Downstream = + mk(name) { _ => + val rsp = Response() + rsp.contentString = value + rsp + } + + def constTls( + name: String, + value: String, + cert: File, + key: File + ): Downstream = + mkTls(name, cert, key) { _ => + val rsp = Response() + rsp.contentString = value + rsp + } + } + + val DevNull = ProcessLogger(_ => ()) def mkCaDirs(dir: File): File = { @@ -92,7 +193,6 @@ object TlsUtils { |nameopt = default_ca |certopt = default_ca |policy = policy_match - |x509_extensions = x509_extensions | |[ policy_match ] |commonName = supplied @@ -120,12 +220,6 @@ object TlsUtils { |[ v3_req ] |basicConstraints = CA:FALSE |subjectKeyIdentifier = hash - | - |[ x509_extensions ] - |subjectAltName = @alt_names - | - |[alt_names] - |URI.1 = https://buoyant.io |""".stripMargin def newKeyAndCert(subj: String, cfg: File, key: File, cert: File): ProcessBuilder = diff --git a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/Upstream.scala b/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/Upstream.scala deleted file mode 100644 index c4e6b73151..0000000000 --- a/linkerd/protocol/http/src/integration/scala/io/buoyant/linkerd/protocol/Upstream.scala +++ /dev/null @@ -1,44 +0,0 @@ -package io.buoyant.linkerd.protocol - -import com.twitter.finagle.http.TlsFilter -import com.twitter.finagle.ssl.KeyCredentials.Unspecified -import com.twitter.finagle.ssl.client.SslClientConfiguration -import com.twitter.finagle.ssl.{KeyCredentials, TrustCredentials} -import com.twitter.finagle.stats.NullStatsReceiver -import com.twitter.finagle.tracing.NullTracer -import com.twitter.finagle.transport.Transport -import com.twitter.finagle.{Http => FinagleHttp, _} -import com.twitter.util.Var -import io.buoyant.linkerd.tls.TlsUtils.ServiceCert -import java.io.File -import java.net.InetSocketAddress - -object Upstream { - def mkTls(server: ListeningServer, tlsName: String, caCert: File, certAndKey: Option[ServiceCert] = None) = { - val address = Address(server.boundAddress.asInstanceOf[InetSocketAddress]) - val name = Name.Bound(Var.value(Addr.Bound(address)), address) - FinagleHttp.client - .configured(param.Stats(NullStatsReceiver)) - .configured(param.Tracer(NullTracer)) - .configured( - Transport.ClientSsl(Some(SslClientConfiguration( - hostname = Some(tlsName), - keyCredentials = certAndKey.map(c => KeyCredentials.CertAndKey(c.cert, c.key)).getOrElse(Unspecified), - trustCredentials = TrustCredentials.CertCollection(caCert) - ))) - ) - .transformed(_.remove(TlsFilter.role)) // do NOT rewrite Host headers using tlsName - .newClient(name, "upstream").toService - } - - def mk(server: ListeningServer) = { - val address = Address(server.boundAddress.asInstanceOf[InetSocketAddress]) - - val name = Name.Bound(Var.value(Addr.Bound(address)), address) - FinagleHttp.client - .configured(param.Stats(NullStatsReceiver)) - .configured(param.Tracer(NullTracer)) - .transformed(_.remove(TlsFilter.role)) // do NOT rewrite Host headers using tlsName - .newClient(name, "upstream").toService - } -} diff --git a/linkerd/protocol/http/src/main/scala/io/buoyant/linkerd/protocol/HttpConfig.scala b/linkerd/protocol/http/src/main/scala/io/buoyant/linkerd/protocol/HttpConfig.scala index a356c83b56..31b7a875df 100644 --- a/linkerd/protocol/http/src/main/scala/io/buoyant/linkerd/protocol/HttpConfig.scala +++ b/linkerd/protocol/http/src/main/scala/io/buoyant/linkerd/protocol/HttpConfig.scala @@ -20,7 +20,7 @@ import com.twitter.util.Future import io.buoyant.linkerd.protocol.http._ import io.buoyant.router.{ClassifiedRetries, Http, RoutingFactory} import io.buoyant.router.RoutingFactory.{IdentifiedRequest, RequestIdentification, UnidentifiedRequest} -import io.buoyant.router.http.{AddForwardedHeader, ForwardClientCertFilter, TimestampHeaderFilter} +import io.buoyant.router.http.{AddForwardedHeader, TimestampHeaderFilter} import scala.collection.JavaConverters._ class HttpInitializer extends ProtocolInitializer.Simple { @@ -113,15 +113,7 @@ class HttpStaticClient(val configs: Seq[HttpPrefixConfig]) extends HttpClient wi class HttpPrefixConfig(prefix: PathMatcher) extends PrefixConfig(prefix) with HttpClientConfig -trait HttpClientConfig extends ClientConfig { - var forwardClientCert: Option[Boolean] = None - - @JsonIgnore - override def params(vars: Map[String, String]): Stack.Params = { - super.params(vars) - .maybeWith(forwardClientCert.map(ForwardClientCertFilter.Enabled)) - } -} +trait HttpClientConfig extends ClientConfig @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, diff --git a/project/LinkerdBuild.scala b/project/LinkerdBuild.scala index 1d804149eb..9c455c49cc 100644 --- a/project/LinkerdBuild.scala +++ b/project/LinkerdBuild.scala @@ -62,16 +62,13 @@ object LinkerdBuild extends Base { .withE2e() .settings(coverageExcludedPackages := ".*XXX_.*") - val baseHttp = projectDir("router/base-http") - .dependsOn(core) - val h2 = projectDir("router/h2") - .dependsOn(baseHttp, Finagle.h2 % "compile->compile;test->test") + .dependsOn(core, Finagle.h2 % "compile->compile;test->test") .withTests() .withE2e() val http = projectDir("router/http") - .dependsOn(baseHttp) + .dependsOn(core) .withTwitterLibs(Deps.finagle("http")) .withLib(Deps.boringssl) .withTests() @@ -105,7 +102,7 @@ object LinkerdBuild extends Base { thriftIdl % "test,e2e" ) - val all = aggregateDir("router", core, baseHttp, h2, http, mux, thrift, thriftMux) + val all = aggregateDir("router", core, h2, http, mux, thrift, thriftMux) } object Mesh { @@ -487,6 +484,8 @@ object LinkerdBuild extends Base { .configWithLibs(Test)(Deps.jacksonDatabind, Deps.jacksonYaml) val tls = projectDir("linkerd/tls") + .dependsOn(core) + .withTests() val failureAccrual = projectDir("linkerd/failure-accrual") .dependsOn(core) @@ -495,8 +494,8 @@ object LinkerdBuild extends Base { object Protocol { val h2 = projectDir("linkerd/protocol/h2") - .dependsOn(core, Router.h2, istio, Finagle.h2 % "test->test;e2e->test", tls % Test) - .withTests().withE2e().withIntegration() + .dependsOn(core, Router.h2, istio, Finagle.h2 % "test->test;e2e->test") + .withTests().withE2e() .withGrpc .withTwitterLibs(Deps.finagle("netty4")) @@ -661,7 +660,6 @@ object LinkerdBuild extends Base { val router = Router.all val routerCore = Router.core - val routerBaseHttp = Router.baseHttp val routerH2 = Router.h2 val routerHttp = Router.http val routerMux = Router.mux diff --git a/router/base-http/src/main/scala/io/buoyant/router/http/ForwardClientCertFilter.scala b/router/base-http/src/main/scala/io/buoyant/router/http/ForwardClientCertFilter.scala deleted file mode 100644 index 998f51d2b6..0000000000 --- a/router/base-http/src/main/scala/io/buoyant/router/http/ForwardClientCertFilter.scala +++ /dev/null @@ -1,68 +0,0 @@ -package io.buoyant.router.http - -import com.twitter.finagle._ -import com.twitter.finagle.transport.Transport -import com.twitter.util.Future -import java.security.MessageDigest -import java.security.cert.X509Certificate -import javax.xml.bind.DatatypeConverter.printHexBinary -import scala.collection.mutable - -class ForwardClientCertFilter[Req, H: HeadersLike, Rep](implicit requestLike: RequestLike[Req, H]) extends SimpleFilter[Req, Rep] { - - val GeneralNameTypeUri = 6 - - val digest: MessageDigest = MessageDigest.getInstance("SHA-256") - - def apply(req: Req, svc: Service[Req, Rep]): Future[Rep] = { - Transport.peerCertificate.foreach(clientCert => { - val clientCertHeader = new mutable.StringBuilder(128) - - clientCertHeader ++= s"Hash=${printHexBinary(digest.digest(clientCert.getEncoded))}" - - clientCert match { - case x509ClientCert: X509Certificate => - val altNames = x509ClientCert.getSubjectAlternativeNames - if (altNames != null && altNames.size > 0) { - val altName = altNames.iterator.next - val nameType = altName.get(0) - val nameValue = altName.get(1) - if (nameType == GeneralNameTypeUri) { - clientCertHeader ++= s";SAN=$nameValue" - } - } - - val subject = x509ClientCert.getSubjectX500Principal.getName - if (subject.nonEmpty) { - clientCertHeader ++= s""";Subject="$subject"""" - } - case _ => - } - - val headersLike = implicitly[HeadersLike[H]] - headersLike.set(requestLike.headers(req), "x-forwarded-client-cert", clientCertHeader.result) - }) - svc(req) - } -} - -object ForwardClientCertFilter { - - case class Enabled(enabled: Boolean) - implicit object Param extends Stack.Param[Enabled] { - val default = Enabled(false) - } - - val role = Stack.Role("ForwardClientCertFilter") - - def module[Req, H: HeadersLike, Rep](implicit requestLike: RequestLike[Req, H]): Stackable[ServiceFactory[Req, Rep]] = - new Stack.Module1[Enabled, ServiceFactory[Req, Rep]] { - val role = ForwardClientCertFilter.role - val description = "Adds a 'x-forwarded-client-cert' header to requests as they are received" - def make(_param: Enabled, next: ServiceFactory[Req, Rep]) = { - if (_param.enabled) new ForwardClientCertFilter().andThen(next) - else next - } - } -} - diff --git a/router/base-http/src/main/scala/io/buoyant/router/http/HeadersLike.scala b/router/base-http/src/main/scala/io/buoyant/router/http/HeadersLike.scala deleted file mode 100644 index 902ab9df01..0000000000 --- a/router/base-http/src/main/scala/io/buoyant/router/http/HeadersLike.scala +++ /dev/null @@ -1,15 +0,0 @@ -package io.buoyant.router.http - -/** - * Type class for HTTP headers object - * @tparam H Headers object type - */ -trait HeadersLike[H] { - def toSeq(headers: H): Seq[(String, String)] - def contains(headers: H, k: String): Boolean - def get(headers: H, k: String): Option[String] - def getAll(headers: H, k: String): Seq[String] - def add(headers: H, k: String, v: String): Unit - def set(headers: H, k: String, v: String): Unit - def remove(headers: H, key: String): Seq[String] -} diff --git a/router/base-http/src/main/scala/io/buoyant/router/http/RequestLike.scala b/router/base-http/src/main/scala/io/buoyant/router/http/RequestLike.scala deleted file mode 100644 index 2fa6f98a2e..0000000000 --- a/router/base-http/src/main/scala/io/buoyant/router/http/RequestLike.scala +++ /dev/null @@ -1,10 +0,0 @@ -package io.buoyant.router.http - -/** - * Type class for HTTP 1.1/2 requests - * @tparam R Request type - * @tparam H Headers object type - */ -abstract class RequestLike[R, H: HeadersLike] { - def headers(request: R): H -} diff --git a/router/h2/src/main/scala/io/buoyant/router/H2.scala b/router/h2/src/main/scala/io/buoyant/router/H2.scala index 1aba3b0b29..95c8c81c3a 100644 --- a/router/h2/src/main/scala/io/buoyant/router/H2.scala +++ b/router/h2/src/main/scala/io/buoyant/router/H2.scala @@ -1,6 +1,6 @@ package io.buoyant.router -import com.twitter.finagle.buoyant.h2.{H2FailureAccrualFactory, Headers, Request, Response, param => h2param} +import com.twitter.finagle.buoyant.h2.{H2FailureAccrualFactory, Request, Response, param => h2param} import com.twitter.finagle.buoyant.{H2 => FinagleH2} import com.twitter.finagle.client.StackClient import com.twitter.finagle.{param, _} @@ -12,8 +12,6 @@ import com.twitter.finagle.service.StatsFilter import io.buoyant.router.context.ResponseClassifierCtx import io.buoyant.router.context.h2.H2ClassifierCtx import io.buoyant.router.h2.{ClassifiedRetries => H2ClassifiedRetries, _} -import io.buoyant.router.http.ForwardClientCertFilter -import io.buoyant.router.H2Instances._ object H2 extends Router[Request, Response] with Client[Request, Response] @@ -47,7 +45,7 @@ object H2 extends Router[Request, Response] val clientStack: Stack[ServiceFactory[Request, Response]] = { val stk = FinagleH2.Client.newStack - (ForwardClientCertFilter.module[Request, Headers, Response] +: StackRouter.Client.mkStack(stk)) + StackRouter.Client.mkStack(stk) .replace(PerDstPathStatsFilter.role, PerDstPathStreamStatsFilter.module) .replace(LocalClassifierStatsFilter.role, LocalClassifierStreamStatsFilter.module) .replace(FailureAccrualFactory.role, H2FailureAccrualFactory.module) diff --git a/router/h2/src/main/scala/io/buoyant/router/H2Instances.scala b/router/h2/src/main/scala/io/buoyant/router/H2Instances.scala deleted file mode 100644 index 520e7da708..0000000000 --- a/router/h2/src/main/scala/io/buoyant/router/H2Instances.scala +++ /dev/null @@ -1,27 +0,0 @@ -package io.buoyant.router - -import com.twitter.finagle.buoyant.h2.{Headers, Request} -import io.buoyant.router.http.{HeadersLike, RequestLike} - -object H2Instances { - - implicit object H2HeadersLike extends HeadersLike[Headers] { - override def toSeq(headers: Headers): Seq[(String, String)] = headers.toSeq - - override def contains(headers: Headers, k: String): Boolean = headers.contains(k) - - override def get(headers: Headers, k: String): Option[String] = headers.get(k) - - override def getAll(headers: Headers, k: String): Seq[String] = headers.getAll(k) - - override def add(headers: Headers, k: String, v: String): Unit = headers.add(k, v) - - override def set(headers: Headers, k: String, v: String): Unit = headers.set(k, v) - - override def remove(headers: Headers, key: String): Seq[String] = headers.remove(key) - } - - implicit object H2RequestLike extends RequestLike[Request, Headers] { - override def headers(request: Request): Headers = request.headers - } -} diff --git a/router/http/src/main/scala/io/buoyant/router/Http.scala b/router/http/src/main/scala/io/buoyant/router/Http.scala index f78a9dc34d..9c4ee34aa1 100644 --- a/router/http/src/main/scala/io/buoyant/router/Http.scala +++ b/router/http/src/main/scala/io/buoyant/router/Http.scala @@ -1,7 +1,7 @@ package io.buoyant.router import com.twitter.finagle.client.StackClient -import com.twitter.finagle.http.{HeaderMap, Request, Response, TlsFilter} +import com.twitter.finagle.http.{Request, Response, TlsFilter} import com.twitter.finagle.http.service.HttpResponseClassifier import com.twitter.finagle.param.{ProtocolLibrary, ResponseClassifier} import com.twitter.finagle.server.StackServer @@ -9,7 +9,6 @@ import com.twitter.finagle.{Http => FinagleHttp, Server => FinagleServer, http = import io.buoyant.router.ClassifiedRetries.ResponseDiscarder import io.buoyant.router.Http.param.HttpIdentifier import io.buoyant.router.http._ -import io.buoyant.router.HttpInstances._ import java.net.SocketAddress object Http extends Router[Request, Response] with FinagleServer[Request, Response] { @@ -38,7 +37,6 @@ object Http extends Router[Request, Response] with FinagleServer[Request, Respon .transformed(StackRouter.Client.mkStack(_)) .transformed(_.replace(TracingFilter.role, TracingFilter.module)) .transformed(_.remove(TlsFilter.role)) - .transformed(ForwardClientCertFilter.module[Request, HeaderMap, Response] +: _) val responseDiscarder = ResponseDiscarder[Response] { rsp => if (rsp.isChunked) { diff --git a/router/http/src/main/scala/io/buoyant/router/HttpInstances.scala b/router/http/src/main/scala/io/buoyant/router/HttpInstances.scala deleted file mode 100644 index 99f705b1c6..0000000000 --- a/router/http/src/main/scala/io/buoyant/router/HttpInstances.scala +++ /dev/null @@ -1,37 +0,0 @@ -package io.buoyant.router - -import com.twitter.finagle.http.{HeaderMap, Request} -import io.buoyant.router.http.{HeadersLike, RequestLike} - -object HttpInstances { - - implicit object HttpHeadersLike extends HeadersLike[HeaderMap] { - override def toSeq(headers: HeaderMap): Seq[(String, String)] = headers.toSeq - - override def contains(headers: HeaderMap, k: String): Boolean = headers.contains(k) - - override def get(headers: HeaderMap, k: String): Option[String] = headers.get(k) - - override def getAll(headers: HeaderMap, k: String): Seq[String] = headers.getAll(k) - - override def add(headers: HeaderMap, k: String, v: String): Unit = { - headers.add(k, v) - () - } - - override def set(headers: HeaderMap, k: String, v: String): Unit = { - headers.set(k, v) - () - } - - override def remove(headers: HeaderMap, key: String): Seq[String] = { - val r = getAll(headers, key) - headers -= key - r - } - } - - implicit object HttpRequestLike extends RequestLike[Request, HeaderMap] { - override def headers(request: Request): HeaderMap = request.headerMap - } -}