mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-03-13 17:46:58 +08:00
fix(microsoft): retry 5 times when socket timeout. Closes #1691.
This commit is contained in:
parent
5e1ae56740
commit
0c7b0f285e
@ -89,6 +89,7 @@ public class OAuth {
|
||||
pair("grant_type", "authorization_code"), pair("client_secret", options.callback.getClientSecret()),
|
||||
pair("redirect_uri", session.getRedirectURI()), pair("scope", options.scope))
|
||||
.ignoreHttpCode()
|
||||
.retry(5)
|
||||
.getJson(AuthorizationResponse.class);
|
||||
handleErrorResponse(response);
|
||||
return new Result(response.accessToken, response.refreshToken);
|
||||
@ -98,6 +99,7 @@ public class OAuth {
|
||||
DeviceTokenResponse deviceTokenResponse = HttpRequest.POST(deviceCodeURL)
|
||||
.form(pair("client_id", options.callback.getClientId()), pair("scope", options.scope))
|
||||
.ignoreHttpCode()
|
||||
.retry(5)
|
||||
.getJson(DeviceTokenResponse.class);
|
||||
handleErrorResponse(deviceTokenResponse);
|
||||
|
||||
@ -124,6 +126,7 @@ public class OAuth {
|
||||
pair("code", deviceTokenResponse.deviceCode),
|
||||
pair("client_id", options.callback.getClientId()))
|
||||
.ignoreHttpCode()
|
||||
.retry(5)
|
||||
.getJson(TokenResponse.class);
|
||||
|
||||
if ("authorization_pending".equals(tokenResponse.error)) {
|
||||
@ -158,6 +161,7 @@ public class OAuth {
|
||||
.form(query)
|
||||
.accept("application/json")
|
||||
.ignoreHttpCode()
|
||||
.retry(5)
|
||||
.getJson(RefreshResponse.class);
|
||||
|
||||
handleErrorResponse(response);
|
||||
|
@ -119,6 +119,7 @@ public class MicrosoftService {
|
||||
mapOf(pair("AuthMethod", "RPS"), pair("SiteName", "user.auth.xboxlive.com"),
|
||||
pair("RpsTicket", "d=" + liveAccessToken))),
|
||||
pair("RelyingParty", "http://auth.xboxlive.com"), pair("TokenType", "JWT")))
|
||||
.retry(5)
|
||||
.accept("application/json").getJson(XBoxLiveAuthenticationResponse.class);
|
||||
|
||||
String uhs = getUhs(xboxResponse, null);
|
||||
@ -132,6 +133,7 @@ public class MicrosoftService {
|
||||
pair("UserTokens", Collections.singletonList(xboxResponse.token)))),
|
||||
pair("RelyingParty", "rp://api.minecraftservices.com/"), pair("TokenType", "JWT")))
|
||||
.ignoreHttpErrorCode(401)
|
||||
.retry(5)
|
||||
.getJson(XBoxLiveAuthenticationResponse.class);
|
||||
|
||||
getUhs(minecraftXstsResponse, uhs);
|
||||
@ -140,6 +142,7 @@ public class MicrosoftService {
|
||||
MinecraftLoginWithXBoxResponse minecraftResponse = HttpRequest
|
||||
.POST("https://api.minecraftservices.com/authentication/login_with_xbox")
|
||||
.json(mapOf(pair("identityToken", "XBL3.0 x=" + uhs + ";" + minecraftXstsResponse.token)))
|
||||
.retry(5)
|
||||
.accept("application/json").getJson(MinecraftLoginWithXBoxResponse.class);
|
||||
|
||||
long notAfter = minecraftResponse.expiresIn * 1000L + System.currentTimeMillis();
|
||||
|
@ -21,6 +21,7 @@ import com.google.gson.JsonParseException;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.function.ExceptionalBiConsumer;
|
||||
import org.jackhuang.hmcl.util.function.ExceptionalSupplier;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -28,6 +29,7 @@ import java.io.OutputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
@ -49,6 +51,7 @@ public abstract class HttpRequest {
|
||||
protected final Map<String, String> headers = new HashMap<>();
|
||||
protected ExceptionalBiConsumer<URL, Integer, IOException> responseCodeTester;
|
||||
protected final Set<Integer> toleratedHttpCodes = new HashSet<>();
|
||||
protected int retryTimes = 1;
|
||||
protected boolean ignoreHttpCode;
|
||||
|
||||
private HttpRequest(String url, String method) {
|
||||
@ -82,6 +85,14 @@ public abstract class HttpRequest {
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpRequest retry(int retryTimes) {
|
||||
if (retryTimes < 1) {
|
||||
throw new IllegalArgumentException("retryTimes >= 1");
|
||||
}
|
||||
this.retryTimes = retryTimes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract String getString() throws IOException;
|
||||
|
||||
public CompletableFuture<String> getStringAsync() {
|
||||
@ -129,9 +140,11 @@ public abstract class HttpRequest {
|
||||
}
|
||||
|
||||
public String getString() throws IOException {
|
||||
HttpURLConnection con = createConnection();
|
||||
con = resolveConnection(con);
|
||||
return IOUtils.readFullyAsString(con.getInputStream(), StandardCharsets.UTF_8);
|
||||
return getStringWithRetry(() -> {
|
||||
HttpURLConnection con = createConnection();
|
||||
con = resolveConnection(con);
|
||||
return IOUtils.readFullyAsString(con.getInputStream(), StandardCharsets.UTF_8);
|
||||
}, retryTimes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,25 +181,27 @@ public abstract class HttpRequest {
|
||||
}
|
||||
|
||||
public String getString() throws IOException {
|
||||
HttpURLConnection con = createConnection();
|
||||
con.setDoOutput(true);
|
||||
return getStringWithRetry(() -> {
|
||||
HttpURLConnection con = createConnection();
|
||||
con.setDoOutput(true);
|
||||
|
||||
try (OutputStream os = con.getOutputStream()) {
|
||||
os.write(bytes);
|
||||
}
|
||||
try (OutputStream os = con.getOutputStream()) {
|
||||
os.write(bytes);
|
||||
}
|
||||
|
||||
if (responseCodeTester != null) {
|
||||
responseCodeTester.accept(new URL(url), con.getResponseCode());
|
||||
} else {
|
||||
if (con.getResponseCode() / 100 != 2) {
|
||||
if (!ignoreHttpCode && !toleratedHttpCodes.contains(con.getResponseCode())) {
|
||||
String data = NetworkUtils.readData(con);
|
||||
throw new ResponseCodeException(new URL(url), con.getResponseCode(), data);
|
||||
if (responseCodeTester != null) {
|
||||
responseCodeTester.accept(new URL(url), con.getResponseCode());
|
||||
} else {
|
||||
if (con.getResponseCode() / 100 != 2) {
|
||||
if (!ignoreHttpCode && !toleratedHttpCodes.contains(con.getResponseCode())) {
|
||||
String data = NetworkUtils.readData(con);
|
||||
throw new ResponseCodeException(new URL(url), con.getResponseCode(), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NetworkUtils.readData(con);
|
||||
return NetworkUtils.readData(con);
|
||||
}, retryTimes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,6 +218,20 @@ public abstract class HttpRequest {
|
||||
return new HttpPostRequest(url);
|
||||
}
|
||||
|
||||
private static String getStringWithRetry(ExceptionalSupplier<String, IOException> supplier, int retryTimes) throws IOException {
|
||||
SocketTimeoutException exception = null;
|
||||
for (int i = 0; i < retryTimes; i++) {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (SocketTimeoutException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
throw new IOException("retry 0");
|
||||
}
|
||||
|
||||
public interface Authorization {
|
||||
String getTokenType();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user