diff --git a/.pubnub.yml b/.pubnub.yml
index 3d1620b0d..d0158c947 100644
--- a/.pubnub.yml
+++ b/.pubnub.yml
@@ -1,10 +1,19 @@
name: java
-version: 4.33.2
+version: 4.33.3
schema: 1
scm: github.com/pubnub/java
files:
- - build/libs/pubnub-gson-4.33.2-all.jar
+ - build/libs/pubnub-gson-4.33.3-all.jar
changelog:
+ - version: v4.33.3
+ date: 2020-10-21
+ changes:
+ - type: bug
+ text: "Improved handling of random initialization vector for encrypting messages."
+ - type: bug
+ text: "Restore Android compatibility for Gradle 3.X by removing Stringjoin()."
+ - type: bug
+ text: "Return appropriate error information when payload is too large."
- version: v4.33.2
date: 2020-10-08
changes:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e6a663d1..365f3a36a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+## [v4.33.3](https://github.com/pubnub/java/releases/tag/v4.33.3)
+October-21-2020
+
+[Full Changelog](https://github.com/pubnub/java/compare/v4.33.2...v4.33.3)
+
+- 🐛 Improved handling of random initialization vector for encrypting messages.
+- 🐛 Restore Android compatibility for Gradle 3.X by removing Stringjoin().
+- 🐛 Return appropriate error information when payload is too large.
+
## [v4.33.2](https://github.com/pubnub/java/releases/tag/v4.33.2)
October-08-2020
diff --git a/build.gradle b/build.gradle
index 4794778bc..2262f2f96 100644
--- a/build.gradle
+++ b/build.gradle
@@ -11,7 +11,7 @@ plugins {
}
group = 'com.pubnub'
-version = '4.33.2'
+version = '4.33.3'
description = """"""
diff --git a/src/main/java/com/pubnub/api/PubNub.java b/src/main/java/com/pubnub/api/PubNub.java
index 931f36fea..3548a6c13 100644
--- a/src/main/java/com/pubnub/api/PubNub.java
+++ b/src/main/java/com/pubnub/api/PubNub.java
@@ -92,7 +92,7 @@ public class PubNub {
private static final int TIMESTAMP_DIVIDER = 1000;
private static final int MAX_SEQUENCE = 65535;
- private static final String SDK_VERSION = "4.33.2";
+ private static final String SDK_VERSION = "4.33.3";
public PubNub(@NotNull PNConfiguration initialConfig) {
this.configuration = initialConfig;
diff --git a/src/main/java/com/pubnub/api/builder/PubNubErrorBuilder.java b/src/main/java/com/pubnub/api/builder/PubNubErrorBuilder.java
index 8b2f9bf4a..c244d1a0c 100644
--- a/src/main/java/com/pubnub/api/builder/PubNubErrorBuilder.java
+++ b/src/main/java/com/pubnub/api/builder/PubNubErrorBuilder.java
@@ -341,6 +341,11 @@ public final class PubNubErrorBuilder {
*/
public static final int PNERR_PAGINATION_PREV_OUT_OF_BOUNDS = 166;
+ /**
+ * Payload too large
+ */
+ public static final int PNERR_PAYLOAD_TOO_LARGE = 167;
+
// Error Objects
public static final PubNubError PNERROBJ_TIMEOUT = PubNubError.builder()
.errorCode(PNERR_TIMEOUT)
@@ -680,6 +685,11 @@ public final class PubNubErrorBuilder {
.message("No pages to load before first one.")
.build();
+ public static final PubNubError PNERROBJ_PAYLOAD_TOO_LARGE = PubNubError.builder()
+ .errorCode(PNERR_PAYLOAD_TOO_LARGE)
+ .message("Payload too large.")
+ .build();
+
private PubNubErrorBuilder() {
}
diff --git a/src/main/java/com/pubnub/api/endpoints/Endpoint.java b/src/main/java/com/pubnub/api/endpoints/Endpoint.java
index 67bd2c692..c3acf1a75 100644
--- a/src/main/java/com/pubnub/api/endpoints/Endpoint.java
+++ b/src/main/java/com/pubnub/api/endpoints/Endpoint.java
@@ -109,13 +109,7 @@ public Output sync() throws PubNubException {
responseBody = null;
}
- throw PubNubException.builder()
- .pubnubError(PubNubErrorBuilder.PNERROBJ_HTTP_ERROR)
- .errormsg(responseBodyText)
- .jso(responseBody)
- .statusCode(serverResponse.code())
- .affectedCall(call)
- .build();
+ throw createPubNubException(serverResponse, responseBodyText, responseBody);
}
storeRequestLatency(serverResponse, getOperationType());
@@ -170,12 +164,7 @@ public void onResponse(Call performedCall, Response response) {
}
PNStatusCategory pnStatusCategory = PNStatusCategory.PNUnknownCategory;
- PubNubException ex = PubNubException.builder()
- .pubnubError(PubNubErrorBuilder.PNERROBJ_HTTP_ERROR)
- .errormsg(responseBodyText)
- .jso(responseBody)
- .statusCode(response.code())
- .build();
+ final PubNubException ex = createPubNubException(response, responseBodyText, responseBody);
if (response.code() == HttpURLConnection.HTTP_FORBIDDEN) {
pnStatusCategory = PNStatusCategory.PNAccessDeniedCategory;
@@ -266,6 +255,29 @@ public void onFailure(Call performedCall, Throwable throwable) {
});
}
+ private PubNubException createPubNubException(Response response,
+ String responseBodyText,
+ JsonElement responseBody) {
+ if (response.code() == HttpURLConnection.HTTP_ENTITY_TOO_LARGE
+ || response.code() == HttpURLConnection.HTTP_REQ_TOO_LONG) {
+ return PubNubException.builder()
+ .pubnubError(PubNubErrorBuilder.PNERROBJ_PAYLOAD_TOO_LARGE)
+ .affectedCall(call)
+ .statusCode(response.code())
+ .jso(responseBody)
+ .errormsg(PubNubErrorBuilder.PNERROBJ_PAYLOAD_TOO_LARGE.getMessage())
+ .build();
+ }
+
+ return PubNubException.builder()
+ .pubnubError(PubNubErrorBuilder.PNERROBJ_HTTP_ERROR)
+ .errormsg(responseBodyText)
+ .jso(responseBody)
+ .statusCode(response.code())
+ .affectedCall(call)
+ .build();
+ }
+
@Override
public void retry() {
silenceFailures = false;
diff --git a/src/main/java/com/pubnub/api/endpoints/objects_api/utils/Include.java b/src/main/java/com/pubnub/api/endpoints/objects_api/utils/Include.java
index 49eb3b455..2c7104193 100644
--- a/src/main/java/com/pubnub/api/endpoints/objects_api/utils/Include.java
+++ b/src/main/java/com/pubnub/api/endpoints/objects_api/utils/Include.java
@@ -3,7 +3,9 @@
import com.pubnub.api.endpoints.Endpoint;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -90,8 +92,21 @@ public void addInclusionFlag(final String inclusionFlag) {
public Map enrichParameters(Map baseParams) {
final Map enrichedMap = new HashMap<>(baseParams);
if (!inclusionFlags.isEmpty()) {
- enrichedMap.put(INCLUDE_PARAM_NAME, String.join(",", inclusionFlags));
+ enrichedMap.put(INCLUDE_PARAM_NAME, join(inclusionFlags));
}
return enrichedMap;
}
+
+ private String join(Collection values) {
+ final StringBuilder builder = new StringBuilder();
+ Iterator flagsIterator = values.iterator();
+
+ while (flagsIterator.hasNext()) {
+ builder.append(flagsIterator.next());
+ if (flagsIterator.hasNext()) {
+ builder.append(",");
+ }
+ }
+ return builder.toString();
+ }
}
diff --git a/src/main/java/com/pubnub/api/vendor/Crypto.java b/src/main/java/com/pubnub/api/vendor/Crypto.java
index 14d3f587d..ef73c234a 100644
--- a/src/main/java/com/pubnub/api/vendor/Crypto.java
+++ b/src/main/java/com/pubnub/api/vendor/Crypto.java
@@ -12,7 +12,6 @@
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
-import java.nio.Buffer;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
@@ -97,12 +96,12 @@ public String encrypt(String input) throws PubNubException {
Cipher cipher = null;
cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
- if (dynamicIV){
- byte[] outputBytes = input.getBytes(ENCODING_UTF_8);
- byte[] newOutputBytes = new byte[ivBytes.length+ outputBytes.length];
- System.arraycopy(ivBytes, 0, newOutputBytes, 0, ivBytes.length);
- System.arraycopy(outputBytes, 0, newOutputBytes, ivBytes.length, outputBytes.length);
- return new String(Base64.encode(cipher.doFinal(newOutputBytes), 0), Charset.forName(ENCODING_UTF_8));
+ if (dynamicIV) {
+ byte[] encrypted = cipher.doFinal(input.getBytes(ENCODING_UTF_8));
+ byte[] encryptedWithIV = new byte[ivBytes.length + encrypted.length];
+ System.arraycopy(ivBytes, 0, encryptedWithIV, 0, ivBytes.length);
+ System.arraycopy(encrypted, 0, encryptedWithIV, ivBytes.length, encrypted.length);
+ return new String(Base64.encode(encryptedWithIV, 0), Charset.forName(ENCODING_UTF_8));
}
else {
return new String(Base64.encode(cipher.doFinal(input.getBytes(ENCODING_UTF_8)), 0), Charset.forName(ENCODING_UTF_8));
diff --git a/src/test/java/com/pubnub/api/PubNubTest.java b/src/test/java/com/pubnub/api/PubNubTest.java
index ba27bcc95..110966284 100644
--- a/src/test/java/com/pubnub/api/PubNubTest.java
+++ b/src/test/java/com/pubnub/api/PubNubTest.java
@@ -98,7 +98,7 @@ public void getVersionAndTimeStamp() {
pubnub = new PubNub(pnConfiguration);
String version = pubnub.getVersion();
int timeStamp = pubnub.getTimestamp();
- Assert.assertEquals("4.33.2", version);
+ Assert.assertEquals("4.33.3", version);
Assert.assertTrue(timeStamp > 0);
}
diff --git a/src/test/java/com/pubnub/api/endpoints/EndpointTest.java b/src/test/java/com/pubnub/api/endpoints/EndpointTest.java
index 36643185c..5dc55d1bb 100644
--- a/src/test/java/com/pubnub/api/endpoints/EndpointTest.java
+++ b/src/test/java/com/pubnub/api/endpoints/EndpointTest.java
@@ -2,8 +2,15 @@
import com.pubnub.api.PubNub;
import com.pubnub.api.PubNubException;
+import com.pubnub.api.builder.PubNubErrorBuilder;
+import com.pubnub.api.callbacks.PNCallback;
import com.pubnub.api.enums.PNOperationType;
+import com.pubnub.api.models.consumer.PNStatus;
+import okhttp3.MediaType;
import okhttp3.Request;
+import okhttp3.ResponseBody;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -13,8 +20,10 @@
import retrofit2.Response;
import java.io.IOException;
+import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executors;
public class EndpointTest extends TestHarness {
@@ -68,53 +77,129 @@ protected boolean isAuthRequired() {
@Override
protected Call doWork(Map baseParams) throws PubNubException {
- Call fakeCall = new Call