@wizlif144, First let me say that these changes were made around March or April of this year, and I haven’t merged any changes from Couchbase since then, so things may have changed a bit. I also had to change some of the Android test cases to get all the tests to pass.
Here are the git logs for the changes I made:
coudhbase-lite-java-core (parent = 1ee944aee15ca597b07431e69b7779dafe54cc67
):
commit d133b4376cdfbc0c7aa93a7665908bc68a62a3eb
Fixed the issue where filter parameters are not being passed in the
query string of a POST message within the replicator. This change is
in the code that tracks the _changes channel from CouchDB/Cloudant.
diff --git a/src/main/java/com/couchbase/lite/replicator/ChangeTracker.java b/src/main/java/com/couchbase/lite/replicator/ChangeTracker.java
index f0f96927..3ebf40de 100644
--- a/src/main/java/com/couchbase/lite/replicator/ChangeTracker.java
+++ b/src/main/java/com/couchbase/lite/replicator/ChangeTracker.java
@@ -105,7 +105,11 @@ public class ChangeTracker implements Runnable {
this.limit = 0;
this.requestHeaders = new HashMap<String, Object>();
this.heartBeatSeconds = Replication.DEFAULT_HEARTBEAT;
- this.usePOST = true;
+ // Set the default for _changes queries to GET, and only use POST
+ // when there are docIDs present or when the filter is set to
+ // sync_gateway/bychannel. This prevents query strings from
+ // getting prohibitively long when long docIDs or channel lists are set.
+ this.usePOST = false;
}
public boolean isContinuous() {
@@ -118,6 +122,12 @@ public class ChangeTracker implements Runnable {
public void setFilterName(String filterName) {
this.filterName = filterName;
+ // If the filter is set to filter by channels, then use the POST
+ // to query _changes. This keeps things as they were for channel
+ // filtering, and prevents long query strings.
+ if (ReplicationInternal.BY_CHANNEL_FILTER_NAME.equals(filterName)) {
+ setUsePOST(true);
+ }
}
public void setFilterParams(Map<String, Object> filterParams) {
@@ -322,6 +332,10 @@ public class ChangeTracker implements Runnable {
.addHeader("Accept-Encoding", "gzip")
.post(RequestBody.create(JSON, changesFeedPOSTBody()));
}
+ else {
+ builder.header("User-Agent", Manager.getUserAgent())
+ .addHeader("Accept-Encoding", "gzip");
+ }
addRequestHeaders(builder);
// Perform BASIC Authentication if needed
@@ -577,6 +591,16 @@ public class ChangeTracker implements Runnable {
public void setDocIDs(List<String> docIDs) {
this.docIDs = docIDs;
+ if (docIDs == null) {
+ return;
+ }
+ if (docIDs.size() == 0) {
+ return;
+ }
+ // If docIDs has been set to a list with at least one element, then
+ // use a POST to query _changes. Otherwise, if docIDs has been set
+ // to null or an empty List, then stay with GET.
+ setUsePOST(true);
}
public String changesFeedPOSTBody() {
couchbase-lite-android (parent = 603259066dad077f71884df774fc37bad5938bfe
):
commit d83e695a6e4d68d01eddefd97d0ed6df7754096e (HEAD -> fix/942)
Modified unit tests so that the use of GET for some _changes queries
is acceptable and the tests still pass.
diff --git a/src/androidTest/java/com/couchbase/lite/replicator/ChangeTrackerTest.java b/src/androidTest/java/com/couchbase/lite/replicator/ChangeTrackerTest.java
index e9e1ef96..0e3e7146 100644
--- a/src/androidTest/java/com/couchbase/lite/replicator/ChangeTrackerTest.java
+++ b/src/androidTest/java/com/couchbase/lite/replicator/ChangeTrackerTest.java
@@ -203,11 +203,11 @@ public class ChangeTrackerTest extends LiteTestCaseWithDB {
ChangeTracker changeTracker = new ChangeTracker(testURL,
ChangeTracker.ChangeTrackerMode.LongPoll, false, 0L, null);
- changeTracker.setUsePOST(false);
List<String> docIds = new ArrayList<String>();
docIds.add("doc1");
docIds.add("doc2");
changeTracker.setDocIDs(docIds);
+ changeTracker.setUsePOST(false);
String docIdsUnencoded = "[\"doc1\",\"doc2\"]";
String docIdsEncoded = URLEncoder.encode(docIdsUnencoded);
diff --git a/src/androidTest/java/com/couchbase/lite/replicator/ReplicationMockWebServerTest.java b/src/androidTest/java/com/couchbase/lite/replicator/ReplicationMockWebServerTest.java
index 517133ba..085dd487 100644
--- a/src/androidTest/java/com/couchbase/lite/replicator/ReplicationMockWebServerTest.java
+++ b/src/androidTest/java/com/couchbase/lite/replicator/ReplicationMockWebServerTest.java
@@ -377,7 +377,7 @@ public class ReplicationMockWebServerTest extends LiteTestCaseWithDB {
assertTrue(getCheckpointRequest.getMethod().equals("GET"));
assertTrue(getCheckpointRequest.getPath().matches(MockHelper.PATH_REGEX_CHECKPOINT));
RecordedRequest getChangesFeedRequest = dispatcher.takeRequest(MockHelper.PATH_REGEX_CHANGES);
- assertTrue(getChangesFeedRequest.getMethod().equals("POST"));
+ assertTrue(getChangesFeedRequest.getMethod().equals("GET"));
assertTrue(getChangesFeedRequest.getPath().matches(MockHelper.PATH_REGEX_CHANGES));
// wait until the mock webserver receives a PUT checkpoint request with doc #2's sequence
@@ -503,12 +503,12 @@ public class ReplicationMockWebServerTest extends LiteTestCaseWithDB {
assertTrue(getCheckpointRequest.getMethod().equals("GET"));
assertTrue(getCheckpointRequest.getPath().matches(MockHelper.PATH_REGEX_CHECKPOINT));
RecordedRequest getChangesFeedRequest = dispatcher.takeRequest(MockHelper.PATH_REGEX_CHANGES);
- assertTrue(getChangesFeedRequest.getMethod().equals("POST"));
+ assertTrue(getChangesFeedRequest.getMethod().equals("GET"));
assertTrue(getChangesFeedRequest.getPath().matches(MockHelper.PATH_REGEX_CHANGES));
if (serverType == MockDispatcher.ServerType.SYNC_GW) {
- Map<String, Object> jsonMap = Manager.getObjectMapper().readValue(getChangesFeedRequest.getUtf8Body(), Map.class);
- assertTrue(jsonMap.containsKey("since"));
- Integer since = (Integer) jsonMap.get("since");
+ Map<String, String> queryMap = query2map(getChangesFeedRequest.getPath());
+ assertTrue(queryMap.containsKey("since"));
+ Integer since = Integer.valueOf(queryMap.get("since"));
assertEquals(2, since.intValue());
}