Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-cloud-netflix
Project
Overview
Details
Activity
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
openSource
spring-cloud-netflix
Commits
20da63c2
Commit
20da63c2
authored
Apr 13, 2015
by
Spencer Gibb
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #299 from royclarkson/dashboard-cf-fix
Ignore 'Connection: close' header from stream response
parents
45449cfb
408910e8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
174 additions
and
4 deletions
+174
-4
HystrixDashboardConfiguration.java
...flix/hystrix/dashboard/HystrixDashboardConfiguration.java
+42
-4
HystrixDashboardProperties.java
...netflix/hystrix/dashboard/HystrixDashboardProperties.java
+41
-0
HystrixDashboardConfigurationTests.java
...hystrix/dashboard/HystrixDashboardConfigurationTests.java
+91
-0
No files found.
spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java
View file @
20da63c2
...
@@ -37,10 +37,14 @@ import org.apache.http.impl.client.DefaultHttpClient;
...
@@ -37,10 +37,14 @@ import org.apache.http.impl.client.DefaultHttpClient;
import
org.apache.http.impl.conn.PoolingClientConnectionManager
;
import
org.apache.http.impl.conn.PoolingClientConnectionManager
;
import
org.apache.http.params.HttpConnectionParams
;
import
org.apache.http.params.HttpConnectionParams
;
import
org.apache.http.params.HttpParams
;
import
org.apache.http.params.HttpParams
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration
;
import
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration
;
import
org.springframework.boot.context.embedded.ServletRegistrationBean
;
import
org.springframework.boot.context.embedded.ServletRegistrationBean
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.ui.freemarker.SpringTemplateLoader
;
import
org.springframework.ui.freemarker.SpringTemplateLoader
;
import
org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer
;
import
org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer
;
...
@@ -50,12 +54,16 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
...
@@ -50,12 +54,16 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
*/
*/
@SuppressWarnings
(
"deprecation"
)
@SuppressWarnings
(
"deprecation"
)
@Configuration
@Configuration
@EnableConfigurationProperties
(
HystrixDashboardProperties
.
class
)
public
class
HystrixDashboardConfiguration
{
public
class
HystrixDashboardConfiguration
{
private
static
final
String
DEFAULT_TEMPLATE_LOADER_PATH
=
"classpath:/templates/"
;
private
static
final
String
DEFAULT_TEMPLATE_LOADER_PATH
=
"classpath:/templates/"
;
private
static
final
String
DEFAULT_CHARSET
=
"UTF-8"
;
private
static
final
String
DEFAULT_CHARSET
=
"UTF-8"
;
@Autowired
private
HystrixDashboardProperties
dashboardProperties
;
/**
/**
* Overrides Spring Boot's {@link FreeMarkerAutoConfiguration} to prefer using a
* Overrides Spring Boot's {@link FreeMarkerAutoConfiguration} to prefer using a
* {@link SpringTemplateLoader} instead of the file system. This corrects an issue
* {@link SpringTemplateLoader} instead of the file system. This corrects an issue
...
@@ -74,7 +82,10 @@ public class HystrixDashboardConfiguration {
...
@@ -74,7 +82,10 @@ public class HystrixDashboardConfiguration {
@Bean
@Bean
public
ServletRegistrationBean
proxyStreamServlet
()
{
public
ServletRegistrationBean
proxyStreamServlet
()
{
return
new
ServletRegistrationBean
(
new
ProxyStreamServlet
(),
"/proxy.stream"
);
ProxyStreamServlet
proxyStreamServlet
=
new
ProxyStreamServlet
();
proxyStreamServlet
.
setEnableIgnoreConnectionCloseHeader
(
dashboardProperties
.
isEnableIgnoreConnectionCloseHeader
());
return
new
ServletRegistrationBean
(
proxyStreamServlet
,
"/proxy.stream"
);
}
}
@Bean
@Bean
...
@@ -92,6 +103,15 @@ public class HystrixDashboardConfiguration {
...
@@ -92,6 +103,15 @@ public class HystrixDashboardConfiguration {
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
long
serialVersionUID
=
1L
;
private
static
final
String
CONNECTION_CLOSE_VALUE
=
"close"
;
private
boolean
enableIgnoreConnectionCloseHeader
=
false
;
public
void
setEnableIgnoreConnectionCloseHeader
(
boolean
enableIgnoreConnectionCloseHeader
)
{
this
.
enableIgnoreConnectionCloseHeader
=
enableIgnoreConnectionCloseHeader
;
}
public
ProxyStreamServlet
()
{
public
ProxyStreamServlet
()
{
super
();
super
();
}
}
...
@@ -155,9 +175,7 @@ public class HystrixDashboardConfiguration {
...
@@ -155,9 +175,7 @@ public class HystrixDashboardConfiguration {
is
=
httpResponse
.
getEntity
().
getContent
();
is
=
httpResponse
.
getEntity
().
getContent
();
// set headers
// set headers
for
(
Header
header
:
httpResponse
.
getAllHeaders
())
{
copyHeadersToServletResponse
(
httpResponse
.
getAllHeaders
(),
response
);
response
.
addHeader
(
header
.
getName
(),
header
.
getValue
());
}
// copy data from source to response
// copy data from source to response
OutputStream
os
=
response
.
getOutputStream
();
OutputStream
os
=
response
.
getOutputStream
();
...
@@ -217,6 +235,26 @@ public class HystrixDashboardConfiguration {
...
@@ -217,6 +235,26 @@ public class HystrixDashboardConfiguration {
}
}
}
}
}
}
}
private
void
copyHeadersToServletResponse
(
Header
[]
headers
,
HttpServletResponse
response
)
{
for
(
Header
header
:
headers
)
{
// Some versions of Cloud Foundry (HAProxy) are
// incorrectly setting a "Connection: close" header
// causing the Hystrix dashboard to close the connection
// to the stream
// https://github.com/cloudfoundry/gorouter/issues/71
if
(
this
.
enableIgnoreConnectionCloseHeader
&&
HttpHeaders
.
CONNECTION
.
equalsIgnoreCase
(
header
.
getName
())
&&
CONNECTION_CLOSE_VALUE
.
equalsIgnoreCase
(
header
.
getValue
()))
{
log
.
warn
(
"Ignoring 'Connection: close' header from stream response"
);
}
else
{
response
.
addHeader
(
header
.
getName
(),
header
.
getValue
());
}
}
}
}
private
static
class
ProxyConnectionManager
{
private
static
class
ProxyConnectionManager
{
...
...
spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardProperties.java
0 → 100644
View file @
20da63c2
/*
* Copyright 2013-2015 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
.
cloud
.
netflix
.
hystrix
.
dashboard
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
/**
* @author Roy Clarkson
*/
@ConfigurationProperties
(
"hystrix.dashboard"
)
public
class
HystrixDashboardProperties
{
/**
* Directs the Hystrix dashboard to ignore 'Connection:close' headers if present in
* the Hystrix response stream
*/
private
boolean
enableIgnoreConnectionCloseHeader
=
false
;
public
boolean
isEnableIgnoreConnectionCloseHeader
()
{
return
enableIgnoreConnectionCloseHeader
;
}
public
void
setEnableIgnoreConnectionCloseHeader
(
boolean
enableIgnoreConnectionCloseHeader
)
{
this
.
enableIgnoreConnectionCloseHeader
=
enableIgnoreConnectionCloseHeader
;
}
}
spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfigurationTests.java
0 → 100644
View file @
20da63c2
/*
* Copyright 2013-2015 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
.
cloud
.
netflix
.
hystrix
.
dashboard
;
import
org.apache.http.Header
;
import
org.apache.http.message.BasicHeader
;
import
org.junit.Test
;
import
org.springframework.mock.web.MockHttpServletResponse
;
import
org.springframework.test.util.ReflectionTestUtils
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertThat
;
/**
* @author Roy Clarkson
*/
public
class
HystrixDashboardConfigurationTests
{
@Test
public
void
normal
()
{
MockHttpServletResponse
response
=
new
MockHttpServletResponse
();
Header
[]
headers
=
new
Header
[
1
];
headers
[
0
]
=
new
BasicHeader
(
"Content-Type"
,
"text/proxy.stream"
);
HystrixDashboardConfiguration
.
ProxyStreamServlet
proxyStreamServlet
=
new
HystrixDashboardConfiguration
.
ProxyStreamServlet
();
ReflectionTestUtils
.
invokeMethod
(
proxyStreamServlet
,
"copyHeadersToServletResponse"
,
headers
,
response
);
assertThat
(
response
.
getHeaderNames
().
size
(),
is
(
1
));
assertThat
(
response
.
getHeader
(
"Content-Type"
),
is
(
"text/proxy.stream"
));
}
@Test
public
void
connectionClose
()
{
MockHttpServletResponse
response
=
new
MockHttpServletResponse
();
Header
[]
headers
=
new
Header
[
2
];
headers
[
0
]
=
new
BasicHeader
(
"Content-Type"
,
"text/proxy.stream"
);
headers
[
1
]
=
new
BasicHeader
(
"Connection"
,
"close"
);
HystrixDashboardConfiguration
.
ProxyStreamServlet
proxyStreamServlet
=
new
HystrixDashboardConfiguration
.
ProxyStreamServlet
();
ReflectionTestUtils
.
invokeMethod
(
proxyStreamServlet
,
"copyHeadersToServletResponse"
,
headers
,
response
);
assertThat
(
response
.
getHeaderNames
().
size
(),
is
(
2
));
assertThat
(
response
.
getHeader
(
"Content-Type"
),
is
(
"text/proxy.stream"
));
assertThat
(
response
.
getHeader
(
"Connection"
),
is
(
"close"
));
}
@Test
public
void
ignoreConnectionClose
()
{
MockHttpServletResponse
response
=
new
MockHttpServletResponse
();
Header
[]
headers
=
new
Header
[
2
];
headers
[
0
]
=
new
BasicHeader
(
"Content-Type"
,
"text/proxy.stream"
);
headers
[
1
]
=
new
BasicHeader
(
"Connection"
,
"close"
);
HystrixDashboardConfiguration
.
ProxyStreamServlet
proxyStreamServlet
=
new
HystrixDashboardConfiguration
.
ProxyStreamServlet
();
proxyStreamServlet
.
setEnableIgnoreConnectionCloseHeader
(
true
);
ReflectionTestUtils
.
invokeMethod
(
proxyStreamServlet
,
"copyHeadersToServletResponse"
,
headers
,
response
);
assertThat
(
response
.
getHeaderNames
().
size
(),
is
(
1
));
assertThat
(
response
.
getHeader
(
"Content-Type"
),
is
(
"text/proxy.stream"
));
assertNull
(
response
.
getHeader
(
"Connection"
));
}
@Test
public
void
doNotIgnoreConnectionClose
()
{
MockHttpServletResponse
response
=
new
MockHttpServletResponse
();
Header
[]
headers
=
new
Header
[
2
];
headers
[
0
]
=
new
BasicHeader
(
"Content-Type"
,
"text/proxy.stream"
);
headers
[
1
]
=
new
BasicHeader
(
"Connection"
,
"close"
);
HystrixDashboardConfiguration
.
ProxyStreamServlet
proxyStreamServlet
=
new
HystrixDashboardConfiguration
.
ProxyStreamServlet
();
proxyStreamServlet
.
setEnableIgnoreConnectionCloseHeader
(
false
);
ReflectionTestUtils
.
invokeMethod
(
proxyStreamServlet
,
"copyHeadersToServletResponse"
,
headers
,
response
);
assertThat
(
response
.
getHeaderNames
().
size
(),
is
(
2
));
assertThat
(
response
.
getHeader
(
"Content-Type"
),
is
(
"text/proxy.stream"
));
assertThat
(
response
.
getHeader
(
"Connection"
),
is
(
"close"
));
}
}
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