Ensure network call resources are closed.

main
Cody Henthorne 2022-10-12 09:12:45 -04:00 zatwierdzone przez Alex Hart
rodzic 1f581c074d
commit 7fafa4d5e6
6 zmienionych plików z 243 dodań i 367 usunięć

Wyświetl plik

@ -95,13 +95,12 @@ public class RetrieveProfileAvatarJob extends BaseJob {
return;
}
File downloadDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
File downloadDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
try {
SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE);
SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
try {
try (InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE)) {
AvatarHelper.setAvatar(context, recipient.getId(), avatarStream);
if (recipient.isSelf()) {

Wyświetl plik

@ -71,28 +71,29 @@ public class UpdateApkJob extends BaseJob {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(String.format("%s/latest.json", BuildConfig.NOPLAY_UPDATE_URL)).build();
Response response = client.newCall(request).execute();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Bad response: " + response.message());
}
if (!response.isSuccessful() || response.body() == null) {
throw new IOException("Bad response: " + response.message());
}
UpdateDescriptor updateDescriptor = JsonUtils.fromJson(response.body().string(), UpdateDescriptor.class);
byte[] digest = Hex.fromStringCondensed(updateDescriptor.getDigest());
UpdateDescriptor updateDescriptor = JsonUtils.fromJson(response.body().string(), UpdateDescriptor.class);
byte[] digest = Hex.fromStringCondensed(updateDescriptor.getDigest());
Log.i(TAG, "Got descriptor: " + updateDescriptor);
Log.i(TAG, "Got descriptor: " + updateDescriptor);
if (updateDescriptor.getVersionCode() > getVersionCode()) {
DownloadStatus downloadStatus = getDownloadStatus(updateDescriptor.getUrl(), digest);
if (updateDescriptor.getVersionCode() > getVersionCode()) {
DownloadStatus downloadStatus = getDownloadStatus(updateDescriptor.getUrl(), digest);
Log.i(TAG, "Download status: " + downloadStatus.getStatus());
Log.i(TAG, "Download status: " + downloadStatus.getStatus());
if (downloadStatus.getStatus() == DownloadStatus.Status.COMPLETE) {
Log.i(TAG, "Download status complete, notifying...");
handleDownloadNotify(downloadStatus.getDownloadId());
} else if (downloadStatus.getStatus() == DownloadStatus.Status.MISSING) {
Log.i(TAG, "Download status missing, starting download...");
handleDownloadStart(updateDescriptor.getUrl(), updateDescriptor.getVersionName(), digest);
if (downloadStatus.getStatus() == DownloadStatus.Status.COMPLETE) {
Log.i(TAG, "Download status complete, notifying...");
handleDownloadNotify(downloadStatus.getDownloadId());
} else if (downloadStatus.getStatus() == DownloadStatus.Status.MISSING) {
Log.i(TAG, "Download status missing, starting download...");
handleDownloadStart(updateDescriptor.getUrl(), updateDescriptor.getVersionName(), digest);
}
}
}
}

Wyświetl plik

@ -182,8 +182,7 @@ public class LinkPreviewRepository {
CallRequestController controller = new CallRequestController(call);
SignalExecutors.UNBOUNDED.execute(() -> {
try {
Response response = call.execute();
try (Response response = call.execute()) {
if (!response.isSuccessful() || response.body() == null) {
callback.accept(Optional.empty());
return;

Wyświetl plik

@ -236,10 +236,10 @@ public class SubmitDebugLogRepository {
@WorkerThread
private @NonNull String uploadContent(@NonNull String contentType, @NonNull RequestBody requestBody) throws IOException {
try {
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new StandardUserAgentInterceptor()).dns(SignalServiceNetworkAccess.DNS).build();
Response response = client.newCall(new Request.Builder().url(API_ENDPOINT).get().build()).execute();
ResponseBody body = response.body();
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new StandardUserAgentInterceptor()).dns(SignalServiceNetworkAccess.DNS).build();
try (Response response = client.newCall(new Request.Builder().url(API_ENDPOINT).get().build()).execute()) {
ResponseBody body = response.body();
if (!response.isSuccessful() || body == null) {
throw new IOException("Unsuccessful response: " + response);
@ -261,10 +261,10 @@ public class SubmitDebugLogRepository {
post.addFormDataPart("file", "file", requestBody);
Response postResponse = client.newCall(new Request.Builder().url(url).post(post.build()).build()).execute();
if (!postResponse.isSuccessful()) {
throw new IOException("Bad response: " + postResponse);
try (Response postResponse = client.newCall(new Request.Builder().url(url).post(post.build()).build()).execute()) {
if (!postResponse.isSuccessful()) {
throw new IOException("Bad response: " + postResponse);
}
}
return API_ENDPOINT + "/" + item;

Wyświetl plik

@ -328,7 +328,7 @@ public class PushServiceSocket {
path += "&challenge=" + challenge.get();
}
makeServiceRequest(path, "GET", null, NO_HEADERS, new VerificationCodeResponseHandler());
makeServiceRequest(path, "GET", null, NO_HEADERS, new VerificationCodeResponseHandler(), Optional.empty());
}
public void requestVoiceVerificationCode(Locale locale, Optional<String> captchaToken, Optional<String> challenge) throws IOException {
@ -341,7 +341,7 @@ public class PushServiceSocket {
path += "?challenge=" + challenge.get();
}
makeServiceRequest(path, "GET", null, headers, new VerificationCodeResponseHandler());
makeServiceRequest(path, "GET", null, headers, new VerificationCodeResponseHandler(), Optional.empty());
}
public WhoAmIResponse getWhoAmI() throws IOException {
@ -487,7 +487,7 @@ public class PushServiceSocket {
}
public SendGroupMessageResponse sendGroupMessage(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online, boolean urgent, boolean story)
throws IOException
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
ServiceConnectionHolder connectionHolder = (ServiceConnectionHolder) getRandom(serviceClients, random);
@ -512,10 +512,27 @@ public class PushServiceSocket {
connections.add(call);
}
Response response;
try {
response = call.execute();
try (Response response = call.execute()) {
switch (response.code()) {
case 200:
return readBodyJson(response.body(), SendGroupMessageResponse.class);
case 401:
throw new InvalidUnidentifiedAccessHeaderException();
case 404:
throw new NotFoundException("At least one unregistered user in message send.");
case 409:
GroupMismatchedDevices[] mismatchedDevices = readBodyJson(response.body(), GroupMismatchedDevices[].class);
throw new GroupMismatchedDevicesException(mismatchedDevices);
case 410:
GroupStaleDevices[] staleDevices = readBodyJson(response.body(), GroupStaleDevices[].class);
throw new GroupStaleDevicesException(staleDevices);
case 508:
throw new ServerRejectedException();
default:
throw new NonSuccessfulResponseCodeException(response.code());
}
} catch (PushNetworkException | NonSuccessfulResponseCodeException | MalformedResponseException e) {
throw e;
} catch (IOException e) {
throw new PushNetworkException(e);
} finally {
@ -523,32 +540,13 @@ public class PushServiceSocket {
connections.remove(call);
}
}
switch (response.code()) {
case 200:
return readBodyJson(response.body(), SendGroupMessageResponse.class);
case 401:
throw new InvalidUnidentifiedAccessHeaderException();
case 404:
throw new NotFoundException("At least one unregistered user in message send.");
case 409:
GroupMismatchedDevices[] mismatchedDevices = readBodyJson(response.body(), GroupMismatchedDevices[].class);
throw new GroupMismatchedDevicesException(mismatchedDevices);
case 410:
GroupStaleDevices[] staleDevices = readBodyJson(response.body(), GroupStaleDevices[].class);
throw new GroupStaleDevicesException(staleDevices);
case 508:
throw new ServerRejectedException();
default:
throw new NonSuccessfulResponseCodeException(response.code());
}
}
public SendMessageResponse sendMessage(OutgoingPushMessageList bundle, Optional<UnidentifiedAccess> unidentifiedAccess, boolean story)
throws IOException
{
try {
String responseText = makeServiceRequest(String.format("/v1/messages/%s?story=%s", bundle.getDestination(), story ? "true" : "false"), "PUT", JsonUtil.toJson(bundle), NO_HEADERS, unidentifiedAccess);
String responseText = makeServiceRequest(String.format("/v1/messages/%s?story=%s", bundle.getDestination(), story ? "true" : "false"), "PUT", JsonUtil.toJson(bundle), NO_HEADERS, NO_HANDLER, unidentifiedAccess);
SendMessageResponse response = JsonUtil.fromJson(responseText, SendMessageResponse.class);
response.setSentUnidentfied(unidentifiedAccess.isPresent());
@ -562,7 +560,7 @@ public class PushServiceSocket {
public SignalServiceMessagesResult getMessages(boolean allowStories) throws IOException {
Map<String, String> headers = Collections.singletonMap("X-Signal-Receive-Stories", allowStories ? "true" : "false");
try (Response response = makeServiceRequest(String.format(MESSAGE_PATH, ""), "GET", (RequestBody) null, headers, NO_HANDLER, Optional.empty())) {
try (Response response = makeServiceRequest(String.format(MESSAGE_PATH, ""), "GET", (RequestBody) null, headers, NO_HANDLER, Optional.empty(), false)) {
validateServiceResponse(response);
List<SignalServiceEnvelopeEntity> envelopes = readBodyJson(response.body(), SignalServiceEnvelopeEntityList.class).getMessages();
@ -640,7 +638,7 @@ public class PushServiceSocket {
Log.d(TAG, "Fetching prekeys for " + destination.getIdentifier() + "." + deviceId + ", i.e. GET " + path);
String responseText = makeServiceRequest(path, "GET", null, NO_HEADERS, unidentifiedAccess);
String responseText = makeServiceRequest(path, "GET", null, NO_HEADERS, NO_HANDLER, unidentifiedAccess);
PreKeyResponse response = JsonUtil.fromJson(responseText, PreKeyResponse.class);
List<PreKeyBundle> bundles = new LinkedList<>();
@ -885,9 +883,10 @@ public class PushServiceSocket {
@Nonnull ResponseMapper<IdentityCheckResponse> responseMapper)
{
Single<ServiceResponse<IdentityCheckResponse>> requestSingle = Single.fromCallable(() -> {
Response response = getServiceConnection(PROFILE_BATCH_CHECK_PATH, "POST", jsonRequestBody(JsonUtil.toJson(request)), Collections.emptyMap(), unidentifiedAccess, false);
String body = response.body() != null ? response.body().string() : "";
return responseMapper.map(response.code(), body, response::header, unidentifiedAccess.isPresent());
try (Response response = getServiceConnection(PROFILE_BATCH_CHECK_PATH, "POST", jsonRequestBody(JsonUtil.toJson(request)), Collections.emptyMap(), unidentifiedAccess, false)) {
String body = response.body() != null ? readBodyString(response.body()): "";
return responseMapper.map(response.code(), body, response::header, unidentifiedAccess.isPresent());
}
});
return requestSingle
@ -915,6 +914,7 @@ public class PushServiceSocket {
String.format(GET_USERNAME_PATH, URLEncoder.encode(username, StandardCharsets.UTF_8.toString())),
"GET",
null,
NO_HEADERS,
(responseCode, body) -> {
if (responseCode == 404) {
throw new UsernameIsNotAssociatedWithAnAccountException();
@ -1036,7 +1036,7 @@ public class PushServiceSocket {
}
public SubscriptionLevels getBoostLevels(Locale locale) throws IOException {
String result = makeServiceRequestWithoutAuthentication(BOOST_BADGES, "GET", null, AcceptLanguagesUtil.getHeadersWithAcceptLanguage(locale));
String result = makeServiceRequestWithoutAuthentication(BOOST_BADGES, "GET", null, AcceptLanguagesUtil.getHeadersWithAcceptLanguage(locale), NO_HANDLER);
return JsonUtil.fromJsonResponse(result, SubscriptionLevels.class);
}
@ -1046,6 +1046,7 @@ public class PushServiceSocket {
BOOST_RECEIPT_CREDENTIALS,
"POST",
payload,
NO_HEADERS,
(code, body) -> {
if (code == 204) throw new NonSuccessfulResponseCodeException(204);
});
@ -1060,7 +1061,7 @@ public class PushServiceSocket {
public SubscriptionLevels getSubscriptionLevels(Locale locale) throws IOException {
String result = makeServiceRequestWithoutAuthentication(SUBSCRIPTION_LEVELS, "GET", null, AcceptLanguagesUtil.getHeadersWithAcceptLanguage(locale));
String result = makeServiceRequestWithoutAuthentication(SUBSCRIPTION_LEVELS, "GET", null, AcceptLanguagesUtil.getHeadersWithAcceptLanguage(locale), NO_HANDLER);
return JsonUtil.fromJsonResponse(result, SubscriptionLevels.class);
}
@ -1096,6 +1097,7 @@ public class PushServiceSocket {
String.format(SUBSCRIPTION_RECEIPT_CREDENTIALS, subscriptionId),
"POST",
payload,
NO_HEADERS,
(code, body) -> {
if (code == 204) throw new NonSuccessfulResponseCodeException(204);
});
@ -1109,7 +1111,7 @@ public class PushServiceSocket {
}
private AuthCredentials getAuthCredentials(String authPath) throws IOException {
String response = makeServiceRequest(authPath, "GET", null, NO_HEADERS);
String response = makeServiceRequest(authPath, "GET", null);
AuthCredentials token = JsonUtil.fromJson(response, AuthCredentials.class);
return token;
}
@ -1133,36 +1135,24 @@ public class PushServiceSocket {
public TokenResponse getKeyBackupServiceToken(String authorizationToken, String enclaveName)
throws IOException
{
ResponseBody body = makeRequest(ClientSet.KeyBackup, authorizationToken, null, "/v1/token/" + enclaveName, "GET", null).body();
if (body != null) {
return JsonUtil.fromJson(body.string(), TokenResponse.class);
} else {
throw new MalformedResponseException("Empty response!");
try (Response response = makeRequest(ClientSet.KeyBackup, authorizationToken, null, "/v1/token/" + enclaveName, "GET", null)) {
return readBodyJson(response, TokenResponse.class);
}
}
public DiscoveryResponse getContactDiscoveryRegisteredUsers(String authorizationToken, DiscoveryRequest request, List<String> cookies, String mrenclave)
throws IOException
{
ResponseBody body = makeRequest(ClientSet.ContactDiscovery, authorizationToken, cookies, "/v1/discovery/" + mrenclave, "PUT", JsonUtil.toJson(request)).body();
if (body != null) {
return JsonUtil.fromJson(body.string(), DiscoveryResponse.class);
} else {
throw new MalformedResponseException("Empty response!");
try (Response response = makeRequest(ClientSet.ContactDiscovery, authorizationToken, cookies, "/v1/discovery/" + mrenclave, "PUT", JsonUtil.toJson(request))) {
return readBodyJson(response, DiscoveryResponse.class);
}
}
public KeyBackupResponse putKbsData(String authorizationToken, KeyBackupRequest request, List<String> cookies, String mrenclave)
throws IOException
{
ResponseBody body = makeRequest(ClientSet.KeyBackup, authorizationToken, cookies, "/v1/backup/" + mrenclave, "PUT", JsonUtil.toJson(request)).body();
if (body != null) {
return JsonUtil.fromJson(body.string(), KeyBackupResponse.class);
} else {
throw new MalformedResponseException("Empty response!");
try (Response response = makeRequest(ClientSet.KeyBackup, authorizationToken, cookies, "/v1/backup/" + mrenclave, "PUT", JsonUtil.toJson(request))) {
return readBodyJson(response, KeyBackupResponse.class);
}
}
@ -1179,38 +1169,25 @@ public class PushServiceSocket {
}
public StorageManifest getStorageManifest(String authToken) throws IOException {
ResponseBody response = makeStorageRequest(authToken, "/v1/storage/manifest", "GET", null);
if (response == null) {
throw new IOException("Missing body!");
try (Response response = makeStorageRequest(authToken, "/v1/storage/manifest", "GET", null, NO_HANDLER)) {
return StorageManifest.parseFrom(readBodyBytes(response));
}
return StorageManifest.parseFrom(readBodyBytes(response));
}
public StorageManifest getStorageManifestIfDifferentVersion(String authToken, long version) throws IOException {
ResponseBody response = makeStorageRequest(authToken, "/v1/storage/manifest/version/" + version, "GET", null);
if (response == null) {
throw new IOException("Missing body!");
try (Response response = makeStorageRequest(authToken, "/v1/storage/manifest/version/" + version, "GET", null, NO_HANDLER)) {
return StorageManifest.parseFrom(readBodyBytes(response));
}
return StorageManifest.parseFrom(readBodyBytes(response));
}
public StorageItems readStorageItems(String authToken, ReadOperation operation) throws IOException {
ResponseBody response = makeStorageRequest(authToken, "/v1/storage/read", "PUT", protobufRequestBody(operation));
if (response == null) {
throw new IOException("Missing body!");
try (Response response = makeStorageRequest(authToken, "/v1/storage/read", "PUT", protobufRequestBody(operation), NO_HANDLER)) {
return StorageItems.parseFrom(readBodyBytes(response));
}
return StorageItems.parseFrom(readBodyBytes(response));
}
public Optional<StorageManifest> writeStorageContacts(String authToken, WriteOperation writeOperation) throws IOException {
try {
makeAndCloseStorageRequest(authToken, "/v1/storage", "PUT", protobufRequestBody(writeOperation));
try (Response response = makeStorageRequest(authToken, "/v1/storage", "PUT", protobufRequestBody(writeOperation), NO_HANDLER)) {
return Optional.empty();
} catch (ContactManifestMismatchException e) {
return Optional.of(StorageManifest.parseFrom(e.getResponseBody()));
@ -1218,7 +1195,9 @@ public class PushServiceSocket {
}
public void pingStorageService() throws IOException {
makeAndCloseStorageRequest(null, "/ping", "GET", null);
try (Response response = makeStorageRequest(null, "/ping", "GET", null, NO_HANDLER)) {
return;
}
}
public RemoteConfigResponse getRemoteConfig() throws IOException {
@ -1354,14 +1333,9 @@ public class PushServiceSocket {
connections.add(call);
}
Response response = null;
ResponseBody body = null;
try {
response = call.execute();
try (Response response = call.execute()) {
if (response.isSuccessful()) {
body = response.body();
ResponseBody body = response.body();
if (body == null) throw new PushNetworkException("No response body!");
if (body.contentLength() > maxSizeBytes) throw new PushNetworkException("Response exceeds max size!");
@ -1380,25 +1354,20 @@ public class PushServiceSocket {
listener.onAttachmentProgress(body.contentLength() + offset, totalRead);
}
}
return;
} else if (response.code() == 416) {
throw new RangeException(offset);
} else {
throw new NonSuccessfulResponseCodeException(response.code(), "Response: " + response);
}
} catch (NonSuccessfulResponseCodeException | PushNetworkException e) {
throw e;
} catch (IOException e) {
throw new PushNetworkException(e);
} finally {
if (body != null) {
body.close();
}
synchronized (connections) {
connections.remove(call);
}
}
throw new NonSuccessfulResponseCodeException(response.code(), "Response: " + response);
}
private byte[] uploadToCdn0(String path, String acl, String key, String policy, String algorithm,
@ -1444,17 +1413,13 @@ public class PushServiceSocket {
connections.add(call);
}
try {
Response response;
try {
response = call.execute();
} catch (IOException e) {
throw new PushNetworkException(e);
}
try (Response response = call.execute()) {
if (response.isSuccessful()) return file.getTransmittedDigest();
else throw new NonSuccessfulResponseCodeException(response.code(), "Response: " + response);
} catch (PushNetworkException | NonSuccessfulResponseCodeException e) {
throw e;
} catch (IOException e) {
throw new PushNetworkException(e);
} finally {
synchronized (connections) {
connections.remove(call);
@ -1493,20 +1458,16 @@ public class PushServiceSocket {
connections.add(call);
}
try {
Response response;
try {
response = call.execute();
} catch (IOException e) {
throw new PushNetworkException(e);
}
try (Response response = call.execute()) {
if (response.isSuccessful()) {
return response.header("location");
} else {
throw new NonSuccessfulResponseCodeException(response.code(), "Response: " + response);
}
} catch (PushNetworkException | NonSuccessfulResponseCodeException e) {
throw e;
} catch (IOException e) {
throw new PushNetworkException(e);
} finally {
synchronized (connections) {
connections.remove(call);
@ -1550,6 +1511,8 @@ public class PushServiceSocket {
try (Response response = call.execute()) {
if (response.isSuccessful()) return file.getTransmittedDigest();
else throw new NonSuccessfulResponseCodeException(response.code(), "Response: " + response);
} catch (PushNetworkException | NonSuccessfulResponseCodeException e) {
throw e;
} catch (IOException e) {
throw new PushNetworkException(e);
} finally {
@ -1584,15 +1547,7 @@ public class PushServiceSocket {
connections.add(call);
}
try {
Response response;
try {
response = call.execute();
} catch (IOException e) {
throw new PushNetworkException(e);
}
try (Response response = call.execute()) {
if (response.isSuccessful()) {
offset = contentLength;
contentRange = null;
@ -1611,6 +1566,10 @@ public class PushServiceSocket {
} else {
throw new NonSuccessfulResumableUploadResponseCodeException(response.code(), "Response: " + response);
}
} catch (PushNetworkException | NonSuccessfulResponseCodeException e) {
throw e;
} catch (IOException e) {
throw new PushNetworkException(e);
} finally {
synchronized (connections) {
connections.remove(call);
@ -1642,29 +1601,14 @@ public class PushServiceSocket {
private String makeServiceRequestWithoutAuthentication(String urlFragment, String method, String jsonBody)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
return makeServiceRequestWithoutAuthentication(urlFragment, method, jsonBody, NO_HANDLER);
}
private String makeServiceRequestWithoutAuthentication(String urlFragment, String method, String jsonBody, ResponseCodeHandler responseCodeHandler)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
return makeServiceRequestWithoutAuthentication(urlFragment, method, jsonBody, NO_HEADERS, responseCodeHandler);
}
private String makeServiceRequestWithoutAuthentication(String urlFragment, String method, String jsonBody, Map<String, String> headers)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
return makeServiceRequestWithoutAuthentication(urlFragment, method, jsonBody, headers, NO_HANDLER);
return makeServiceRequestWithoutAuthentication(urlFragment, method, jsonBody, NO_HEADERS, NO_HANDLER);
}
private String makeServiceRequestWithoutAuthentication(String urlFragment, String method, String jsonBody, Map<String, String> headers, ResponseCodeHandler responseCodeHandler)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
ResponseBody responseBody = makeServiceRequest(urlFragment, method, jsonRequestBody(jsonBody), headers, responseCodeHandler, Optional.empty(), true).body();
try {
return responseBody.string();
} catch (IOException e) {
throw new PushNetworkException(e);
try (Response response = makeServiceRequest(urlFragment, method, jsonRequestBody(jsonBody), headers, responseCodeHandler, Optional.empty(), true)) {
return readBodyString(response);
}
}
@ -1674,45 +1618,22 @@ public class PushServiceSocket {
return makeServiceRequest(urlFragment, method, jsonBody, NO_HEADERS, NO_HANDLER, Optional.empty());
}
private String makeServiceRequest(String urlFragment, String method, String jsonBody, Map<String, String> headers)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
return makeServiceRequest(urlFragment, method, jsonBody, headers, NO_HANDLER, Optional.empty());
}
private String makeServiceRequest(String urlFragment, String method, String jsonBody, Map<String, String> headers, ResponseCodeHandler responseCodeHandler)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
return makeServiceRequest(urlFragment, method, jsonBody, headers, responseCodeHandler, Optional.empty());
}
private String makeServiceRequest(String urlFragment, String method, String jsonBody, Map<String, String> headers, Optional<UnidentifiedAccess> unidentifiedAccessKey)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
return makeServiceRequest(urlFragment, method, jsonBody, headers, NO_HANDLER, unidentifiedAccessKey);
}
private String makeServiceRequest(String urlFragment, String method, String jsonBody, Map<String, String> headers, ResponseCodeHandler responseCodeHandler, Optional<UnidentifiedAccess> unidentifiedAccessKey)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
ResponseBody responseBody = makeServiceBodyRequest(urlFragment, method, jsonRequestBody(jsonBody), headers, responseCodeHandler, unidentifiedAccessKey);
try {
return responseBody.string();
} catch (IOException e) {
throw new PushNetworkException(e);
try (Response response = makeServiceRequest(urlFragment, method, jsonRequestBody(jsonBody), headers, responseCodeHandler, unidentifiedAccessKey, false)) {
return readBodyString(response);
}
}
private static RequestBody jsonRequestBody(String jsonBody) {
return jsonBody != null
? RequestBody.create(MediaType.parse("application/json"), jsonBody)
: null;
return jsonBody != null ? RequestBody.create(MediaType.parse("application/json"), jsonBody)
: null;
}
private static RequestBody protobufRequestBody(MessageLite protobufBody) {
return protobufBody != null
? RequestBody.create(MediaType.parse("application/x-protobuf"), protobufBody.toByteArray())
: null;
return protobufBody != null ? RequestBody.create(MediaType.parse("application/x-protobuf"), protobufBody.toByteArray())
: null;
}
@ -1751,28 +1672,6 @@ public class PushServiceSocket {
return bodyFuture;
}
private ResponseBody makeServiceBodyRequest(String urlFragment,
String method,
RequestBody body,
Map<String, String> headers,
ResponseCodeHandler responseCodeHandler,
Optional<UnidentifiedAccess> unidentifiedAccessKey)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
return makeServiceRequest(urlFragment, method, body, headers, responseCodeHandler, unidentifiedAccessKey).body();
}
private Response makeServiceRequest(String urlFragment,
String method,
RequestBody body,
Map<String, String> headers,
ResponseCodeHandler responseCodeHandler,
Optional<UnidentifiedAccess> unidentifiedAccessKey)
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
return makeServiceRequest(urlFragment, method, body, headers, responseCodeHandler, unidentifiedAccessKey, false);
}
private Response makeServiceRequest(String urlFragment,
String method,
RequestBody body,
@ -1783,18 +1682,8 @@ public class PushServiceSocket {
throws NonSuccessfulResponseCodeException, PushNetworkException, MalformedResponseException
{
Response response = getServiceConnection(urlFragment, method, body, headers, unidentifiedAccessKey, doNotAddAuthenticationOrUnidentifiedAccessKey);
ResponseBody responseBody = response.body();
try {
responseCodeHandler.handle(response.code(), responseBody);
return validateServiceResponse(response);
} catch (NonSuccessfulResponseCodeException | PushNetworkException | MalformedResponseException e) {
if (responseBody != null) {
responseBody.close();
}
throw e;
}
responseCodeHandler.handle(response.code(), response.body());
return validateServiceResponse(response);
}
private Response validateServiceResponse(Response response)
@ -1952,12 +1841,6 @@ public class PushServiceSocket {
{
ConnectionHolder connectionHolder = getRandom(clientsFor(clientSet), random);
return makeRequest(connectionHolder, authorization, cookies, path, method, body);
}
private Response makeRequest(ConnectionHolder connectionHolder, String authorization, List<String> cookies, String path, String method, String body)
throws PushNetworkException, NonSuccessfulResponseCodeException
{
OkHttpClient okHttpClient = connectionHolder.getClient()
.newBuilder()
.connectTimeout(soTimeoutMillis, TimeUnit.MILLISECONDS)
@ -2019,34 +1902,7 @@ public class PushServiceSocket {
throw new NonSuccessfulResponseCodeException(response.code(), "Response: " + response);
}
private void makeAndCloseStorageRequest(String authorization, String path, String method, RequestBody body)
throws PushNetworkException, NonSuccessfulResponseCodeException
{
makeAndCloseStorageRequest(authorization, path, method, body, NO_HANDLER);
}
private void makeAndCloseStorageRequest(String authorization, String path, String method, RequestBody body, ResponseCodeHandler responseCodeHandler)
throws PushNetworkException, NonSuccessfulResponseCodeException
{
ResponseBody responseBody = makeStorageRequest(authorization, path, method, body, responseCodeHandler);
if (responseBody != null) {
responseBody.close();
}
}
private ResponseBody makeStorageRequest(String authorization, String path, String method, RequestBody body)
throws PushNetworkException, NonSuccessfulResponseCodeException
{
return makeStorageRequest(authorization, path, method, body, NO_HANDLER);
}
private ResponseBody makeStorageRequest(String authorization, String path, String method, RequestBody body, ResponseCodeHandler responseCodeHandler)
throws PushNetworkException, NonSuccessfulResponseCodeException
{
return makeStorageRequestResponse(authorization, path, method, body, responseCodeHandler).body();
}
private Response makeStorageRequestResponse(String authorization, String path, String method, RequestBody body, ResponseCodeHandler responseCodeHandler)
private Response makeStorageRequest(String authorization, String path, String method, RequestBody body, ResponseCodeHandler responseCodeHandler)
throws PushNetworkException, NonSuccessfulResponseCodeException
{
ConnectionHolder connectionHolder = getRandom(storageClients, random);
@ -2091,8 +1947,7 @@ public class PushServiceSocket {
}
}
ResponseBody responseBody = response.body();
try {
try (ResponseBody responseBody = response.body()) {
responseCodeHandler.handle(response.code(), responseBody, response::header);
switch (response.code()) {
@ -2116,11 +1971,6 @@ public class PushServiceSocket {
}
throw new NonSuccessfulResponseCodeException(response.code(), "Response: " + response);
} catch (NonSuccessfulResponseCodeException | PushNetworkException e) {
if (responseBody != null) {
responseBody.close();
}
throw e;
}
}
@ -2276,12 +2126,21 @@ public class PushServiceSocket {
/**
* Converts {@link IOException} on body byte reading to {@link PushNetworkException}.
*/
private static byte[] readBodyBytes(ResponseBody response) throws PushNetworkException {
if (response == null) {
throw new PushNetworkException("No body!");
private static byte[] readBodyBytes(Response response) throws PushNetworkException, MalformedResponseException {
if (response.body() == null) {
throw new MalformedResponseException("No body!");
}
try {
return response.bytes();
return response.body().bytes();
} catch (IOException e) {
throw new PushNetworkException(e);
}
}
private static byte[] readBodyBytes(@Nonnull ResponseBody responseBody) throws PushNetworkException {
try {
return responseBody.bytes();
} catch (IOException e) {
throw new PushNetworkException(e);
}
@ -2290,9 +2149,16 @@ public class PushServiceSocket {
/**
* Converts {@link IOException} on body reading to {@link PushNetworkException}.
*/
private static String readBodyString(ResponseBody body) throws PushNetworkException {
static String readBodyString(Response response) throws PushNetworkException, MalformedResponseException {
return readBodyString(response.body());
}
/**
* Converts {@link IOException} on body reading to {@link PushNetworkException}.
*/
private static String readBodyString(ResponseBody body) throws PushNetworkException, MalformedResponseException {
if (body == null) {
throw new PushNetworkException("No body!");
throw new MalformedResponseException("No body!");
}
try {
@ -2302,12 +2168,21 @@ public class PushServiceSocket {
}
}
/**
* Converts {@link IOException} on body reading to {@link PushNetworkException}.
* {@link IOException} during json parsing is converted to a {@link MalformedResponseException}
*/
private static <T> T readBodyJson(Response response, Class<T> clazz) throws PushNetworkException, MalformedResponseException {
return readBodyJson(response.body(), clazz);
}
/**
* Converts {@link IOException} on body reading to {@link PushNetworkException}.
* {@link IOException} during json parsing is converted to a {@link MalformedResponseException}
*/
private static <T> T readBodyJson(ResponseBody body, Class<T> clazz) throws PushNetworkException, MalformedResponseException {
String json = readBodyString(body);
try {
return JsonUtil.fromJson(json, clazz);
} catch (JsonProcessingException e) {
@ -2439,6 +2314,7 @@ public class PushServiceSocket {
"GET",
null,
NO_HEADERS,
NO_HANDLER,
Optional.empty());
return JsonUtil.fromJson(response, CredentialResponse.class);
@ -2474,39 +2350,44 @@ public class PushServiceSocket {
public void putNewGroupsV2Group(Group group, GroupsV2AuthorizationString authorization)
throws NonSuccessfulResponseCodeException, PushNetworkException
{
makeAndCloseStorageRequest(authorization.toString(),
GROUPSV2_GROUP,
"PUT",
protobufRequestBody(group),
GROUPS_V2_PUT_RESPONSE_HANDLER);
try (Response response = makeStorageRequest(authorization.toString(),
GROUPSV2_GROUP,
"PUT",
protobufRequestBody(group),
GROUPS_V2_PUT_RESPONSE_HANDLER))
{
return;
}
}
public Group getGroupsV2Group(GroupsV2AuthorizationString authorization)
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException, MalformedResponseException
{
ResponseBody response = makeStorageRequest(authorization.toString(),
GROUPSV2_GROUP,
"GET",
null,
GROUPS_V2_GET_CURRENT_HANDLER);
return Group.parseFrom(readBodyBytes(response));
try (Response response = makeStorageRequest(authorization.toString(),
GROUPSV2_GROUP,
"GET",
null,
GROUPS_V2_GET_CURRENT_HANDLER))
{
return Group.parseFrom(readBodyBytes(response));
}
}
public AvatarUploadAttributes getGroupsV2AvatarUploadForm(String authorization)
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException, MalformedResponseException
{
ResponseBody response = makeStorageRequest(authorization,
GROUPSV2_AVATAR_REQUEST,
"GET",
null,
NO_HANDLER);
return AvatarUploadAttributes.parseFrom(readBodyBytes(response));
try (Response response = makeStorageRequest(authorization,
GROUPSV2_AVATAR_REQUEST,
"GET",
null,
NO_HANDLER))
{
return AvatarUploadAttributes.parseFrom(readBodyBytes(response));
}
}
public GroupChange patchGroupsV2Group(GroupChange.Actions groupChange, String authorization, Optional<byte[]> groupLinkPassword)
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException, MalformedResponseException
{
String path;
@ -2516,74 +2397,79 @@ public class PushServiceSocket {
path = GROUPSV2_GROUP;
}
ResponseBody response = makeStorageRequest(authorization,
path,
"PATCH",
protobufRequestBody(groupChange),
GROUPS_V2_PATCH_RESPONSE_HANDLER);
return GroupChange.parseFrom(readBodyBytes(response));
try (Response response = makeStorageRequest(authorization,
path,
"PATCH",
protobufRequestBody(groupChange),
GROUPS_V2_PATCH_RESPONSE_HANDLER))
{
return GroupChange.parseFrom(readBodyBytes(response));
}
}
public GroupHistory getGroupsV2GroupHistory(int fromVersion, GroupsV2AuthorizationString authorization, int highestKnownEpoch, boolean includeFirstState)
throws IOException
throws IOException
{
Response response = makeStorageRequestResponse(authorization.toString(),
String.format(Locale.US, GROUPSV2_GROUP_CHANGES, fromVersion, highestKnownEpoch, includeFirstState),
"GET",
null,
GROUPS_V2_GET_LOGS_HANDLER);
try (Response response = makeStorageRequest(authorization.toString(),
String.format(Locale.US, GROUPSV2_GROUP_CHANGES, fromVersion, highestKnownEpoch, includeFirstState),
"GET",
null,
GROUPS_V2_GET_LOGS_HANDLER))
{
if (response.body() == null) {
throw new PushNetworkException("No body!");
}
GroupChanges groupChanges;
try (InputStream input = response.body().byteStream()) {
groupChanges = GroupChanges.parseFrom(input);
} catch (IOException e) {
throw new PushNetworkException(e);
}
if (response.code() == 206) {
String contentRangeHeader = response.header("Content-Range");
Optional<ContentRange> contentRange = ContentRange.parse(contentRangeHeader);
if (contentRange.isPresent()) {
Log.i(TAG, "Additional logs for group: " + contentRangeHeader);
return new GroupHistory(groupChanges, contentRange);
} else {
Log.w(TAG, "Unable to parse Content-Range header: " + contentRangeHeader);
throw new MalformedResponseException("Unable to parse content range header on 206");
if (response.body() == null) {
throw new PushNetworkException("No body!");
}
}
return new GroupHistory(groupChanges, Optional.empty());
GroupChanges groupChanges;
try (InputStream input = response.body().byteStream()) {
groupChanges = GroupChanges.parseFrom(input);
} catch (IOException e) {
throw new PushNetworkException(e);
}
if (response.code() == 206) {
String contentRangeHeader = response.header("Content-Range");
Optional<ContentRange> contentRange = ContentRange.parse(contentRangeHeader);
if (contentRange.isPresent()) {
Log.i(TAG, "Additional logs for group: " + contentRangeHeader);
return new GroupHistory(groupChanges, contentRange);
} else {
Log.w(TAG, "Unable to parse Content-Range header: " + contentRangeHeader);
throw new MalformedResponseException("Unable to parse content range header on 206");
}
}
return new GroupHistory(groupChanges, Optional.empty());
}
}
public GroupJoinInfo getGroupJoinInfo(Optional<byte[]> groupLinkPassword, GroupsV2AuthorizationString authorization)
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException, MalformedResponseException
{
String passwordParam = groupLinkPassword.map(Base64UrlSafe::encodeBytesWithoutPadding).orElse("");
ResponseBody response = makeStorageRequest(authorization.toString(),
String.format(GROUPSV2_GROUP_JOIN, passwordParam),
"GET",
null,
GROUPS_V2_GET_JOIN_INFO_HANDLER);
return GroupJoinInfo.parseFrom(readBodyBytes(response));
String passwordParam = groupLinkPassword.map(Base64UrlSafe::encodeBytesWithoutPadding).orElse("");
try (Response response = makeStorageRequest(authorization.toString(),
String.format(GROUPSV2_GROUP_JOIN, passwordParam),
"GET",
null,
GROUPS_V2_GET_JOIN_INFO_HANDLER))
{
return GroupJoinInfo.parseFrom(readBodyBytes(response));
}
}
public GroupExternalCredential getGroupExternalCredential(GroupsV2AuthorizationString authorization)
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException
throws NonSuccessfulResponseCodeException, PushNetworkException, InvalidProtocolBufferException, MalformedResponseException
{
ResponseBody response = makeStorageRequest(authorization.toString(),
GROUPSV2_TOKEN,
"GET",
null,
NO_HANDLER);
return GroupExternalCredential.parseFrom(readBodyBytes(response));
try (Response response = makeStorageRequest(authorization.toString(),
GROUPSV2_TOKEN,
"GET",
null,
NO_HANDLER))
{
return GroupExternalCredential.parseFrom(readBodyBytes(response));
}
}
public CurrencyConversions getCurrencyConversions()
@ -2609,22 +2495,16 @@ public class PushServiceSocket {
public void handle(int responseCode, ResponseBody responseBody) throws NonSuccessfulResponseCodeException, PushNetworkException {
switch (responseCode) {
case 400:
String body;
try {
body = responseBody != null ? responseBody.string() : "";
} catch (IOException e) {
throw new PushNetworkException(e);
}
if (body.isEmpty()) {
throw new ImpossiblePhoneNumberException();
} else {
try {
throw NonNormalizedPhoneNumberException.forResponse(body);
} catch (MalformedResponseException e) {
Log.w(TAG, "Unable to parse 400 response! Assuming a generic 400.");
String body = responseBody != null ? readBodyString(responseBody) : "";
if (body.isEmpty()) {
throw new ImpossiblePhoneNumberException();
} else {
throw NonNormalizedPhoneNumberException.forResponse(body);
}
} catch (MalformedResponseException e) {
Log.w(TAG, "Unable to parse 400 response! Assuming a generic 400.");
throw new ImpossiblePhoneNumberException();
}
case 402:
throw new CaptchaRequiredException();

Wyświetl plik

@ -18,6 +18,7 @@ import org.whispersystems.signalservice.internal.util.JsonUtil;
import java.io.IOException;
import java.security.KeyStore;
import java.security.SignatureException;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@ -87,14 +88,10 @@ public final class RemoteAttestationUtil {
throws IOException
{
RemoteAttestationRequest attestationRequest = new RemoteAttestationRequest(keyPair.getPublicKey().getPublicKeyBytes());
Response response = socket.makeRequest(clientSet, authorization, new LinkedList<String>(), "/v1/attestation/" + enclaveName, "PUT", JsonUtil.toJson(attestationRequest));
ResponseBody body = response.body();
if (body == null) {
throw new MalformedResponseException("Empty response!");
try (Response response = socket.makeRequest(clientSet, authorization, Collections.emptyList(), "/v1/attestation/" +enclaveName, "PUT", JsonUtil.toJson(attestationRequest))) {
return new ResponsePair(PushServiceSocket.readBodyString(response), parseCookies(response));
}
return new ResponsePair(body.string(), parseCookies(response));
}
private static List<String> parseCookies(Response response) {