提交 982a8faf 编写于 作者: J James Nord

[JENKINS-37062] incorporate changes from stapler servlet 3.1

Downstream updates from stapler/stapler#131

The stapler API was built using servlet 2.5 and yet Jenkins uses 3.1.
This meant some of the code that stapler used was missing new methods
that where part of the updated spec and if a plugin happened to call
them you would end up with a LinkageError or some other crazyness.

This also make Jenkins depend on a dummy version of the old serlet-api
maven co-ordinates such that if any plugin gets aa dependency on it
transitivly (e.g. Jenkins test harness) they will get a version with no
code so the classpath should always be clean (this was more an issue for
eclipse than an mvn command)
上级 112ceeba
......@@ -39,7 +39,7 @@ THE SOFTWARE.
<properties>
<staplerFork>true</staplerFork>
<stapler.version>1.252</stapler.version>
<stapler.version>1.253-SNAPSHOT</stapler.version>
<spring.version>2.5.6.SEC03</spring.version>
<groovy.version>2.4.11</groovy.version>
<!-- TODO: Actually many issues are being filtered by src/findbugs/findbugs-excludes.xml -->
......@@ -472,9 +472,9 @@ THE SOFTWARE.
<scope>test</scope>
</dependency>
<dependency><!-- needed by Jelly -->
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.0</version>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
......
......@@ -4,12 +4,12 @@ import hudson.security.AccessControlled;
import hudson.security.Permission;
import hudson.slaves.SlaveComputer;
import hudson.util.Secret;
import hudson.Util;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.ResponseImpl;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.compression.FilterServletOutputStream;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
......@@ -18,12 +18,15 @@ import javax.crypto.spec.SecretKeySpec;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Serves the JNLP file.
......@@ -35,6 +38,9 @@ import java.security.SecureRandom;
* @since 1.560
*/
public class EncryptedSlaveAgentJnlpFile implements HttpResponse {
private static final Logger LOG = Logger.getLogger(EncryptedSlaveAgentJnlpFile.class.getName());
/**
* The object that owns the Jelly view that renders JNLP file.
* This is typically a {@link SlaveComputer} and if so we'll use {@link SlaveComputer#getJnlpMac()}
......@@ -64,13 +70,13 @@ public class EncryptedSlaveAgentJnlpFile implements HttpResponse {
}
@Override
public void generateResponse(StaplerRequest req, StaplerResponse res, Object node) throws IOException, ServletException {
public void generateResponse(StaplerRequest req, final StaplerResponse res, Object node) throws IOException, ServletException {
RequestDispatcher view = req.getView(it, viewName);
if ("true".equals(req.getParameter("encrypt"))) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final CapturingServletOutputStream csos = new CapturingServletOutputStream();
StaplerResponse temp = new ResponseImpl(req.getStapler(), new HttpServletResponseWrapper(res) {
@Override public ServletOutputStream getOutputStream() throws IOException {
return new FilterServletOutputStream(baos);
return csos;
}
@Override public PrintWriter getWriter() throws IOException {
throw new IllegalStateException();
......@@ -92,7 +98,7 @@ public class EncryptedSlaveAgentJnlpFile implements HttpResponse {
try {
Cipher c = Secret.getCipher("AES/CFB8/NoPadding");
c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
encrypted = c.doFinal(baos.toByteArray());
encrypted = c.doFinal(csos.getBytes());
} catch (GeneralSecurityException x) {
throw new IOException(x);
}
......@@ -104,4 +110,52 @@ public class EncryptedSlaveAgentJnlpFile implements HttpResponse {
view.forward(req, res);
}
}
/**
* A {@link ServletOutputStream} that captures all the data rather than writing to a client.
*/
private static class CapturingServletOutputStream extends ServletOutputStream {
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
// we are always ready to write so we just call once to say we are ready.
try {
// should we do this on a separate thread to avoid deadlocaks?
writeListener.onWritePossible();
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to notify WriteListener.onWritePossible", e);
}
}
@Override
public void write(int b) throws IOException {
baos.write(b);
}
@Override
public void write(byte[] b) throws IOException {
baos.write(b);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
baos.write(b, off, len);
}
/**
* Get the data that has been written to this ServletOutputStream.
* @return the data that has been written to this ServletOutputStream.
*/
byte[] getBytes() {
return baos.toByteArray();
}
}
}
......@@ -230,6 +230,19 @@ THE SOFTWARE.
<artifactId>access-modifier-annotation</artifactId>
<version>${access-modifier-annotation.version}</version>
</dependency>
<!-- make sure these plugins are never used by us or by any plugins which end up depening on this version -->
<dependency>
<!-- Jenkins test Harness tries to fudge this, causes issues with some IDEs -->
<groupId>javax.servlet</groupId>
<!-- the old artifactID for the servlet API -->
<artifactId>servlet-api</artifactId>
<version>[0-SNAPSHOT]</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- TODO also add commons-logging and log4j -->
</dependencies>
</dependencyManagement>
......@@ -246,6 +259,12 @@ THE SOFTWARE.
<artifactId>test-annotations</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<!-- make sure our dependency tree and all others are clean of the legacy servlet api. -->
<groupId>javax.servlet</groupId>
<!-- the old artifactID for the servlet API -->
<artifactId>servlet-api</artifactId>
</dependency>
</dependencies>
<build>
......@@ -324,8 +343,8 @@ THE SOFTWARE.
<dependency>
<!-- this provided scope dependency doesn't get added to GMaven unless explicitly added here -->
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.gmaven.runtime</groupId>
......
......@@ -61,12 +61,8 @@ THE SOFTWARE.
jars that are not needed in war. most of the exclusions should happen in the core, to make IDEs happy, not here.
-->
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
</exclusion>
<!-- Stapler 1.195 fails to declare this as optional, and the 1.1 version lacks a license: -->
<exclusion>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册