Skip to content

Commit

Permalink
Allow setting Server header in Netty config (#3615)
Browse files Browse the repository at this point in the history
  • Loading branch information
kciesielski committed Mar 16, 2024
1 parent ba35f6b commit 7db23f9
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 13 deletions.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,7 @@ lazy val jdkhttpServer: ProjectMatrix = (projectMatrix in file("server/jdkhttp-s

lazy val nettyServer: ProjectMatrix = (projectMatrix in file("server/netty-server"))
.settings(commonJvmSettings)
.enablePlugins(BuildInfoPlugin)
.settings(
name := "tapir-netty-server",
libraryDependencies ++= Seq(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ case class NettyCatsServer[F[_]: Async](routes: Vector[Route[F]], options: Netty
val channelFuture =
NettyBootstrap(
config,
new NettyServerHandler(route, unsafeRunAsync, channelGroup, isShuttingDown),
new NettyServerHandler(route, unsafeRunAsync, channelGroup, isShuttingDown, config.serverHeader),
eventLoopGroup,
socketOverride
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ case class NettyIdServer(routes: Vector[IdRoute], options: NettyIdServerOptions,
route,
unsafeRunF,
channelGroup,
isShuttingDown
isShuttingDown,
config.serverHeader
),
eventLoopGroup,
socketOverride
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ import scala.concurrent.duration._
* @param gracefulShutdownTimeout
* If set, attempts to wait for a given time for all in-flight requests to complete, before proceeding with shutting down the server. If
* `None`, closes the channels and terminates the server without waiting.
*
* @param serverHeader
* If set, send this value in the 'Server' response header. If None, don't set the header.
*/
case class NettyConfig(
host: String,
Expand All @@ -59,7 +62,8 @@ case class NettyConfig(
eventLoopConfig: EventLoopConfig,
socketConfig: NettySocketConfig,
initPipeline: NettyConfig => (ChannelPipeline, ChannelHandler) => Unit,
gracefulShutdownTimeout: Option[FiniteDuration]
gracefulShutdownTimeout: Option[FiniteDuration],
serverHeader: Option[String]
) {
def host(h: String): NettyConfig = copy(host = h)

Expand Down Expand Up @@ -96,6 +100,8 @@ case class NettyConfig(

def withGracefulShutdownTimeout(t: FiniteDuration) = copy(gracefulShutdownTimeout = Some(t))
def noGracefulShutdown = copy(gracefulShutdownTimeout = None)

def serverHeader(h: String): NettyConfig = copy(serverHeader = Some(h))
}

object NettyConfig {
Expand All @@ -114,7 +120,8 @@ object NettyConfig {
sslContext = None,
eventLoopConfig = EventLoopConfig.auto,
socketConfig = NettySocketConfig.default,
initPipeline = cfg => defaultInitPipeline(cfg)(_, _)
initPipeline = cfg => defaultInitPipeline(cfg)(_, _),
serverHeader = Some(s"tapir/${buildinfo.BuildInfo.version}")
)

def defaultInitPipeline(cfg: NettyConfig)(pipeline: ChannelPipeline, handler: ChannelHandler): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ case class NettyFutureServer(routes: Vector[FutureRoute], options: NettyFutureSe
val channelFuture =
NettyBootstrap(
config,
new NettyServerHandler(route, unsafeRunAsync, channelGroup, isShuttingDown),
new NettyServerHandler(route, unsafeRunAsync, channelGroup, isShuttingDown, config.serverHeader),
eventLoopGroup,
socketOverride
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.netty.handler.codec.http._
import io.netty.handler.stream.{ChunkedFile, ChunkedStream}
import org.playframework.netty.http.{DefaultStreamedHttpResponse, StreamedHttpRequest}
import org.reactivestreams.Publisher
import org.slf4j.{Logger, LoggerFactory}
import org.slf4j.LoggerFactory
import sttp.monad.MonadError
import sttp.monad.syntax._
import sttp.tapir.server.model.ServerResponse
Expand Down Expand Up @@ -35,7 +35,8 @@ class NettyServerHandler[F[_]](
route: Route[F],
unsafeRunAsync: (() => F[ServerResponse[NettyResponse]]) => (Future[ServerResponse[NettyResponse]], () => Future[Unit]),
channelGroup: ChannelGroup,
isShuttingDown: AtomicBoolean
isShuttingDown: AtomicBoolean,
serverHeader: Option[String]
)(implicit
me: MonadError[F]
) extends SimpleChannelInboundHandler[HttpRequest] {
Expand Down Expand Up @@ -80,12 +81,9 @@ class NettyServerHandler[F[_]](
// Since the listener will be executed from the channels EventLoop everything is thread safe.
val _ = ctx.channel.closeFuture.addListener { (_: ChannelFuture) =>
if (logger.isDebugEnabled) {
logger.debug("Http channel to {} closed. Cancelling {} responses.",
ctx.channel.remoteAddress,
pendingResponses.length
)
logger.debug("Http channel to {} closed. Cancelling {} responses.", ctx.channel.remoteAddress, pendingResponses.length)
}
while(pendingResponses.nonEmpty) {
while (pendingResponses.nonEmpty) {
pendingResponses.dequeue().apply()
}
}
Expand Down Expand Up @@ -256,6 +254,7 @@ class NettyServerHandler[F[_]](

private implicit class RichHttpMessage(val m: HttpMessage) {
def setHeadersFrom(response: ServerResponse[_]): Unit = {
serverHeader.foreach(m.headers().set(HttpHeaderNames.SERVER, _))
response.headers
.groupBy(_.name)
.foreach { case (k, v) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ case class NettyZioServer[R](routes: Vector[RIO[R, Route[RIO[R, *]]]], options:
route,
unsafeRunAsync(runtime),
channelGroup,
isShuttingDown
isShuttingDown,
config.serverHeader
),
eventLoopGroup,
socketOverride
Expand Down

0 comments on commit 7db23f9

Please sign in to comment.