Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
f068f9fc
Commit
f068f9fc
authored
Jul 16, 2020
by
Julien Eyraud
Committed by
Andy Wilkinson
Jul 17, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add properties for Netty HttpDecoderSpec
See gh-22367
parent
530a2673
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
125 additions
and
6 deletions
+125
-6
ServerProperties.java
...ingframework/boot/autoconfigure/web/ServerProperties.java
+65
-0
NettyWebServerFactoryCustomizer.java
...nfigure/web/embedded/NettyWebServerFactoryCustomizer.java
+29
-6
NettyWebServerFactoryCustomizerTests.java
...re/web/embedded/NettyWebServerFactoryCustomizerTests.java
+31
-0
No files found.
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java
View file @
f068f9fc
...
...
@@ -1396,6 +1396,31 @@ public class ServerProperties {
*/
private
Duration
connectionTimeout
;
/**
* The maximum chunk size that can be decoded for the HTTP request.
*/
private
DataSize
maxChunkSize
;
/**
* The maximum length that can be decoded for the HTTP request's initial line.
*/
private
DataSize
maxInitialLineLength
;
/**
* Configure whether or not to validate headers when decoding requests.
*/
private
Boolean
validateHeaders
;
/**
* The maximum length of the content of the HTTP/2.0 clear-text upgrade request.
*/
private
DataSize
h2cMaxContentLength
;
/**
* The initial buffer size for HTTP request decoding.
*/
private
DataSize
initialBufferSize
;
public
Duration
getConnectionTimeout
()
{
return
this
.
connectionTimeout
;
}
...
...
@@ -1404,6 +1429,46 @@ public class ServerProperties {
this
.
connectionTimeout
=
connectionTimeout
;
}
public
DataSize
getMaxChunkSize
()
{
return
this
.
maxChunkSize
;
}
public
void
setMaxChunkSize
(
DataSize
maxChunkSize
)
{
this
.
maxChunkSize
=
maxChunkSize
;
}
public
DataSize
getMaxInitialLineLength
()
{
return
this
.
maxInitialLineLength
;
}
public
void
setMaxInitialLineLength
(
DataSize
maxInitialLineLength
)
{
this
.
maxInitialLineLength
=
maxInitialLineLength
;
}
public
Boolean
getValidateHeaders
()
{
return
this
.
validateHeaders
;
}
public
void
setValidateHeaders
(
Boolean
validateHeaders
)
{
this
.
validateHeaders
=
validateHeaders
;
}
public
DataSize
getH2cMaxContentLength
()
{
return
this
.
h2cMaxContentLength
;
}
public
void
setH2cMaxContentLength
(
DataSize
h2cMaxContentLength
)
{
this
.
h2cMaxContentLength
=
h2cMaxContentLength
;
}
public
DataSize
getInitialBufferSize
()
{
return
this
.
initialBufferSize
;
}
public
void
setInitialBufferSize
(
DataSize
initialBufferSize
)
{
this
.
initialBufferSize
=
initialBufferSize
;
}
}
/**
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizer.java
View file @
f068f9fc
...
...
@@ -17,6 +17,8 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
embedded
;
import
java.time.Duration
;
import
java.util.Objects
;
import
java.util.stream.Stream
;
import
io.netty.channel.ChannelOption
;
...
...
@@ -27,7 +29,6 @@ import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory
import
org.springframework.boot.web.server.WebServerFactoryCustomizer
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.env.Environment
;
import
org.springframework.util.unit.DataSize
;
/**
* Customization for Netty-specific features.
...
...
@@ -58,11 +59,16 @@ public class NettyWebServerFactoryCustomizer
public
void
customize
(
NettyReactiveWebServerFactory
factory
)
{
factory
.
setUseForwardHeaders
(
getOrDeduceUseForwardHeaders
());
PropertyMapper
propertyMapper
=
PropertyMapper
.
get
().
alwaysApplyingWhenNonNull
();
propertyMapper
.
from
(
this
.
serverProperties
::
getMaxHttpHeaderSize
)
.
to
((
maxHttpRequestHeaderSize
)
->
customizeMaxHttpHeaderSize
(
factory
,
maxHttpRequestHeaderSize
));
ServerProperties
.
Netty
nettyProperties
=
this
.
serverProperties
.
getNetty
();
propertyMapper
.
from
(
nettyProperties:
:
getConnectionTimeout
).
whenNonNull
()
.
to
((
connectionTimeout
)
->
customizeConnectionTimeout
(
factory
,
connectionTimeout
));
if
(
Stream
.
of
(
this
.
serverProperties
.
getMaxHttpHeaderSize
(),
nettyProperties
.
getH2cMaxContentLength
(),
nettyProperties
.
getMaxChunkSize
(),
nettyProperties
.
getMaxInitialLineLength
(),
nettyProperties
.
getValidateHeaders
(),
nettyProperties
.
getInitialBufferSize
())
.
anyMatch
(
Objects:
:
nonNull
))
{
customizeRequestDecoder
(
factory
,
propertyMapper
);
}
}
private
boolean
getOrDeduceUseForwardHeaders
()
{
...
...
@@ -73,9 +79,26 @@ public class NettyWebServerFactoryCustomizer
return
this
.
serverProperties
.
getForwardHeadersStrategy
().
equals
(
ServerProperties
.
ForwardHeadersStrategy
.
NATIVE
);
}
private
void
customizeMaxHttpHeaderSize
(
NettyReactiveWebServerFactory
factory
,
DataSize
maxHttpHeaderSize
)
{
factory
.
addServerCustomizers
((
httpServer
)
->
httpServer
.
httpRequestDecoder
(
(
httpRequestDecoderSpec
)
->
httpRequestDecoderSpec
.
maxHeaderSize
((
int
)
maxHttpHeaderSize
.
toBytes
())));
private
void
customizeRequestDecoder
(
NettyReactiveWebServerFactory
factory
,
PropertyMapper
propertyMapper
)
{
factory
.
addServerCustomizers
((
httpServer
)
->
httpServer
.
httpRequestDecoder
((
httpRequestDecoderSpec
)
->
{
propertyMapper
.
from
(
this
.
serverProperties
.
getMaxHttpHeaderSize
()).
whenNonNull
()
.
to
((
maxHttpRequestHeader
)
->
httpRequestDecoderSpec
.
maxHeaderSize
((
int
)
maxHttpRequestHeader
.
toBytes
()));
ServerProperties
.
Netty
nettyProperties
=
this
.
serverProperties
.
getNetty
();
propertyMapper
.
from
(
nettyProperties
.
getMaxChunkSize
()).
whenNonNull
()
.
to
((
maxChunkSize
)
->
httpRequestDecoderSpec
.
maxChunkSize
((
int
)
maxChunkSize
.
toBytes
()));
propertyMapper
.
from
(
nettyProperties
.
getMaxInitialLineLength
()).
whenNonNull
()
.
to
((
maxInitialLineLength
)
->
httpRequestDecoderSpec
.
maxInitialLineLength
((
int
)
maxInitialLineLength
.
toBytes
()));
propertyMapper
.
from
(
nettyProperties
.
getH2cMaxContentLength
()).
whenNonNull
()
.
to
((
h2cMaxContentLength
)
->
httpRequestDecoderSpec
.
h2cMaxContentLength
((
int
)
h2cMaxContentLength
.
toBytes
()));
propertyMapper
.
from
(
nettyProperties
.
getInitialBufferSize
()).
whenNonNull
().
to
(
(
initialBufferSize
)
->
httpRequestDecoderSpec
.
initialBufferSize
((
int
)
initialBufferSize
.
toBytes
()));
propertyMapper
.
from
(
nettyProperties
.
getValidateHeaders
()).
whenNonNull
()
.
to
(
httpRequestDecoderSpec:
:
validateHeaders
);
return
httpRequestDecoderSpec
;
}));
}
private
void
customizeConnectionTimeout
(
NettyReactiveWebServerFactory
factory
,
Duration
connectionTimeout
)
{
...
...
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizerTests.java
View file @
f068f9fc
...
...
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
import
org.mockito.ArgumentCaptor
;
import
org.mockito.Captor
;
import
org.mockito.MockitoAnnotations
;
import
reactor.netty.http.server.HttpRequestDecoderSpec
;
import
reactor.netty.http.server.HttpServer
;
import
org.springframework.boot.autoconfigure.web.ServerProperties
;
...
...
@@ -33,6 +34,7 @@ import org.springframework.boot.context.properties.source.ConfigurationPropertyS
import
org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory
;
import
org.springframework.boot.web.embedded.netty.NettyServerCustomizer
;
import
org.springframework.mock.env.MockEnvironment
;
import
org.springframework.util.unit.DataSize
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
...
...
@@ -107,6 +109,35 @@ class NettyWebServerFactoryCustomizerTests {
verifyConnectionTimeout
(
factory
,
1000
);
}
@Test
void
setHttpRequestDecoder
()
{
ServerProperties
.
Netty
nettyProperties
=
this
.
serverProperties
.
getNetty
();
nettyProperties
.
setValidateHeaders
(
true
);
nettyProperties
.
setInitialBufferSize
(
DataSize
.
ofBytes
(
512
));
nettyProperties
.
setH2cMaxContentLength
(
DataSize
.
ofKilobytes
(
1
));
nettyProperties
.
setMaxChunkSize
(
DataSize
.
ofKilobytes
(
16
));
nettyProperties
.
setMaxInitialLineLength
(
DataSize
.
ofKilobytes
(
32
));
NettyReactiveWebServerFactory
factory
=
mock
(
NettyReactiveWebServerFactory
.
class
);
this
.
customizer
.
customize
(
factory
);
verify
(
factory
,
times
(
1
)).
addServerCustomizers
(
this
.
customizerCaptor
.
capture
());
NettyServerCustomizer
serverCustomizer
=
this
.
customizerCaptor
.
getValue
();
HttpServer
httpServer
=
serverCustomizer
.
apply
(
HttpServer
.
create
());
HttpRequestDecoderSpec
decoder
=
httpServer
.
configuration
().
decoder
();
assertThat
(
decoder
.
validateHeaders
()).
isTrue
();
assertThat
(
decoder
.
initialBufferSize
()).
isEqualTo
(
nettyProperties
.
getInitialBufferSize
().
toBytes
());
assertThat
(
decoder
.
h2cMaxContentLength
()).
isEqualTo
(
nettyProperties
.
getH2cMaxContentLength
().
toBytes
());
assertThat
(
decoder
.
maxChunkSize
()).
isEqualTo
(
nettyProperties
.
getMaxChunkSize
().
toBytes
());
assertThat
(
decoder
.
maxInitialLineLength
()).
isEqualTo
(
nettyProperties
.
getMaxInitialLineLength
().
toBytes
());
}
@Test
void
shouldNotSetAnyHttpRequestDecoderProperties
()
{
this
.
serverProperties
.
setMaxHttpHeaderSize
(
null
);
NettyReactiveWebServerFactory
factory
=
mock
(
NettyReactiveWebServerFactory
.
class
);
this
.
customizer
.
customize
(
factory
);
verify
(
factory
,
never
()).
addServerCustomizers
(
this
.
customizerCaptor
.
capture
());
}
private
void
verifyConnectionTimeout
(
NettyReactiveWebServerFactory
factory
,
Integer
expected
)
{
if
(
expected
==
null
)
{
verify
(
factory
,
never
()).
addServerCustomizers
(
any
(
NettyServerCustomizer
.
class
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment