Skip to content

Commit b24ce11

Browse files
committed
Avoid encoding the slash of design documents.
It may cause 301 redirects, that can easilly be avoided.
1 parent cbf2734 commit b24ce11

3 files changed

Lines changed: 25 additions & 9 deletions

File tree

src/main/java/com/couchbase/lite/replicator/PullerInternal.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
import com.couchbase.lite.support.SequenceMap;
1717
import com.couchbase.lite.util.CollectionUtils;
1818
import com.couchbase.lite.util.Log;
19+
import com.couchbase.lite.util.URIUtils;
1920
import com.couchbase.lite.util.Utils;
2021

2122
import org.apache.http.HttpResponse;
2223
import org.apache.http.client.HttpClient;
2324
import org.apache.http.client.HttpResponseException;
2425

2526
import java.net.URL;
26-
import java.net.URLEncoder;
2727
import java.util.ArrayList;
2828
import java.util.Collection;
2929
import java.util.Collections;
@@ -591,7 +591,10 @@ public void pullRemoteRevision(final RevisionInternal rev) {
591591
// Construct a query. We want the revision history, and the bodies of attachments that have
592592
// been added since the latest revisions we have locally.
593593
// See: http://wiki.apache.org/couchdb/HTTP_Document_API#Getting_Attachments_With_a_Document
594-
StringBuilder path = new StringBuilder("/" + URLEncoder.encode(rev.getDocId()) + "?rev=" + URLEncoder.encode(rev.getRevId()) + "&revs=true&attachments=true");
594+
StringBuilder path = new StringBuilder("/");
595+
path.append(encodeDocumentId(rev.getDocId()));
596+
path.append("?rev=").append(URIUtils.encode(rev.getRevId()));
597+
path.append("&revs=true&attachments=true");
595598

596599
// If the document has attachments, add an 'atts_since' param with a list of
597600
// already-known revisions, so the server can skip sending the bodies of any
@@ -645,9 +648,9 @@ public String joinQuotedEscaped(List<String> strings) {
645648
try {
646649
json = Manager.getObjectMapper().writeValueAsBytes(strings);
647650
} catch (Exception e) {
648-
Log.w(Log.TAG_SYNC, "Unable to serialize json", e);
651+
throw new IllegalStateException("Unable to serialize json", e);
649652
}
650-
return URLEncoder.encode(new String(json));
653+
return URIUtils.encode(new String(json));
651654
}
652655

653656
/**

src/main/java/com/couchbase/lite/replicator/PusherInternal.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ private boolean uploadMultipartRevision(final RevisionInternal revision) {
632632
return false;
633633
}
634634

635-
final String path = String.format("/%s?new_edits=false", URIUtils.encode(revision.getDocId()));
635+
final String path = String.format("/%s?new_edits=false", encodeDocumentId(revision.getDocId()));
636636

637637
Log.d(Log.TAG_SYNC, "Uploading multipart request. Revision: %s", revision);
638638

@@ -681,7 +681,7 @@ private void uploadJsonRevision(final RevisionInternal rev) {
681681
return;
682682
}
683683

684-
final String path = String.format("/%s?new_edits=false", URIUtils.encode(rev.getDocId()));
684+
final String path = String.format("/%s?new_edits=false", encodeDocumentId(rev.getDocId()));
685685
Future future = sendAsyncRequest("PUT",
686686
path,
687687
rev.getProperties(),
@@ -698,9 +698,6 @@ public void onCompletion(HttpResponse httpResponse, Object result, Throwable e)
698698
pendingFutures.add(future);
699699
}
700700

701-
702-
703-
704701
// Given a revision and an array of revIDs, finds the latest common ancestor revID
705702
// and returns its generation #. If there is none, returns 0.
706703
private static int findCommonAncestor(RevisionInternal rev, List<String> possibleRevIDs) {

src/main/java/com/couchbase/lite/replicator/ReplicationInternal.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.couchbase.lite.util.CollectionUtils;
1919
import com.couchbase.lite.util.Log;
2020
import com.couchbase.lite.util.TextUtils;
21+
import com.couchbase.lite.util.URIUtils;
2122
import com.couchbase.lite.util.Utils;
2223
import com.couchbase.org.apache.http.entity.mime.MultipartEntity;
2324
import com.github.oxo42.stateless4j.StateMachine;
@@ -1611,6 +1612,21 @@ public void run() {
16111612
}
16121613
}
16131614
}
1615+
1616+
/**
1617+
* Encodes the given document id for use in an URI.
1618+
* <p>
1619+
* Avoids encoding the slash in _design documents since it may cause a 301 redirect.
1620+
*/
1621+
/* package */ String encodeDocumentId(String docId) {
1622+
if (docId.startsWith("_design/")) {
1623+
// http://docs.couchdb.org/en/1.6.1/http-api.html#cap-/{db}/_design/{ddoc}
1624+
String designDocId = docId.substring("_design/".length());
1625+
return "_design/".concat(URIUtils.encode(designDocId));
1626+
} else {
1627+
return URIUtils.encode(docId);
1628+
}
1629+
}
16141630
}
16151631

16161632

0 commit comments

Comments
 (0)