提交 ee5c1a3a 编写于 作者: D Daniel Beck

Merge pull request #2156 from kzantow/JENKINS-33557-tcp-timeouts-during-install

[JENKINS-33557] - connectivity checks may cause setup wizard to hang for a long time
......@@ -74,6 +74,12 @@ import org.kohsuke.stapler.QueryParameter;
* @see jenkins.model.Jenkins#proxy
*/
public final class ProxyConfiguration extends AbstractDescribableImpl<ProxyConfiguration> implements Saveable, Serializable {
/**
* Holds a default TCP connect timeout set on all connections returned from this class,
* note this is value is in milliseconds, it's passed directly to {@link URLConnection#setConnectTimeout(int)}
*/
private static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = Integer.getInteger("hudson.ProxyConfiguration.DEFAULT_CONNECT_TIMEOUT_MILLIS", 20 * 1000);
public final String name;
public final int port;
......@@ -218,22 +224,29 @@ public final class ProxyConfiguration extends AbstractDescribableImpl<ProxyConfi
*/
public static URLConnection open(URL url) throws IOException {
final ProxyConfiguration p = get();
if(p==null)
return url.openConnection();
URLConnection con = url.openConnection(p.createProxy(url.getHost()));
if(p.getUserName()!=null) {
// Add an authenticator which provides the credentials for proxy authentication
Authenticator.setDefault(new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType()!=RequestorType.PROXY) return null;
return new PasswordAuthentication(p.getUserName(),
p.getPassword().toCharArray());
}
});
URLConnection con;
if(p==null) {
con = url.openConnection();
} else {
con = url.openConnection(p.createProxy(url.getHost()));
if(p.getUserName()!=null) {
// Add an authenticator which provides the credentials for proxy authentication
Authenticator.setDefault(new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType()!=RequestorType.PROXY) return null;
return new PasswordAuthentication(p.getUserName(),
p.getPassword().toCharArray());
}
});
}
}
if(DEFAULT_CONNECT_TIMEOUT_MILLIS > 0) {
con.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS);
}
if (JenkinsJVM.isJenkinsJVM()) { // this code may run on a slave
decorate(con);
}
......@@ -329,7 +342,7 @@ public final class ProxyConfiguration extends AbstractDescribableImpl<ProxyConfi
GetMethod method = null;
try {
method = new GetMethod(testUrl);
method.getParams().setParameter("http.socket.timeout", new Integer(30 * 1000));
method.getParams().setParameter("http.socket.timeout", DEFAULT_CONNECT_TIMEOUT_MILLIS > 0 ? DEFAULT_CONNECT_TIMEOUT_MILLIS : new Integer(30 * 1000));
HttpClient client = new HttpClient();
if (Util.fixEmptyAndTrim(name) != null) {
......
......@@ -77,6 +77,8 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpRetryException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
......@@ -1132,7 +1134,16 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
private void testConnection(URL url) throws IOException {
try {
Util.copyStreamAndClose(ProxyConfiguration.open(url).getInputStream(),new NullOutputStream());
URLConnection connection = (URLConnection) ProxyConfiguration.open(url);
if(connection instanceof HttpURLConnection) {
int responseCode = ((HttpURLConnection)connection).getResponseCode();
if(HttpURLConnection.HTTP_OK != responseCode) {
throw new HttpRetryException("Invalid response code (" + responseCode + ") from URL: " + url, responseCode);
}
} else {
Util.copyStreamAndClose(connection.getInputStream(),new NullOutputStream());
}
} catch (SSLHandshakeException e) {
if (e.getMessage().contains("PKIX path building failed"))
// fix up this crappy error message from JDK
......@@ -1315,22 +1326,29 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
return;
}
LOGGER.fine("Doing a connectivity check");
Future<?> internetCheck = null;
try {
String connectionCheckUrl = site.getConnectionCheckUrl();
final String connectionCheckUrl = site.getConnectionCheckUrl();
if (connectionCheckUrl!=null) {
connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.CHECKING);
statuses.add(Messages.UpdateCenter_Status_CheckingInternet());
try {
config.checkConnection(this, connectionCheckUrl);
} catch (Exception e) {
if(e.getMessage().contains("Connection timed out")) {
// Google can't be down, so this is probably a proxy issue
connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.FAILED);
statuses.add(Messages.UpdateCenter_Status_ConnectionFailed(connectionCheckUrl));
return;
// Run the internet check in parallel
internetCheck = updateService.submit(new Runnable() {
@Override
public void run() {
try {
config.checkConnection(ConnectionCheckJob.this, connectionCheckUrl);
} catch (Exception e) {
if(e.getMessage().contains("Connection timed out")) {
// Google can't be down, so this is probably a proxy issue
connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.FAILED);
statuses.add(Messages.UpdateCenter_Status_ConnectionFailed(connectionCheckUrl));
return;
}
}
connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.OK);
}
}
connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.OK);
});
}
connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.CHECKING);
......@@ -1350,6 +1368,15 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
statuses.add(Functions.printThrowable(e));
error = e;
}
if(internetCheck != null) {
try {
// Wait for internet check to complete
internetCheck.get();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error completing internet connectivity check: " + e.getMessage(), e);
}
}
}
private void addStatus(UnknownHostException e) {
......
......@@ -99,7 +99,7 @@ public class UpdateCenterConnectionStatusTest {
job.run();
Assert.assertEquals(ConnectionStatus.FAILED, job.connectionStates.get(ConnectionStatus.INTERNET));
Assert.assertEquals(ConnectionStatus.UNCHECKED, job.connectionStates.get(ConnectionStatus.UPDATE_SITE));
Assert.assertEquals(ConnectionStatus.OK, job.connectionStates.get(ConnectionStatus.UPDATE_SITE));
}
@Test
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册