Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to handle GOAWAY with a retry of the GET call falling back to Http/1 #2696

Merged
merged 1 commit into from
Aug 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.Authenticator;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
Expand All @@ -33,12 +32,13 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.eclipse.tycho.MavenRepositorySettings.Credentials;
import org.eclipse.tycho.p2maven.helper.ProxyHelper;

/**
Expand All @@ -59,20 +59,23 @@ public class Java11HttpTransportFactory implements HttpTransportFactory, Initial
// RFC 1036
ThreadLocal.withInitial(() -> new SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss zzz", Locale.ENGLISH)),
// ANSI C's asctime() format
ThreadLocal.withInitial(() -> new SimpleDateFormat("EEE MMMd HH:mm:ss yyyy", Locale.ENGLISH))
);
ThreadLocal.withInitial(() -> new SimpleDateFormat("EEE MMMd HH:mm:ss yyyy", Locale.ENGLISH)));

static final String HINT = "Java11Client";
@Requirement
ProxyHelper proxyHelper;
@Requirement
MavenAuthenticator authenticator;
@Requirement
Logger logger;

private HttpClient client;
private HttpClient clientHttp1;

@Override
public HttpTransport createTransport(URI uri) {
Java11HttpTransport transport = new Java11HttpTransport(client, HttpRequest.newBuilder().uri(uri));
Java11HttpTransport transport = new Java11HttpTransport(client, clientHttp1, HttpRequest.newBuilder().uri(uri),
logger);
authenticator.preemtiveAuth((k, v) -> transport.setHeader(k, v), uri);
return transport;
}
Expand All @@ -81,10 +84,14 @@ private static final class Java11HttpTransport implements HttpTransport {

private Builder builder;
private HttpClient client;
private Logger logger;
private HttpClient clientHttp1;

public Java11HttpTransport(HttpClient client, Builder builder) {
public Java11HttpTransport(HttpClient client, HttpClient clientHttp1, Builder builder, Logger logger) {
this.client = client;
this.clientHttp1 = clientHttp1;
this.builder = builder;
this.logger = logger;
}

@Override
Expand All @@ -95,7 +102,7 @@ public void setHeader(String key, String value) {
@Override
public Response<InputStream> get() throws IOException {
try {
HttpResponse<InputStream> response = client.send(builder.GET().build(), BodyHandlers.ofInputStream());
HttpResponse<InputStream> response = performGet();
return new ResponseImplementation<>(response) {

@Override
Expand Down Expand Up @@ -129,6 +136,21 @@ public void close() {
}
}

private HttpResponse<InputStream> performGet() throws IOException, InterruptedException {
HttpRequest request = builder.GET().build();
try {
return client.send(request, BodyHandlers.ofInputStream());
} catch (IOException e) {
if (isGoaway(e)) {
logger.warn("Received GOAWAY from server " + request.uri().getHost()
+ " will retry after one second with Http/1...");
TimeUnit.SECONDS.sleep(1);
return clientHttp1.send(request, BodyHandlers.ofInputStream());
}
throw e;
}
}

@Override
public Response<Void> head() throws IOException {
try {
Expand Down Expand Up @@ -203,22 +225,45 @@ public long getLastModified() {

@Override
public void initialize() throws InitializationException {
client = HttpClient.newBuilder().followRedirects(Redirect.NEVER)
.proxy(new ProxySelector() {
ProxySelector proxySelector = new ProxySelector() {

@Override
public List<Proxy> select(URI uri) {
Proxy proxy = proxyHelper.getProxy(uri);
return List.of(proxy);
}
@Override
public List<Proxy> select(URI uri) {
Proxy proxy = proxyHelper.getProxy(uri);
return List.of(proxy);
}

@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
// anything useful we can do here?
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
// anything useful we can do here?

}
}).build();
}
};
client = HttpClient.newBuilder().followRedirects(Redirect.NEVER).proxy(proxySelector).build();
clientHttp1 = HttpClient.newBuilder().version(Version.HTTP_1_1).followRedirects(Redirect.NEVER)
.proxy(proxySelector).build();

}

private static boolean isGoaway(Throwable e) {
if (e == null) {
return false;
}
if (e instanceof IOException) {
// first check the message
String message = e.getMessage();
if (message != null && message.contains("GOAWAY received")) {
return true;
}
// maybe it is in the stack?!?
for (StackTraceElement stack : e.getStackTrace()) {
if ("jdk.internal.net.http.Http2Connection.handleGoAway".equals(stack.getMethodName())) {
return true;
}
}
}
// look further in the chain...
return isGoaway(e.getCause());
}

}
Loading