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
a6e4744c
Commit
a6e4744c
authored
Nov 18, 2014
by
Phillip Webb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixup line endings
parent
b5832622
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
753 additions
and
753 deletions
+753
-753
pom.xml
spring-boot-starters/spring-boot-starter-undertow/pom.xml
+41
-41
MANIFEST.MF
...oot-starters/spring-boot-starter-web/META-INF/MANIFEST.MF
+3
-3
UndertowEmbeddedServletContainer.java
...t/embedded/undertow/UndertowEmbeddedServletContainer.java
+106
-106
UndertowEmbeddedServletContainerFactory.java
...ded/undertow/UndertowEmbeddedServletContainerFactory.java
+507
-507
UndertowEmbeddedServletContainerFactoryTests.java
...ndertow/UndertowEmbeddedServletContainerFactoryTests.java
+96
-96
No files found.
spring-boot-starters/spring-boot-starter-undertow/pom.xml
View file @
a6e4744c
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starters
</artifactId>
<version>
1.2.0.BUILD-SNAPSHOT
</version>
</parent>
<artifactId>
spring-boot-starter-undertow
</artifactId>
<name>
Spring Boot Undertow Starter
</name>
<description>
Spring Boot Undertow Starter
</description>
<url>
http://projects.spring.io/spring-boot/
</url>
<organization>
<name>
Pivotal Software, Inc.
</name>
<url>
http://www.spring.io
</url>
</organization>
<properties>
<main.basedir>
${basedir}/../..
</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>
io.undertow
</groupId>
<artifactId>
undertow-core
</artifactId>
</dependency>
<dependency>
<groupId>
io.undertow
</groupId>
<artifactId>
undertow-servlet
</artifactId>
<exclusions>
<exclusion>
<groupId>
org.jboss.spec.javax.servlet
</groupId>
<artifactId>
jboss-servlet-api_3.1_spec
</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
javax.servlet
</groupId>
<artifactId>
javax.servlet-api
</artifactId>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starters
</artifactId>
<version>
1.2.0.BUILD-SNAPSHOT
</version>
</parent>
<artifactId>
spring-boot-starter-undertow
</artifactId>
<name>
Spring Boot Undertow Starter
</name>
<description>
Spring Boot Undertow Starter
</description>
<url>
http://projects.spring.io/spring-boot/
</url>
<organization>
<name>
Pivotal Software, Inc.
</name>
<url>
http://www.spring.io
</url>
</organization>
<properties>
<main.basedir>
${basedir}/../..
</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>
io.undertow
</groupId>
<artifactId>
undertow-core
</artifactId>
</dependency>
<dependency>
<groupId>
io.undertow
</groupId>
<artifactId>
undertow-servlet
</artifactId>
<exclusions>
<exclusion>
<groupId>
org.jboss.spec.javax.servlet
</groupId>
<artifactId>
jboss-servlet-api_3.1_spec
</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
javax.servlet
</groupId>
<artifactId>
javax.servlet-api
</artifactId>
</dependency>
</dependencies>
</project>
spring-boot-starters/spring-boot-starter-web/META-INF/MANIFEST.MF
View file @
a6e4744c
Manifest-Version: 1.0
Class-Path:
Manifest-Version: 1.0
Class-Path:
spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java
View file @
a6e4744c
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
context
.
embedded
.
undertow
;
import
io.undertow.Handlers
;
import
io.undertow.Undertow
;
import
io.undertow.Undertow.Builder
;
import
io.undertow.server.HttpHandler
;
import
io.undertow.server.handlers.PathHandler
;
import
io.undertow.servlet.api.DeploymentManager
;
import
javax.servlet.ServletException
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainer
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainerException
;
import
org.springframework.util.StringUtils
;
/**
* {@link EmbeddedServletContainer} that can be used to control an embedded Undertow
* server. Typically this class should be created using
* {@link UndertowEmbeddedServletContainerFactory} and not directly.
*
* @author Ivan Sopov
* @author Andy Wilkinson
* @since 1.2.0
* @see UndertowEmbeddedServletContainer
*/
public
class
UndertowEmbeddedServletContainer
implements
EmbeddedServletContainer
{
private
final
DeploymentManager
manager
;
private
final
Builder
builder
;
private
final
String
contextPath
;
private
final
int
port
;
private
final
boolean
autoStart
;
private
Undertow
undertow
;
private
boolean
started
=
false
;
public
UndertowEmbeddedServletContainer
(
Builder
builder
,
DeploymentManager
manager
,
String
contextPath
,
int
port
,
boolean
autoStart
)
{
this
.
builder
=
builder
;
this
.
manager
=
manager
;
this
.
contextPath
=
contextPath
;
this
.
port
=
port
;
this
.
autoStart
=
autoStart
;
}
@Override
public
synchronized
void
start
()
throws
EmbeddedServletContainerException
{
if
(!
this
.
autoStart
)
{
return
;
}
if
(
this
.
undertow
==
null
)
{
try
{
HttpHandler
servletHandler
=
this
.
manager
.
start
();
if
(
StringUtils
.
isEmpty
(
this
.
contextPath
))
{
this
.
builder
.
setHandler
(
servletHandler
);
}
else
{
PathHandler
pathHandler
=
Handlers
.
path
().
addPrefixPath
(
this
.
contextPath
,
servletHandler
);
this
.
builder
.
setHandler
(
pathHandler
);
}
this
.
undertow
=
this
.
builder
.
build
();
}
catch
(
ServletException
ex
)
{
throw
new
EmbeddedServletContainerException
(
"Unable to start embdedded Undertow"
,
ex
);
}
}
this
.
undertow
.
start
();
this
.
started
=
true
;
}
@Override
public
synchronized
void
stop
()
throws
EmbeddedServletContainerException
{
if
(
this
.
started
)
{
this
.
started
=
false
;
this
.
undertow
.
stop
();
}
}
@Override
public
int
getPort
()
{
return
this
.
port
;
}
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
context
.
embedded
.
undertow
;
import
io.undertow.Handlers
;
import
io.undertow.Undertow
;
import
io.undertow.Undertow.Builder
;
import
io.undertow.server.HttpHandler
;
import
io.undertow.server.handlers.PathHandler
;
import
io.undertow.servlet.api.DeploymentManager
;
import
javax.servlet.ServletException
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainer
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainerException
;
import
org.springframework.util.StringUtils
;
/**
* {@link EmbeddedServletContainer} that can be used to control an embedded Undertow
* server. Typically this class should be created using
* {@link UndertowEmbeddedServletContainerFactory} and not directly.
*
* @author Ivan Sopov
* @author Andy Wilkinson
* @since 1.2.0
* @see UndertowEmbeddedServletContainer
*/
public
class
UndertowEmbeddedServletContainer
implements
EmbeddedServletContainer
{
private
final
DeploymentManager
manager
;
private
final
Builder
builder
;
private
final
String
contextPath
;
private
final
int
port
;
private
final
boolean
autoStart
;
private
Undertow
undertow
;
private
boolean
started
=
false
;
public
UndertowEmbeddedServletContainer
(
Builder
builder
,
DeploymentManager
manager
,
String
contextPath
,
int
port
,
boolean
autoStart
)
{
this
.
builder
=
builder
;
this
.
manager
=
manager
;
this
.
contextPath
=
contextPath
;
this
.
port
=
port
;
this
.
autoStart
=
autoStart
;
}
@Override
public
synchronized
void
start
()
throws
EmbeddedServletContainerException
{
if
(!
this
.
autoStart
)
{
return
;
}
if
(
this
.
undertow
==
null
)
{
try
{
HttpHandler
servletHandler
=
this
.
manager
.
start
();
if
(
StringUtils
.
isEmpty
(
this
.
contextPath
))
{
this
.
builder
.
setHandler
(
servletHandler
);
}
else
{
PathHandler
pathHandler
=
Handlers
.
path
().
addPrefixPath
(
this
.
contextPath
,
servletHandler
);
this
.
builder
.
setHandler
(
pathHandler
);
}
this
.
undertow
=
this
.
builder
.
build
();
}
catch
(
ServletException
ex
)
{
throw
new
EmbeddedServletContainerException
(
"Unable to start embdedded Undertow"
,
ex
);
}
}
this
.
undertow
.
start
();
this
.
started
=
true
;
}
@Override
public
synchronized
void
stop
()
throws
EmbeddedServletContainerException
{
if
(
this
.
started
)
{
this
.
started
=
false
;
this
.
undertow
.
stop
();
}
}
@Override
public
int
getPort
()
{
return
this
.
port
;
}
}
\ No newline at end of file
spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java
View file @
a6e4744c
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
context
.
embedded
.
undertow
;
import
io.undertow.Undertow
;
import
io.undertow.Undertow.Builder
;
import
io.undertow.UndertowMessages
;
import
io.undertow.server.handlers.resource.ClassPathResourceManager
;
import
io.undertow.server.handlers.resource.FileResourceManager
;
import
io.undertow.server.handlers.resource.Resource
;
import
io.undertow.server.handlers.resource.ResourceChangeListener
;
import
io.undertow.server.handlers.resource.ResourceManager
;
import
io.undertow.server.handlers.resource.URLResource
;
import
io.undertow.servlet.api.DeploymentInfo
;
import
io.undertow.servlet.api.DeploymentManager
;
import
io.undertow.servlet.api.InstanceFactory
;
import
io.undertow.servlet.api.InstanceHandle
;
import
io.undertow.servlet.api.ListenerInfo
;
import
io.undertow.servlet.api.MimeMapping
;
import
io.undertow.servlet.api.ServletStackTraces
;
import
io.undertow.servlet.handlers.DefaultServlet
;
import
io.undertow.servlet.util.ImmediateInstanceHandle
;
import
java.io.File
;
import
java.io.IOException
;
import
java.net.URL
;
import
java.security.KeyManagementException
;
import
java.security.KeyStore
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.List
;
import
javax.net.ssl.KeyManager
;
import
javax.net.ssl.KeyManagerFactory
;
import
javax.net.ssl.SSLContext
;
import
javax.net.ssl.TrustManager
;
import
javax.net.ssl.TrustManagerFactory
;
import
javax.servlet.ServletContextEvent
;
import
javax.servlet.ServletContextListener
;
import
javax.servlet.ServletException
;
import
org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainer
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
;
import
org.springframework.boot.context.embedded.ErrorPage
;
import
org.springframework.boot.context.embedded.MimeMappings.Mapping
;
import
org.springframework.boot.context.embedded.ServletContextInitializer
;
import
org.springframework.boot.context.embedded.Ssl
;
import
org.springframework.boot.context.embedded.Ssl.ClientAuth
;
import
org.springframework.context.ResourceLoaderAware
;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ResourceUtils
;
import
org.springframework.util.SocketUtils
;
import
static
io
.
undertow
.
servlet
.
Servlets
.
defaultContainer
;
import
static
io
.
undertow
.
servlet
.
Servlets
.
deployment
;
import
static
io
.
undertow
.
servlet
.
Servlets
.
servlet
;
import
static
org
.
xnio
.
Options
.
SSL_CLIENT_AUTH_MODE
;
import
static
org
.
xnio
.
SslClientAuthMode
.
NOT_REQUESTED
;
import
static
org
.
xnio
.
SslClientAuthMode
.
REQUESTED
;
import
static
org
.
xnio
.
SslClientAuthMode
.
REQUIRED
;
/**
* {@link EmbeddedServletContainerFactory} that can be used to create
* {@link UndertowEmbeddedServletContainer}s.
* <p>
* Unless explicitly configured otherwise, the factory will create containers that listen
* for HTTP requests on port 8080.
*
* @author Ivan Sopov
* @author Andy Wilkinson
* @since 1.2.0
* @see UndertowEmbeddedServletContainer
*/
public
class
UndertowEmbeddedServletContainerFactory
extends
AbstractEmbeddedServletContainerFactory
implements
ResourceLoaderAware
{
private
List
<
UndertowBuilderCustomizer
>
undertowBuilderCustomizers
=
new
ArrayList
<
UndertowBuilderCustomizer
>();
private
ResourceLoader
resourceLoader
;
private
Integer
bufferSize
;
private
Integer
buffersPerRegion
;
private
Integer
ioThreads
;
private
Integer
workerThreads
;
private
Boolean
directBuffers
;
/**
* Create a new {@link UndertowEmbeddedServletContainerFactory} instance.
*/
public
UndertowEmbeddedServletContainerFactory
()
{
super
();
setRegisterJspServlet
(
false
);
}
/**
* Create a new {@link UndertowEmbeddedServletContainerFactory} that listens for
* requests using the specified port.
* @param port the port to listen on
*/
public
UndertowEmbeddedServletContainerFactory
(
int
port
)
{
super
(
port
);
setRegisterJspServlet
(
false
);
}
/**
* Create a new {@link UndertowEmbeddedServletContainerFactory} with the specified
* context path and port.
* @param contextPath root the context path
* @param port the port to listen on
*/
public
UndertowEmbeddedServletContainerFactory
(
String
contextPath
,
int
port
)
{
super
(
contextPath
,
port
);
setRegisterJspServlet
(
false
);
}
/**
* Set {@link UndertowBuilderCustomizer}s that should be applied to the Undertow
* {@link Builder}. Calling this method will replace any existing customizers.
* @param undertowBuilderCustomizers the customizers to set
*/
public
void
setUndertowBuilderCustomizers
(
Collection
<?
extends
UndertowBuilderCustomizer
>
undertowBuilderCustomizers
)
{
Assert
.
notNull
(
undertowBuilderCustomizers
,
"undertowBuilderCustomizers must not be null"
);
this
.
undertowBuilderCustomizers
=
new
ArrayList
<
UndertowBuilderCustomizer
>(
undertowBuilderCustomizers
);
}
/**
* Returns a mutable collection of the {@link UndertowBuilderCustomizer}s that will be
* applied to the Undertow {@link Builder} .
* @return the customizers that will be applied
*/
public
Collection
<
UndertowBuilderCustomizer
>
getUndertowBuilderCustomizers
()
{
return
this
.
undertowBuilderCustomizers
;
}
/**
* Add {@link UndertowBuilderCustomizer}s that should be used to customize the
* Undertow {@link Builder}.
* @param undertowBuilderCustomizers the customizers to add
*/
public
void
addUndertowBuilderCustomizers
(
UndertowBuilderCustomizer
...
undertowBuilderCustomizers
)
{
Assert
.
notNull
(
undertowBuilderCustomizers
,
"undertowBuilderCustomizers must not be null"
);
this
.
undertowBuilderCustomizers
.
addAll
(
Arrays
.
asList
(
undertowBuilderCustomizers
));
}
@Override
public
EmbeddedServletContainer
getEmbeddedServletContainer
(
ServletContextInitializer
...
initializers
)
{
DeploymentManager
manager
=
createDeploymentManager
(
initializers
);
int
port
=
getPort
();
if
(
port
==
0
)
{
port
=
SocketUtils
.
findAvailableTcpPort
(
40000
);
}
Builder
builder
=
createBuilder
(
port
);
return
new
UndertowEmbeddedServletContainer
(
builder
,
manager
,
getContextPath
(),
port
,
port
>=
0
);
}
private
Builder
createBuilder
(
int
port
)
{
Builder
builder
=
Undertow
.
builder
();
if
(
this
.
bufferSize
!=
null
)
{
builder
.
setBufferSize
(
this
.
bufferSize
);
}
if
(
this
.
buffersPerRegion
!=
null
)
{
builder
.
setBuffersPerRegion
(
this
.
buffersPerRegion
);
}
if
(
this
.
ioThreads
!=
null
)
{
builder
.
setIoThreads
(
this
.
ioThreads
);
}
if
(
this
.
workerThreads
!=
null
)
{
builder
.
setWorkerThreads
(
this
.
workerThreads
);
}
if
(
this
.
directBuffers
!=
null
)
{
builder
.
setDirectBuffers
(
this
.
directBuffers
);
}
if
(
getSsl
()
==
null
)
{
builder
.
addHttpListener
(
port
,
"0.0.0.0"
);
}
else
{
configureSsl
(
port
,
builder
);
}
for
(
UndertowBuilderCustomizer
customizer
:
this
.
undertowBuilderCustomizers
)
{
customizer
.
customize
(
builder
);
}
return
builder
;
}
private
void
configureSsl
(
int
port
,
Builder
builder
)
{
try
{
Ssl
ssl
=
getSsl
();
SSLContext
sslContext
=
SSLContext
.
getInstance
(
ssl
.
getProtocol
());
sslContext
.
init
(
getKeyManagers
(),
getTrustManagers
(),
null
);
builder
.
addHttpsListener
(
port
,
"0.0.0.0"
,
sslContext
);
if
(
ssl
.
getClientAuth
()
==
ClientAuth
.
NEED
)
{
builder
.
setSocketOption
(
SSL_CLIENT_AUTH_MODE
,
REQUIRED
);
}
else
if
(
ssl
.
getClientAuth
()
==
ClientAuth
.
WANT
)
{
builder
.
setSocketOption
(
SSL_CLIENT_AUTH_MODE
,
REQUESTED
);
}
else
{
builder
.
setSocketOption
(
SSL_CLIENT_AUTH_MODE
,
NOT_REQUESTED
);
}
}
catch
(
NoSuchAlgorithmException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
catch
(
KeyManagementException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
KeyManager
[]
getKeyManagers
()
{
try
{
Ssl
ssl
=
getSsl
();
String
keyStoreType
=
ssl
.
getKeyStoreType
();
if
(
keyStoreType
==
null
)
{
keyStoreType
=
"JKS"
;
}
KeyStore
keyStore
=
KeyStore
.
getInstance
(
keyStoreType
);
URL
url
=
ResourceUtils
.
getURL
(
ssl
.
getKeyStore
());
keyStore
.
load
(
url
.
openStream
(),
ssl
.
getKeyStorePassword
().
toCharArray
());
// Get key manager to provide client credentials.
KeyManagerFactory
keyManagerFactory
=
KeyManagerFactory
.
getInstance
(
KeyManagerFactory
.
getDefaultAlgorithm
());
char
[]
keyPassword
=
ssl
.
getKeyPassword
()
!=
null
?
ssl
.
getKeyPassword
()
.
toCharArray
()
:
ssl
.
getKeyStorePassword
().
toCharArray
();
keyManagerFactory
.
init
(
keyStore
,
keyPassword
);
return
keyManagerFactory
.
getKeyManagers
();
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
TrustManager
[]
getTrustManagers
()
{
try
{
Ssl
ssl
=
getSsl
();
String
trustStoreType
=
ssl
.
getTrustStoreType
();
if
(
trustStoreType
==
null
)
{
trustStoreType
=
"JKS"
;
}
String
trustStore
=
ssl
.
getTrustStore
();
if
(
trustStore
==
null
)
{
return
null
;
}
KeyStore
trustedKeyStore
=
KeyStore
.
getInstance
(
trustStoreType
);
URL
url
=
ResourceUtils
.
getURL
(
trustStore
);
trustedKeyStore
.
load
(
url
.
openStream
(),
ssl
.
getTrustStorePassword
()
.
toCharArray
());
TrustManagerFactory
trustManagerFactory
=
TrustManagerFactory
.
getInstance
(
TrustManagerFactory
.
getDefaultAlgorithm
());
trustManagerFactory
.
init
(
trustedKeyStore
);
return
trustManagerFactory
.
getTrustManagers
();
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
DeploymentManager
createDeploymentManager
(
ServletContextInitializer
...
initializers
)
{
DeploymentInfo
servletBuilder
=
deployment
();
servletBuilder
.
addListener
(
new
ListenerInfo
(
UndertowSpringServletContextListener
.
class
,
new
UndertowSpringServletContextListenerFactory
(
new
UndertowSpringServletContextListener
(
mergeInitializers
(
initializers
)))));
if
(
this
.
resourceLoader
!=
null
)
{
servletBuilder
.
setClassLoader
(
this
.
resourceLoader
.
getClassLoader
());
}
else
{
servletBuilder
.
setClassLoader
(
getClass
().
getClassLoader
());
}
servletBuilder
.
setContextPath
(
getContextPath
());
servletBuilder
.
setDeploymentName
(
"spring-boot"
);
if
(
isRegisterDefaultServlet
())
{
servletBuilder
.
addServlet
(
servlet
(
"default"
,
DefaultServlet
.
class
));
}
configureErrorPages
(
servletBuilder
);
servletBuilder
.
setServletStackTraces
(
ServletStackTraces
.
NONE
);
File
root
=
getValidDocumentRoot
();
if
(
root
!=
null
&&
root
.
isDirectory
())
{
servletBuilder
.
setResourceManager
(
new
FileResourceManager
(
root
,
0
));
}
else
if
(
root
!=
null
&&
root
.
isFile
())
{
servletBuilder
.
setResourceManager
(
new
JarResourcemanager
(
root
));
}
else
if
(
this
.
resourceLoader
!=
null
)
{
servletBuilder
.
setResourceManager
(
new
ClassPathResourceManager
(
this
.
resourceLoader
.
getClassLoader
(),
""
));
}
else
{
servletBuilder
.
setResourceManager
(
new
ClassPathResourceManager
(
getClass
()
.
getClassLoader
(),
""
));
}
for
(
Mapping
mimeMapping
:
getMimeMappings
())
{
servletBuilder
.
addMimeMapping
(
new
MimeMapping
(
mimeMapping
.
getExtension
(),
mimeMapping
.
getMimeType
()));
}
DeploymentManager
manager
=
defaultContainer
().
addDeployment
(
servletBuilder
);
manager
.
deploy
();
manager
.
getDeployment
().
getSessionManager
()
.
setDefaultSessionTimeout
(
getSessionTimeout
());
return
manager
;
}
private
void
configureErrorPages
(
DeploymentInfo
servletBuilder
)
{
for
(
ErrorPage
errorPage
:
getErrorPages
())
{
if
(
errorPage
.
getStatus
()
!=
null
)
{
io
.
undertow
.
servlet
.
api
.
ErrorPage
undertowErrorpage
=
new
io
.
undertow
.
servlet
.
api
.
ErrorPage
(
errorPage
.
getPath
(),
errorPage
.
getStatusCode
());
servletBuilder
.
addErrorPage
(
undertowErrorpage
);
}
else
if
(
errorPage
.
getException
()
!=
null
)
{
io
.
undertow
.
servlet
.
api
.
ErrorPage
undertowErrorpage
=
new
io
.
undertow
.
servlet
.
api
.
ErrorPage
(
errorPage
.
getPath
(),
errorPage
.
getException
());
servletBuilder
.
addErrorPage
(
undertowErrorpage
);
}
else
{
io
.
undertow
.
servlet
.
api
.
ErrorPage
undertowErrorpage
=
new
io
.
undertow
.
servlet
.
api
.
ErrorPage
(
errorPage
.
getPath
());
servletBuilder
.
addErrorPage
(
undertowErrorpage
);
}
}
}
/**
* Factory method called to create the {@link UndertowEmbeddedServletContainer}.
* Subclasses can override this method to return a different
* {@link UndertowEmbeddedServletContainer} or apply additional processing to the
* {@link Builder} and {@link DeploymentManager} used to bootstrap Undertow
*
* @param builder the builder
* @param manager the deployment manager
* @param port the port that Undertow should listen on
* @return a new {@link UndertowEmbeddedServletContainer} instance
*/
protected
UndertowEmbeddedServletContainer
getUndertowEmbeddedServletContainer
(
Builder
builder
,
DeploymentManager
manager
,
int
port
)
{
return
new
UndertowEmbeddedServletContainer
(
builder
,
manager
,
getContextPath
(),
port
,
port
>=
0
);
}
@Override
public
void
setResourceLoader
(
ResourceLoader
resourceLoader
)
{
this
.
resourceLoader
=
resourceLoader
;
}
public
void
setBufferSize
(
Integer
bufferSize
)
{
this
.
bufferSize
=
bufferSize
;
}
public
void
setBuffersPerRegion
(
Integer
buffersPerRegion
)
{
this
.
buffersPerRegion
=
buffersPerRegion
;
}
public
void
setIoThreads
(
Integer
ioThreads
)
{
this
.
ioThreads
=
ioThreads
;
}
public
void
setWorkerThreads
(
Integer
workerThreads
)
{
this
.
workerThreads
=
workerThreads
;
}
public
void
setDirectBuffers
(
Boolean
directBuffers
)
{
this
.
directBuffers
=
directBuffers
;
}
@Override
public
void
setRegisterJspServlet
(
boolean
registerJspServlet
)
{
Assert
.
isTrue
(!
registerJspServlet
,
"Undertow does not support JSPs"
);
super
.
setRegisterJspServlet
(
registerJspServlet
);
}
private
static
class
JarResourcemanager
implements
ResourceManager
{
private
final
String
jarPath
;
public
JarResourcemanager
(
File
jarFile
)
{
this
(
jarFile
.
getAbsolutePath
());
}
public
JarResourcemanager
(
String
jarPath
)
{
this
.
jarPath
=
jarPath
;
}
@Override
public
void
close
()
throws
IOException
{
// no code
}
@Override
public
Resource
getResource
(
String
path
)
throws
IOException
{
URL
url
=
new
URL
(
"jar:file:"
+
this
.
jarPath
+
"!"
+
path
);
URLResource
resource
=
new
URLResource
(
url
,
url
.
openConnection
(),
path
);
if
(
resource
.
getContentLength
()
<
0
)
{
return
null
;
}
return
resource
;
}
@Override
public
boolean
isResourceChangeListenerSupported
()
{
return
false
;
}
@Override
public
void
registerResourceChangeListener
(
ResourceChangeListener
listener
)
{
throw
UndertowMessages
.
MESSAGES
.
resourceChangeListenerNotSupported
();
}
@Override
public
void
removeResourceChangeListener
(
ResourceChangeListener
listener
)
{
throw
UndertowMessages
.
MESSAGES
.
resourceChangeListenerNotSupported
();
}
}
private
static
class
UndertowSpringServletContextListenerFactory
implements
InstanceFactory
<
UndertowSpringServletContextListener
>
{
private
final
UndertowSpringServletContextListener
listener
;
public
UndertowSpringServletContextListenerFactory
(
UndertowSpringServletContextListener
listener
)
{
this
.
listener
=
listener
;
}
@Override
public
InstanceHandle
<
UndertowSpringServletContextListener
>
createInstance
()
throws
InstantiationException
{
return
new
ImmediateInstanceHandle
<
UndertowSpringServletContextListener
>(
this
.
listener
);
}
}
private
static
class
UndertowSpringServletContextListener
implements
ServletContextListener
{
private
final
ServletContextInitializer
[]
initializers
;
public
UndertowSpringServletContextListener
(
ServletContextInitializer
...
initializers
)
{
this
.
initializers
=
initializers
;
}
@Override
public
void
contextInitialized
(
ServletContextEvent
event
)
{
try
{
for
(
ServletContextInitializer
initializer
:
this
.
initializers
)
{
initializer
.
onStartup
(
event
.
getServletContext
());
}
}
catch
(
ServletException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
@Override
public
void
contextDestroyed
(
ServletContextEvent
sce
)
{
// no code
}
}
}
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
context
.
embedded
.
undertow
;
import
io.undertow.Undertow
;
import
io.undertow.Undertow.Builder
;
import
io.undertow.UndertowMessages
;
import
io.undertow.server.handlers.resource.ClassPathResourceManager
;
import
io.undertow.server.handlers.resource.FileResourceManager
;
import
io.undertow.server.handlers.resource.Resource
;
import
io.undertow.server.handlers.resource.ResourceChangeListener
;
import
io.undertow.server.handlers.resource.ResourceManager
;
import
io.undertow.server.handlers.resource.URLResource
;
import
io.undertow.servlet.api.DeploymentInfo
;
import
io.undertow.servlet.api.DeploymentManager
;
import
io.undertow.servlet.api.InstanceFactory
;
import
io.undertow.servlet.api.InstanceHandle
;
import
io.undertow.servlet.api.ListenerInfo
;
import
io.undertow.servlet.api.MimeMapping
;
import
io.undertow.servlet.api.ServletStackTraces
;
import
io.undertow.servlet.handlers.DefaultServlet
;
import
io.undertow.servlet.util.ImmediateInstanceHandle
;
import
java.io.File
;
import
java.io.IOException
;
import
java.net.URL
;
import
java.security.KeyManagementException
;
import
java.security.KeyStore
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.List
;
import
javax.net.ssl.KeyManager
;
import
javax.net.ssl.KeyManagerFactory
;
import
javax.net.ssl.SSLContext
;
import
javax.net.ssl.TrustManager
;
import
javax.net.ssl.TrustManagerFactory
;
import
javax.servlet.ServletContextEvent
;
import
javax.servlet.ServletContextListener
;
import
javax.servlet.ServletException
;
import
org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainer
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
;
import
org.springframework.boot.context.embedded.ErrorPage
;
import
org.springframework.boot.context.embedded.MimeMappings.Mapping
;
import
org.springframework.boot.context.embedded.ServletContextInitializer
;
import
org.springframework.boot.context.embedded.Ssl
;
import
org.springframework.boot.context.embedded.Ssl.ClientAuth
;
import
org.springframework.context.ResourceLoaderAware
;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ResourceUtils
;
import
org.springframework.util.SocketUtils
;
import
static
io
.
undertow
.
servlet
.
Servlets
.
defaultContainer
;
import
static
io
.
undertow
.
servlet
.
Servlets
.
deployment
;
import
static
io
.
undertow
.
servlet
.
Servlets
.
servlet
;
import
static
org
.
xnio
.
Options
.
SSL_CLIENT_AUTH_MODE
;
import
static
org
.
xnio
.
SslClientAuthMode
.
NOT_REQUESTED
;
import
static
org
.
xnio
.
SslClientAuthMode
.
REQUESTED
;
import
static
org
.
xnio
.
SslClientAuthMode
.
REQUIRED
;
/**
* {@link EmbeddedServletContainerFactory} that can be used to create
* {@link UndertowEmbeddedServletContainer}s.
* <p>
* Unless explicitly configured otherwise, the factory will create containers that listen
* for HTTP requests on port 8080.
*
* @author Ivan Sopov
* @author Andy Wilkinson
* @since 1.2.0
* @see UndertowEmbeddedServletContainer
*/
public
class
UndertowEmbeddedServletContainerFactory
extends
AbstractEmbeddedServletContainerFactory
implements
ResourceLoaderAware
{
private
List
<
UndertowBuilderCustomizer
>
undertowBuilderCustomizers
=
new
ArrayList
<
UndertowBuilderCustomizer
>();
private
ResourceLoader
resourceLoader
;
private
Integer
bufferSize
;
private
Integer
buffersPerRegion
;
private
Integer
ioThreads
;
private
Integer
workerThreads
;
private
Boolean
directBuffers
;
/**
* Create a new {@link UndertowEmbeddedServletContainerFactory} instance.
*/
public
UndertowEmbeddedServletContainerFactory
()
{
super
();
setRegisterJspServlet
(
false
);
}
/**
* Create a new {@link UndertowEmbeddedServletContainerFactory} that listens for
* requests using the specified port.
* @param port the port to listen on
*/
public
UndertowEmbeddedServletContainerFactory
(
int
port
)
{
super
(
port
);
setRegisterJspServlet
(
false
);
}
/**
* Create a new {@link UndertowEmbeddedServletContainerFactory} with the specified
* context path and port.
* @param contextPath root the context path
* @param port the port to listen on
*/
public
UndertowEmbeddedServletContainerFactory
(
String
contextPath
,
int
port
)
{
super
(
contextPath
,
port
);
setRegisterJspServlet
(
false
);
}
/**
* Set {@link UndertowBuilderCustomizer}s that should be applied to the Undertow
* {@link Builder}. Calling this method will replace any existing customizers.
* @param undertowBuilderCustomizers the customizers to set
*/
public
void
setUndertowBuilderCustomizers
(
Collection
<?
extends
UndertowBuilderCustomizer
>
undertowBuilderCustomizers
)
{
Assert
.
notNull
(
undertowBuilderCustomizers
,
"undertowBuilderCustomizers must not be null"
);
this
.
undertowBuilderCustomizers
=
new
ArrayList
<
UndertowBuilderCustomizer
>(
undertowBuilderCustomizers
);
}
/**
* Returns a mutable collection of the {@link UndertowBuilderCustomizer}s that will be
* applied to the Undertow {@link Builder} .
* @return the customizers that will be applied
*/
public
Collection
<
UndertowBuilderCustomizer
>
getUndertowBuilderCustomizers
()
{
return
this
.
undertowBuilderCustomizers
;
}
/**
* Add {@link UndertowBuilderCustomizer}s that should be used to customize the
* Undertow {@link Builder}.
* @param undertowBuilderCustomizers the customizers to add
*/
public
void
addUndertowBuilderCustomizers
(
UndertowBuilderCustomizer
...
undertowBuilderCustomizers
)
{
Assert
.
notNull
(
undertowBuilderCustomizers
,
"undertowBuilderCustomizers must not be null"
);
this
.
undertowBuilderCustomizers
.
addAll
(
Arrays
.
asList
(
undertowBuilderCustomizers
));
}
@Override
public
EmbeddedServletContainer
getEmbeddedServletContainer
(
ServletContextInitializer
...
initializers
)
{
DeploymentManager
manager
=
createDeploymentManager
(
initializers
);
int
port
=
getPort
();
if
(
port
==
0
)
{
port
=
SocketUtils
.
findAvailableTcpPort
(
40000
);
}
Builder
builder
=
createBuilder
(
port
);
return
new
UndertowEmbeddedServletContainer
(
builder
,
manager
,
getContextPath
(),
port
,
port
>=
0
);
}
private
Builder
createBuilder
(
int
port
)
{
Builder
builder
=
Undertow
.
builder
();
if
(
this
.
bufferSize
!=
null
)
{
builder
.
setBufferSize
(
this
.
bufferSize
);
}
if
(
this
.
buffersPerRegion
!=
null
)
{
builder
.
setBuffersPerRegion
(
this
.
buffersPerRegion
);
}
if
(
this
.
ioThreads
!=
null
)
{
builder
.
setIoThreads
(
this
.
ioThreads
);
}
if
(
this
.
workerThreads
!=
null
)
{
builder
.
setWorkerThreads
(
this
.
workerThreads
);
}
if
(
this
.
directBuffers
!=
null
)
{
builder
.
setDirectBuffers
(
this
.
directBuffers
);
}
if
(
getSsl
()
==
null
)
{
builder
.
addHttpListener
(
port
,
"0.0.0.0"
);
}
else
{
configureSsl
(
port
,
builder
);
}
for
(
UndertowBuilderCustomizer
customizer
:
this
.
undertowBuilderCustomizers
)
{
customizer
.
customize
(
builder
);
}
return
builder
;
}
private
void
configureSsl
(
int
port
,
Builder
builder
)
{
try
{
Ssl
ssl
=
getSsl
();
SSLContext
sslContext
=
SSLContext
.
getInstance
(
ssl
.
getProtocol
());
sslContext
.
init
(
getKeyManagers
(),
getTrustManagers
(),
null
);
builder
.
addHttpsListener
(
port
,
"0.0.0.0"
,
sslContext
);
if
(
ssl
.
getClientAuth
()
==
ClientAuth
.
NEED
)
{
builder
.
setSocketOption
(
SSL_CLIENT_AUTH_MODE
,
REQUIRED
);
}
else
if
(
ssl
.
getClientAuth
()
==
ClientAuth
.
WANT
)
{
builder
.
setSocketOption
(
SSL_CLIENT_AUTH_MODE
,
REQUESTED
);
}
else
{
builder
.
setSocketOption
(
SSL_CLIENT_AUTH_MODE
,
NOT_REQUESTED
);
}
}
catch
(
NoSuchAlgorithmException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
catch
(
KeyManagementException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
KeyManager
[]
getKeyManagers
()
{
try
{
Ssl
ssl
=
getSsl
();
String
keyStoreType
=
ssl
.
getKeyStoreType
();
if
(
keyStoreType
==
null
)
{
keyStoreType
=
"JKS"
;
}
KeyStore
keyStore
=
KeyStore
.
getInstance
(
keyStoreType
);
URL
url
=
ResourceUtils
.
getURL
(
ssl
.
getKeyStore
());
keyStore
.
load
(
url
.
openStream
(),
ssl
.
getKeyStorePassword
().
toCharArray
());
// Get key manager to provide client credentials.
KeyManagerFactory
keyManagerFactory
=
KeyManagerFactory
.
getInstance
(
KeyManagerFactory
.
getDefaultAlgorithm
());
char
[]
keyPassword
=
ssl
.
getKeyPassword
()
!=
null
?
ssl
.
getKeyPassword
()
.
toCharArray
()
:
ssl
.
getKeyStorePassword
().
toCharArray
();
keyManagerFactory
.
init
(
keyStore
,
keyPassword
);
return
keyManagerFactory
.
getKeyManagers
();
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
TrustManager
[]
getTrustManagers
()
{
try
{
Ssl
ssl
=
getSsl
();
String
trustStoreType
=
ssl
.
getTrustStoreType
();
if
(
trustStoreType
==
null
)
{
trustStoreType
=
"JKS"
;
}
String
trustStore
=
ssl
.
getTrustStore
();
if
(
trustStore
==
null
)
{
return
null
;
}
KeyStore
trustedKeyStore
=
KeyStore
.
getInstance
(
trustStoreType
);
URL
url
=
ResourceUtils
.
getURL
(
trustStore
);
trustedKeyStore
.
load
(
url
.
openStream
(),
ssl
.
getTrustStorePassword
()
.
toCharArray
());
TrustManagerFactory
trustManagerFactory
=
TrustManagerFactory
.
getInstance
(
TrustManagerFactory
.
getDefaultAlgorithm
());
trustManagerFactory
.
init
(
trustedKeyStore
);
return
trustManagerFactory
.
getTrustManagers
();
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
DeploymentManager
createDeploymentManager
(
ServletContextInitializer
...
initializers
)
{
DeploymentInfo
servletBuilder
=
deployment
();
servletBuilder
.
addListener
(
new
ListenerInfo
(
UndertowSpringServletContextListener
.
class
,
new
UndertowSpringServletContextListenerFactory
(
new
UndertowSpringServletContextListener
(
mergeInitializers
(
initializers
)))));
if
(
this
.
resourceLoader
!=
null
)
{
servletBuilder
.
setClassLoader
(
this
.
resourceLoader
.
getClassLoader
());
}
else
{
servletBuilder
.
setClassLoader
(
getClass
().
getClassLoader
());
}
servletBuilder
.
setContextPath
(
getContextPath
());
servletBuilder
.
setDeploymentName
(
"spring-boot"
);
if
(
isRegisterDefaultServlet
())
{
servletBuilder
.
addServlet
(
servlet
(
"default"
,
DefaultServlet
.
class
));
}
configureErrorPages
(
servletBuilder
);
servletBuilder
.
setServletStackTraces
(
ServletStackTraces
.
NONE
);
File
root
=
getValidDocumentRoot
();
if
(
root
!=
null
&&
root
.
isDirectory
())
{
servletBuilder
.
setResourceManager
(
new
FileResourceManager
(
root
,
0
));
}
else
if
(
root
!=
null
&&
root
.
isFile
())
{
servletBuilder
.
setResourceManager
(
new
JarResourcemanager
(
root
));
}
else
if
(
this
.
resourceLoader
!=
null
)
{
servletBuilder
.
setResourceManager
(
new
ClassPathResourceManager
(
this
.
resourceLoader
.
getClassLoader
(),
""
));
}
else
{
servletBuilder
.
setResourceManager
(
new
ClassPathResourceManager
(
getClass
()
.
getClassLoader
(),
""
));
}
for
(
Mapping
mimeMapping
:
getMimeMappings
())
{
servletBuilder
.
addMimeMapping
(
new
MimeMapping
(
mimeMapping
.
getExtension
(),
mimeMapping
.
getMimeType
()));
}
DeploymentManager
manager
=
defaultContainer
().
addDeployment
(
servletBuilder
);
manager
.
deploy
();
manager
.
getDeployment
().
getSessionManager
()
.
setDefaultSessionTimeout
(
getSessionTimeout
());
return
manager
;
}
private
void
configureErrorPages
(
DeploymentInfo
servletBuilder
)
{
for
(
ErrorPage
errorPage
:
getErrorPages
())
{
if
(
errorPage
.
getStatus
()
!=
null
)
{
io
.
undertow
.
servlet
.
api
.
ErrorPage
undertowErrorpage
=
new
io
.
undertow
.
servlet
.
api
.
ErrorPage
(
errorPage
.
getPath
(),
errorPage
.
getStatusCode
());
servletBuilder
.
addErrorPage
(
undertowErrorpage
);
}
else
if
(
errorPage
.
getException
()
!=
null
)
{
io
.
undertow
.
servlet
.
api
.
ErrorPage
undertowErrorpage
=
new
io
.
undertow
.
servlet
.
api
.
ErrorPage
(
errorPage
.
getPath
(),
errorPage
.
getException
());
servletBuilder
.
addErrorPage
(
undertowErrorpage
);
}
else
{
io
.
undertow
.
servlet
.
api
.
ErrorPage
undertowErrorpage
=
new
io
.
undertow
.
servlet
.
api
.
ErrorPage
(
errorPage
.
getPath
());
servletBuilder
.
addErrorPage
(
undertowErrorpage
);
}
}
}
/**
* Factory method called to create the {@link UndertowEmbeddedServletContainer}.
* Subclasses can override this method to return a different
* {@link UndertowEmbeddedServletContainer} or apply additional processing to the
* {@link Builder} and {@link DeploymentManager} used to bootstrap Undertow
*
* @param builder the builder
* @param manager the deployment manager
* @param port the port that Undertow should listen on
* @return a new {@link UndertowEmbeddedServletContainer} instance
*/
protected
UndertowEmbeddedServletContainer
getUndertowEmbeddedServletContainer
(
Builder
builder
,
DeploymentManager
manager
,
int
port
)
{
return
new
UndertowEmbeddedServletContainer
(
builder
,
manager
,
getContextPath
(),
port
,
port
>=
0
);
}
@Override
public
void
setResourceLoader
(
ResourceLoader
resourceLoader
)
{
this
.
resourceLoader
=
resourceLoader
;
}
public
void
setBufferSize
(
Integer
bufferSize
)
{
this
.
bufferSize
=
bufferSize
;
}
public
void
setBuffersPerRegion
(
Integer
buffersPerRegion
)
{
this
.
buffersPerRegion
=
buffersPerRegion
;
}
public
void
setIoThreads
(
Integer
ioThreads
)
{
this
.
ioThreads
=
ioThreads
;
}
public
void
setWorkerThreads
(
Integer
workerThreads
)
{
this
.
workerThreads
=
workerThreads
;
}
public
void
setDirectBuffers
(
Boolean
directBuffers
)
{
this
.
directBuffers
=
directBuffers
;
}
@Override
public
void
setRegisterJspServlet
(
boolean
registerJspServlet
)
{
Assert
.
isTrue
(!
registerJspServlet
,
"Undertow does not support JSPs"
);
super
.
setRegisterJspServlet
(
registerJspServlet
);
}
private
static
class
JarResourcemanager
implements
ResourceManager
{
private
final
String
jarPath
;
public
JarResourcemanager
(
File
jarFile
)
{
this
(
jarFile
.
getAbsolutePath
());
}
public
JarResourcemanager
(
String
jarPath
)
{
this
.
jarPath
=
jarPath
;
}
@Override
public
void
close
()
throws
IOException
{
// no code
}
@Override
public
Resource
getResource
(
String
path
)
throws
IOException
{
URL
url
=
new
URL
(
"jar:file:"
+
this
.
jarPath
+
"!"
+
path
);
URLResource
resource
=
new
URLResource
(
url
,
url
.
openConnection
(),
path
);
if
(
resource
.
getContentLength
()
<
0
)
{
return
null
;
}
return
resource
;
}
@Override
public
boolean
isResourceChangeListenerSupported
()
{
return
false
;
}
@Override
public
void
registerResourceChangeListener
(
ResourceChangeListener
listener
)
{
throw
UndertowMessages
.
MESSAGES
.
resourceChangeListenerNotSupported
();
}
@Override
public
void
removeResourceChangeListener
(
ResourceChangeListener
listener
)
{
throw
UndertowMessages
.
MESSAGES
.
resourceChangeListenerNotSupported
();
}
}
private
static
class
UndertowSpringServletContextListenerFactory
implements
InstanceFactory
<
UndertowSpringServletContextListener
>
{
private
final
UndertowSpringServletContextListener
listener
;
public
UndertowSpringServletContextListenerFactory
(
UndertowSpringServletContextListener
listener
)
{
this
.
listener
=
listener
;
}
@Override
public
InstanceHandle
<
UndertowSpringServletContextListener
>
createInstance
()
throws
InstantiationException
{
return
new
ImmediateInstanceHandle
<
UndertowSpringServletContextListener
>(
this
.
listener
);
}
}
private
static
class
UndertowSpringServletContextListener
implements
ServletContextListener
{
private
final
ServletContextInitializer
[]
initializers
;
public
UndertowSpringServletContextListener
(
ServletContextInitializer
...
initializers
)
{
this
.
initializers
=
initializers
;
}
@Override
public
void
contextInitialized
(
ServletContextEvent
event
)
{
try
{
for
(
ServletContextInitializer
initializer
:
this
.
initializers
)
{
initializer
.
onStartup
(
event
.
getServletContext
());
}
}
catch
(
ServletException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
@Override
public
void
contextDestroyed
(
ServletContextEvent
sce
)
{
// no code
}
}
}
spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java
View file @
a6e4744c
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
context
.
embedded
.
undertow
;
import
io.undertow.Undertow.Builder
;
import
java.util.Arrays
;
import
org.junit.Test
;
import
org.mockito.InOrder
;
import
org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory
;
import
org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests
;
import
org.springframework.boot.context.embedded.ErrorPage
;
import
org.springframework.boot.context.embedded.ExampleServlet
;
import
org.springframework.boot.context.embedded.ServletRegistrationBean
;
import
org.springframework.http.HttpStatus
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
mockito
.
Matchers
.
anyObject
;
import
static
org
.
mockito
.
Mockito
.
inOrder
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* Tests for {@link UndertowEmbeddedServletContainerFactory} and
* {@link UndertowEmbeddedServletContainer} .
*
* @author Ivan Sopov
* @author Andy Wilkinson
*/
public
class
UndertowEmbeddedServletContainerFactoryTests
extends
AbstractEmbeddedServletContainerFactoryTests
{
@Override
protected
UndertowEmbeddedServletContainerFactory
getFactory
()
{
return
new
UndertowEmbeddedServletContainerFactory
(
0
);
}
@Test
public
void
errorPage404
()
throws
Exception
{
AbstractEmbeddedServletContainerFactory
factory
=
getFactory
();
factory
.
addErrorPages
(
new
ErrorPage
(
HttpStatus
.
NOT_FOUND
,
"/hello"
));
this
.
container
=
factory
.
getEmbeddedServletContainer
(
new
ServletRegistrationBean
(
new
ExampleServlet
(),
"/hello"
));
this
.
container
.
start
();
assertThat
(
getResponse
(
getLocalUrl
(
"/hello"
)),
equalTo
(
"Hello World"
));
assertThat
(
getResponse
(
getLocalUrl
(
"/not-found"
)),
equalTo
(
"Hello World"
));
}
@Test
public
void
setNullUndertowBuilderCustomizersThrows
()
{
UndertowEmbeddedServletContainerFactory
factory
=
getFactory
();
this
.
thrown
.
expect
(
IllegalArgumentException
.
class
);
this
.
thrown
.
expectMessage
(
"undertowBuilderCustomizers must not be null"
);
factory
.
setUndertowBuilderCustomizers
(
null
);
}
@Test
public
void
addNullContextCustomizersThrows
()
{
UndertowEmbeddedServletContainerFactory
factory
=
getFactory
();
this
.
thrown
.
expect
(
IllegalArgumentException
.
class
);
this
.
thrown
.
expectMessage
(
"undertowBuilderCustomizers must not be null"
);
factory
.
addUndertowBuilderCustomizers
((
UndertowBuilderCustomizer
[])
null
);
}
@Test
public
void
builderCustomizers
()
throws
Exception
{
UndertowEmbeddedServletContainerFactory
factory
=
getFactory
();
UndertowBuilderCustomizer
[]
customizers
=
new
UndertowBuilderCustomizer
[
4
];
for
(
int
i
=
0
;
i
<
customizers
.
length
;
i
++)
{
customizers
[
i
]
=
mock
(
UndertowBuilderCustomizer
.
class
);
}
factory
.
setUndertowBuilderCustomizers
(
Arrays
.
asList
(
customizers
[
0
],
customizers
[
1
]));
factory
.
addUndertowBuilderCustomizers
(
customizers
[
2
],
customizers
[
3
]);
this
.
container
=
factory
.
getEmbeddedServletContainer
();
InOrder
ordered
=
inOrder
((
Object
[])
customizers
);
for
(
UndertowBuilderCustomizer
customizer
:
customizers
)
{
ordered
.
verify
(
customizer
).
customize
((
Builder
)
anyObject
());
}
}
}
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
context
.
embedded
.
undertow
;
import
io.undertow.Undertow.Builder
;
import
java.util.Arrays
;
import
org.junit.Test
;
import
org.mockito.InOrder
;
import
org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory
;
import
org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests
;
import
org.springframework.boot.context.embedded.ErrorPage
;
import
org.springframework.boot.context.embedded.ExampleServlet
;
import
org.springframework.boot.context.embedded.ServletRegistrationBean
;
import
org.springframework.http.HttpStatus
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
mockito
.
Matchers
.
anyObject
;
import
static
org
.
mockito
.
Mockito
.
inOrder
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* Tests for {@link UndertowEmbeddedServletContainerFactory} and
* {@link UndertowEmbeddedServletContainer} .
*
* @author Ivan Sopov
* @author Andy Wilkinson
*/
public
class
UndertowEmbeddedServletContainerFactoryTests
extends
AbstractEmbeddedServletContainerFactoryTests
{
@Override
protected
UndertowEmbeddedServletContainerFactory
getFactory
()
{
return
new
UndertowEmbeddedServletContainerFactory
(
0
);
}
@Test
public
void
errorPage404
()
throws
Exception
{
AbstractEmbeddedServletContainerFactory
factory
=
getFactory
();
factory
.
addErrorPages
(
new
ErrorPage
(
HttpStatus
.
NOT_FOUND
,
"/hello"
));
this
.
container
=
factory
.
getEmbeddedServletContainer
(
new
ServletRegistrationBean
(
new
ExampleServlet
(),
"/hello"
));
this
.
container
.
start
();
assertThat
(
getResponse
(
getLocalUrl
(
"/hello"
)),
equalTo
(
"Hello World"
));
assertThat
(
getResponse
(
getLocalUrl
(
"/not-found"
)),
equalTo
(
"Hello World"
));
}
@Test
public
void
setNullUndertowBuilderCustomizersThrows
()
{
UndertowEmbeddedServletContainerFactory
factory
=
getFactory
();
this
.
thrown
.
expect
(
IllegalArgumentException
.
class
);
this
.
thrown
.
expectMessage
(
"undertowBuilderCustomizers must not be null"
);
factory
.
setUndertowBuilderCustomizers
(
null
);
}
@Test
public
void
addNullContextCustomizersThrows
()
{
UndertowEmbeddedServletContainerFactory
factory
=
getFactory
();
this
.
thrown
.
expect
(
IllegalArgumentException
.
class
);
this
.
thrown
.
expectMessage
(
"undertowBuilderCustomizers must not be null"
);
factory
.
addUndertowBuilderCustomizers
((
UndertowBuilderCustomizer
[])
null
);
}
@Test
public
void
builderCustomizers
()
throws
Exception
{
UndertowEmbeddedServletContainerFactory
factory
=
getFactory
();
UndertowBuilderCustomizer
[]
customizers
=
new
UndertowBuilderCustomizer
[
4
];
for
(
int
i
=
0
;
i
<
customizers
.
length
;
i
++)
{
customizers
[
i
]
=
mock
(
UndertowBuilderCustomizer
.
class
);
}
factory
.
setUndertowBuilderCustomizers
(
Arrays
.
asList
(
customizers
[
0
],
customizers
[
1
]));
factory
.
addUndertowBuilderCustomizers
(
customizers
[
2
],
customizers
[
3
]);
this
.
container
=
factory
.
getEmbeddedServletContainer
();
InOrder
ordered
=
inOrder
((
Object
[])
customizers
);
for
(
UndertowBuilderCustomizer
customizer
:
customizers
)
{
ordered
.
verify
(
customizer
).
customize
((
Builder
)
anyObject
());
}
}
}
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