Bläddra i källkod

Merge pull request #449 from sonudoo/bug-fix-interrupted-downloads

Bug fix for download interruption promise rejection
Travis Nuttall 5 år sedan
förälder
incheckning
d490a3be54
No account linked to committer's email address

+ 13
- 3
android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java Visa fil

@@ -530,16 +530,26 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
530 530
                 }
531 531
                 break;
532 532
             case FileStorage:
533
+                ResponseBody responseBody = resp.body();
534
+
533 535
                 try {
534 536
                     // In order to write response data to `destPath` we have to invoke this method.
535 537
                     // It uses customized response body which is able to report download progress
536 538
                     // and write response data to destination path.
537
-                    resp.body().bytes();
539
+                    responseBody.bytes();
538 540
                 } catch (Exception ignored) {
539 541
 //                    ignored.printStackTrace();
540 542
                 }
541
-                this.destPath = this.destPath.replace("?append=true", "");
542
-                callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
543
+
544
+                RNFetchBlobFileResp rnFetchBlobFileResp = (RNFetchBlobFileResp) responseBody;
545
+
546
+                if(rnFetchBlobFileResp != null && rnFetchBlobFileResp.isDownloadComplete() == false){
547
+                    callback.invoke("RNFetchBlob failed. Download interrupted.", null);
548
+                }
549
+                else {
550
+                    this.destPath = this.destPath.replace("?append=true", "");
551
+                    callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
552
+                }
543 553
                 break;
544 554
             default:
545 555
                 try {

+ 41
- 7
android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java Visa fil

@@ -33,6 +33,7 @@ public class RNFetchBlobFileResp extends ResponseBody {
33 33
     long bytesDownloaded = 0;
34 34
     ReactApplicationContext rctContext;
35 35
     FileOutputStream ofStream;
36
+    boolean isEndMarkerReceived;
36 37
 
37 38
     public RNFetchBlobFileResp(ReactApplicationContext ctx, String taskId, ResponseBody body, String path, boolean overwrite) throws IOException {
38 39
         super();
@@ -41,6 +42,7 @@ public class RNFetchBlobFileResp extends ResponseBody {
41 42
         this.originalBody = body;
42 43
         assert path != null;
43 44
         this.mPath = path;
45
+        this.isEndMarkerReceived = false;
44 46
         if (path != null) {
45 47
             boolean appendToExistingFile = !overwrite;
46 48
             path = path.replace("?append=true", "");
@@ -68,6 +70,11 @@ public class RNFetchBlobFileResp extends ResponseBody {
68 70
         return originalBody.contentLength();
69 71
     }
70 72
 
73
+    public boolean isDownloadComplete() {
74
+        return (bytesDownloaded == contentLength()) // Case of non-chunked downloads
75
+                || (contentLength() == -1 && isEndMarkerReceived); // Case of chunked downloads
76
+    }
77
+
71 78
     @Override
72 79
     public BufferedSource source() {
73 80
         ProgressReportingSource countable = new ProgressReportingSource();
@@ -83,22 +90,49 @@ public class RNFetchBlobFileResp extends ResponseBody {
83 90
                 bytesDownloaded += read > 0 ? read : 0;
84 91
                 if (read > 0) {
85 92
                     ofStream.write(bytes, 0, (int) read);
93
+                } else if (contentLength() == -1 && read == -1) {
94
+                    // End marker has been received for chunked download
95
+                    isEndMarkerReceived = true;
86 96
                 }
87 97
                 RNFetchBlobProgressConfig reportConfig = RNFetchBlobReq.getReportProgress(mTaskId);
88
-                if (reportConfig != null && contentLength() != 0 &&reportConfig.shouldReport(bytesDownloaded / contentLength())) {
89
-                    WritableMap args = Arguments.createMap();
90
-                    args.putString("taskId", mTaskId);
91
-                    args.putString("written", String.valueOf(bytesDownloaded));
92
-                    args.putString("total", String.valueOf(contentLength()));
93
-                    rctContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
94
-                            .emit(RNFetchBlobConst.EVENT_PROGRESS, args);
98
+
99
+                if (contentLength() != 0) {
100
+
101
+                    // For non-chunked download, progress is received / total
102
+                    // For chunked download, progress can be either 0 (started) or 1 (ended)
103
+                    float progress = (contentLength() != -1) ? bytesDownloaded / contentLength() : ( ( isEndMarkerReceived ) ? 1 : 0 );
104
+
105
+                    if (reportConfig != null && reportConfig.shouldReport(progress /* progress */)) {
106
+                        if (contentLength() != -1) {
107
+                            // For non-chunked downloads
108
+                            reportProgress(mTaskId, bytesDownloaded, contentLength());
109
+                        } else {
110
+                            // For chunked downloads
111
+                            if (!isEndMarkerReceived) {
112
+                                reportProgress(mTaskId, 0, contentLength());
113
+                            } else{
114
+                                reportProgress(mTaskId, bytesDownloaded, bytesDownloaded);
115
+                            }
116
+                        }
117
+                    }
118
+
95 119
                 }
120
+
96 121
                 return read;
97 122
             } catch(Exception ex) {
98 123
                 return -1;
99 124
             }
100 125
         }
101 126
 
127
+        private void reportProgress(String taskId, long bytesDownloaded, long contentLength) {
128
+            WritableMap args = Arguments.createMap();
129
+            args.putString("taskId", taskId);
130
+            args.putString("written", String.valueOf(bytesDownloaded));
131
+            args.putString("total", String.valueOf(contentLength));
132
+            rctContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
133
+                    .emit(RNFetchBlobConst.EVENT_PROGRESS, args);
134
+        }
135
+
102 136
         @Override
103 137
         public Timeout timeout() {
104 138
             return null;