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
f0d90020
Commit
f0d90020
authored
Jul 27, 2020
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.2.x' into 2.3.x
Closes gh-22578
parents
5279b90c
b98c3dcc
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
40 deletions
+71
-40
UndertowWebServerFactoryCustomizer.java
...gure/web/embedded/UndertowWebServerFactoryCustomizer.java
+65
-36
UndertowWebServerFactoryCustomizerTests.java
...web/embedded/UndertowWebServerFactoryCustomizerTests.java
+6
-4
No files found.
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java
View file @
f0d90020
...
...
@@ -26,7 +26,9 @@ import java.util.function.Consumer;
import
java.util.function.Function
;
import
io.undertow.UndertowOptions
;
import
org.apache.commons.lang.ClassUtils
;
import
org.xnio.Option
;
import
org.xnio.Options
;
import
org.springframework.boot.autoconfigure.web.ServerProperties
;
import
org.springframework.boot.autoconfigure.web.ServerProperties.Undertow
;
...
...
@@ -74,16 +76,16 @@ public class UndertowWebServerFactoryCustomizer
@Override
public
void
customize
(
ConfigurableUndertowWebServerFactory
factory
)
{
PropertyMapper
map
=
PropertyMapper
.
get
().
alwaysApplyingWhenNonNull
();
FactoryOptions
options
=
new
Factory
Options
(
factory
);
ServerOptions
options
=
new
Server
Options
(
factory
);
ServerProperties
properties
=
this
.
serverProperties
;
map
.
from
(
properties:
:
getMaxHttpHeaderSize
).
asInt
(
DataSize:
:
toBytes
).
when
(
this
::
isPositive
)
.
to
(
options
.
server
(
UndertowOptions
.
MAX_HEADER_SIZE
));
.
to
(
options
.
option
(
UndertowOptions
.
MAX_HEADER_SIZE
));
mapUndertowProperties
(
factory
,
options
);
mapAccessLogProperties
(
factory
);
map
.
from
(
this
::
getOrDeduceUseForwardHeaders
).
to
(
factory:
:
setUseForwardHeaders
);
}
private
void
mapUndertowProperties
(
ConfigurableUndertowWebServerFactory
factory
,
FactoryOptions
o
ptions
)
{
private
void
mapUndertowProperties
(
ConfigurableUndertowWebServerFactory
factory
,
ServerOptions
serverO
ptions
)
{
PropertyMapper
map
=
PropertyMapper
.
get
().
alwaysApplyingWhenNonNull
();
Undertow
properties
=
this
.
serverProperties
.
getUndertow
();
map
.
from
(
properties:
:
getBufferSize
).
whenNonNull
().
asInt
(
DataSize:
:
toBytes
).
to
(
factory:
:
setBufferSize
);
...
...
@@ -92,18 +94,19 @@ public class UndertowWebServerFactoryCustomizer
map
.
from
(
threadProperties:
:
getWorker
).
to
(
factory:
:
setWorkerThreads
);
map
.
from
(
properties:
:
getDirectBuffers
).
to
(
factory:
:
setUseDirectBuffers
);
map
.
from
(
properties:
:
getMaxHttpPostSize
).
as
(
DataSize:
:
toBytes
).
when
(
this
::
isPositive
)
.
to
(
options
.
server
(
UndertowOptions
.
MAX_ENTITY_SIZE
));
map
.
from
(
properties:
:
getMaxParameters
).
to
(
options
.
server
(
UndertowOptions
.
MAX_PARAMETERS
));
map
.
from
(
properties:
:
getMaxHeaders
).
to
(
options
.
server
(
UndertowOptions
.
MAX_HEADERS
));
map
.
from
(
properties:
:
getMaxCookies
).
to
(
options
.
server
(
UndertowOptions
.
MAX_COOKIES
));
map
.
from
(
properties:
:
isAllowEncodedSlash
).
to
(
options
.
server
(
UndertowOptions
.
ALLOW_ENCODED_SLASH
));
map
.
from
(
properties:
:
isDecodeUrl
).
to
(
options
.
server
(
UndertowOptions
.
DECODE_URL
));
map
.
from
(
properties:
:
getUrlCharset
).
as
(
Charset:
:
name
).
to
(
options
.
server
(
UndertowOptions
.
URL_CHARSET
));
map
.
from
(
properties:
:
isAlwaysSetKeepAlive
).
to
(
options
.
server
(
UndertowOptions
.
ALWAYS_SET_KEEP_ALIVE
));
.
to
(
serverOptions
.
option
(
UndertowOptions
.
MAX_ENTITY_SIZE
));
map
.
from
(
properties:
:
getMaxParameters
).
to
(
serverOptions
.
option
(
UndertowOptions
.
MAX_PARAMETERS
));
map
.
from
(
properties:
:
getMaxHeaders
).
to
(
serverOptions
.
option
(
UndertowOptions
.
MAX_HEADERS
));
map
.
from
(
properties:
:
getMaxCookies
).
to
(
serverOptions
.
option
(
UndertowOptions
.
MAX_COOKIES
));
map
.
from
(
properties:
:
isAllowEncodedSlash
).
to
(
serverOptions
.
option
(
UndertowOptions
.
ALLOW_ENCODED_SLASH
));
map
.
from
(
properties:
:
isDecodeUrl
).
to
(
serverOptions
.
option
(
UndertowOptions
.
DECODE_URL
));
map
.
from
(
properties:
:
getUrlCharset
).
as
(
Charset:
:
name
).
to
(
serverOptions
.
option
(
UndertowOptions
.
URL_CHARSET
));
map
.
from
(
properties:
:
isAlwaysSetKeepAlive
).
to
(
serverOptions
.
option
(
UndertowOptions
.
ALWAYS_SET_KEEP_ALIVE
));
map
.
from
(
properties:
:
getNoRequestTimeout
).
asInt
(
Duration:
:
toMillis
)
.
to
(
options
.
server
(
UndertowOptions
.
NO_REQUEST_TIMEOUT
));
map
.
from
(
properties
.
getOptions
()::
getServer
).
to
(
options
.
forEach
(
options:
:
server
));
map
.
from
(
properties
.
getOptions
()::
getSocket
).
to
(
options
.
forEach
(
options:
:
socket
));
.
to
(
serverOptions
.
option
(
UndertowOptions
.
NO_REQUEST_TIMEOUT
));
map
.
from
(
properties
.
getOptions
()::
getServer
).
to
(
serverOptions
.
forEach
(
serverOptions:
:
option
));
SocketOptions
socketOptions
=
new
SocketOptions
(
factory
);
map
.
from
(
properties
.
getOptions
()::
getSocket
).
to
(
socketOptions
.
forEach
(
socketOptions:
:
option
));
}
private
boolean
isPositive
(
Number
value
)
{
...
...
@@ -129,16 +132,17 @@ public class UndertowWebServerFactoryCustomizer
return
this
.
serverProperties
.
getForwardHeadersStrategy
().
equals
(
ServerProperties
.
ForwardHeadersStrategy
.
NATIVE
);
}
/**
* {@link ConfigurableUndertowWebServerFactory} wrapper that makes it easier to apply
* {@link UndertowOptions}.
*/
private
static
class
FactoryOptions
{
private
abstract
static
class
AbstractOptions
{
private
final
Class
<?>
source
;
private
final
Map
<
String
,
Option
<?>>
nameLookup
;
private
static
final
Map
<
String
,
Option
<?>>
NAME_LOOKUP
;
static
{
private
final
ConfigurableUndertowWebServerFactory
factory
;
AbstractOptions
(
Class
<?>
source
,
ConfigurableUndertowWebServerFactory
factory
)
{
Map
<
String
,
Option
<?>>
lookup
=
new
HashMap
<>();
ReflectionUtils
.
doWithLocalFields
(
UndertowOptions
.
class
,
(
field
)
->
{
ReflectionUtils
.
doWithLocalFields
(
source
,
(
field
)
->
{
int
modifiers
=
field
.
getModifiers
();
if
(
Modifier
.
isPublic
(
modifiers
)
&&
Modifier
.
isStatic
(
modifiers
)
&&
Option
.
class
.
isAssignableFrom
(
field
.
getType
()))
{
...
...
@@ -150,28 +154,21 @@ public class UndertowWebServerFactoryCustomizer
}
}
});
NAME_LOOKUP
=
Collections
.
unmodifiableMap
(
lookup
);
}
private
final
ConfigurableUndertowWebServerFactory
factory
;
FactoryOptions
(
ConfigurableUndertowWebServerFactory
factory
)
{
this
.
source
=
source
;
this
.
nameLookup
=
Collections
.
unmodifiableMap
(
lookup
);
this
.
factory
=
factory
;
}
<
T
>
Consumer
<
T
>
server
(
Option
<
T
>
option
)
{
return
(
value
)
->
this
.
factory
.
addBuilderCustomizers
((
builder
)
->
builder
.
setServerOption
(
option
,
value
));
}
<
T
>
Consumer
<
T
>
socket
(
Option
<
T
>
option
)
{
return
(
value
)
->
this
.
factory
.
addBuilderCustomizers
((
builder
)
->
builder
.
setSocketOption
(
option
,
value
));
protected
ConfigurableUndertowWebServerFactory
getFactory
()
{
return
this
.
factory
;
}
@SuppressWarnings
(
"unchecked"
)
<
T
>
Consumer
<
Map
<
String
,
String
>>
forEach
(
Function
<
Option
<
T
>,
Consumer
<
T
>>
function
)
{
return
(
map
)
->
map
.
forEach
((
key
,
value
)
->
{
Option
<
T
>
option
=
(
Option
<
T
>)
NAME_LOOKUP
.
get
(
getCanonicalName
(
key
));
Assert
.
state
(
option
!=
null
,
"Unable to find '"
+
key
+
"' in UndertowOptions"
);
Option
<
T
>
option
=
(
Option
<
T
>)
this
.
nameLookup
.
get
(
getCanonicalName
(
key
));
Assert
.
state
(
option
!=
null
,
"Unable to find '"
+
key
+
"' in "
+
ClassUtils
.
getShortClassName
(
this
.
source
));
T
parsed
=
option
.
parseValue
(
value
,
getClass
().
getClassLoader
());
function
.
apply
(
option
).
accept
(
parsed
);
});
...
...
@@ -186,4 +183,36 @@ public class UndertowWebServerFactoryCustomizer
}
/**
* {@link ConfigurableUndertowWebServerFactory} wrapper that makes it easier to apply
* {@link UndertowOptions server options}.
*/
private
static
class
ServerOptions
extends
AbstractOptions
{
ServerOptions
(
ConfigurableUndertowWebServerFactory
factory
)
{
super
(
UndertowOptions
.
class
,
factory
);
}
<
T
>
Consumer
<
T
>
option
(
Option
<
T
>
option
)
{
return
(
value
)
->
getFactory
().
addBuilderCustomizers
((
builder
)
->
builder
.
setServerOption
(
option
,
value
));
}
}
/**
* {@link ConfigurableUndertowWebServerFactory} wrapper that makes it easier to apply
* {@link Options socket options}.
*/
private
static
class
SocketOptions
extends
AbstractOptions
{
SocketOptions
(
ConfigurableUndertowWebServerFactory
factory
)
{
super
(
Options
.
class
,
factory
);
}
<
T
>
Consumer
<
T
>
option
(
Option
<
T
>
option
)
{
return
(
value
)
->
getFactory
().
addBuilderCustomizers
((
builder
)
->
builder
.
setSocketOption
(
option
,
value
));
}
}
}
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java
View file @
f0d90020
...
...
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.BeforeEach;
import
org.junit.jupiter.api.Test
;
import
org.xnio.Option
;
import
org.xnio.OptionMap
;
import
org.xnio.Options
;
import
org.springframework.boot.autoconfigure.web.ServerProperties
;
import
org.springframework.boot.context.properties.bind.Bindable
;
...
...
@@ -186,13 +187,14 @@ class UndertowWebServerFactoryCustomizerTests {
@Test
void
customSocketOption
()
{
bind
(
"server.undertow.options.socket.
ALWAYS_SET_KEEP_ALIVE=false
"
);
assertThat
(
boundSocketOption
(
UndertowOptions
.
ALWAYS_SET_KEEP_ALIVE
)).
isFalse
(
);
bind
(
"server.undertow.options.socket.
CONNECTION_LOW_WATER=8
"
);
assertThat
(
boundSocketOption
(
Options
.
CONNECTION_LOW_WATER
)).
isEqualTo
(
8
);
}
@Test
void
customSocketOptionShouldBeRelaxed
()
{
bind
(
"server.undertow.options.socket.
always-set-keep-alive=false
"
);
assertThat
(
boundSocketOption
(
UndertowOptions
.
ALWAYS_SET_KEEP_ALIVE
)).
isFalse
(
);
bind
(
"server.undertow.options.socket.
connection-low-water=8
"
);
assertThat
(
boundSocketOption
(
Options
.
CONNECTION_LOW_WATER
)).
isEqualTo
(
8
);
}
@Test
...
...
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