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
ca1a666f
Commit
ca1a666f
authored
Apr 18, 2019
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Polish "Add support for configuring remaining Undertow server options"
See gh-16278
parent
186b1fae
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
121 additions
and
115 deletions
+121
-115
ServerProperties.java
...ingframework/boot/autoconfigure/web/ServerProperties.java
+34
-32
UndertowWebServerFactoryCustomizer.java
...gure/web/embedded/UndertowWebServerFactoryCustomizer.java
+17
-17
UndertowWebServerFactoryCustomizerTests.java
...web/embedded/UndertowWebServerFactoryCustomizerTests.java
+70
-66
No files found.
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java
View file @
ca1a666f
...
...
@@ -29,6 +29,8 @@ import java.util.Locale;
import
java.util.Map
;
import
java.util.TimeZone
;
import
io.undertow.UndertowOptions
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.boot.context.properties.DeprecatedConfigurationProperty
;
import
org.springframework.boot.context.properties.NestedConfigurationProperty
;
...
...
@@ -1117,47 +1119,47 @@ public class ServerProperties {
private
boolean
eagerFilterInit
=
true
;
/**
*
The maximum number of query or path parameters that are allowed. This limit
*
exists
to prevent hash collision based DOS attacks.
*
Maximum number of query or path parameters that are allowed. This limit exists
* to prevent hash collision based DOS attacks.
*/
private
Integer
maxParameters
;
private
int
maxParameters
=
UndertowOptions
.
DEFAULT_MAX_PARAMETERS
;
/**
*
The maximum number of headers that are allowed. This limit exists to prevent
*
hash
collision based DOS attacks.
*
Maximum number of headers that are allowed. This limit exists to prevent hash
* collision based DOS attacks.
*/
private
Integer
maxHeaders
;
private
int
maxHeaders
=
UndertowOptions
.
DEFAULT_MAX_HEADERS
;
/**
*
The maximum number of cookies that are allowed. This limit exists to prevent
*
hash
collision based DOS attacks.
*
Maximum number of cookies that are allowed. This limit exists to prevent hash
* collision based DOS attacks.
*/
private
Integer
maxCookies
;
private
int
maxCookies
=
200
;
/**
*
Set this to true if you want the server to decode percent encoded slash
*
characters. This is probably a bad idea, as it can have security implications,
*
due to different servers interpreting the slash differently. Only enable this
*
if you have a legacy
application that requires it.
*
Whether the server should decode percent encoded slash characters. Enabling
*
encoded slashes can have security implications due to different servers
*
interpreting the slash differently. Only enable this if you have a legacy
* application that requires it.
*/
private
Boolean
allowEncodedSlash
;
private
boolean
allowEncodedSlash
=
false
;
/**
*
If the URL should be decoded. If this is not set to true then percent encoded
*
characters in the URL will be left as
is.
*
Whether the URL should be decoded. When disabled, percent-encoded characters in
*
the URL will be left as-
is.
*/
private
Boolean
decodeUrl
;
private
boolean
decodeUrl
=
true
;
/**
*
The charset to decode the URL to
.
*
Charset used to decode URLs
.
*/
private
String
urlCharset
;
private
Charset
urlCharset
=
StandardCharsets
.
UTF_8
;
/**
*
If the 'Connection: keep-alive' header should be added to all responses, even
*
if not required by spec
.
*
Whether the 'Connection: keep-alive' header should be added to all responses,
*
even if not required by the HTTP specification
.
*/
private
Boolean
alwaysSetKeepAliv
e
;
private
boolean
alwaysSetKeepAlive
=
tru
e
;
private
final
Accesslog
accesslog
=
new
Accesslog
();
...
...
@@ -1209,7 +1211,7 @@ public class ServerProperties {
this
.
eagerFilterInit
=
eagerFilterInit
;
}
public
Integer
getMaxParameters
()
{
public
int
getMaxParameters
()
{
return
this
.
maxParameters
;
}
...
...
@@ -1217,11 +1219,11 @@ public class ServerProperties {
this
.
maxParameters
=
maxParameters
;
}
public
Integer
getMaxHeaders
()
{
public
int
getMaxHeaders
()
{
return
this
.
maxHeaders
;
}
public
void
setMaxHeaders
(
Integer
maxHeaders
)
{
public
void
setMaxHeaders
(
int
maxHeaders
)
{
this
.
maxHeaders
=
maxHeaders
;
}
...
...
@@ -1233,15 +1235,15 @@ public class ServerProperties {
this
.
maxCookies
=
maxCookies
;
}
public
B
oolean
isAllowEncodedSlash
()
{
public
b
oolean
isAllowEncodedSlash
()
{
return
this
.
allowEncodedSlash
;
}
public
void
setAllowEncodedSlash
(
B
oolean
allowEncodedSlash
)
{
public
void
setAllowEncodedSlash
(
b
oolean
allowEncodedSlash
)
{
this
.
allowEncodedSlash
=
allowEncodedSlash
;
}
public
B
oolean
isDecodeUrl
()
{
public
b
oolean
isDecodeUrl
()
{
return
this
.
decodeUrl
;
}
...
...
@@ -1249,19 +1251,19 @@ public class ServerProperties {
this
.
decodeUrl
=
decodeUrl
;
}
public
String
getUrlCharset
()
{
public
Charset
getUrlCharset
()
{
return
this
.
urlCharset
;
}
public
void
setUrlCharset
(
String
urlCharset
)
{
public
void
setUrlCharset
(
Charset
urlCharset
)
{
this
.
urlCharset
=
urlCharset
;
}
public
B
oolean
isAlwaysSetKeepAlive
()
{
public
b
oolean
isAlwaysSetKeepAlive
()
{
return
this
.
alwaysSetKeepAlive
;
}
public
void
setAlwaysSetKeepAlive
(
B
oolean
alwaysSetKeepAlive
)
{
public
void
setAlwaysSetKeepAlive
(
b
oolean
alwaysSetKeepAlive
)
{
this
.
alwaysSetKeepAlive
=
alwaysSetKeepAlive
;
}
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java
View file @
ca1a666f
...
...
@@ -89,45 +89,45 @@ public class UndertowWebServerFactoryCustomizer implements
propertyMapper
.
from
(
properties:
:
getMaxHttpHeaderSize
).
whenNonNull
()
.
asInt
(
DataSize:
:
toBytes
).
when
(
this
::
isPositive
)
.
to
((
maxHttpHeaderSize
)
->
customize
Properties
(
factory
,
.
to
((
maxHttpHeaderSize
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
MAX_HEADER_SIZE
,
maxHttpHeaderSize
));
propertyMapper
.
from
(
undertowProperties:
:
getMaxHttpPostSize
)
.
asInt
(
DataSize:
:
toBytes
).
when
(
this
::
isPositive
)
.
to
((
maxHttpPostSize
)
->
customize
Properties
(
factory
,
UndertowOptions
.
MAX_
HEADER
_SIZE
,
maxHttpPostSize
));
propertyMapper
.
from
(
undertowProperties:
:
getMaxHttpPostSize
)
.
as
(
DataSize:
:
toBytes
)
.
when
(
this
::
isPositive
)
.
to
((
maxHttpPostSize
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
MAX_
ENTITY
_SIZE
,
maxHttpPostSize
));
propertyMapper
.
from
(
properties:
:
getConnectionTimeout
)
.
to
((
connectionTimeout
)
->
customize
Properties
(
factory
,
.
to
((
connectionTimeout
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
NO_REQUEST_TIMEOUT
,
(
int
)
connectionTimeout
.
toMillis
()));
propertyMapper
.
from
(
undertowProperties:
:
getMaxParameters
)
.
to
((
maxParameters
)
->
customize
Properties
(
factory
,
.
to
((
maxParameters
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
MAX_PARAMETERS
,
maxParameters
));
propertyMapper
.
from
(
undertowProperties:
:
getMaxHeaders
)
.
to
((
maxHeaders
)
->
customize
Properties
(
factory
,
.
to
((
maxHeaders
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
MAX_HEADERS
,
maxHeaders
));
propertyMapper
.
from
(
undertowProperties:
:
getMaxCookies
)
.
to
((
maxCookies
)
->
customize
Properties
(
factory
,
.
to
((
maxCookies
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
MAX_COOKIES
,
maxCookies
));
propertyMapper
.
from
(
undertowProperties:
:
isAllowEncodedSlash
)
.
to
((
allowEncodedSlash
)
->
customize
Properties
(
factory
,
.
to
((
allowEncodedSlash
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
ALLOW_ENCODED_SLASH
,
allowEncodedSlash
));
propertyMapper
.
from
(
undertowProperties:
:
isDecodeUrl
)
.
to
((
isDecodeUrl
)
->
customize
Properties
(
factory
,
.
to
((
isDecodeUrl
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
DECODE_URL
,
isDecodeUrl
));
propertyMapper
.
from
(
undertowProperties:
:
getUrlCharset
)
.
to
((
urlCharset
)
->
customize
Properties
(
factory
,
UndertowOptions
.
URL_CHARSET
,
urlCharset
));
.
to
((
urlCharset
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
URL_CHARSET
,
urlCharset
.
name
()
));
propertyMapper
.
from
(
undertowProperties:
:
isAlwaysSetKeepAlive
)
.
to
((
alwaysSetKeepAlive
)
->
customize
Properties
(
factory
,
.
to
((
alwaysSetKeepAlive
)
->
customize
ServerOption
(
factory
,
UndertowOptions
.
ALWAYS_SET_KEEP_ALIVE
,
alwaysSetKeepAlive
));
factory
.
addDeploymentInfoCustomizers
((
deploymentInfo
)
->
deploymentInfo
...
...
@@ -138,10 +138,10 @@ public class UndertowWebServerFactoryCustomizer implements
return
value
.
longValue
()
>
0
;
}
private
<
T
>
void
customize
Properties
(
ConfigurableUndertowWebServerFactory
factory
,
Option
<
T
>
propType
,
T
prop
)
{
private
<
T
>
void
customize
ServerOption
(
ConfigurableUndertowWebServerFactory
factory
,
Option
<
T
>
option
,
T
value
)
{
factory
.
addBuilderCustomizers
(
(
builder
)
->
builder
.
setServerOption
(
propType
,
prop
));
(
builder
)
->
builder
.
setServerOption
(
option
,
value
));
}
private
boolean
getOrDeduceUseForwardHeaders
()
{
...
...
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java
View file @
ca1a666f
...
...
@@ -17,6 +17,7 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
embedded
;
import
java.io.File
;
import
java.nio.charset.StandardCharsets
;
import
java.util.Arrays
;
import
io.undertow.Undertow
;
...
...
@@ -24,6 +25,7 @@ import io.undertow.Undertow.Builder;
import
io.undertow.UndertowOptions
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.xnio.Option
;
import
org.xnio.OptionMap
;
import
org.springframework.boot.autoconfigure.web.ServerProperties
;
...
...
@@ -88,37 +90,75 @@ public class UndertowWebServerFactoryCustomizerTests {
}
@Test
public
void
customizeUndertowConnectionCommonSettings
()
{
bind
(
"server.undertow.maxParameters=50"
,
"server.undertow.maxHeaders=60"
,
"server.undertow.maxCookies=70"
,
"server.undertow.allowEncodedSlash=true"
,
"server.undertow.decodeUrl=true"
,
"server.undertow.urlCharset=UTF-8"
,
"server.undertow.alwaysSetKeepAlive=true"
);
Builder
builder
=
Undertow
.
builder
();
ConfigurableUndertowWebServerFactory
factory
=
mockFactory
(
builder
);
this
.
customizer
.
customize
(
factory
);
OptionMap
map
=
((
OptionMap
.
Builder
)
ReflectionTestUtils
.
getField
(
builder
,
"serverOptions"
)).
getMap
();
assertThat
(
map
.
get
(
UndertowOptions
.
MAX_PARAMETERS
)).
isEqualTo
(
50
);
assertThat
(
map
.
get
(
UndertowOptions
.
MAX_HEADERS
)).
isEqualTo
(
60
);
assertThat
(
map
.
get
(
UndertowOptions
.
MAX_COOKIES
)).
isEqualTo
(
70
);
assertThat
(
map
.
get
(
UndertowOptions
.
ALLOW_ENCODED_SLASH
)).
isTrue
();
assertThat
(
map
.
get
(
UndertowOptions
.
DECODE_URL
)).
isTrue
();
assertThat
(
map
.
get
(
UndertowOptions
.
URL_CHARSET
)).
isEqualTo
(
"UTF-8"
);
assertThat
(
map
.
get
(
UndertowOptions
.
ALWAYS_SET_KEEP_ALIVE
)).
isTrue
();
public
void
customMaxHttpHeaderSize
()
{
bind
(
"server.max-http-header-size=2048"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
MAX_HEADER_SIZE
)).
isEqualTo
(
2048
);
}
@Test
public
void
customizeUndertowCommonConnectionCommonBoolSettings
()
{
bind
(
"server.undertow.allowEncodedSlash=false"
,
"server.undertow.decodeUrl=false"
,
"server.undertow.alwaysSetKeepAlive=false"
);
Builder
builder
=
Undertow
.
builder
();
ConfigurableUndertowWebServerFactory
factory
=
mockFactory
(
builder
);
this
.
customizer
.
customize
(
factory
);
OptionMap
map
=
((
OptionMap
.
Builder
)
ReflectionTestUtils
.
getField
(
builder
,
"serverOptions"
)).
getMap
();
assertThat
(
map
.
get
(
UndertowOptions
.
ALLOW_ENCODED_SLASH
)).
isFalse
();
assertThat
(
map
.
get
(
UndertowOptions
.
DECODE_URL
)).
isFalse
();
assertThat
(
map
.
get
(
UndertowOptions
.
ALWAYS_SET_KEEP_ALIVE
)).
isFalse
();
public
void
customMaxHttpHeaderSizeIgnoredIfNegative
()
{
bind
(
"server.max-http-header-size=-1"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
MAX_HEADER_SIZE
)).
isNull
();
}
public
void
customMaxHttpHeaderSizeIgnoredIfZero
()
{
bind
(
"server.max-http-header-size=0"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
MAX_HEADER_SIZE
)).
isNull
();
}
@Test
public
void
customMaxHttpPostSize
()
{
bind
(
"server.undertow.max-http-post-size=256"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
MAX_ENTITY_SIZE
)).
isEqualTo
(
256
);
}
@Test
public
void
customConnectionTimeout
()
{
bind
(
"server.connectionTimeout=100"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
NO_REQUEST_TIMEOUT
)).
isEqualTo
(
100
);
}
@Test
public
void
customMaxParameters
()
{
bind
(
"server.undertow.max-parameters=4"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
MAX_PARAMETERS
)).
isEqualTo
(
4
);
}
@Test
public
void
customMaxHeaders
()
{
bind
(
"server.undertow.max-headers=4"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
MAX_HEADERS
)).
isEqualTo
(
4
);
}
@Test
public
void
customMaxCookies
()
{
bind
(
"server.undertow.max-cookies=4"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
MAX_COOKIES
)).
isEqualTo
(
4
);
}
@Test
public
void
allowEncodedSlashes
()
{
bind
(
"server.undertow.allow-encoded-slash=true"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
ALLOW_ENCODED_SLASH
)).
isTrue
();
}
@Test
public
void
disableUrlDecoding
()
{
bind
(
"server.undertow.decode-url=false"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
DECODE_URL
)).
isFalse
();
}
@Test
public
void
customUrlCharset
()
{
bind
(
"server.undertow.url-charset=UTF-16"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
URL_CHARSET
))
.
isEqualTo
(
StandardCharsets
.
UTF_16
.
name
());
}
@Test
public
void
disableAlwaysSetKeepAlive
()
{
bind
(
"server.undertow.always-set-keep-alive=false"
);
assertThat
(
boundServerOption
(
UndertowOptions
.
ALWAYS_SET_KEEP_ALIVE
)).
isFalse
();
}
@Test
...
...
@@ -147,49 +187,13 @@ public class UndertowWebServerFactoryCustomizerTests {
verify
(
factory
).
setUseForwardHeaders
(
true
);
}
@Test
public
void
customizeMaxHttpHeaderSize
()
{
bind
(
"server.max-http-header-size=2048"
);
Builder
builder
=
Undertow
.
builder
();
ConfigurableUndertowWebServerFactory
factory
=
mockFactory
(
builder
);
this
.
customizer
.
customize
(
factory
);
OptionMap
map
=
((
OptionMap
.
Builder
)
ReflectionTestUtils
.
getField
(
builder
,
"serverOptions"
)).
getMap
();
assertThat
(
map
.
get
(
UndertowOptions
.
MAX_HEADER_SIZE
).
intValue
()).
isEqualTo
(
2048
);
}
@Test
public
void
customMaxHttpHeaderSizeIgnoredIfNegative
()
{
bind
(
"server.max-http-header-size=-1"
);
Builder
builder
=
Undertow
.
builder
();
ConfigurableUndertowWebServerFactory
factory
=
mockFactory
(
builder
);
this
.
customizer
.
customize
(
factory
);
OptionMap
map
=
((
OptionMap
.
Builder
)
ReflectionTestUtils
.
getField
(
builder
,
"serverOptions"
)).
getMap
();
assertThat
(
map
.
contains
(
UndertowOptions
.
MAX_HEADER_SIZE
)).
isFalse
();
}
@Test
public
void
customMaxHttpHeaderSizeIgnoredIfZero
()
{
bind
(
"server.max-http-header-size=0"
);
Builder
builder
=
Undertow
.
builder
();
ConfigurableUndertowWebServerFactory
factory
=
mockFactory
(
builder
);
this
.
customizer
.
customize
(
factory
);
OptionMap
map
=
((
OptionMap
.
Builder
)
ReflectionTestUtils
.
getField
(
builder
,
"serverOptions"
)).
getMap
();
assertThat
(
map
.
contains
(
UndertowOptions
.
MAX_HEADER_SIZE
)).
isFalse
();
}
@Test
public
void
customConnectionTimeout
()
{
bind
(
"server.connection-timeout=100"
);
private
<
T
>
T
boundServerOption
(
Option
<
T
>
option
)
{
Builder
builder
=
Undertow
.
builder
();
ConfigurableUndertowWebServerFactory
factory
=
mockFactory
(
builder
);
this
.
customizer
.
customize
(
factory
);
OptionMap
map
=
((
OptionMap
.
Builder
)
ReflectionTestUtils
.
getField
(
builder
,
"serverOptions"
)).
getMap
();
assertThat
(
map
.
contains
(
UndertowOptions
.
NO_REQUEST_TIMEOUT
)).
isTrue
();
assertThat
(
map
.
get
(
UndertowOptions
.
NO_REQUEST_TIMEOUT
)).
isEqualTo
(
100
);
return
map
.
get
(
option
);
}
private
ConfigurableUndertowWebServerFactory
mockFactory
(
Builder
builder
)
{
...
...
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