You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by GitBox <gi...@apache.org> on 2017/11/22 00:22:45 UTC

[GitHub] maverickmishra closed pull request #152: ??????????

maverickmishra closed pull request #152: ??????????
URL: https://github.com/apache/cordova-plugin-file-transfer/pull/152
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/src/android/FileProgressResult.java b/src/android/FileProgressResult.java
old mode 100644
new mode 100755
diff --git a/src/android/FileTransfer.java b/src/android/FileTransfer.java
old mode 100644
new mode 100755
index 86176a2..f83bfd7
--- a/src/android/FileTransfer.java
+++ b/src/android/FileTransfer.java
@@ -35,8 +35,10 @@ Licensed to the Apache Software Foundation (ASF) under one
 import java.net.URLConnection;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.Inflater;
 
@@ -83,13 +85,13 @@ Licensed to the Apache Software Foundation (ASF) under one
     private static final int MAX_BUFFER_SIZE = 16 * 1024;
 
     private static final class RequestContext {
-        String source;
+        List<String> source;
         String target;
         File targetFile;
         CallbackContext callbackContext;
         HttpURLConnection connection;
         boolean aborted;
-        RequestContext(String source, String target, CallbackContext callbackContext) {
+        RequestContext(List<String> source, String target, CallbackContext callbackContext) {
             this.source = source;
             this.target = target;
             this.callbackContext = callbackContext;
@@ -109,20 +111,20 @@ void sendPluginResult(PluginResult pluginResult) {
      * the HTTP Content-Length header value from the server.
      */
     private static abstract class TrackingInputStream extends FilterInputStream {
-      public TrackingInputStream(final InputStream in) {
-        super(in);
-      }
+        public TrackingInputStream(final InputStream in) {
+            super(in);
+        }
         public abstract long getTotalRawBytesRead();
-  }
+    }
 
     private static class ExposedGZIPInputStream extends GZIPInputStream {
-      public ExposedGZIPInputStream(final InputStream in) throws IOException {
-        super(in);
-      }
-      public Inflater getInflater() {
-        return inf;
-      }
-  }
+        public ExposedGZIPInputStream(final InputStream in) throws IOException {
+            super(in);
+        }
+        public Inflater getInflater() {
+            return inf;
+        }
+    }
 
     /**
      * Provides raw bytes-read tracking for a GZIP input stream. Reports the
@@ -130,15 +132,15 @@ public Inflater getInflater() {
      * number of uncompressed bytes.
      */
     private static class TrackingGZIPInputStream extends TrackingInputStream {
-      private ExposedGZIPInputStream gzin;
-      public TrackingGZIPInputStream(final ExposedGZIPInputStream gzin) throws IOException {
-        super(gzin);
-        this.gzin = gzin;
-      }
-      public long getTotalRawBytesRead() {
-        return gzin.getInflater().getBytesRead();
-      }
-  }
+        private ExposedGZIPInputStream gzin;
+        public TrackingGZIPInputStream(final ExposedGZIPInputStream gzin) throws IOException {
+            super(gzin);
+            this.gzin = gzin;
+        }
+        public long getTotalRawBytesRead() {
+            return gzin.getInflater().getBytesRead();
+        }
+    }
 
     /**
      * Provides simple total-bytes-read tracking for an existing InputStream
@@ -150,10 +152,10 @@ public SimpleTrackingInputStream(InputStream stream) {
         }
 
         private int updateBytesRead(int newBytesRead) {
-          if (newBytesRead != -1) {
-            bytesRead += newBytesRead;
-          }
-          return newBytesRead;
+            if (newBytesRead != -1) {
+                bytesRead += newBytesRead;
+            }
+            return newBytesRead;
         }
 
         @Override
@@ -169,23 +171,22 @@ public int read(byte[] bytes, int offset, int count) throws IOException {
         }
 
         public long getTotalRawBytesRead() {
-          return bytesRead;
+            return bytesRead;
         }
     }
 
     @Override
     public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
-        if (action.equals("upload") || action.equals("download")) {
-            String source = args.getString(0);
+        if (action.equals("upload")) {
+            JSONArray source = args.getJSONArray(0);
             String target = args.getString(1);
-
-            if (action.equals("upload")) {
-                upload(source, target, args, callbackContext);
-            } else {
-                download(source, target, args, callbackContext);
-            }
+            upload(source, target, args, callbackContext);
             return true;
-        } else if (action.equals("abort")) {
+        }else if(action.equals("download")){
+            String source = args.getString(0);
+            String target = args.getString(1);
+            download(source, target, args, callbackContext);
+        }else if (action.equals("abort")) {
             String objectId = args.getString(0);
             abort(objectId);
             callbackContext.success();
@@ -231,7 +232,7 @@ private static void addHeadersToRequest(URLConnection connection, JSONObject hea
                 }
             }
         } catch (JSONException e1) {
-          // No headers to be manipulated!
+            // No headers to be manipulated!
         }
     }
 
@@ -245,9 +246,9 @@ private String getCookies(final String target) {
             Method gcMethod  = iccmClass.getMethod("getCookie", String.class);
 
             cookie = (String)gcMethod.invoke(
-                        iccmClass.cast(
+                    iccmClass.cast(
                             gcmMethod.invoke(webView)
-                        ), target);
+                    ), target);
 
             gotCookie = true;
         } catch (NoSuchMethodException e) {
@@ -265,7 +266,6 @@ private String getCookies(final String target) {
 
     /**
      * Uploads the specified file to the server URL provided using an HTTP multipart request.
-     * @param source        Full path of the file on the file system
      * @param target        URL of the server to receive the file
      * @param args          JSON Array of args
      * @param callbackContext    callback id for optional progress reports
@@ -276,9 +276,8 @@ private String getCookies(final String target) {
      * args[5] params        key:value pairs of user-defined parameters
      * @return FileUploadResult containing result of upload request
      */
-    private void upload(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {
-        Log.d(LOG_TAG, "upload " + source + " to " +  target);
-
+    private void upload(final JSONArray sources, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {
+        Log.d(LOG_TAG, "upload " + sources + " to " +  target);
         // Setup the options
         final String fileKey = getArgument(args, 2, "file");
         final String fileName = getArgument(args, 3, "image.jpg");
@@ -306,20 +305,29 @@ private void upload(final String source, final String target, JSONArray args, Ca
 
         final Uri targetUri = resourceApi.remapUri(Uri.parse(target));
         // Accept a path or a URI for the source.
-        Uri tmpSrc = Uri.parse(source);
-        final Uri sourceUri = resourceApi.remapUri(
-            tmpSrc.getScheme() != null ? tmpSrc : Uri.fromFile(new File(source)));
-
+        //??????????
+        List<String> sourceList = new ArrayList<String>();
+        List<Uri> uriList = new ArrayList<Uri>();
+        List<Boolean> localFlagList = new ArrayList<Boolean>();
+        List<Boolean> useHttpsList = new ArrayList<Boolean>();
         int uriType = CordovaResourceApi.getUriType(targetUri);
         final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;
-        if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) {
-            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0, null);
-            Log.e(LOG_TAG, "Unsupported URI: " + targetUri);
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-            return;
+        for(int i=0;i<sources.length();i++){
+            String source = sources.getJSONObject(i).getString("path");
+            sourceList.add(source);
+            Uri tmpSrc = Uri.parse(source);
+            Uri source_uri = resourceApi.remapUri(
+                    tmpSrc.getScheme() != null ? tmpSrc : Uri.fromFile(new File(source)));
+            uriList.add(source_uri);
+            if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) {
+                JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0, null);
+                Log.e(LOG_TAG, "Unsupported URI: " + targetUri);
+                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
+                return;
+            }
         }
-
-        final RequestContext context = new RequestContext(source, target, callbackContext);
+        final List<Uri> sourceUri = uriList;
+        final RequestContext context = new RequestContext(sourceList, target, callbackContext);
         synchronized (activeRequests) {
             activeRequests.put(objectId, context);
         }
@@ -334,8 +342,12 @@ public void run() {
                 SSLSocketFactory oldSocketFactory = null;
                 int totalBytes = 0;
                 int fixedLength = -1;
+                String sourcePath = "";
                 try {
                     // Create return object
+                    if(sources.length()>0){
+                        sourcePath = sources.getJSONObject(0).getString("path");
+                    }
                     FileUploadResult result = new FileUploadResult();
                     FileProgressResult progress = new FileProgressResult();
 
@@ -392,41 +404,21 @@ public void run() {
                             Object key = iter.next();
                             if(!String.valueOf(key).equals("headers"))
                             {
-                              beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);
-                              beforeData.append("Content-Disposition: form-data; name=\"").append(key.toString()).append('"');
-                              beforeData.append(LINE_END).append(LINE_END);
-                              beforeData.append(params.getString(key.toString()));
-                              beforeData.append(LINE_END);
+                                beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);
+                                beforeData.append("Content-Disposition: form-data; name=\"").append(key.toString()).append('"');
+                                beforeData.append(LINE_END).append(LINE_END);
+                                beforeData.append(params.getString(key.toString()));
+                                beforeData.append(LINE_END);
                             }
                         }
                     } catch (JSONException e) {
                         Log.e(LOG_TAG, e.getMessage(), e);
                     }
-
-                    beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);
-                    beforeData.append("Content-Disposition: form-data; name=\"").append(fileKey).append("\";");
-                    beforeData.append(" filename=\"").append(fileName).append('"').append(LINE_END);
-                    beforeData.append("Content-Type: ").append(mimeType).append(LINE_END).append(LINE_END);
-                    byte[] beforeDataBytes = beforeData.toString().getBytes("UTF-8");
-                    byte[] tailParamsBytes = (LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END).getBytes("UTF-8");
-
-
-                    // Get a input stream of the file on the phone
-                    OpenForReadResult readResult = resourceApi.openForRead(sourceUri);
-
-                    int stringLength = beforeDataBytes.length + tailParamsBytes.length;
-                    if (readResult.length >= 0) {
-                        fixedLength = (int)readResult.length;
-                        if (multipartFormUpload)
-                            fixedLength += stringLength;
-                        progress.setLengthComputable(true);
-                        progress.setTotal(fixedLength);
-                    }
-                    Log.d(LOG_TAG, "Content Length: " + fixedLength);
+//                    beforeDataBytes = beforeData.toString().getBytes("UTF-8");
                     // setFixedLengthStreamingMode causes and OutOfMemoryException on pre-Froyo devices.
                     // http://code.google.com/p/android/issues/detail?id=3164
                     // It also causes OOM if HTTPS is used, even on newer devices.
-                    boolean useChunkedMode = chunkedMode || (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps);
+                    boolean useChunkedMode = chunkedMode && (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps);
                     useChunkedMode = useChunkedMode || (fixedLength == -1);
 
                     if (useChunkedMode) {
@@ -437,11 +429,10 @@ public void run() {
                     } else {
                         conn.setFixedLengthStreamingMode(fixedLength);
                     }
-
                     conn.connect();
-
                     OutputStream sendStream = null;
                     try {
+
                         sendStream = conn.getOutputStream();
                         synchronized (context) {
                             if (context.aborted) {
@@ -449,41 +440,92 @@ public void run() {
                             }
                             context.connection = conn;
                         }
-
+                        byte[] beforeDataBytes = beforeData.toString().getBytes("UTF-8");
                         if (multipartFormUpload) {
                             //We don't want to change encoding, we just want this to write for all Unicode.
                             sendStream.write(beforeDataBytes);
                             totalBytes += beforeDataBytes.length;
                         }
 
-                        // create a buffer of maximum size
-                        int bytesAvailable = readResult.inputStream.available();
-                        int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
-                        byte[] buffer = new byte[bufferSize];
-
-                        // read file and write it into form...
-                        int bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);
-
-                        long prevBytesRead = 0;
-                        while (bytesRead > 0) {
-                            totalBytes += bytesRead;
-                            result.setBytesSent(totalBytes);
-                            sendStream.write(buffer, 0, bytesRead);
-                            if (totalBytes > prevBytesRead + 102400) {
-                                prevBytesRead = totalBytes;
-                                Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes");
+                        // Get a input stream of the file on the phone
+                        byte[] tailParamsBytes = (LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END).getBytes("UTF-8");
+                        byte[] endBytes = (LINE_END).getBytes("UTF-8");
+                        int total = fixedLength;
+                        for(int i=0;i<sources.length();i++) {
+                            StringBuilder tempData = new StringBuilder();
+                            JSONObject obj = sources.getJSONObject(i);
+                            String filename = obj.get("fileName").toString();
+                            tempData.append(LINE_START).append(BOUNDARY).append(LINE_END);
+                            tempData.append("Content-Disposition: form-data; name=\"").append(fileKey).append("\";");
+                            tempData.append(" filename=\"").append(filename).append('"').append(LINE_END);
+                            tempData.append("Content-Type: ").append(mimeType).append(LINE_END).append(LINE_END);
+                            byte[] tempDataBytes = tempData.toString().getBytes("UTF-8");
+                            OpenForReadResult readResult = resourceApi.openForRead(sourceUri.get(i));
+                            int stringLength = 0;
+                            stringLength = tempDataBytes.length;
+                            if (readResult.length >= 0) {
+                                total += (int)readResult.length;
+                                if (multipartFormUpload)
+                                    total += stringLength;
+                                progress.setLengthComputable(true);
+
+                            }
+                            safeClose(readResult.inputStream);
+                        }
+                        progress.setTotal(total);
+
+
+
+
+
+
+
+                        for(int i=0;i<sources.length();i++){
+                            StringBuilder tempData = new StringBuilder();
+                            JSONObject obj = sources.getJSONObject(i);
+                            String filename = obj.get("fileName").toString();
+                            tempData.append(LINE_START).append(BOUNDARY).append(LINE_END);
+                            tempData.append("Content-Disposition: form-data; name=\"").append(fileKey).append("\";");
+                            tempData.append(" filename=\"").append(filename).append('"').append(LINE_END);
+                            tempData.append("Content-Type: ").append(mimeType).append(LINE_END).append(LINE_END);
+                            byte[] tempDataBytes = tempData.toString().getBytes("UTF-8");
+                            sendStream.write(tempDataBytes);
+                            OpenForReadResult readResult = resourceApi.openForRead(sourceUri.get(i));
+                            try{
+
+                                Log.d(LOG_TAG, "Content Length: " + fixedLength);
+                                int bytesAvailable = readResult.inputStream.available();
+                                int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
+                                byte[] buffer = new byte[bufferSize];
+
+                                // read file and write it into form...
+                                int bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);
+                                long prevBytesRead = 0;
+                                while (bytesRead > 0) {
+                                    totalBytes += bytesRead;
+                                    result.setBytesSent(totalBytes);
+                                    sendStream.write(buffer, 0, bytesRead);
+                                    if (totalBytes > prevBytesRead + 102400) {
+                                        prevBytesRead = totalBytes;
+                                        Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes");
+                                    }
+                                    bytesAvailable = readResult.inputStream.available();
+                                    bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
+                                    bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);
+
+                                    // Send a progress event.
+                                    progress.setLoaded(totalBytes);
+                                    PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());
+                                    progressResult.setKeepCallback(true);
+                                    context.sendPluginResult(progressResult);
+                                }
+                                sendStream.write(endBytes);
+                            }catch(Exception e){
+                                Log.e(LOG_TAG, e.toString(), e);
+                            }finally{
+                                safeClose(readResult.inputStream);
                             }
-                            bytesAvailable = readResult.inputStream.available();
-                            bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
-                            bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);
-
-                            // Send a progress event.
-                            progress.setLoaded(totalBytes);
-                            PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());
-                            progressResult.setKeepCallback(true);
-                            context.sendPluginResult(progressResult);
                         }
-
                         if (multipartFormUpload) {
                             // send multipart form data necessary after file data...
                             sendStream.write(tailParamsBytes);
@@ -491,8 +533,8 @@ public void run() {
                         }
                         sendStream.flush();
                     } finally {
-                        safeClose(readResult.inputStream);
                         safeClose(sendStream);
+
                     }
                     synchronized (context) {
                         context.connection = null;
@@ -537,21 +579,12 @@ public void run() {
                     result.setResponse(responseString);
 
                     context.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));
-                } catch (FileNotFoundException e) {
-                    JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn, e);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-                } catch (IOException e) {
-                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn, e);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    Log.e(LOG_TAG, "Failed after uploading " + totalBytes + " of " + fixedLength + " bytes.");
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
                 } catch (JSONException e) {
                     Log.e(LOG_TAG, e.getMessage(), e);
                     context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
                 } catch (Throwable t) {
                     // Shouldn't happen, but will
-                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn, t);
+                    JSONObject error = createFileTransferError(CONNECTION_ERR, sourcePath, target, conn, t);
                     Log.e(LOG_TAG, error.toString(), t);
                     context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
                 } finally {
@@ -585,7 +618,7 @@ private static void safeClose(Closeable stream) {
     private static TrackingInputStream getInputStream(URLConnection conn) throws IOException {
         String encoding = conn.getContentEncoding();
         if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
-          return new TrackingGZIPInputStream(new ExposedGZIPInputStream(conn.getInputStream()));
+            return new TrackingGZIPInputStream(new ExposedGZIPInputStream(conn.getInputStream()));
         }
         return new SimpleTrackingInputStream(conn.getInputStream());
     }
@@ -603,11 +636,11 @@ public boolean verify(String hostname, SSLSession session) {
         }
 
         public void checkClientTrusted(X509Certificate[] chain,
-                String authType) throws CertificateException {
+                                       String authType) throws CertificateException {
         }
 
         public void checkServerTrusted(X509Certificate[] chain,
-                String authType) throws CertificateException {
+                                       String authType) throws CertificateException {
         }
     } };
 
@@ -662,7 +695,7 @@ private static JSONObject createFileTransferError(int errorCode, String source,
                         }
                     }
                 }
-            // IOException can leave connection object in a bad state, so catch all exceptions.
+                // IOException can leave connection object in a bad state, so catch all exceptions.
             } catch (Throwable e) {
                 Log.w(LOG_TAG, "Error getting HTTP status code from connection.", e);
             }
@@ -671,11 +704,11 @@ private static JSONObject createFileTransferError(int errorCode, String source,
         return createFileTransferError(errorCode, source, target, body, httpStatus, throwable);
     }
 
-        /**
-        * Create an error object based on the passed in errorCode
-        * @param errorCode      the error
-        * @return JSONObject containing the error
-        */
+    /**
+     * Create an error object based on the passed in errorCode
+     * @param errorCode      the error
+     * @return JSONObject containing the error
+     */
     private static JSONObject createFileTransferError(int errorCode, String source, String target, String body, Integer httpStatus, Throwable throwable) {
         JSONObject error = null;
         try {
@@ -686,7 +719,7 @@ private static JSONObject createFileTransferError(int errorCode, String source,
             if(body != null)
             {
                 error.put("body", body);
-            }   
+            }
             if (httpStatus != null) {
                 error.put("http_status", httpStatus);
             }
@@ -740,7 +773,7 @@ private void download(final String source, final String target, JSONArray args,
         // Accept a path or a URI for the source.
         Uri tmpTarget = Uri.parse(target);
         final Uri targetUri = resourceApi.remapUri(
-            tmpTarget.getScheme() != null ? tmpTarget : Uri.fromFile(new File(target)));
+                tmpTarget.getScheme() != null ? tmpTarget : Uri.fromFile(new File(target)));
 
         int uriType = CordovaResourceApi.getUriType(sourceUri);
         final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;
@@ -790,8 +823,9 @@ private void download(final String source, final String target, JSONArray args,
             return;
         }
 
-
-        final RequestContext context = new RequestContext(source, target, callbackContext);
+        List<String> sourceList = new ArrayList<String>();
+        sourceList.add(source);
+        final RequestContext context = new RequestContext(sourceList, target, callbackContext);
         synchronized (activeRequests) {
             activeRequests.put(objectId, context);
         }
@@ -1006,7 +1040,7 @@ public void run() {
                             file.delete();
                         }
                         // Trigger the abort callback immediately to minimize latency between it and abort() being called.
-                        JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, null, -1, null);
+                        JSONObject error = createFileTransferError(ABORTED_ERR, context.source.get(0), context.target, null, -1, null);
                         context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, error));
                         context.aborted = true;
                         if (context.connection != null) {
diff --git a/src/android/FileUploadResult.java b/src/android/FileUploadResult.java
old mode 100644
new mode 100755
diff --git a/src/ios/CDVFileTransfer.m b/src/ios/CDVFileTransfer.m
index 6024901..cb997b3 100644
--- a/src/ios/CDVFileTransfer.m
+++ b/src/ios/CDVFileTransfer.m
@@ -6,9 +6,9 @@ Licensed to the Apache Software Foundation (ASF) under one
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at
-
+ 
  http://www.apache.org/licenses/LICENSE-2.0
-
+ 
  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -28,9 +28,9 @@ Licensed to the Apache Software Foundation (ASF) under one
 
 #ifndef DLog
 #ifdef DEBUG
-    #define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
 #else
-    #define DLog(...)
+#define DLog(...)
 #endif
 #endif
 
@@ -59,11 +59,11 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
     UInt8* bytes = (UInt8*)[data bytes];
     long long bytesToWrite = [data length];
     long long totalBytesWritten = 0;
-
+    
     while (totalBytesWritten < bytesToWrite) {
         CFIndex result = CFWriteStreamWrite(stream,
-                bytes + totalBytesWritten,
-                bytesToWrite - totalBytesWritten);
+                                            bytes + totalBytesWritten,
+                                            bytesToWrite - totalBytesWritten);
         if (result < 0) {
             CFStreamError error = CFWriteStreamGetError(stream);
             NSLog(@"WriteStreamError domain: %ld error: %ld", error.domain, (long)error.error);
@@ -73,7 +73,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
         }
         totalBytesWritten += result;
     }
-
+    
     return totalBytesWritten;
 }
 
@@ -87,41 +87,41 @@ - (void)pluginInitialize {
 - (NSString*)escapePathComponentForUrlString:(NSString*)urlString
 {
     NSRange schemeAndHostRange = [urlString rangeOfString:@"://.*?/" options:NSRegularExpressionSearch];
-
+    
     if (schemeAndHostRange.length == 0) {
         return urlString;
     }
-
+    
     NSInteger schemeAndHostEndIndex = NSMaxRange(schemeAndHostRange);
     NSString* schemeAndHost = [urlString substringToIndex:schemeAndHostEndIndex];
     NSString* pathComponent = [urlString substringFromIndex:schemeAndHostEndIndex];
     pathComponent = [pathComponent stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-
+    
     return [schemeAndHost stringByAppendingString:pathComponent];
 }
 
 - (void)applyRequestHeaders:(NSDictionary*)headers toRequest:(NSMutableURLRequest*)req
 {
     [req setValue:@"XMLHttpRequest" forHTTPHeaderField:@"X-Requested-With"];
-
+    
     NSString* userAgent = [self.commandDelegate userAgent];
     if (userAgent) {
         [req setValue:userAgent forHTTPHeaderField:@"User-Agent"];
     }
-
+    
     for (NSString* headerName in headers) {
         id value = [headers objectForKey:headerName];
         if (!value || (value == [NSNull null])) {
             value = @"null";
         }
-
+        
         // First, remove an existing header if one exists.
         [req setValue:nil forHTTPHeaderField:headerName];
-
+        
         if (![value isKindOfClass:[NSArray class]]) {
             value = [NSArray arrayWithObject:value];
         }
-
+        
         // Then, append all header values.
         for (id __strong subValue in value) {
             // Convert from an NSNumber -> NSString.
@@ -135,7 +135,7 @@ - (void)applyRequestHeaders:(NSDictionary*)headers toRequest:(NSMutableURLReques
     }
 }
 
-- (NSURLRequest*)requestForUploadCommand:(CDVInvokedUrlCommand*)command fileData:(NSData*)fileData
+- (NSURLRequest*)requestForUploadCommand:(CDVInvokedUrlCommand*)command fileData:(NSArray*)fileArray
 {
     // arguments order from js: [filePath, server, fileKey, fileName, mimeType, params, debug, chunkedMode]
     // however, params is a JavaScript object and during marshalling is put into the options dict,
@@ -143,11 +143,11 @@ - (NSURLRequest*)requestForUploadCommand:(CDVInvokedUrlCommand*)command fileData
     NSString* target = [command argumentAtIndex:0];
     NSString* server = [command argumentAtIndex:1];
     NSString* fileKey = [command argumentAtIndex:2 withDefault:@"file"];
-    NSString* fileName = [command argumentAtIndex:3 withDefault:@"image.jpg"];
-    NSString* mimeType = [command argumentAtIndex:4 withDefault:@"image/jpeg"];
+    NSString* fileName = [command argumentAtIndex:3 withDefault:@"no-filename"];
+    NSString* mimeType = [command argumentAtIndex:4 withDefault:nil];
     NSDictionary* options = [command argumentAtIndex:5 withDefault:nil];
-    //    BOOL trustAllHosts = [[command argumentAtIndex:6 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
-    BOOL chunkedMode = [[command argumentAtIndex:7 withDefault:[NSNumber numberWithBool:YES]] boolValue];
+    //    BOOL trustAllHosts = [[arguments objectAtIndex:6 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
+    //    BOOL chunkedMode = [[command argumentAtIndex:7 withDefault:[NSNumber numberWithBool:YES]] boolValue];
     NSDictionary* headers = [command argumentAtIndex:8 withDefault:nil];
     // Allow alternative http method, default to POST. JS side checks
     // for allowed methods, currently PUT or POST (forces POST for
@@ -155,45 +155,41 @@ - (NSURLRequest*)requestForUploadCommand:(CDVInvokedUrlCommand*)command fileData
     NSString* httpMethod = [command argumentAtIndex:10 withDefault:@"POST"];
     CDVPluginResult* result = nil;
     CDVFileTransferError errorCode = 0;
-
+    
     // NSURL does not accepts URLs with spaces in the path. We escape the path in order
     // to be more lenient.
     NSURL* url = [NSURL URLWithString:server];
-
+    
     if (!url) {
         errorCode = INVALID_URL_ERR;
         NSLog(@"File Transfer Error: Invalid server URL %@", server);
-    } else if (!fileData) {
+    } else if (!fileArray) {
         errorCode = FILE_NOT_FOUND_ERR;
     }
-
+    
     if (errorCode > 0) {
         result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:errorCode AndSource:target AndTarget:server]];
         [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
         return nil;
     }
-
+    
     NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
-
+    
     [req setHTTPMethod:httpMethod];
-
+    
     //    Magic value to set a cookie
     if ([options objectForKey:kOptionsKeyCookie]) {
         [req setValue:[options objectForKey:kOptionsKeyCookie] forHTTPHeaderField:@"Cookie"];
         [req setHTTPShouldHandleCookies:NO];
     }
-
-    // if we specified a Content-Type header, don't do multipart form upload
-    BOOL multipartFormUpload = [headers objectForKey:@"Content-Type"] == nil;
-    if (multipartFormUpload) {
-        NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kFormBoundary];
-        [req setValue:contentType forHTTPHeaderField:@"Content-Type"];
-    }
+    
+    NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kFormBoundary];
+    [req setValue:contentType forHTTPHeaderField:@"Content-Type"];
     [self applyRequestHeaders:headers toRequest:req];
-
+    
     NSData* formBoundaryData = [[NSString stringWithFormat:@"--%@\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
     NSMutableData* postBodyBeforeFile = [NSMutableData data];
-
+    
     for (NSString* key in options) {
         id val = [options objectForKey:key];
         if (!val || (val == [NSNull null]) || [key isEqualToString:kOptionsKeyCookie]) {
@@ -207,75 +203,45 @@ - (NSURLRequest*)requestForUploadCommand:(CDVInvokedUrlCommand*)command fileData
         if (![val isKindOfClass:[NSString class]]) {
             continue;
         }
-
+        
         [postBodyBeforeFile appendData:formBoundaryData];
         [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
         [postBodyBeforeFile appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];
         [postBodyBeforeFile appendData:[@"\r\n" dataUsingEncoding : NSUTF8StringEncoding]];
     }
-
-    [postBodyBeforeFile appendData:formBoundaryData];
-    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fileKey, fileName] dataUsingEncoding:NSUTF8StringEncoding]];
-    if (mimeType != nil) {
-        [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
-    }
-    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Length: %ld\r\n\r\n", (long)[fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];
-
-    DLog(@"fileData length: %d", [fileData length]);
-    NSData* postBodyAfterFile = [[NSString stringWithFormat:@"\r\n--%@--\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
-
-    long long totalPayloadLength = [fileData length];
-    if (multipartFormUpload) {
-        totalPayloadLength += [postBodyBeforeFile length] + [postBodyAfterFile length];
-    }
-
-    if (chunkedMode) {
-        CFReadStreamRef readStream = NULL;
-        CFWriteStreamRef writeStream = NULL;
-        CFStreamCreateBoundPair(NULL, &readStream, &writeStream, kStreamBufferSize);
-        [req setHTTPBodyStream:CFBridgingRelease(readStream)];
-
-        [self.commandDelegate runInBackground:^{
-            if (CFWriteStreamOpen(writeStream)) {
-                if (multipartFormUpload) {
-                    NSData* chunks[] = { postBodyBeforeFile, fileData, postBodyAfterFile };
-                    int numChunks = sizeof(chunks) / sizeof(chunks[0]);
-
-                    for (int i = 0; i < numChunks; ++i) {
-                        // Allow uploading of an empty file
-                        if (chunks[i].length == 0) {
-                            continue;
-                        }
-
-                        CFIndex result = WriteDataToStream(chunks[i], writeStream);
-                        if (result <= 0) {
-                            break;
-                        }
-                    }
-                } else {
-                    if (totalPayloadLength > 0) {
-                        WriteDataToStream(fileData, writeStream);
-                    } else {
-                        NSLog(@"Uploading of an empty file is not supported for chunkedMode=true and multipart=false");
-                    }
-                }
-            } else {
-                NSLog(@"FileTransfer: Failed to open writeStream");
-            }
-            CFWriteStreamClose(writeStream);
-            CFRelease(writeStream);
-        }];
-    } else {
-        [req setValue:[[NSNumber numberWithLongLong:totalPayloadLength] stringValue] forHTTPHeaderField:@"Content-Length"];
-        if (multipartFormUpload) {
-            [postBodyBeforeFile appendData:fileData];
-            [postBodyBeforeFile appendData:postBodyAfterFile];
-            [req setHTTPBody:postBodyBeforeFile];
-        } else {
-            [req setHTTPBody:fileData];
+    for (int i=0; i<fileArray.count; i++) {
+        
+        NSData *dataFile = [[fileArray objectAtIndex:i] objectForKey:@"fileData"];
+        [postBodyBeforeFile appendData:formBoundaryData];
+        [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fileKey, [[fileArray objectAtIndex:i] objectForKey:@"fileName"]] dataUsingEncoding:NSUTF8StringEncoding]];
+        if (mimeType != nil) {
+            [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
         }
+        
+        [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Length: %ld\r\n\r\n", (long)[dataFile length]] dataUsingEncoding:NSUTF8StringEncoding]];
+        [postBodyBeforeFile appendData:dataFile];
+        //????
+        [postBodyBeforeFile appendData:[@"\r\n" dataUsingEncoding : NSUTF8StringEncoding]];
+        DLog(@"fileData length: %d", [dataFile length]);
     }
+    
+    
+    NSData* postBodyAfterFile = [[NSString stringWithFormat:@"\r\n--%@--\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
+    
+    [postBodyBeforeFile appendData:postBodyAfterFile];
+    
+    
+    
+    
+    [req setValue:[NSString stringWithFormat:@"%ld",(unsigned long)[postBodyBeforeFile length]] forHTTPHeaderField:@"Content-Length"];
+    //    DLog(@"post data is :%@",postBodyBeforeFile);
+    //
+    //    DLog(@"myRequestData:%@",[[NSString alloc] initWithData:postBodyBeforeFile encoding:NSUTF8StringEncoding]);
+    
+    [req setHTTPBody:postBodyBeforeFile];
+    
     return req;
+    
 }
 
 - (CDVFileTransferDelegate*)delegateForUploadCommand:(CDVInvokedUrlCommand*)command
@@ -284,10 +250,9 @@ - (CDVFileTransferDelegate*)delegateForUploadCommand:(CDVInvokedUrlCommand*)comm
     NSString* server = [command argumentAtIndex:1];
     BOOL trustAllHosts = [[command argumentAtIndex:6 withDefault:[NSNumber numberWithBool:NO]] boolValue]; // allow self-signed certs
     NSString* objectId = [command argumentAtIndex:9];
-    BOOL chunkedMode = [[command argumentAtIndex:7 withDefault:[NSNumber numberWithBool:YES]] boolValue];
-
+    
     CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];
-
+    
     delegate.command = self;
     delegate.callbackId = command.callbackId;
     delegate.direction = CDV_TRANSFER_UPLOAD;
@@ -296,79 +261,74 @@ - (CDVFileTransferDelegate*)delegateForUploadCommand:(CDVInvokedUrlCommand*)comm
     delegate.target = server;
     delegate.trustAllHosts = trustAllHosts;
     delegate.filePlugin = [self.commandDelegate getCommandInstance:@"File"];
-    delegate.chunkedMode = chunkedMode;
-
+    
     return delegate;
 }
 
 - (void)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command
 {
-    NSString* source = (NSString*)[command argumentAtIndex:0];
-    NSString* server = [command argumentAtIndex:1];
+    NSMutableArray* sourceArray = (NSMutableArray*)[command argumentAtIndex:0];
+    DLog(@"fileDataForUploadCommand sourceArray:%@",sourceArray);
+    NSString* server = [command.arguments objectAtIndex:1];
     NSError* __autoreleasing err = nil;
-
-    if ([source hasPrefix:@"data:"] && [source rangeOfString:@"base64"].location != NSNotFound) {
-        NSRange commaRange = [source rangeOfString: @","];
-        if (commaRange.location == NSNotFound) {
-            // Return error is there is no comma
-            __weak CDVFileTransfer* weakSelf = self;
-            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[weakSelf createFileTransferError:INVALID_URL_ERR AndSource:source AndTarget:server]];
-            [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-            return;
+    NSUInteger len=[sourceArray count];
+    //    __block  NSUInteger counter=0;
+    NSMutableArray *arrarRet = [[NSMutableArray alloc] init];
+    for (int i = 0; i<sourceArray.count; i++) {
+        NSMutableDictionary *sourceObj = [[NSMutableDictionary alloc] initWithDictionary:[sourceArray objectAtIndex:i]];
+        
+        CDVFilesystemURL *sourceURL = [CDVFilesystemURL fileSystemURLWithString:[sourceObj objectForKey:@"path"]];
+        NSObject<CDVFileSystem> *fs;
+        if (sourceURL) {
+            // Try to get a CDVFileSystem which will handle this file.
+            // This requires talking to the current CDVFile plugin.
+            fs = [[self.commandDelegate getCommandInstance:@"File"] filesystemForURL:sourceURL];
         }
-
-        if (commaRange.location + 1 > source.length - 1) {
-            // Init as an empty data
-            NSData *fileData = [[NSData alloc] init];
-            [self uploadData:fileData command:command];
-            return;
-        }
-
-        NSData *fileData = [[NSData alloc] initWithBase64EncodedString:[source substringFromIndex:(commaRange.location + 1)] options:NSDataBase64DecodingIgnoreUnknownCharacters];
-        [self uploadData:fileData command:command];
-        return;
-    }
-
-    CDVFilesystemURL *sourceURL = [CDVFilesystemURL fileSystemURLWithString:source];
-    NSObject<CDVFileSystem> *fs;
-    if (sourceURL) {
-        // Try to get a CDVFileSystem which will handle this file.
-        // This requires talking to the current CDVFile plugin.
-        fs = [[self.commandDelegate getCommandInstance:@"File"] filesystemForURL:sourceURL];
-    }
-    if (fs) {
-        __weak CDVFileTransfer* weakSelf = self;
-        [fs readFileAtURL:sourceURL start:0 end:-1 callback:^(NSData *fileData, NSString *mimeType, CDVFileError err) {
-            if (err) {
+        if (fs) {
+            [fs readFileAtURL:sourceURL start:0 end:-1 callback:^(NSData *fileData, NSString *mimeType, CDVFileError err) {
+                if (err) {
+                    // We couldn't find the asset.  Send the appropriate error.
+                    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:[sourceObj objectForKey:@"path"] AndTarget:server]];
+                    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+                }  else {
+                    [sourceObj setObject:fileData forKey:@"fileData"];
+                    [arrarRet addObject:sourceObj];
+                    //                    counter++;
+                    if (i == len-1) {
+                        [self uploadData:arrarRet command:command];
+                    }
+                }
+            }];
+            
+        } else {
+            // Extract the path part out of a file: URL.
+            NSString* filePath = [[sourceObj objectForKey:@"path"] hasPrefix:@"/"] ? [[sourceObj objectForKey:@"path"] copy] : [(NSURL *)[NSURL URLWithString:[sourceObj objectForKey:@"path"]] path];
+            if (filePath == nil) {
                 // We couldn't find the asset.  Send the appropriate error.
-                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[weakSelf createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];
-                [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-            }  else {
-                [weakSelf uploadData:fileData command:command];
+                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:[sourceObj objectForKey:@"path"] AndTarget:server]];
+                [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+                return;
+            }
+            
+            // Memory map the file so that it can be read efficiently even if it is large.
+            NSData* fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err];
+            
+            if (err != nil) {
+                DLog(@"Error opening file %@: %@", [sourceObj objectForKey:@"path"], err);
+                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:[sourceObj objectForKey:@"path"] AndTarget:server]];
+                [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+            } else {
+                [sourceObj setObject:fileData forKey:@"fileData"];
+                [arrarRet addObject:sourceObj];
+                
+                if (i == len-1) {
+                    [self uploadData:arrarRet command:command];
+                }
             }
-        }];
-        return;
-    } else {
-        // Extract the path part out of a file: URL.
-        NSString* filePath = [source hasPrefix:@"/"] ? [source copy] : [(NSURL *)[NSURL URLWithString:source] path];
-        if (filePath == nil) {
-            // We couldn't find the asset.  Send the appropriate error.
-            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];
-            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-            return;
-        }
-
-        // Memory map the file so that it can be read efficiently even if it is large.
-        NSData* fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err];
-
-        if (err != nil) {
-            NSLog(@"Error opening file %@: %@", source, err);
-            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];
-            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-        } else {
-            [self uploadData:fileData command:command];
         }
+        
     }
+    
 }
 
 - (void)upload:(CDVInvokedUrlCommand*)command
@@ -378,10 +338,10 @@ - (void)upload:(CDVInvokedUrlCommand*)command
     [self fileDataForUploadCommand:command];
 }
 
-- (void)uploadData:(NSData*)fileData command:(CDVInvokedUrlCommand*)command
+- (void)uploadData:(NSArray*)fileData command:(CDVInvokedUrlCommand*)command
 {
     NSURLRequest* req = [self requestForUploadCommand:command fileData:fileData];
-
+    
     if (req == nil) {
         return;
     }
@@ -391,12 +351,12 @@ - (void)uploadData:(NSData*)fileData command:(CDVInvokedUrlCommand*)command
         self.queue = [[NSOperationQueue alloc] init];
     }
     [delegate.connection setDelegateQueue:self.queue];
-
+    
     // sets a background task ID for the transfer object.
     delegate.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
         [delegate cancelTransfer:delegate.connection];
     }];
-
+    
     @synchronized (activeTransfers) {
         activeTransfers[delegate.objectId] = delegate;
     }
@@ -405,8 +365,8 @@ - (void)uploadData:(NSData*)fileData command:(CDVInvokedUrlCommand*)command
 
 - (void)abort:(CDVInvokedUrlCommand*)command
 {
-    NSString* objectId = [command argumentAtIndex:0];
-
+    NSString* objectId = [command.arguments objectAtIndex:0];
+    
     @synchronized (activeTransfers) {
         CDVFileTransferDelegate* delegate = activeTransfers[objectId];
         if (delegate != nil) {
@@ -423,14 +383,14 @@ - (void)download:(CDVInvokedUrlCommand*)command
     NSString* source = [command argumentAtIndex:0];
     NSString* target = [command argumentAtIndex:1];
     BOOL trustAllHosts = [[command argumentAtIndex:2 withDefault:[NSNumber numberWithBool:NO]] boolValue]; // allow self-signed certs
-    NSString* objectId = [command argumentAtIndex:3];
+    NSString* objectId = [command.arguments objectAtIndex:3];
     NSDictionary* headers = [command argumentAtIndex:4 withDefault:nil];
-
+    
     CDVPluginResult* result = nil;
     CDVFileTransferError errorCode = 0;
-
+    
     NSURL* targetURL;
-
+    
     if ([target hasPrefix:@"/"]) {
         /* Backwards-compatibility:
          * Check here to see if it looks like the user passed in a raw filesystem path. (Perhaps they had the path saved, and were previously using it with the old version of File). If so, normalize it by removing empty path segments, and check with File to see if any of the installed filesystems will handle it. If so, then we will end up with a filesystem url to use for the remainder of this operation.
@@ -440,29 +400,29 @@ - (void)download:(CDVInvokedUrlCommand*)command
     } else {
         targetURL = [NSURL URLWithString:target];
     }
-
+    
     NSURL* sourceURL = [NSURL URLWithString:source];
-
+    
     if (!sourceURL) {
         errorCode = INVALID_URL_ERR;
         NSLog(@"File Transfer Error: Invalid server URL %@", source);
     } else if (![targetURL isFileURL]) {
         CDVFilesystemURL *fsURL = [CDVFilesystemURL fileSystemURLWithString:target];
         if (!fsURL) {
-           errorCode = FILE_NOT_FOUND_ERR;
-           NSLog(@"File Transfer Error: Invalid file path or URL %@", target);
+            errorCode = FILE_NOT_FOUND_ERR;
+            NSLog(@"File Transfer Error: Invalid file path or URL %@", target);
         }
     }
-
+    
     if (errorCode > 0) {
         result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:errorCode AndSource:source AndTarget:target]];
         [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
         return;
     }
-
+    
     NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:sourceURL];
     [self applyRequestHeaders:headers toRequest:req];
-
+    
     CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];
     delegate.command = self;
     delegate.direction = CDV_TRANSFER_DOWNLOAD;
@@ -476,14 +436,14 @@ - (void)download:(CDVInvokedUrlCommand*)command
     delegate.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
         [delegate cancelTransfer:delegate.connection];
     }];
-
+    
     delegate.connection = [[NSURLConnection alloc] initWithRequest:req delegate:delegate startImmediately:NO];
-
+    
     if (self.queue == nil) {
         self.queue = [[NSOperationQueue alloc] init];
     }
     [delegate.connection setDelegateQueue:self.queue];
-
+    
     @synchronized (activeTransfers) {
         activeTransfers[delegate.objectId] = delegate;
     }
@@ -498,7 +458,7 @@ - (void)download:(CDVInvokedUrlCommand*)command
 - (NSMutableDictionary*)createFileTransferError:(int)code AndSource:(NSString*)source AndTarget:(NSString*)target
 {
     NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:3];
-
+    
     [result setObject:[NSNumber numberWithInt:code] forKey:@"code"];
     if (source != nil) {
         [result setObject:source forKey:@"source"];
@@ -507,7 +467,7 @@ - (NSMutableDictionary*)createFileTransferError:(int)code AndSource:(NSString*)s
         [result setObject:target forKey:@"target"];
     }
     NSLog(@"FileTransferError %@", result);
-
+    
     return result;
 }
 
@@ -518,7 +478,7 @@ - (NSMutableDictionary*)createFileTransferError:(int)code
                                         AndBody:(NSString*)body
 {
     NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:5];
-
+    
     [result setObject:[NSNumber numberWithInt:code] forKey:@"code"];
     if (source != nil) {
         [result setObject:source forKey:@"source"];
@@ -531,7 +491,7 @@ - (NSMutableDictionary*)createFileTransferError:(int)code
         [result setObject:body forKey:@"body"];
     }
     NSLog(@"FileTransferError %@", result);
-
+    
     return result;
 }
 
@@ -561,11 +521,11 @@ - (CDVFileTransferEntityLengthRequest*)initWithOriginalRequest:(NSURLRequest*)or
 {
     if (self) {
         DLog(@"Requesting entity length for GZIPped content...");
-
+        
         NSMutableURLRequest* req = [originalRequest mutableCopy];
         [req setHTTPMethod:@"HEAD"];
         [req setValue:@"identity" forHTTPHeaderField:@"Accept-Encoding"];
-
+        
         _originalDelegate = originalDelegate;
         _connection = [NSURLConnection connectionWithRequest:req delegate:self];
     }
@@ -596,15 +556,15 @@ - (void)connectionDidFinishLoading:(NSURLConnection*)connection
     NSString* downloadResponse = nil;
     NSMutableDictionary* uploadResult;
     CDVPluginResult* result = nil;
-
+    
     NSLog(@"File Transfer Finished with response code %d", self.responseCode);
-
+    
     if (self.direction == CDV_TRANSFER_UPLOAD) {
         uploadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
         if (uploadResponse == nil) {
             uploadResponse = [[NSString alloc] initWithData: self.responseData encoding:NSISOLatin1StringEncoding];
         }
-
+        
         if ((self.responseCode >= 200) && (self.responseCode < 300)) {
             // create dictionary to return FileUploadResult object
             uploadResult = [NSMutableDictionary dictionaryWithCapacity:3];
@@ -624,22 +584,22 @@ - (void)connectionDidFinishLoading:(NSURLConnection*)connection
             [self.targetFileHandle closeFile];
             self.targetFileHandle = nil;
             DLog(@"File Transfer Download success");
-
+            
             result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self.filePlugin makeEntryForURL:self.targetURL]];
         } else {
             downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
             if (downloadResponse == nil) {
                 downloadResponse = [[NSString alloc] initWithData: self.responseData encoding:NSISOLatin1StringEncoding];
             }
-
+            
             CDVFileTransferError errorCode = self.responseCode == 404 ? FILE_NOT_FOUND_ERR
-                : (self.responseCode == 304 ? NOT_MODIFIED : CONNECTION_ERR);
-            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:errorCode AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
+            : (self.responseCode == 304 ? NOT_MODIFIED : CONNECTION_ERR);
+            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
         }
     }
-
+    
     [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];
-
+    
     // remove connection for activeTransfers
     @synchronized (command.activeTransfers) {
         [command.activeTransfers removeObjectForKey:objectId];
@@ -652,12 +612,8 @@ - (void)connectionDidFinishLoading:(NSURLConnection*)connection
 - (void)removeTargetFile
 {
     NSFileManager* fileMgr = [NSFileManager defaultManager];
-
-    NSString *targetPath = [self targetFilePath];
-    if ([fileMgr fileExistsAtPath:targetPath])
-    {
-        [fileMgr removeItemAtPath:targetPath error:nil];
-    }
+    
+    [fileMgr removeItemAtPath:[self targetFilePath] error:nil];
 }
 
 - (void)cancelTransfer:(NSURLConnection*)connection
@@ -669,16 +625,14 @@ - (void)cancelTransfer:(NSURLConnection*)connection
         [[UIApplication sharedApplication] endBackgroundTask:delegate.backgroundTaskID];
         delegate.backgroundTaskID = UIBackgroundTaskInvalid;
     }
-
-    if (self.direction == CDV_TRANSFER_DOWNLOAD) {
-        [self removeTargetFile];
-    }
+    
+    [self removeTargetFile];
 }
 
 - (void)cancelTransferWithError:(NSURLConnection*)connection errorMessage:(NSString*)errorMessage
 {
     CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsDictionary:[self.command createFileTransferError:FILE_NOT_FOUND_ERR AndSource:self.source AndTarget:self.target AndHttpStatus:self.responseCode AndBody:errorMessage]];
-
+    
     NSLog(@"File Transfer Error: %@", errorMessage);
     [self cancelTransfer:connection];
     [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];
@@ -702,15 +656,15 @@ - (NSString *)targetFilePath
 - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
 {
     NSError* __autoreleasing error = nil;
-
+    
     self.mimeType = [response MIMEType];
     self.targetFileHandle = nil;
-
+    
     // required for iOS 4.3, for some reason; response is
     // a plain NSURLResponse, not the HTTP subclass
     if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
         NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
-
+        
         self.responseCode = (int)[httpResponse statusCode];
         self.bytesExpected = [response expectedContentLength];
         self.responseHeaders = [httpResponse allHeaderFields];
@@ -735,9 +689,9 @@ - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLRespons
             [self cancelTransferWithError:connection errorMessage:[NSString stringWithFormat:@"Could not create target file"]];
             return;
         }
-
+        
         NSString* parentPath = [filePath stringByDeletingLastPathComponent];
-
+        
         // create parent directories if needed
         if ([[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:&error] == NO) {
             if (error) {
@@ -765,9 +719,9 @@ - (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
 {
     NSString* body = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
     CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:body]];
-
+    
     NSLog(@"File Transfer Error: %@", [error localizedDescription]);
-
+    
     [self cancelTransfer:connection];
     [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];
 }
@@ -813,7 +767,7 @@ - (void)connection:(NSURLConnection*)connection didSendBodyData:(NSInteger)bytes
 {
     if (self.direction == CDV_TRANSFER_UPLOAD) {
         NSMutableDictionary* uploadProgress = [NSMutableDictionary dictionaryWithCapacity:3];
-
+        
         [uploadProgress setObject:[NSNumber numberWithBool:(!self.chunkedMode)] forKey:@"lengthComputable"];
         [uploadProgress setObject:[NSNumber numberWithLongLong:totalBytesWritten] forKey:@"loaded"];
         [uploadProgress setObject:[NSNumber numberWithLongLong:totalBytesExpectedToWrite] forKey:@"total"];
diff --git a/www/FileTransfer.js b/www/FileTransfer.js
index 80cf91c..a4eb243 100644
--- a/www/FileTransfer.js
+++ b/www/FileTransfer.js
@@ -101,7 +101,7 @@ var FileTransfer = function() {
 * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
 */
 FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
-    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
+     argscheck.checkArgs('*sFFO*', 'FileTransfer.upload', arguments);
     // check for options
     var fileKey = null;
     var fileName = null;
@@ -140,6 +140,20 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
             params = {};
         }
     }
+    var pathArray=[];
+               if(typeof filePath==='object'){
+               filePath.forEach(function(path){
+                                pathArray.push({
+                                              path:path,
+                                              fileName:path.substr(path.lastIndexOf('/')+1)
+                                              });
+                                })
+               }else{
+               pathArray.push({
+               path:filePath,
+                             fileName:filePath.substr(filePath.lastIndexOf('/')+1)
+               })
+               }
 
     if (cordova.platformId === "windowsphone") {
         headers = headers && convertHeadersToArray(headers);
@@ -163,7 +177,7 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
             }
         }
     };
-    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
+    exec(win, fail, 'FileTransfer', 'upload', [pathArray, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
 };
 
 /**


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org