Browse code

Fix AuthZ plugins headers change issue

This fix tries to address the issue raised in 25927 where
the HTTP headers have been chaged when AUthZ plugin is in
place.

This issue is that in `FlushAll` (`pkg/authorization/response.go`),
the headers have been written (with `WriteHeader`) before all the
headers have bee copied.

This fix fixes the issue by placing `WriteHeader` after.

A test has been added to cover the changes.`

This fix fixes 25927

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/08/24 13:08:23
Showing 2 changed files
... ...
@@ -443,6 +443,25 @@ func (s *DockerAuthzSuite) TestAuthZPluginEnsureLoadImportWorking(c *check.C) {
443 443
 	c.Assert(err, check.IsNil, check.Commentf(out))
444 444
 }
445 445
 
446
+func (s *DockerAuthzSuite) TestAuthZPluginHeader(c *check.C) {
447
+	c.Assert(s.d.Start("--debug", "--authorization-plugin="+testAuthZPlugin), check.IsNil)
448
+	s.ctrl.reqRes.Allow = true
449
+	s.ctrl.resRes.Allow = true
450
+	c.Assert(s.d.LoadBusybox(), check.IsNil)
451
+
452
+	daemonURL, err := url.Parse(s.d.sock())
453
+
454
+	conn, err := net.DialTimeout(daemonURL.Scheme, daemonURL.Path, time.Second*10)
455
+	c.Assert(err, check.IsNil)
456
+	client := httputil.NewClientConn(conn, nil)
457
+	req, err := http.NewRequest("GET", "/version", nil)
458
+	c.Assert(err, check.IsNil)
459
+	resp, err := client.Do(req)
460
+
461
+	c.Assert(err, check.IsNil)
462
+	c.Assert(resp.Header["Content-Type"][0], checker.Equals, "application/json")
463
+}
464
+
446 465
 // assertURIRecorded verifies that the given URI was sent and recorded in the authz plugin
447 466
 func assertURIRecorded(c *check.C, uris []string, uri string) {
448 467
 	var found bool
... ...
@@ -175,11 +175,6 @@ func (rm *responseModifier) Flush() {
175 175
 
176 176
 // FlushAll flushes all data to the HTTP response
177 177
 func (rm *responseModifier) FlushAll() error {
178
-	// Copy the status code
179
-	if rm.statusCode > 0 {
180
-		rm.rw.WriteHeader(rm.statusCode)
181
-	}
182
-
183 178
 	// Copy the header
184 179
 	for k, vv := range rm.header {
185 180
 		for _, v := range vv {
... ...
@@ -187,6 +182,13 @@ func (rm *responseModifier) FlushAll() error {
187 187
 		}
188 188
 	}
189 189
 
190
+	// Copy the status code
191
+	// Also WriteHeader needs to be done after all the headers
192
+	// have been copied (above).
193
+	if rm.statusCode > 0 {
194
+		rm.rw.WriteHeader(rm.statusCode)
195
+	}
196
+
190 197
 	var err error
191 198
 	if len(rm.body) > 0 {
192 199
 		// Write body