Skip to content

Commit 5f6fcdf

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 4c6ab96 + 6bb4ff0 commit 5f6fcdf

File tree

6 files changed

+107
-5
lines changed

6 files changed

+107
-5
lines changed

actions/reconfigure.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,18 @@ func (m *Reconfigure) getHeaders(sr *proxy.Service) string {
330330
header,
331331
)
332332
}
333+
for _, header := range sr.DelReqHeader {
334+
tmpl += fmt.Sprintf(`
335+
http-request del-header %s`,
336+
header,
337+
)
338+
}
339+
for _, header := range sr.DelResHeader {
340+
tmpl += fmt.Sprintf(`
341+
http-response del-header %s`,
342+
header,
343+
)
344+
}
333345
return tmpl
334346
}
335347

actions/reconfigure_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,70 @@ backend %s-be%s
756756
s.Equal(expectedData, actualData)
757757
}
758758

759+
func (s ReconfigureTestSuite) Test_Execute_DelReqHeader_WhenDelReqHeaderIsSet() {
760+
s.reconfigure.Mode = "swarm"
761+
s.reconfigure.DelReqHeader = []string{"header-1", "header-2"}
762+
var actualFilename, actualData string
763+
expectedFilename := fmt.Sprintf("%s/%s-be.cfg", s.TemplatesPath, s.ServiceName)
764+
expectedData := fmt.Sprintf(
765+
`
766+
backend %s-be%s
767+
mode http
768+
http-request del-header header-1
769+
http-request del-header header-2
770+
server %s %s:%s`,
771+
s.ServiceName,
772+
s.reconfigure.ServiceDest[0].Port,
773+
s.ServiceName,
774+
s.ServiceName,
775+
s.reconfigure.ServiceDest[0].Port,
776+
)
777+
writeBeTemplateOrig := writeBeTemplate
778+
defer func() { writeBeTemplate = writeBeTemplateOrig }()
779+
writeBeTemplate = func(filename string, data []byte, perm os.FileMode) error {
780+
actualFilename = filename
781+
actualData = string(data)
782+
return nil
783+
}
784+
785+
s.reconfigure.Execute(true)
786+
787+
s.Equal(expectedFilename, actualFilename)
788+
s.Equal(expectedData, actualData)
789+
}
790+
791+
func (s ReconfigureTestSuite) Test_Execute_DelResHeader_WhenDelResHeaderIsSet() {
792+
s.reconfigure.Mode = "swarm"
793+
s.reconfigure.DelResHeader = []string{"header-1", "header-2"}
794+
var actualFilename, actualData string
795+
expectedFilename := fmt.Sprintf("%s/%s-be.cfg", s.TemplatesPath, s.ServiceName)
796+
expectedData := fmt.Sprintf(
797+
`
798+
backend %s-be%s
799+
mode http
800+
http-response del-header header-1
801+
http-response del-header header-2
802+
server %s %s:%s`,
803+
s.ServiceName,
804+
s.reconfigure.ServiceDest[0].Port,
805+
s.ServiceName,
806+
s.ServiceName,
807+
s.reconfigure.ServiceDest[0].Port,
808+
)
809+
writeBeTemplateOrig := writeBeTemplate
810+
defer func() { writeBeTemplate = writeBeTemplateOrig }()
811+
writeBeTemplate = func(filename string, data []byte, perm os.FileMode) error {
812+
actualFilename = filename
813+
actualData = string(data)
814+
return nil
815+
}
816+
817+
s.reconfigure.Execute(true)
818+
819+
s.Equal(expectedFilename, actualFilename)
820+
s.Equal(expectedData, actualData)
821+
}
822+
759823
func (s ReconfigureTestSuite) Test_Execute_DoesNotInvokeRegistrarableCreateConfigs_WhenModeIsService() {
760824
mockObj := getRegistrarableMock("")
761825
registryInstanceOrig := registryInstance

docs/usage.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ The following query parameters can be used to send a *reconfigure* request to *D
1515
|Query |Description |Required|Default|
1616
|---------------|------------------------------------------------------------------------------------------|--------|-------|
1717
|aclName |ACLs are ordered alphabetically by their names. If not specified, serviceName is used instead.<br>Example: `05-go-demo-acl`|No | |
18-
|addReqHeader |Additional headers that will be added to the request before forwarding it to the service. Multiple headers should be separated with comma (`,`). Please consult [Add a header to the request](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#add-a-header-to-the-request) for more info.<br>Example: `X-Forwarded-Port %[dst_port],X-Forwarded-Ssl on if { ssl_fc }`|No| |
19-
|addResHeader |Additional headers that will be added to the response before forwarding it to the client. Multiple headers should be separated with comma (`,`). Please consult [Add a header to the response](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#rewriting-http-responses) for more info.<br>Example: `X-Via %[env(HOSTNAME)],Server haproxy`|No| |
18+
|addReqHeader |Additional headers that will be added to the request before forwarding it to the service. Multiple headers should be separated with comma (`,`). Please consult [Add a header to the request](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#add-a-header-to-the-request) for more info.<br>Example: `X-Forwarded-Port %[dst_port],X-Forwarded-Ssl on if { ssl_fc }`|No| |
19+
|addResHeader |Additional headers that will be added to the response before forwarding it to the client. Multiple headers should be separated with comma (`,`). Please consult [Add a header to the response](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#rewriting-http-responses) for more info.<br>Example: `X-Via %[env(HOSTNAME)],Server haproxy`|No| |
2020
|connectionMode |HAProxy supports 5 connection modes.<br><br>`http-keep-alive`: all requests and responses are processed.<br>`http-tunnel`: only the first request and response are processed, everything else is forwarded with no analysis.<br>`httpclose`: tunnel with "Connection: close" added in both directions.<br>`http-server-close`: the server-facing connection is closed after the response.<br>`forceclose`: the connection is actively closed after end of response.<br><br>In general, it is preferred to use `http-server-close` with application servers, and some static servers might benefit from `http-keep-alive`.<br>Connection mode is restricted to HTTP mode only. If specified, connection mode will be applied to the backend section.<br>Example: http-keep-alive|No| |
21+
|delReqHeader |Additional headers that will be deleted in the request before forwarding it to the service. Multiple headers should be separated with comma (`,`). Please consult [Delete a header in the request](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#delete-a-header-in-the-request) for more info.<br>Example: `X-Forwarded-For,Cookie`|No| |
22+
|delResHeader |Additional headers that will be deleted in the response before forwarding it to the client. Multiple headers should be separated with comma (`,`). Please consult [Delete a header in the response](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#delete-a-header-in-the-response) for more info.<br>Example: `X-Varnish,X-Cache`|No| |
2123
|httpsPort |The internal HTTPS port of a service that should be reconfigured. The port is used only in the `swarm` mode. If not specified, the `port` parameter will be used instead.<br>Example: `443`|No| |
2224
|port |The internal port of a service that should be reconfigured. The port is used only in the `swarm` mode. The parameter can be prefixed with an index thus allowing definition of multiple destinations for a single service (e.g. `port.1`, `port.2`, and so on).<br>Example: `8080`|Only in `swarm` mode.| |
2325
|reqMode |The request mode. The proxy should be able to work with any mode supported by HAProxy. However, actively supported and tested modes are `http`, `tcp`, and `sni`. The `sni` mode implies TCP with an SNI-based routing.<br>Example: `tcp`|No|http|
@@ -26,8 +28,8 @@ The following query parameters can be used to send a *reconfigure* request to *D
2628
|serviceDomain |The domain of the service. If set, the proxy will allow access only to requests coming to that domain. Multiple domains should be separated with comma (`,`).**This parameter cannot be used with TCP.**<br>Example: ecme.com|No| |
2729
|serviceDomainMatchAll|Whether to include subdomains and FDQN domains in the match. If set to false, and, for example, `serviceDomain` is set to `acme.com`, `something.acme.com` would not be considered a match unless this parameter is set to `true`. If this option is used, it is recommended to put any subdomains higher in the list using `aclName`.<br>Example: `true`|No|false|
2830
|serviceName |The name of the service. It must match the name of the Swarm service.<br>Example: `go-demo`|Yes| |
29-
|setReqHeader |Additional headers that will be set to the request before forwarding it to the service. If a specified header exists, it will be replaced with the new one. Multiple headers should be separated with comma (`,`). Please consult [Set a header to the request](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#set-a-header-in-the-request) for more info.<br>Example: `X-Forwarded-Port %[dst_port],X-Forwarded-Ssl on if { ssl_fc }`|No| |
30-
|setResHeader |Additional headers that will be set to the response before forwarding it to the client. If a specified header exists, it will be replaced with the new one. Multiple headers should be separated with comma (`,`). Please consult [Set a header to the response](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#set-a-header-in-the-response) for more info.<br>Example: `X-Via %[env(HOSTNAME)],Server haproxy`|No| |
31+
|setReqHeader |Additional headers that will be set to the request before forwarding it to the service. If a specified header exists, it will be replaced with the new one. Multiple headers should be separated with comma (`,`). Please consult [Set a header to the request](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#set-a-header-in-the-request) for more info.<br>Example: `X-Forwarded-Port %[dst_port],X-Forwarded-Ssl on if { ssl_fc }`|No| |
32+
|setResHeader |Additional headers that will be set to the response before forwarding it to the client. If a specified header exists, it will be replaced with the new one. Multiple headers should be separated with comma (`,`). Please consult [Set a header to the response](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#set-a-header-in-the-response) for more info.<br>Example: `X-Via %[env(HOSTNAME)],Server haproxy`|No| |
3133
|srcPort |The source (entry) port of a service. Useful only when specifying multiple destinations of a single service. The parameter can be prefixed with an index thus allowing definition of multiple destinations for a single service (e.g. `srcPort.1`, `srcPort.2`, and so on).<br>Example: `80`|No| |
3234
|timeoutServer |The server timeout in seconds.<br>Example: `60` |No |20 |
3335
|timeoutTunnel |The tunnel timeout in seconds.<br>Example: `3600` |No |3600 |

proxy/types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ type Service struct {
5050
// The path to the Consul Template representing a snippet of the frontend configuration.
5151
// If specified, proxy template will be loaded from the specified file.
5252
ConsulTemplateFePath string `split_words:"true"`
53+
// Additional headers that will be deleted in the request before forwarding it to the service. Please consult https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#delete-a-header-in-the-request for more info.
54+
DelReqHeader []string `split_words:"true"`
55+
// Additional headers that will be deleted in the response before forwarding it to the client. Please consult https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#delete-a-header-in-the-response for more info.
56+
DelResHeader []string `split_words:"true"`
5357
// Whether to distribute a request to all the instances of the proxy.
5458
// Used only in the swarm mode.
5559
Distribute bool `split_words:"true"`
@@ -285,12 +289,18 @@ func GetServiceFromProvider(provider ServiceParameterProvider) *Service {
285289
} else if len(provider.GetString("setHeader")) > 0 { // TODO: Deprecated since Apr. 2017.
286290
sr.SetReqHeader = strings.Split(provider.GetString("setHeader"), ",")
287291
}
292+
if len(provider.GetString("delReqHeader")) > 0 {
293+
sr.DelReqHeader = strings.Split(provider.GetString("delReqHeader"), ",")
294+
}
288295
if len(provider.GetString("addResHeader")) > 0 {
289296
sr.AddResHeader = strings.Split(provider.GetString("addResHeader"), ",")
290297
}
291298
if len(provider.GetString("setResHeader")) > 0 {
292299
sr.SetResHeader = strings.Split(provider.GetString("setResHeader"), ",")
293300
}
301+
if len(provider.GetString("delResHeader")) > 0 {
302+
sr.DelResHeader = strings.Split(provider.GetString("delResHeader"), ",")
303+
}
294304
globalUsersString := GetSecretOrEnvVar("USERS", "")
295305
globalUsersEncrypted := strings.EqualFold(GetSecretOrEnvVar("USERS_PASS_ENCRYPTED", ""), "true")
296306
sr.Users = mergeUsers(

proxy/types_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ func (s *TypesTestSuite) Test_GetServiceFromMap_ReturnsProxyService() {
172172
AddResHeader: []string{"add-header-1", "add-header-2"},
173173
ConsulTemplateFePath: "consulTemplateFePath",
174174
ConsulTemplateBePath: "consulTemplateBePath",
175+
DelReqHeader: []string{"del-header-1", "del-header-2"},
176+
DelResHeader: []string{"del-header-1", "del-header-2"},
175177
Distribute: true,
176178
HttpsOnly: true,
177179
HttpsPort: 1234,
@@ -230,6 +232,8 @@ func (s *TypesTestSuite) Test_GetServiceFromMap_ReturnsProxyService() {
230232
"addResHeader": strings.Join(expected.AddResHeader, ","),
231233
"setReqHeader": strings.Join(expected.SetReqHeader, ","),
232234
"setResHeader": strings.Join(expected.SetResHeader, ","),
235+
"delReqHeader": strings.Join(expected.DelReqHeader, ","),
236+
"delResHeader": strings.Join(expected.DelResHeader, ","),
233237
"port": expected.ServiceDest[0].Port,
234238
"servicePath": strings.Join(expected.ServiceDest[0].ServicePath, ","),
235239
}

server/server_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,8 @@ func (s *ServerTestSuite) Test_GetServiceFromUrl_ReturnsProxyService() {
606606
ConnectionMode: "my-connection-mode",
607607
ConsulTemplateFePath: "consulTemplateFePath",
608608
ConsulTemplateBePath: "consulTemplateBePath",
609+
DelReqHeader: []string{"add-header-1", "add-header-2"},
610+
DelResHeader: []string{"add-header-1", "add-header-2"},
609611
Distribute: true,
610612
HttpsOnly: true,
611613
HttpsPort: 1234,
@@ -634,7 +636,7 @@ func (s *ServerTestSuite) Test_GetServiceFromUrl_ReturnsProxyService() {
634636
{Username: "user2", Password: "pass2", PassEncrypted: true}},
635637
}
636638
addr := fmt.Sprintf(
637-
"%s?serviceName=%s&users=%s&usersPassEncrypted=%t&aclName=%s&serviceColor=%s&serviceCert=%s&outboundHostname=%s&consulTemplateFePath=%s&consulTemplateBePath=%s&pathType=%s&reqPathSearch=%s&reqPathReplace=%s&templateFePath=%s&templateBePath=%s&timeoutServer=%s&timeoutTunnel=%s&reqMode=%s&httpsOnly=%t&xForwardedProto=%t&redirectWhenHttpProto=%t&httpsPort=%d&serviceDomain=%s&skipCheck=%t&distribute=%t&sslVerifyNone=%t&serviceDomainMatchAll=%t&addReqHeader=%s&addResHeader=%s&setReqHeader=%s&setResHeader=%s&servicePath=/&port=1234&connectionMode=%s",
639+
"%s?serviceName=%s&users=%s&usersPassEncrypted=%t&aclName=%s&serviceColor=%s&serviceCert=%s&outboundHostname=%s&consulTemplateFePath=%s&consulTemplateBePath=%s&pathType=%s&reqPathSearch=%s&reqPathReplace=%s&templateFePath=%s&templateBePath=%s&timeoutServer=%s&timeoutTunnel=%s&reqMode=%s&httpsOnly=%t&xForwardedProto=%t&redirectWhenHttpProto=%t&httpsPort=%d&serviceDomain=%s&skipCheck=%t&distribute=%t&sslVerifyNone=%t&serviceDomainMatchAll=%t&addReqHeader=%s&addResHeader=%s&setReqHeader=%s&setResHeader=%s&delReqHeader=%s&delResHeader=%s&servicePath=/&port=1234&connectionMode=%s",
638640
s.BaseUrl,
639641
expected.ServiceName,
640642
"user1:pass1,user2:pass2",
@@ -666,6 +668,8 @@ func (s *ServerTestSuite) Test_GetServiceFromUrl_ReturnsProxyService() {
666668
strings.Join(expected.AddResHeader, ","),
667669
strings.Join(expected.SetReqHeader, ","),
668670
strings.Join(expected.SetResHeader, ","),
671+
strings.Join(expected.DelReqHeader, ","),
672+
strings.Join(expected.DelResHeader, ","),
669673
expected.ConnectionMode,
670674
)
671675
req, _ := http.NewRequest("GET", addr, nil)
@@ -719,6 +723,8 @@ func (s *ServerTestSuite) Test_GetServicesFromEnvVars_ReturnsServices() {
719723
ConnectionMode: "my-connection-mode",
720724
ConsulTemplateBePath: "my-ConsulTemplateBePath",
721725
ConsulTemplateFePath: "my-ConsulTemplateFePath",
726+
DelReqHeader: []string{"del-header-1", "del-header-2"},
727+
DelResHeader: []string{"del-header-1", "del-header-2"},
722728
Distribute: true,
723729
HttpsOnly: true,
724730
HttpsPort: 1234,
@@ -751,6 +757,8 @@ func (s *ServerTestSuite) Test_GetServicesFromEnvVars_ReturnsServices() {
751757
os.Setenv("DFP_SERVICE_CONNECTION_MODE", service.ConnectionMode)
752758
os.Setenv("DFP_SERVICE_CONSUL_TEMPLATE_FE_PATH", service.ConsulTemplateFePath)
753759
os.Setenv("DFP_SERVICE_CONSUL_TEMPLATE_BE_PATH", service.ConsulTemplateBePath)
760+
os.Setenv("DFP_SERVICE_DEL_REQ_HEADER", strings.Join(service.DelReqHeader, ","))
761+
os.Setenv("DFP_SERVICE_DEL_RES_HEADER", strings.Join(service.DelResHeader, ","))
754762
os.Setenv("DFP_SERVICE_DISTRIBUTE", strconv.FormatBool(service.Distribute))
755763
os.Setenv("DFP_SERVICE_HTTPS_ONLY", strconv.FormatBool(service.HttpsOnly))
756764
os.Setenv("DFP_SERVICE_HTTPS_PORT", strconv.Itoa(service.HttpsPort))
@@ -784,6 +792,8 @@ func (s *ServerTestSuite) Test_GetServicesFromEnvVars_ReturnsServices() {
784792
os.Unsetenv("DFP_SERVICE_CONNECTION_MODE")
785793
os.Unsetenv("DFP_SERVICE_CONSUL_TEMPLATE_BE_PATH")
786794
os.Unsetenv("DFP_SERVICE_CONSUL_TEMPLATE_FE_PATH")
795+
os.Unsetenv("DFP_SERVICE_DEL_REQ_HEADER")
796+
os.Unsetenv("DFP_SERVICE_DEL_RES_HEADER")
787797
os.Unsetenv("DFP_SERVICE_DISTRIBUTE")
788798
os.Unsetenv("DFP_SERVICE_HTTPS_ONLY")
789799
os.Unsetenv("DFP_SERVICE_HTTPS_PORT")

0 commit comments

Comments
 (0)