Skip to content

Commit 1a63572

Browse files
karadzhovPetar Karadzhov
and
Petar Karadzhov
authored
feat(blaze-client): Socket options (#985)
Co-authored-by: Petar Karadzhov <[email protected]>
1 parent 705dc52 commit 1a63572

File tree

4 files changed

+38
-4
lines changed

4 files changed

+38
-4
lines changed

http4s-client-blaze-pureconfig/src/main/scala-2/com/avast/sst/http4s/client/pureconfig/ConfigReaders.scala

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.avast.sst.http4s.client.pureconfig
22

3-
import cats.syntax.either._
3+
import cats.syntax.either.*
44
import com.avast.sst.http4s.client.Http4sBlazeClientConfig
5+
import com.avast.sst.http4s.client.Http4sBlazeClientConfig.SocketOptions
56
import org.http4s.blaze.client.ParserMode
67
import org.http4s.headers.`User-Agent`
78
import pureconfig.ConfigReader
89
import pureconfig.error.CannotConvert
910
import pureconfig.generic.ProductHint
10-
import pureconfig.generic.semiauto._
11+
import pureconfig.generic.semiauto.*
1112

1213
trait ConfigReaders {
1314

@@ -17,6 +18,8 @@ trait ConfigReaders {
1718
`User-Agent`.parse(value).leftMap { parseFailure => CannotConvert(value, "User-Agent HTTP header", parseFailure.message) }
1819
}
1920

21+
implicit val http4sClientSocketOptionsReader: ConfigReader[SocketOptions] = deriveReader[SocketOptions]
22+
2023
implicit val http4sClientParserModeReader: ConfigReader[ParserMode] = deriveEnumerationReader
2124

2225
implicit val http4sClientHttp4sBlazeClientConfigReader: ConfigReader[Http4sBlazeClientConfig] = deriveReader[Http4sBlazeClientConfig]

http4s-client-blaze-pureconfig/src/main/scala-3/com/avast/sst/http4s/client/pureconfig/ConfigReaders.scala

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.avast.sst.http4s.client.pureconfig
22

33
import cats.syntax.either.*
44
import com.avast.sst.http4s.client.Http4sBlazeClientConfig
5+
import com.avast.sst.http4s.client.Http4sBlazeClientConfig.SocketOptions
56
import org.http4s.blaze.client.ParserMode
67
import org.http4s.headers.`User-Agent`
78
import pureconfig.ConfigReader
@@ -14,6 +15,8 @@ trait ConfigReaders {
1415
`User-Agent`.parse(value).leftMap { parseFailure => CannotConvert(value, "User-Agent HTTP header", parseFailure.message) }
1516
}
1617

18+
implicit val http4sClientSocketOptionsReader: ConfigReader[SocketOptions] = ConfigReader.derived
19+
1720
implicit val http4sClientParserModeReader: ConfigReader[ParserMode] = ConfigReader.derived
1821

1922
implicit val http4sClientHttp4sBlazeClientConfigReader: ConfigReader[Http4sBlazeClientConfig] =

http4s-client-blaze/src/main/scala/com/avast/sst/http4s/client/Http4sBlazeClientConfig.scala

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.avast.sst.http4s.client
22

3+
import com.avast.sst.http4s.client.Http4sBlazeClientConfig.SocketOptions
34
import org.http4s.blaze.client.ParserMode
45
import org.http4s.client.defaults
56
import org.http4s.headers.`User-Agent`
@@ -23,5 +24,16 @@ final case class Http4sBlazeClientConfig(
2324
maxChunkSize: Int = Int.MaxValue,
2425
chunkBufferMaxSize: Int = 1024 * 1024,
2526
parserMode: ParserMode = ParserMode.Strict,
26-
bufferSize: Int = 8192
27+
bufferSize: Int = 8192,
28+
socketOptions: Option[SocketOptions] = None
2729
)
30+
31+
object Http4sBlazeClientConfig {
32+
final case class SocketOptions(
33+
reuseAddress: Boolean = true,
34+
sendBufferSize: Int = 256 * 1024,
35+
receiveBufferSize: Int = 256 * 1024,
36+
keepAlive: Boolean = false,
37+
noDelay: Boolean = false
38+
)
39+
}

http4s-client-blaze/src/main/scala/com/avast/sst/http4s/client/Http4sBlazeClientModule.scala

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package com.avast.sst.http4s.client
22

33
import cats.effect.{ConcurrentEffect, Resource}
4+
import com.avast.sst.http4s.client.Http4sBlazeClientConfig.SocketOptions
5+
import org.http4s.blaze.channel.{ChannelOptions, OptionValue}
46
import org.http4s.blaze.client.BlazeClientBuilder
57
import org.http4s.client.Client
68

9+
import java.net.StandardSocketOptions
710
import javax.net.ssl.SSLContext
811
import scala.concurrent.ExecutionContext
912
object Http4sBlazeClientModule {
@@ -35,7 +38,20 @@ object Http4sBlazeClientModule {
3538
.withParserMode(config.parserMode)
3639
.withBufferSize(config.bufferSize)
3740

38-
sslContext.map(builder.withSslContext).getOrElse(builder).resource
41+
val builderWithMaybeSocketOptions = config.socketOptions.fold(builder)(s => builder.withChannelOptions(channelOptions(s)))
42+
val builderWithMaybeTLS = sslContext.fold(builderWithMaybeSocketOptions)(builderWithMaybeSocketOptions.withSslContext)
43+
44+
builderWithMaybeTLS.resource
3945
}
4046

47+
def channelOptions(socketOptions: SocketOptions): ChannelOptions =
48+
ChannelOptions(
49+
Vector(
50+
OptionValue[java.lang.Boolean](StandardSocketOptions.SO_REUSEADDR, socketOptions.reuseAddress),
51+
OptionValue[java.lang.Integer](StandardSocketOptions.SO_SNDBUF, socketOptions.sendBufferSize),
52+
OptionValue[java.lang.Integer](StandardSocketOptions.SO_RCVBUF, socketOptions.receiveBufferSize),
53+
OptionValue[java.lang.Boolean](StandardSocketOptions.SO_KEEPALIVE, socketOptions.keepAlive),
54+
OptionValue[java.lang.Boolean](StandardSocketOptions.TCP_NODELAY, socketOptions.noDelay)
55+
)
56+
)
4157
}

0 commit comments

Comments
 (0)