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

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

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