mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-15 06:45:42 -04: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("grant_type", "authorization_code"), pair("client_secret", options.callback.getClientSecret()),
|
||||||
pair("redirect_uri", session.getRedirectURI()), pair("scope", options.scope))
|
pair("redirect_uri", session.getRedirectURI()), pair("scope", options.scope))
|
||||||
.ignoreHttpCode()
|
.ignoreHttpCode()
|
||||||
|
.retry(5)
|
||||||
.getJson(AuthorizationResponse.class);
|
.getJson(AuthorizationResponse.class);
|
||||||
handleErrorResponse(response);
|
handleErrorResponse(response);
|
||||||
return new Result(response.accessToken, response.refreshToken);
|
return new Result(response.accessToken, response.refreshToken);
|
||||||
@ -98,6 +99,7 @@ public class OAuth {
|
|||||||
DeviceTokenResponse deviceTokenResponse = HttpRequest.POST(deviceCodeURL)
|
DeviceTokenResponse deviceTokenResponse = HttpRequest.POST(deviceCodeURL)
|
||||||
.form(pair("client_id", options.callback.getClientId()), pair("scope", options.scope))
|
.form(pair("client_id", options.callback.getClientId()), pair("scope", options.scope))
|
||||||
.ignoreHttpCode()
|
.ignoreHttpCode()
|
||||||
|
.retry(5)
|
||||||
.getJson(DeviceTokenResponse.class);
|
.getJson(DeviceTokenResponse.class);
|
||||||
handleErrorResponse(deviceTokenResponse);
|
handleErrorResponse(deviceTokenResponse);
|
||||||
|
|
||||||
@ -124,6 +126,7 @@ public class OAuth {
|
|||||||
pair("code", deviceTokenResponse.deviceCode),
|
pair("code", deviceTokenResponse.deviceCode),
|
||||||
pair("client_id", options.callback.getClientId()))
|
pair("client_id", options.callback.getClientId()))
|
||||||
.ignoreHttpCode()
|
.ignoreHttpCode()
|
||||||
|
.retry(5)
|
||||||
.getJson(TokenResponse.class);
|
.getJson(TokenResponse.class);
|
||||||
|
|
||||||
if ("authorization_pending".equals(tokenResponse.error)) {
|
if ("authorization_pending".equals(tokenResponse.error)) {
|
||||||
@ -158,6 +161,7 @@ public class OAuth {
|
|||||||
.form(query)
|
.form(query)
|
||||||
.accept("application/json")
|
.accept("application/json")
|
||||||
.ignoreHttpCode()
|
.ignoreHttpCode()
|
||||||
|
.retry(5)
|
||||||
.getJson(RefreshResponse.class);
|
.getJson(RefreshResponse.class);
|
||||||
|
|
||||||
handleErrorResponse(response);
|
handleErrorResponse(response);
|
||||||
|
@ -119,6 +119,7 @@ public class MicrosoftService {
|
|||||||
mapOf(pair("AuthMethod", "RPS"), pair("SiteName", "user.auth.xboxlive.com"),
|
mapOf(pair("AuthMethod", "RPS"), pair("SiteName", "user.auth.xboxlive.com"),
|
||||||
pair("RpsTicket", "d=" + liveAccessToken))),
|
pair("RpsTicket", "d=" + liveAccessToken))),
|
||||||
pair("RelyingParty", "http://auth.xboxlive.com"), pair("TokenType", "JWT")))
|
pair("RelyingParty", "http://auth.xboxlive.com"), pair("TokenType", "JWT")))
|
||||||
|
.retry(5)
|
||||||
.accept("application/json").getJson(XBoxLiveAuthenticationResponse.class);
|
.accept("application/json").getJson(XBoxLiveAuthenticationResponse.class);
|
||||||
|
|
||||||
String uhs = getUhs(xboxResponse, null);
|
String uhs = getUhs(xboxResponse, null);
|
||||||
@ -132,6 +133,7 @@ public class MicrosoftService {
|
|||||||
pair("UserTokens", Collections.singletonList(xboxResponse.token)))),
|
pair("UserTokens", Collections.singletonList(xboxResponse.token)))),
|
||||||
pair("RelyingParty", "rp://api.minecraftservices.com/"), pair("TokenType", "JWT")))
|
pair("RelyingParty", "rp://api.minecraftservices.com/"), pair("TokenType", "JWT")))
|
||||||
.ignoreHttpErrorCode(401)
|
.ignoreHttpErrorCode(401)
|
||||||
|
.retry(5)
|
||||||
.getJson(XBoxLiveAuthenticationResponse.class);
|
.getJson(XBoxLiveAuthenticationResponse.class);
|
||||||
|
|
||||||
getUhs(minecraftXstsResponse, uhs);
|
getUhs(minecraftXstsResponse, uhs);
|
||||||
@ -140,6 +142,7 @@ public class MicrosoftService {
|
|||||||
MinecraftLoginWithXBoxResponse minecraftResponse = HttpRequest
|
MinecraftLoginWithXBoxResponse minecraftResponse = HttpRequest
|
||||||
.POST("https://api.minecraftservices.com/authentication/login_with_xbox")
|
.POST("https://api.minecraftservices.com/authentication/login_with_xbox")
|
||||||
.json(mapOf(pair("identityToken", "XBL3.0 x=" + uhs + ";" + minecraftXstsResponse.token)))
|
.json(mapOf(pair("identityToken", "XBL3.0 x=" + uhs + ";" + minecraftXstsResponse.token)))
|
||||||
|
.retry(5)
|
||||||
.accept("application/json").getJson(MinecraftLoginWithXBoxResponse.class);
|
.accept("application/json").getJson(MinecraftLoginWithXBoxResponse.class);
|
||||||
|
|
||||||
long notAfter = minecraftResponse.expiresIn * 1000L + System.currentTimeMillis();
|
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.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.util.Pair;
|
import org.jackhuang.hmcl.util.Pair;
|
||||||
import org.jackhuang.hmcl.util.function.ExceptionalBiConsumer;
|
import org.jackhuang.hmcl.util.function.ExceptionalBiConsumer;
|
||||||
|
import org.jackhuang.hmcl.util.function.ExceptionalSupplier;
|
||||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -28,6 +29,7 @@ import java.io.OutputStream;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -49,6 +51,7 @@ public abstract class HttpRequest {
|
|||||||
protected final Map<String, String> headers = new HashMap<>();
|
protected final Map<String, String> headers = new HashMap<>();
|
||||||
protected ExceptionalBiConsumer<URL, Integer, IOException> responseCodeTester;
|
protected ExceptionalBiConsumer<URL, Integer, IOException> responseCodeTester;
|
||||||
protected final Set<Integer> toleratedHttpCodes = new HashSet<>();
|
protected final Set<Integer> toleratedHttpCodes = new HashSet<>();
|
||||||
|
protected int retryTimes = 1;
|
||||||
protected boolean ignoreHttpCode;
|
protected boolean ignoreHttpCode;
|
||||||
|
|
||||||
private HttpRequest(String url, String method) {
|
private HttpRequest(String url, String method) {
|
||||||
@ -82,6 +85,14 @@ public abstract class HttpRequest {
|
|||||||
return this;
|
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 abstract String getString() throws IOException;
|
||||||
|
|
||||||
public CompletableFuture<String> getStringAsync() {
|
public CompletableFuture<String> getStringAsync() {
|
||||||
@ -129,9 +140,11 @@ public abstract class HttpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getString() throws IOException {
|
public String getString() throws IOException {
|
||||||
|
return getStringWithRetry(() -> {
|
||||||
HttpURLConnection con = createConnection();
|
HttpURLConnection con = createConnection();
|
||||||
con = resolveConnection(con);
|
con = resolveConnection(con);
|
||||||
return IOUtils.readFullyAsString(con.getInputStream(), StandardCharsets.UTF_8);
|
return IOUtils.readFullyAsString(con.getInputStream(), StandardCharsets.UTF_8);
|
||||||
|
}, retryTimes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +181,7 @@ public abstract class HttpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getString() throws IOException {
|
public String getString() throws IOException {
|
||||||
|
return getStringWithRetry(() -> {
|
||||||
HttpURLConnection con = createConnection();
|
HttpURLConnection con = createConnection();
|
||||||
con.setDoOutput(true);
|
con.setDoOutput(true);
|
||||||
|
|
||||||
@ -187,6 +201,7 @@ public abstract class HttpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return NetworkUtils.readData(con);
|
return NetworkUtils.readData(con);
|
||||||
|
}, retryTimes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +218,20 @@ public abstract class HttpRequest {
|
|||||||
return new HttpPostRequest(url);
|
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 {
|
public interface Authorization {
|
||||||
String getTokenType();
|
String getTokenType();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user