CBL Android retrieved html attachment is scrambled

85 views
Skip to first unread message

Chris Donnelly

unread,
Aug 7, 2014, 4:37:22 AM8/7/14
to mobile-c...@googlegroups.com


I've recently upgraded the android app I'm working on from an old unsupported version of CBL Android to version 1.0.1. 
The app replicates to/from a CouchDB (v1.5) instance using the Replication class where with the old CBL I used the Ektorp API.

When I fetch a locally stored Document with an html attachment, the output is scrambled as per below:

Before utf-8 encoding: 

uSMo@W?=4JG"BġV8c{ٝMuM$>X|y/.gq*J -;g2ú7Ӽ~dSJoa`uO0vlJ1Dr27_

1

OhKj1AOp-*

#zNHyYd٢ҨaondNgB4J"G$ep4Ld&pFzrYګv+

r~

,14`,1<WnREI

uhtlG2g-F|3j9TJk†?̒McŃ34kOh;qkOmJxJFʹSȊpZ#-ƋÒ.]?Tw%w<-c=6ͭS

p\|q&yaߠ{hUjMOeIVTI

tX\>!?7u!%

After utf-8 encoding: %1F%EF%BF%BD%08%00%00%00%00%00%00%03uSMo%EF%BF%BD%40%10%EF%BF%BDW%EF%BF%BD%3F%0C%3D4%12J%13%EF%BF%BDG%1A%22%EF%BF%BDB%C4%A1%EF%BF%BD%EF%BF%BDV%EF%BF%BD8%EF%BF%BD%EF%BF%BDc%7B%EF%BF%BD%EF%BF%BD%D9%9DM%EF%BF%BD%10%EF%BF%BD etc etc..

Relevant code is below:


        /**

        * Load an attachment from the Couch database and set the result in the view on the UI thread. Two views are currently supported, {@link WebView} for HTML and {@link ImageView} for pngs

        *

        * @param view

        * @param activity

        * @param portalItemBase

        */

       public static void loadAttachment(final View view, final Activity activity, final PortalItemBaseNode portalItemBase, final String inAttachmentID) {

               AsyncTask<Void, Void, Object> task = new AsyncTask<Void, Void, Object>() {

                       private ProgressDialog progress;

                       private static final int TYPE_WEB = 1;

                       private static final int TYPE_IMAGE = 2;

                       private static final int TYPE_IMAGE_SCALEABLE = 3;

                       private int mType;

                       private Matrix imageMatrix;

                       @Override

                       protected void onPreExecute() {

                               if (view instanceof WebView) {

                                       mType = TYPE_WEB;

                               } else if (view instanceof ImageViewTouch) {

                                       mType = TYPE_IMAGE_SCALEABLE;

                               } else if (view instanceof ImageView) {

                                       mType = TYPE_IMAGE;

                               }

                               progress = ProgressDialog.show(activity, activity.getString(R.string.please_wait), activity.getString(R.string.loading));

                       }

                       @Override

                       protected Object doInBackground(Void... arg0) {

                               String dbName = SevenCityApplication.getModel().getSelectedSitting().getDatabaseName();

                               String attachmentName = getFirstAttachmentName(portalItemBase);                        

                               InputStream in = SevenCityApplication.getModel().getSyncer().getAttachment(dbName, portalItemBase.getId(), attachmentName);

                               if (in != null) {

                                       if (mType == TYPE_WEB) {

                                               String result = "";

                                               try {

                                                       result = inputStreamAsString(in);

                                                       in.close();

                                               } catch (IOException e) {

                                                       e.printStackTrace();

                                               }

                                               return result;

                                       } else if (mType == TYPE_IMAGE || mType == TYPE_IMAGE_SCALEABLE) {

                                               Bitmap b = BitmapFactory.decodeStream(in);

                                               try {

                                                       in.close();

                                               } catch (IOException e) {

                                                       e.printStackTrace();
                                                                                              }

                                               return b;
                                                                            }

                               }

                               return null;

                       }

                       @Override

                       protected void onPostExecute(Object result) {

                               if (DebugHandler.LOG_ENABLED) {

                                       DebugHandler.log(this, "LOADED " + (result != null) + " " + mType);

                               }

                               if (result != null) {

                                       if (mType == TYPE_WEB) {

                                               try {

                                                       String encoding = UTF_8;

                                                       String data = URLEncoder.encode((String) result, encoding).replaceAll("\\+", " ");

                                                       DebugHandler.log(this, "Before "+encoding+" encoding: "+result+"\nAfter "+encoding+" encoding: "+data);

                                                       ((WebView) view).loadData(data, MIME_TYPE_TEXT_HTML, UTF_8);

                                               } catch (UnsupportedEncodingException e) {

                                                       e.printStackTrace();

                                               }

                                       } else if (mType == TYPE_IMAGE) {

                                               ((ImageView) view).setImageBitmap((Bitmap) result);

                                       } else if (mType == TYPE_IMAGE_SCALEABLE) {

                                               if (null == imageMatrix) {

                                                       imageMatrix = new Matrix();

                                               } else {

                                                       imageMatrix = ((ImageViewTouch) view).getDisplayMatrix();

                                               }

                                               ((ImageViewTouch) view).setImageBitmap((Bitmap) result);

                                       }

                               } else {

                                       if (DebugHandler.LOG_ENABLED) {

                                               DebugHandler.log(this, "Attachment is null " + portalItemBase.getId());

                                       }

                               }

                               progress.dismiss();

                       }

               };

               if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.HONEYCOMB) {

                       task.execute();

               } else {

                       task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

               }

       }

       /**

        * Get the name of the first attachement of the {@link CouchDbDocument} supplied

        *

        * @param doc

        * @return

        */

       public static String getFirstAttachmentName(CouchDbDocument doc) {

               List<String> attachmentNames = doc.getDocument().getCurrentRevision().getAttachmentNames();

               for(String attachmentName : attachmentNames) {

                       return attachmentName;

               }

               return null;

       }

       /**

        * Read an input stream into a String

        *

        * @param stream

        * @return

        * @throws IOException

        */


        public static String inputStreamAsString(InputStream stream) throws IOException {

               BufferedReader br = new BufferedReader(new InputStreamReader(stream));

               StringBuilder sb = new StringBuilder();

               String line = null;

               try {

                       while ((line = br.readLine()) != null) {

                               sb.append(line + "\n");

                       }

               } catch (IOException e) {

                       e.printStackTrace();

               } finally {

                       br.close();

                       stream.close();

               }              

               return sb.toString();

       }

        /**

     * Get the attachment from the DB dbName

        *

      * @param dbName

        * @param id

    * @param attachmentId

  * @return

      */

    public InputStream getAttachment(String dbName, String id, String attachmentId) {

              InputStream ret = null;

        if (id == null || attachmentId == null) {

                      return null;

           } else {

                       Database structuralDB;

                 try {

                          structuralDB = SevenCityApplication.getDatabase(dbName);

                               Document doc = structuralDB.getDocument(id);

                           

                               Revision rev = doc.getCurrentRevision();

                               Attachment att = rev.getAttachment(attachmentId);

                              if(att != null) {

                                      ret = att.getContent();

                        }

                      } catch (CouchbaseLiteException e) {

                           e.printStackTrace();

                   }

                       return ret;

            }

       }


The attachment content type is text/html. The thnl rendered fine with the old CBL/Ektorp setup.

Do I have to process the InputStream in method inputStreamAsString differently with CBL 1.0.x?

Traun Leyden

unread,
Aug 7, 2014, 11:41:41 AM8/7/14
to mobile-c...@googlegroups.com

Hey Chris, thanks for reporting this.  Unfortunately, nothing is ringing a bell as to why this might be happening.

For the purposes of possibly isolating the issue, would it be possible for you to re-test against the latest master branch version of the couchbase lite code?


Another angle that might be productive is if you could put this document + attachment on a publicly accessible CouchDB server (eg, on IrisCouch or Cloudant) and I can try to sync with a Couchbase Lite instance in our test lab.




--
You received this message because you are subscribed to the Google Groups "Couchbase Mobile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mobile-couchba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mobile-couchbase/32ebbd25-f552-4435-a549-b558a79fae45%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris Donnelly

unread,
Aug 11, 2014, 9:13:32 AM8/11/14
to mobile-c...@googlegroups.com
Hey Traun,

Thanks for the response.

I upgraded CBL to the latest master branch and got the same result.

I've put the document and attachment on a public db - 

http://54.74.66.56:5984/_utils/database.html?public

...

Traun Leyden

unread,
Aug 13, 2014, 11:15:22 AM8/13/14
to mobile-c...@googlegroups.com
I tried to pull it and it's not responding.

Can you check the server?


--
You received this message because you are subscribed to the Google Groups "Couchbase Mobile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mobile-couchba...@googlegroups.com.

Chris Donnelly

unread,
Aug 13, 2014, 11:20:00 AM8/13/14
to mobile-c...@googlegroups.com
Apologies, the IP address of the server has changed. Url is now http://54.75.156.177:5984/_utils/database.html?public

                                                       String data = URLEncoder.encode((String) result, encoding).<span style="color:#000

...

Chris Donnelly

unread,
Aug 26, 2014, 11:24:56 AM8/26/14
to mobile-c...@googlegroups.com
Hey Traun,

Have you been able to reproduce the problem?

If not, I can put up a project on github that demonstrates the issue.

               <span style

...

Traun Leyden

unread,
Aug 26, 2014, 11:48:01 AM8/26/14
to mobile-c...@googlegroups.com
Yes, that would be useful.

Also can you move this to a github ticket?





--
You received this message because you are subscribed to the Google Groups "Couchbase Mobile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mobile-couchba...@googlegroups.com.

Chris Donnelly

unread,
Aug 28, 2014, 4:42:00 AM8/28/14
to mobile-c...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages