提交 1e624915 编写于 作者: P Pei-Tang Huang

Merge branch 'master' of https://github.com/jenkinsci/jenkins

......@@ -55,7 +55,14 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
<li class='major bug'>
Saving Global Jenkins Global Config wipes out the crumb issuer settings in the Global Security Config.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-17087">issue 17087</a>)
<li class=bug>
Preview function for textareas using Jenkins markup did not work when CSRF protection was enabled.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-17085">issue 17085</a>)
<li class=rfe>
Improved the duration browsers cache static resources.
</ul>
</div><!--=TRUNK-END=-->
......@@ -79,7 +86,7 @@ Upcoming changes</a>
Absolute URLs in console output
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-16368">issue 16368</a>)
<li class=bug>
Revert ampersand encoding which can cause backwad incompatibility issue
Revert ampersand encoding which can cause backward incompatibility issue
(<a href="https://github.com/jenkinsci/jenkins/pull/683">pull 683</a>)
<li class=bug>
Fix dependency graph computation when upstream build trigger is involved
......
......@@ -9,5 +9,5 @@ CLI.Usage=Jenkins CLI\n\
The available commands depend on the server. Run the 'help' command to\n\
see the list.
CLI.NoURL=Neither -s nor the JENKINS_URL env var is specified.
CLI.VersionMismatch=Version mismatch. This CLI cannot work with this Hudson server
CLI.VersionMismatch=Version mismatch. This CLI cannot work with this Jenkins server.
CLI.NoSuchFileExists=No such file exists: {0}
......@@ -42,7 +42,7 @@ THE SOFTWARE.
<properties>
<staplerFork>true</staplerFork>
<stapler.version>1.199</stapler.version>
<stapler.version>1.204</stapler.version>
<spring.version>2.5.6.SEC03</spring.version>
</properties>
......@@ -199,7 +199,7 @@ THE SOFTWARE.
<dependency><!-- until we get this version through Stapler -->
<groupId>org.kohsuke.stapler</groupId>
<artifactId>json-lib</artifactId>
<version>2.1-rev7</version>
<version>2.4-jenkins-1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
......
......@@ -782,6 +782,7 @@ public class Functions {
*
* @param predicate
* Filter the descriptors based on {@link GlobalConfigurationCategory}
* @since 1.494
*/
public static Collection<Descriptor> getSortedDescriptorsForGlobalConfig(Predicate<GlobalConfigurationCategory> predicate) {
ExtensionList<Descriptor> exts = Jenkins.getInstance().getExtensionList(Descriptor.class);
......@@ -807,13 +808,32 @@ public class Functions {
return DescriptorVisibilityFilter.apply(Jenkins.getInstance(),answer);
}
/**
* Like {@link #getSortedDescriptorsForGlobalConfig(Predicate)} but with a constant truth predicate, to include all descriptors.
*/
public static Collection<Descriptor> getSortedDescriptorsForGlobalConfig() {
return getSortedDescriptorsForGlobalConfig(Predicates.<GlobalConfigurationCategory>alwaysTrue());
}
/**
* @deprecated This is rather meaningless.
*/
@Deprecated
public static Collection<Descriptor> getSortedDescriptorsForGlobalConfigNoSecurity() {
return getSortedDescriptorsForGlobalConfig(Predicates.not(GlobalSecurityConfiguration.FILTER));
}
/**
* Like {@link #getSortedDescriptorsForGlobalConfig(Predicate)} but for unclassified descriptors only.
* @since 1.506
*/
public static Collection<Descriptor> getSortedDescriptorsForGlobalConfigUnclassified() {
return getSortedDescriptorsForGlobalConfig(new Predicate<GlobalConfigurationCategory>() {
public boolean apply(GlobalConfigurationCategory cat) {
return cat instanceof GlobalConfigurationCategory.Unclassified;
}
});
}
private static class Tag implements Comparable<Tag> {
double ordinal;
......
......@@ -23,6 +23,7 @@
*/
package hudson;
import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import hudson.model.Hudson;
import jenkins.model.Jenkins;
import hudson.util.OneShotEvent;
......@@ -52,6 +53,7 @@ public class UDPBroadcastThread extends Thread {
public final OneShotEvent ready = new OneShotEvent();
private MulticastSocket mcs;
private boolean shutdown;
static boolean udpHandlingProblem; // for tests
/**
* @deprecated as of 1.416
......@@ -67,6 +69,7 @@ public class UDPBroadcastThread extends Thread {
mcs = new MulticastSocket(PORT);
}
@SuppressWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
@Override
public void run() {
try {
......@@ -106,6 +109,7 @@ public class UDPBroadcastThread extends Thread {
} catch (IOException e) {
if (shutdown) return; // forcibly closed
LOGGER.log(Level.WARNING, "UDP handling problem",e);
udpHandlingProblem = true;
}
}
......
......@@ -195,7 +195,7 @@ public abstract class Cause {
*/
public @CheckForNull Run<?,?> getUpstreamRun() {
Job<?,?> job = Jenkins.getInstance().getItemByFullName(upstreamProject, Job.class);
return job.getBuildByNumber(upstreamBuild);
return job != null ? job.getBuildByNumber(upstreamBuild) : null;
}
@Exported(visibility=3)
......
......@@ -27,7 +27,6 @@ import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
import hudson.cli.declarative.OptionHandlerExtension;
import hudson.util.EditDistance;
import hudson.util.EnumConverter;
import org.apache.commons.beanutils.Converter;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
......
......@@ -171,7 +171,11 @@ public class UpdateSite {
String uncleanJson = IOUtils.toString(is,"UTF-8");
int jsonStart = uncleanJson.indexOf("{\"");
if (jsonStart >= 0) {
return updateData(uncleanJson.substring(jsonStart), signatureCheck);
uncleanJson = uncleanJson.substring(jsonStart);
int end = uncleanJson.lastIndexOf('}');
if (end>0)
uncleanJson = uncleanJson.substring(0,end+1);
return updateData(uncleanJson, signatureCheck);
} else {
throw new IOException("Could not find json in content of " +
"update center from url: "+src.toExternalForm());
......
......@@ -9,6 +9,7 @@ import jenkins.model.Jenkins;
import java.io.IOException;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.Filter;
......@@ -76,15 +77,14 @@ public class CrumbFilter implements Filter {
if (crumbIssuer.validateCrumb(httpRequest, crumbSalt, crumb)) {
valid = true;
} else {
LOGGER.warning("Found invalid crumb " + crumb +
". Will check remaining parameters for a valid one...");
LOGGER.log(Level.WARNING, "Found invalid crumb {0}. Will check remaining parameters for a valid one...", crumb);
}
}
// Multipart requests need to be handled by each handler.
if (valid || isMultipart(httpRequest)) {
chain.doFilter(request, response);
} else {
LOGGER.warning("No valid crumb was included in request for " + httpRequest.getRequestURI() + ". Returning " + HttpServletResponse.SC_FORBIDDEN + ".");
LOGGER.log(Level.WARNING, "No valid crumb was included in request for {0}. Returning {1}.", new Object[] {httpRequest.getRequestURI(), HttpServletResponse.SC_FORBIDDEN});
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN,"No valid crumb was included in the request");
}
} else {
......
......@@ -94,6 +94,7 @@ import hudson.DNSMultiCast;
import hudson.DescriptorExtensionList;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.FilePath;
import hudson.Functions;
import hudson.Launcher;
......@@ -110,6 +111,7 @@ import hudson.UDPBroadcastThread;
import hudson.Util;
import static hudson.Util.fixEmpty;
import static hudson.Util.fixNull;
import hudson.WebAppMain;
import hudson.XmlFile;
import hudson.cli.CLICommand;
import hudson.cli.CliEntryPoint;
......@@ -247,6 +249,7 @@ import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import static hudson.init.InitMilestone.*;
import hudson.security.BasicAuthenticationFilter;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import java.io.File;
......@@ -790,7 +793,7 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro
// JSON binding needs to be able to see all the classes from all the plugins
WebApp.get(servletContext).setClassLoader(pluginManager.uberClassLoader);
adjuncts = new AdjunctManager(servletContext, pluginManager.uberClassLoader,"adjuncts/"+SESSION_HASH);
adjuncts = new AdjunctManager(servletContext, pluginManager.uberClassLoader,"adjuncts/"+SESSION_HASH, TimeUnit2.DAYS.toMillis(365));
// initialization consists of ...
executeReactor( is,
......@@ -2702,7 +2705,7 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro
jdks.addAll(req.bindJSONToList(JDK.class,json.get("jdks")));
boolean result = true;
for( Descriptor<?> d : Functions.getSortedDescriptorsForGlobalConfig() )
for (Descriptor<?> d : Functions.getSortedDescriptorsForGlobalConfigUnclassified())
result &= configureDescriptor(req,json,d);
version = VERSION;
......@@ -2886,7 +2889,7 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro
* Check if the given name is suitable as a name
* for job, view, etc.
*
* @throws ParseException
* @throws Failure
* if the given name is not good
*/
public static void checkGoodName(String name) throws Failure {
......@@ -2907,7 +2910,7 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro
/**
* Makes sure that the given name is good as a job name.
* @return trimmed name if valid; throws ParseException if not
* @return trimmed name if valid; throws Failure if not
*/
private String checkJobName(String name) throws Failure {
checkGoodName(name);
......
......@@ -42,10 +42,9 @@ THE SOFTWARE.
<p>
You can also specify optional XPath to control the fragment you'd like to obtain (but see <a href="#tree">below</a>).
For example, <tt>../api/xml?xpath=/*/*[0]</tt>. If the XPath only matches a text node,
the result will be sent with <tt>text/plain</tt> MIME type to simplify
further processing.
For example, <tt>../api/xml?xpath=/*/*[0]</tt>.
</p>
<p>
For XPath that matches multiple nodes, you need to also specify the "wrapper" query parameter
to specify the name of the root XML element to be create so that the resulting XML becomes well-formed.
</p>
......@@ -67,9 +66,7 @@ THE SOFTWARE.
<dt><a href="json?pretty=true">JSON API</a></dt>
<dd>
Access the same data as JSON for JavaScript-based access. Supports
<a href="http://ajaxian.com/archives/jsonp-json-with-padding">JSONP</a> through
the optional <tt>jsonp=<i>callbackname</i></tt> query parameter.
Access the same data as JSON for JavaScript-based access. <tt>tree</tt> may be used.
</dd>
<dt><a href="python?pretty=true">Python API</a></dt>
......
......@@ -42,11 +42,11 @@ THE SOFTWARE.
<table id="computers" class="sortable pane bigtable">
<tr>
<th width="32">S</th>
<th initialSortDir="down">${%Name}</th>
<th initialSortDir="down" align="left">${%Name}</th>
<j:forEach var="m" items="${monitors}">
<j:if test="${m.columnCaption!=null}">
<j:set var="tableWidth" value="${tableWidth+1}"/>
<th>${m.columnCaption}</th>
<th align="right">${m.columnCaption}</th>
</j:if>
</j:forEach>
<th />
......
......@@ -24,5 +24,5 @@ THE SOFTWARE.
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:s="/lib/form">
<td align="middle">${data}</td>
<td align="right">${data}</td>
</j:jelly>
\ No newline at end of file
......@@ -53,7 +53,7 @@ THE SOFTWARE.
</f:entry>
<!-- global configuration from everyone -->
<j:forEach var="descriptor" items="${h.getSortedDescriptorsForGlobalConfigNoSecurity()}">
<j:forEach var="descriptor" items="${h.getSortedDescriptorsForGlobalConfigUnclassified()}">
<j:set var="instance" value="${descriptor}" /><!-- this makes the <f:textbox field=.../> work -->
<f:rowSet name="${descriptor.jsonSafeClassName}">
<st:include page="${descriptor.globalConfigPage}" from="${descriptor}" />
......
......@@ -34,8 +34,6 @@ Behaviour.specify("DIV.textarea-preview-container", 'textarea', 100, function (e
};
new Ajax.Request(rootURL + showPreview.getAttribute("previewEndpoint"), {
method: "POST",
requestHeaders: "Content-Type: application/x-www-form-urlencoded",
parameters: {
text: text
},
......
package hudson;
import org.jvnet.hudson.test.HudsonTestCase;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
......@@ -12,30 +11,43 @@ import java.net.DatagramPacket;
import java.net.InetAddress;
import java.io.StringReader;
import java.io.IOException;
import java.net.SocketTimeoutException;
import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
/**
* @author Kohsuke Kawaguchi
*/
public class UDPBroadcastThreadTest extends HudsonTestCase {
public class UDPBroadcastThreadTest {
@Rule public JenkinsRule j = new JenkinsRule();
/**
* Old unicast based clients should still be able to receive some reply,
* as we haven't changed the port.
*/
public void testLegacy() throws Exception {
@Test public void legacy() throws Exception {
DatagramSocket s = new DatagramSocket();
sendQueryTo(s, InetAddress.getLocalHost());
s.setSoTimeout(15000); // to prevent test hang
receiveAndVerify(s);
try {
receiveAndVerify(s);
} catch (SocketTimeoutException x) {
Assume.assumeFalse(UDPBroadcastThread.udpHandlingProblem);
throw x;
}
}
/**
* Multicast based clients should be able to receive multiple replies.
*/
public void testMulticast() throws Exception {
UDPBroadcastThread second = new UDPBroadcastThread(jenkins);
@Test public void multicast() throws Exception {
UDPBroadcastThread second = new UDPBroadcastThread(j.jenkins);
second.start();
UDPBroadcastThread third = new UDPBroadcastThread(jenkins);
UDPBroadcastThread third = new UDPBroadcastThread(j.jenkins);
third.start();
second.ready.block();
......@@ -47,8 +59,13 @@ public class UDPBroadcastThreadTest extends HudsonTestCase {
s.setSoTimeout(15000); // to prevent test hang
// we should at least get two replies since we run two broadcasts
receiveAndVerify(s);
receiveAndVerify(s);
try {
receiveAndVerify(s);
receiveAndVerify(s);
} catch (SocketTimeoutException x) {
Assume.assumeFalse(UDPBroadcastThread.udpHandlingProblem);
throw x;
}
} finally {
third.interrupt();
second.interrupt();
......
......@@ -100,10 +100,12 @@ var crumb = {
wrap: function(headers) {
if (this.fieldName!=null) {
if (headers instanceof Array)
// XXX prototype.js only seems to interpret object
headers.push(this.fieldName, this.value);
else
headers[this.fieldName]=this.value;
}
// XXX return value unused
return headers;
},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册