Skip to content

Commit c77fc15

Browse files
author
Hideki Itakura
committed
Merge pull request #627 from sergio91pt/issue_600_push_repl_no_gzip3
Encoding of doc ids in replication
2 parents 69aa7c0 + b24ce11 commit c77fc15

3 files changed

Lines changed: 31 additions & 17 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: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -602,14 +602,12 @@ private boolean uploadMultipartRevision(final RevisionInternal revision) {
602602
File file = new File(path);
603603
if (!file.exists()) {
604604
Log.w(Log.TAG_SYNC, "Unable to find blob file for blobKey: %s - Skipping upload of multipart revision.", blobKey);
605-
multiPart = null;
606-
}
607-
else {
605+
return false;
606+
} else {
608607
String contentType = null;
609608
if (attachment.containsKey("content_type")) {
610609
contentType = (String) attachment.get("content_type");
611-
}
612-
else if (attachment.containsKey("content-type")) {
610+
} else if (attachment.containsKey("content-type")) {
613611
Log.w(Log.TAG_SYNC, "Found attachment that uses content-type" +
614612
" field name instead of content_type (see couchbase-lite-android" +
615613
" issue #80): %s", attachment);
@@ -623,7 +621,7 @@ else if (attachment.containsKey("content-type")) {
623621
contentEncoding = (String)attachment.get("encoding");
624622
}
625623

626-
FileBody fileBody = new CustomFileBody(file, contentType, contentEncoding);
624+
FileBody fileBody = new CustomFileBody(file, attachmentKey, contentType, contentEncoding);
627625
multiPart.addPart(attachmentKey, fileBody);
628626
}
629627

@@ -634,7 +632,7 @@ else if (attachment.containsKey("content-type")) {
634632
return false;
635633
}
636634

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

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

@@ -683,7 +681,7 @@ private void uploadJsonRevision(final RevisionInternal rev) {
683681
return;
684682
}
685683

686-
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()));
687685
Future future = sendAsyncRequest("PUT",
688686
path,
689687
rev.getProperties(),
@@ -700,9 +698,6 @@ public void onCompletion(HttpResponse httpResponse, Object result, Throwable e)
700698
pendingFutures.add(future);
701699
}
702700

703-
704-
705-
706701
// Given a revision and an array of revIDs, finds the latest common ancestor revID
707702
// and returns its generation #. If there is none, returns 0.
708703
private static int findCommonAncestor(RevisionInternal rev, List<String> possibleRevIDs) {
@@ -730,8 +725,8 @@ private static int findCommonAncestor(RevisionInternal rev, List<String> possibl
730725
private static class CustomFileBody extends FileBody {
731726
private String contentEncoding = null;
732727

733-
public CustomFileBody(final File file, final String mimeType, final String contentEncoding) {
734-
super(file, mimeType);
728+
public CustomFileBody(File file, String filename, String mimeType, String contentEncoding) {
729+
super(file, filename, mimeType, null);
735730
this.contentEncoding = contentEncoding;
736731
}
737732

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)