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
5f250800
Commit
5f250800
authored
Jun 29, 2015
by
Ivan Sopov
Committed by
Phillip Webb
Jul 10, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add HTTP compression excludeUserAgents property
Closes gh-3363
parent
5e243b28
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
85 additions
and
25 deletions
+85
-25
appendix-application-properties.adoc
...cs/src/main/asciidoc/appendix-application-properties.adoc
+1
-0
Compression.java
...rg/springframework/boot/context/embedded/Compression.java
+13
-1
JettyEmbeddedServletContainerFactory.java
.../embedded/jetty/JettyEmbeddedServletContainerFactory.java
+15
-0
TomcatEmbeddedServletContainerFactory.java
...mbedded/tomcat/TomcatEmbeddedServletContainerFactory.java
+5
-0
UndertowEmbeddedServletContainer.java
...t/embedded/undertow/UndertowEmbeddedServletContainer.java
+26
-13
AbstractEmbeddedServletContainerFactoryTests.java
...mbedded/AbstractEmbeddedServletContainerFactoryTests.java
+20
-9
JettyEmbeddedServletContainerFactoryTests.java
...dded/jetty/JettyEmbeddedServletContainerFactoryTests.java
+5
-2
No files found.
spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
View file @
5f250800
...
@@ -68,6 +68,7 @@ content into your application; rather pick only the properties that you need.
...
@@ -68,6 +68,7 @@ content into your application; rather pick only the properties that you need.
server.port=8080
server.port=8080
server.address= # bind to a specific NIC
server.address= # bind to a specific NIC
server.compression.enabled=false # if response compression is enabled
server.compression.enabled=false # if response compression is enabled
server.compression.exclude-user-agents= # list of user-agents to exclude from compression
server.compression.mime-types=text/html,text/xml,text/plain,text/css # comma-separated list of MIME types that should be compressed
server.compression.mime-types=text/html,text/xml,text/plain,text/css # comma-separated list of MIME types that should be compressed
server.compression.min-response-size=2048 # minimum response size that is required for compression to be performed
server.compression.min-response-size=2048 # minimum response size that is required for compression to be performed
server.context-parameters.*= # Servlet context init parameters, e.g. server.context-parameters.a=alpha
server.context-parameters.*= # Servlet context init parameters, e.g. server.context-parameters.a=alpha
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/Compression.java
View file @
5f250800
...
@@ -37,7 +37,12 @@ public class Compression {
...
@@ -37,7 +37,12 @@ public class Compression {
"text/css"
};
"text/css"
};
/**
/**
* Minimum response size that is required for compression to be performed
* Comma-separated list of user agents for which responses should not be compressed.
*/
private
String
[]
excludedUserAgents
=
null
;
/**
* Minimum response size that is required for compression to be performed.
*/
*/
private
int
minResponseSize
=
2048
;
private
int
minResponseSize
=
2048
;
...
@@ -65,4 +70,11 @@ public class Compression {
...
@@ -65,4 +70,11 @@ public class Compression {
this
.
minResponseSize
=
minSize
;
this
.
minResponseSize
=
minSize
;
}
}
public
String
[]
getExcludedUserAgents
()
{
return
this
.
excludedUserAgents
;
}
public
void
setExcludedUserAgents
(
String
[]
excludedUserAgents
)
{
this
.
excludedUserAgents
=
excludedUserAgents
;
}
}
}
spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java
View file @
5f250800
...
@@ -588,6 +588,12 @@ public class JettyEmbeddedServletContainerFactory extends
...
@@ -588,6 +588,12 @@ public class JettyEmbeddedServletContainerFactory extends
.
invoke
(
handler
,
.
invoke
(
handler
,
new
HashSet
<
String
>(
Arrays
.
asList
(
compression
new
HashSet
<
String
>(
Arrays
.
asList
(
compression
.
getMimeTypes
())));
.
getMimeTypes
())));
if
(
compression
.
getExcludedUserAgents
()
!=
null
)
{
ReflectionUtils
.
findMethod
(
handlerClass
,
"setExcluded"
,
Set
.
class
)
.
invoke
(
handler
,
new
HashSet
<
String
>(
Arrays
.
asList
(
compression
.
getExcludedUserAgents
())));
}
return
handler
;
return
handler
;
}
}
catch
(
Exception
ex
)
{
catch
(
Exception
ex
)
{
...
@@ -605,6 +611,10 @@ public class JettyEmbeddedServletContainerFactory extends
...
@@ -605,6 +611,10 @@ public class JettyEmbeddedServletContainerFactory extends
gzipHandler
.
setMinGzipSize
(
compression
.
getMinResponseSize
());
gzipHandler
.
setMinGzipSize
(
compression
.
getMinResponseSize
());
gzipHandler
.
setMimeTypes
(
new
HashSet
<
String
>(
Arrays
.
asList
(
compression
gzipHandler
.
setMimeTypes
(
new
HashSet
<
String
>(
Arrays
.
asList
(
compression
.
getMimeTypes
())));
.
getMimeTypes
())));
if
(
compression
.
getExcludedUserAgents
()
!=
null
)
{
gzipHandler
.
setExcluded
(
new
HashSet
<
String
>(
Arrays
.
asList
(
compression
.
getExcludedUserAgents
())));
}
return
gzipHandler
;
return
gzipHandler
;
}
}
...
@@ -623,6 +633,11 @@ public class JettyEmbeddedServletContainerFactory extends
...
@@ -623,6 +633,11 @@ public class JettyEmbeddedServletContainerFactory extends
ReflectionUtils
.
findMethod
(
handlerClass
,
"setIncludedMimeTypes"
,
ReflectionUtils
.
findMethod
(
handlerClass
,
"setIncludedMimeTypes"
,
String
[].
class
).
invoke
(
handler
,
String
[].
class
).
invoke
(
handler
,
new
Object
[]
{
compression
.
getMimeTypes
()
});
new
Object
[]
{
compression
.
getMimeTypes
()
});
if
(
compression
.
getExcludedUserAgents
()
!=
null
)
{
ReflectionUtils
.
findMethod
(
handlerClass
,
"setExcludedAgentPatterns"
,
String
[].
class
).
invoke
(
handler
,
new
Object
[]
{
compression
.
getExcludedUserAgents
()
});
}
return
handler
;
return
handler
;
}
}
catch
(
Exception
ex
)
{
catch
(
Exception
ex
)
{
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java
View file @
5f250800
...
@@ -280,6 +280,11 @@ public class TomcatEmbeddedServletContainerFactory extends
...
@@ -280,6 +280,11 @@ public class TomcatEmbeddedServletContainerFactory extends
protocol
.
setCompressionMinSize
(
compression
.
getMinResponseSize
());
protocol
.
setCompressionMinSize
(
compression
.
getMinResponseSize
());
protocol
.
setCompressableMimeTypes
(
StringUtils
protocol
.
setCompressableMimeTypes
(
StringUtils
.
arrayToCommaDelimitedString
(
compression
.
getMimeTypes
()));
.
arrayToCommaDelimitedString
(
compression
.
getMimeTypes
()));
if
(
getCompression
().
getExcludedUserAgents
()
!=
null
)
{
protocol
.
setNoCompressionUserAgents
(
StringUtils
.
arrayToCommaDelimitedString
(
getCompression
()
.
getExcludedUserAgents
()));
}
}
}
}
}
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java
View file @
5f250800
...
@@ -19,6 +19,7 @@ package org.springframework.boot.context.embedded.undertow;
...
@@ -19,6 +19,7 @@ package org.springframework.boot.context.embedded.undertow;
import
io.undertow.Handlers
;
import
io.undertow.Handlers
;
import
io.undertow.Undertow
;
import
io.undertow.Undertow
;
import
io.undertow.Undertow.Builder
;
import
io.undertow.Undertow.Builder
;
import
io.undertow.attribute.RequestHeaderAttribute
;
import
io.undertow.predicate.Predicate
;
import
io.undertow.predicate.Predicate
;
import
io.undertow.predicate.Predicates
;
import
io.undertow.predicate.Predicates
;
import
io.undertow.server.HttpHandler
;
import
io.undertow.server.HttpHandler
;
...
@@ -27,6 +28,7 @@ import io.undertow.server.handlers.encoding.ContentEncodingRepository;
...
@@ -27,6 +28,7 @@ import io.undertow.server.handlers.encoding.ContentEncodingRepository;
import
io.undertow.server.handlers.encoding.EncodingHandler
;
import
io.undertow.server.handlers.encoding.EncodingHandler
;
import
io.undertow.server.handlers.encoding.GzipEncodingProvider
;
import
io.undertow.server.handlers.encoding.GzipEncodingProvider
;
import
io.undertow.servlet.api.DeploymentManager
;
import
io.undertow.servlet.api.DeploymentManager
;
import
io.undertow.util.HttpString
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Field
;
import
java.net.ServerSocket
;
import
java.net.ServerSocket
;
...
@@ -100,8 +102,8 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine
...
@@ -100,8 +102,8 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine
private
Undertow
createUndertowServer
()
{
private
Undertow
createUndertowServer
()
{
try
{
try
{
HttpHandler
servlet
Handler
=
this
.
manager
.
start
();
HttpHandler
http
Handler
=
this
.
manager
.
start
();
this
.
builder
.
setHandler
(
getContextHandler
(
servlet
Handler
));
this
.
builder
.
setHandler
(
getContextHandler
(
http
Handler
));
return
this
.
builder
.
build
();
return
this
.
builder
.
build
();
}
}
catch
(
ServletException
ex
)
{
catch
(
ServletException
ex
)
{
...
@@ -110,25 +112,36 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine
...
@@ -110,25 +112,36 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine
}
}
}
}
private
HttpHandler
getContextHandler
(
HttpHandler
servlet
Handler
)
{
private
HttpHandler
getContextHandler
(
HttpHandler
http
Handler
)
{
HttpHandler
contextHandler
=
configurationCompressionIfNecessary
(
servlet
Handler
);
HttpHandler
contextHandler
=
configurationCompressionIfNecessary
(
http
Handler
);
if
(
StringUtils
.
isEmpty
(
this
.
contextPath
))
{
if
(
StringUtils
.
isEmpty
(
this
.
contextPath
))
{
return
contextHandler
;
return
contextHandler
;
}
}
return
Handlers
.
path
().
addPrefixPath
(
this
.
contextPath
,
contextHandler
);
return
Handlers
.
path
().
addPrefixPath
(
this
.
contextPath
,
contextHandler
);
}
}
private
HttpHandler
configurationCompressionIfNecessary
(
HttpHandler
servlet
Handler
)
{
private
HttpHandler
configurationCompressionIfNecessary
(
HttpHandler
http
Handler
)
{
if
(
this
.
compression
==
null
||
!
this
.
compression
.
getEnabled
())
{
if
(
this
.
compression
==
null
||
!
this
.
compression
.
getEnabled
())
{
return
servlet
Handler
;
return
http
Handler
;
}
}
ContentEncodingRepository
encodingRepository
=
new
ContentEncodingRepository
();
ContentEncodingRepository
repository
=
new
ContentEncodingRepository
();
Predicate
mimeAndSizePredicate
=
Predicates
.
and
(
Predicates
repository
.
addEncodingHandler
(
"gzip"
,
new
GzipEncodingProvider
(),
50
,
.
maxContentSize
(
this
.
compression
.
getMinResponseSize
()),
Predicates
Predicates
.
and
(
getCompressionPredicates
(
this
.
compression
)));
.
or
(
new
CompressibleMimeTypePredicate
(
this
.
compression
.
getMimeTypes
())));
return
new
EncodingHandler
(
repository
).
setNext
(
httpHandler
);
encodingRepository
.
addEncodingHandler
(
"gzip"
,
new
GzipEncodingProvider
(),
50
,
}
mimeAndSizePredicate
);
return
new
EncodingHandler
(
encodingRepository
).
setNext
(
servletHandler
);
private
Predicate
[]
getCompressionPredicates
(
Compression
compression
)
{
List
<
Predicate
>
predicates
=
new
ArrayList
<
Predicate
>();
predicates
.
add
(
Predicates
.
maxContentSize
(
compression
.
getMinResponseSize
()));
predicates
.
add
(
new
CompressibleMimeTypePredicate
(
compression
.
getMimeTypes
()));
if
(
compression
.
getExcludedUserAgents
()
!=
null
)
{
for
(
String
agent
:
compression
.
getExcludedUserAgents
())
{
RequestHeaderAttribute
agentHeader
=
new
RequestHeaderAttribute
(
new
HttpString
(
HttpHeaders
.
USER_AGENT
));
predicates
.
add
(
Predicates
.
not
(
Predicates
.
regex
(
agentHeader
,
agent
)));
}
}
return
predicates
.
toArray
(
new
Predicate
[
predicates
.
size
()]);
}
}
private
String
getPortsDescription
()
{
private
String
getPortsDescription
()
{
...
...
spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java
View file @
5f250800
...
@@ -531,35 +531,43 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
...
@@ -531,35 +531,43 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
@Test
@Test
public
void
compression
()
throws
Exception
{
public
void
compression
()
throws
Exception
{
assertTrue
(
doTestCompression
(
10000
,
null
));
assertTrue
(
doTestCompression
(
10000
,
null
,
null
));
}
}
@Test
@Test
public
void
noCompressionForSmallResponse
()
throws
Exception
{
public
void
noCompressionForSmallResponse
()
throws
Exception
{
assertFalse
(
doTestCompression
(
100
,
null
));
assertFalse
(
doTestCompression
(
100
,
null
,
null
));
}
}
@Test
@Test
public
void
noCompressionForMimeType
()
throws
Exception
{
public
void
noCompressionForMimeType
()
throws
Exception
{
String
[]
mimeTypes
=
new
String
[]
{
"text/html"
,
"text/xml"
,
"text/css"
};
String
[]
mimeTypes
=
new
String
[]
{
"text/html"
,
"text/xml"
,
"text/css"
};
assertFalse
(
doTestCompression
(
10000
,
mimeTypes
));
assertFalse
(
doTestCompression
(
10000
,
mimeTypes
,
null
));
}
}
private
boolean
doTestCompression
(
int
contentSize
,
String
[]
mimeTypes
)
@Test
throws
Exception
{
public
void
noCompressionForUserAgent
()
throws
Exception
{
String
testContent
=
setUpFactoryForCompression
(
contentSize
,
mimeTypes
);
assertFalse
(
doTestCompression
(
10000
,
null
,
new
String
[]
{
"testUserAgent"
}));
}
private
boolean
doTestCompression
(
int
contentSize
,
String
[]
mimeTypes
,
String
[]
excludedUserAgents
)
throws
Exception
{
String
testContent
=
setUpFactoryForCompression
(
contentSize
,
mimeTypes
,
excludedUserAgents
);
TestGzipInputStreamFactory
inputStreamFactory
=
new
TestGzipInputStreamFactory
();
TestGzipInputStreamFactory
inputStreamFactory
=
new
TestGzipInputStreamFactory
();
Map
<
String
,
InputStreamFactory
>
contentDecoderMap
=
singletonMap
(
"gzip"
,
Map
<
String
,
InputStreamFactory
>
contentDecoderMap
=
singletonMap
(
"gzip"
,
(
InputStreamFactory
)
inputStreamFactory
);
(
InputStreamFactory
)
inputStreamFactory
);
String
response
=
getResponse
(
getLocalUrl
(
"/test.txt"
),
String
response
=
getResponse
(
getLocalUrl
(
"/test.txt"
),
new
HttpComponentsClientHttpRequestFactory
(
HttpClientBuilder
.
create
()
new
HttpComponentsClientHttpRequestFactory
(
HttpClientBuilder
.
create
()
.
setUserAgent
(
"testUserAgent"
)
.
setContentDecoderRegistry
(
contentDecoderMap
).
build
()));
.
setContentDecoderRegistry
(
contentDecoderMap
).
build
()));
assertThat
(
response
,
equalTo
(
testContent
));
assertThat
(
response
,
equalTo
(
testContent
));
return
inputStreamFactory
.
wasCompressionUsed
();
return
inputStreamFactory
.
wasCompressionUsed
();
}
}
protected
String
setUpFactoryForCompression
(
int
contentSize
,
String
[]
mimeTypes
)
protected
String
setUpFactoryForCompression
(
int
contentSize
,
String
[]
mimeTypes
,
throws
Exception
{
String
[]
excludedUserAgents
)
throws
Exception
{
char
[]
chars
=
new
char
[
contentSize
];
char
[]
chars
=
new
char
[
contentSize
];
Arrays
.
fill
(
chars
,
'F'
);
Arrays
.
fill
(
chars
,
'F'
);
String
testContent
=
new
String
(
chars
);
String
testContent
=
new
String
(
chars
);
...
@@ -572,6 +580,9 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
...
@@ -572,6 +580,9 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
if
(
mimeTypes
!=
null
)
{
if
(
mimeTypes
!=
null
)
{
compression
.
setMimeTypes
(
mimeTypes
);
compression
.
setMimeTypes
(
mimeTypes
);
}
}
if
(
excludedUserAgents
!=
null
)
{
compression
.
setExcludedUserAgents
(
excludedUserAgents
);
}
factory
.
setCompression
(
compression
);
factory
.
setCompression
(
compression
);
this
.
container
=
factory
.
getEmbeddedServletContainer
();
this
.
container
=
factory
.
getEmbeddedServletContainer
();
this
.
container
.
start
();
this
.
container
.
start
();
...
...
spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java
View file @
5f250800
...
@@ -186,8 +186,8 @@ public class JettyEmbeddedServletContainerFactoryTests extends
...
@@ -186,8 +186,8 @@ public class JettyEmbeddedServletContainerFactoryTests extends
@Override
@Override
@SuppressWarnings
(
"serial"
)
@SuppressWarnings
(
"serial"
)
// Workaround for Jetty issue - https://bugs.eclipse.org/bugs/show_bug.cgi?id=470646
// Workaround for Jetty issue - https://bugs.eclipse.org/bugs/show_bug.cgi?id=470646
protected
String
setUpFactoryForCompression
(
final
int
contentSize
,
String
[]
mimeTypes
)
protected
String
setUpFactoryForCompression
(
final
int
contentSize
,
throws
Exception
{
String
[]
mimeTypes
,
String
[]
excludedUserAgents
)
throws
Exception
{
char
[]
chars
=
new
char
[
contentSize
];
char
[]
chars
=
new
char
[
contentSize
];
Arrays
.
fill
(
chars
,
'F'
);
Arrays
.
fill
(
chars
,
'F'
);
final
String
testContent
=
new
String
(
chars
);
final
String
testContent
=
new
String
(
chars
);
...
@@ -197,6 +197,9 @@ public class JettyEmbeddedServletContainerFactoryTests extends
...
@@ -197,6 +197,9 @@ public class JettyEmbeddedServletContainerFactoryTests extends
if
(
mimeTypes
!=
null
)
{
if
(
mimeTypes
!=
null
)
{
compression
.
setMimeTypes
(
mimeTypes
);
compression
.
setMimeTypes
(
mimeTypes
);
}
}
if
(
excludedUserAgents
!=
null
)
{
compression
.
setExcludedUserAgents
(
excludedUserAgents
);
}
factory
.
setCompression
(
compression
);
factory
.
setCompression
(
compression
);
this
.
container
=
factory
.
getEmbeddedServletContainer
(
new
ServletRegistrationBean
(
this
.
container
=
factory
.
getEmbeddedServletContainer
(
new
ServletRegistrationBean
(
new
HttpServlet
()
{
new
HttpServlet
()
{
...
...
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