diff --git a/Sources/GRPC/GRPCServerPipelineConfigurator.swift b/Sources/GRPC/GRPCServerPipelineConfigurator.swift index 39aee8267..218eea213 100644 --- a/Sources/GRPC/GRPCServerPipelineConfigurator.swift +++ b/Sources/GRPC/GRPCServerPipelineConfigurator.swift @@ -90,6 +90,10 @@ final class GRPCServerPipelineConfigurator: ChannelInboundHandler, RemovableChan parameter: .maxHeaderListSize, value: HPACKDecoder.defaultMaxHeaderListSize ), + HTTP2Setting( + parameter: .maxFrameSize, + value: self.configuration.httpMaxFrameSize + ), ] ) } diff --git a/Sources/GRPC/Server.swift b/Sources/GRPC/Server.swift index 7031fab2d..0d5269f5f 100644 --- a/Sources/GRPC/Server.swift +++ b/Sources/GRPC/Server.swift @@ -332,6 +332,14 @@ extension Server { } } + /// The HTTP/2 max frame size. Defaults to 16384. Value is clamped between 2^14 and 2^24-1 + /// octets inclusive (the minimum and maximum allowable values - HTTP/2 RFC 7540 4.2). + public var httpMaxFrameSize: Int = 16384 { + didSet(httpMaxFrameSize) { + self.httpMaxFrameSize = httpMaxFrameSize.clamped(to: 16384 ... 16_777_215) + } + } + /// The root server logger. Accepted connections will branch from this logger and RPCs on /// each connection will use a logger branched from the connections logger. This logger is made /// available to service providers via `context`. Defaults to a no-op logger. @@ -447,3 +455,9 @@ private extension ServerBootstrapProtocol { } } } + +extension Comparable { + fileprivate func clamped(to range: ClosedRange) -> Self { + return min(max(self, range.lowerBound), range.upperBound) + } +} diff --git a/Sources/GRPC/ServerBuilder.swift b/Sources/GRPC/ServerBuilder.swift index 03219918c..bdbdbde9a 100644 --- a/Sources/GRPC/ServerBuilder.swift +++ b/Sources/GRPC/ServerBuilder.swift @@ -168,6 +168,14 @@ extension Server.Builder { } } +extension Server.Builder { + @discardableResult + public func withHTTPMaxFrameSize(_ httpMaxFrameSize: Int) -> Self { + self.configuration.httpMaxFrameSize = httpMaxFrameSize + return self + } +} + extension Server.Builder { /// Sets the root server logger. Accepted connections will branch from this logger and RPCs on /// each connection will use a logger branched from the connections logger. This logger is made