From: Jean-Baptiste Lievremont Date: Tue, 23 Jun 2015 09:58:27 +0000 (+0200) Subject: SONAR-6304 Set Content-Disposition header on profile backup and export X-Git-Tag: 5.2-RC1~1344 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e8bff4270a78e6468a348c87901212dfa6e54f66;p=sonarqube.git SONAR-6304 Set Content-Disposition header on profile backup and export --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BackupAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BackupAction.java index 69e320da5b0..4202334c288 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BackupAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BackupAction.java @@ -19,6 +19,8 @@ */ package org.sonar.server.qualityprofile.ws; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils; import org.sonar.api.resources.Languages; import org.sonar.api.server.ws.Request; @@ -32,9 +34,6 @@ import org.sonar.server.plugins.MimeTypes; import org.sonar.server.qualityprofile.QProfileBackuper; import org.sonar.server.qualityprofile.QProfileFactory; -import java.io.OutputStreamWriter; -import java.nio.charset.StandardCharsets; - public class BackupAction implements QProfileWsAction { private final QProfileBackuper backuper; @@ -71,6 +70,7 @@ public class BackupAction implements QProfileWsAction { try { String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); backuper.backup(profileKey, writer); + response.setHeader("Content-Disposition", String.format("attachment; filename=%s.xml", profileKey)); } finally { session.close(); IOUtils.closeQuietly(writer); diff --git a/server/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java b/server/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java index 3fe0b5b9614..b08c0a6dd85 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java @@ -19,20 +19,23 @@ */ package org.sonar.server.ws; -import org.sonar.api.server.ws.Response; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.utils.text.XmlWriter; -import org.sonar.server.plugins.MimeTypes; - -import javax.annotation.CheckForNull; - import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.CheckForNull; +import org.sonar.api.server.ws.Response; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.api.utils.text.XmlWriter; +import org.sonar.server.plugins.MimeTypes; public class ServletResponse implements Response { + private Map headers = new HashMap(); + public static class ServletStream implements Stream { private String mediaType; private int httpStatus = 200; @@ -98,4 +101,20 @@ public class ServletResponse implements Response { stream.setStatus(204); return this; } + + @Override + public Response setHeader(String name, String value) { + headers.put(name, value); + return this; + } + + @Override + public Collection getHeaderNames() { + return headers.keySet(); + } + + @Override + public String getHeader(String name) { + return headers.get(name); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java index 37c920b63fa..502059c3035 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java @@ -19,6 +19,8 @@ */ package org.sonar.server.qualityprofile.ws; +import java.io.PrintWriter; +import java.io.Writer; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; @@ -35,9 +37,6 @@ import org.sonar.server.qualityprofile.QProfileFactory; import org.sonar.server.ws.WsTester; import org.sonar.server.ws.WsTester.Result; -import java.io.PrintWriter; -import java.io.Writer; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; @@ -84,6 +83,7 @@ public class BackupActionTest { Result result = tester.newGetRequest("api/qualityprofiles", "backup").setParam("profileKey", profileKey).execute(); assertThat(result.outputAsString()).isEqualTo(response); + result.assertHeader("Content-Disposition", "attachment; filename=polop-palap-xoo-12345.xml"); } @Test(expected = IllegalArgumentException.class) diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java b/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java index 186feed789d..5c36bb5834f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java @@ -20,6 +20,11 @@ package org.sonar.server.ws; import com.google.common.collect.Maps; +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; +import java.util.Map; +import javax.annotation.Nullable; import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.Before; @@ -37,12 +42,6 @@ import org.sonar.server.exceptions.Message; import org.sonar.server.plugins.MimeTypes; import org.sonar.server.tester.UserSessionRule; -import javax.annotation.Nullable; -import java.io.IOException; -import java.io.InputStream; -import java.util.Locale; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -291,6 +290,16 @@ public class WebServiceEngineTest { assertThat(response.stream().mediaType()).isEqualTo(MimeTypes.JSON); } + @Test + public void should_handle_headers() throws Exception { + ServletResponse response = new ServletResponse(); + String name = "Content-Disposition"; + String value = "attachment; filename=sonarqube.zip"; + response.setHeader(name, value); + assertThat(response.getHeaderNames()).containsExactly(name); + assertThat(response.getHeader(name)).isEqualTo(value); + } + static class SystemWs implements WebService { @Override public void define(Context context) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java b/server/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java index eb30c9d303d..db00219e90f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ws/WsTester.java @@ -20,18 +20,6 @@ package org.sonar.server.ws; import com.google.common.collect.Maps; -import org.apache.commons.io.IOUtils; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.server.ws.internal.ValidatingRequest; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.utils.text.XmlWriter; -import org.sonar.server.ws.WsTester.TestResponse.TestStream; -import org.sonar.test.JsonAssert; - -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; - import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; @@ -39,7 +27,18 @@ import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.Collection; import java.util.Map; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.apache.commons.io.IOUtils; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.server.ws.internal.ValidatingRequest; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.api.utils.text.XmlWriter; +import org.sonar.server.ws.WsTester.TestResponse.TestStream; +import org.sonar.test.JsonAssert; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.server.ws.RequestVerifier.verifyRequest; @@ -104,6 +103,8 @@ public class WsTester { private TestStream stream; + private Map headers = Maps.newHashMap(); + public class TestStream implements Response.Stream { private String mediaType; private int status; @@ -165,6 +166,22 @@ public class WsTester { public String outputAsString() { return new String(output.toByteArray(), StandardCharsets.UTF_8); } + + @Override + public Response setHeader(String name, String value) { + headers.put(name, value); + return this; + } + + @Override + public Collection getHeaderNames() { + return headers.keySet(); + } + + @Override + public String getHeader(String name) { + return headers.get(name); + } } public static class Result { @@ -220,6 +237,10 @@ public class WsTester { return this; } + public Result assertHeader(String name, String value) { + assertThat(response.getHeader(name)).isEqualTo(value); + return this; + } } private final WebService.Context context = new WebService.Context(); diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb index 6fe8c930626..7ee7e580709 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb @@ -33,6 +33,10 @@ class Api::JavaWsController < Api::ApiController engine = Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerWs::WebServiceEngine.java_class) engine.execute(ws_request, ws_response, params[:wspath], params[:wsaction]) + ws_response.getHeaderNames().to_a.each do |name| + response.header[name] = ws_response.getHeader(name) + end + # response is already written to HttpServletResponse render :text => ws_response.stream().output().toByteArray(), :status => ws_response.stream().httpStatus(), diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Response.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Response.java index 149ae4178c7..39e8b2c1869 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Response.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Response.java @@ -19,11 +19,12 @@ */ package org.sonar.api.server.ws; +import java.io.OutputStream; +import java.util.Collection; +import javax.annotation.CheckForNull; import org.sonar.api.utils.text.JsonWriter; import org.sonar.api.utils.text.XmlWriter; -import java.io.OutputStream; - /** * HTTP response * @@ -43,6 +44,13 @@ public interface Response { Response noContent(); + Response setHeader(String name, String value); + + Collection getHeaderNames(); + + @CheckForNull + String getHeader(String name); + Stream stream(); }