|  | @@ -36,10 +36,6 @@ import java.net.MalformedURLException;
 | 
	
		
			
			| 36 | 36 |  import java.net.SocketException;
 | 
	
		
			
			| 37 | 37 |  import java.net.SocketTimeoutException;
 | 
	
		
			
			| 38 | 38 |  import java.net.URL;
 | 
	
		
			
			| 39 |  | -import java.nio.ByteBuffer;
 | 
	
		
			
			| 40 |  | -import java.nio.charset.CharacterCodingException;
 | 
	
		
			
			| 41 |  | -import java.nio.charset.Charset;
 | 
	
		
			
			| 42 |  | -import java.nio.charset.CharsetEncoder;
 | 
	
		
			
			| 43 | 39 |  import java.security.KeyStore;
 | 
	
		
			
			| 44 | 40 |  import java.util.ArrayList;
 | 
	
		
			
			| 45 | 41 |  import java.util.Arrays;
 | 
	
	
		
			
			|  | @@ -502,44 +498,38 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
 | 
	
		
			
			| 502 | 498 |                          // encoding will somehow break the UTF8 string format, to encode UTF8
 | 
	
		
			
			| 503 | 499 |                          // string correctly, we should do URL encoding before BASE64.
 | 
	
		
			
			| 504 | 500 |                          byte[] b = resp.body().bytes();
 | 
	
		
			
			| 505 |  | -                        CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
 | 
	
		
			
			| 506 | 501 |                          if(responseFormat == ResponseFormat.BASE64) {
 | 
	
		
			
			| 507 | 502 |                              callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP));
 | 
	
		
			
			| 508 | 503 |                              return;
 | 
	
		
			
			| 509 | 504 |                          }
 | 
	
		
			
			| 510 |  | -                        try {
 | 
	
		
			
			| 511 |  | -                            encoder.encode(ByteBuffer.wrap(b).asCharBuffer());
 | 
	
		
			
			| 512 |  | -                            // if the data contains invalid characters the following lines will be
 | 
	
		
			
			| 513 |  | -                            // skipped.
 | 
	
		
			
			| 514 |  | -                            String utf8 = new String(b);
 | 
	
		
			
			| 515 |  | -                            callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, utf8);
 | 
	
		
			
			| 516 |  | -                        }
 | 
	
		
			
			| 517 |  | -                        // This usually mean the data is contains invalid unicode characters, it's
 | 
	
		
			
			| 518 |  | -                        // binary data
 | 
	
		
			
			| 519 |  | -                        catch(CharacterCodingException ignored) {
 | 
	
		
			
			| 520 |  | -                            if(responseFormat == ResponseFormat.UTF8) {
 | 
	
		
			
			| 521 |  | -                                callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, "");
 | 
	
		
			
			| 522 |  | -                            }
 | 
	
		
			
			| 523 |  | -                            else {
 | 
	
		
			
			| 524 |  | -                                callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP));
 | 
	
		
			
			| 525 |  | -                            }
 | 
	
		
			
			| 526 |  | -                        }
 | 
	
		
			
			|  | 505 | +                        String utf8 = new String(b);
 | 
	
		
			
			|  | 506 | +                        callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, utf8);
 | 
	
		
			
			| 527 | 507 |                      }
 | 
	
		
			
			| 528 | 508 |                  } catch (IOException e) {
 | 
	
		
			
			| 529 | 509 |                      callback.invoke("RNFetchBlob failed to encode response data to BASE64 string.", null);
 | 
	
		
			
			| 530 | 510 |                  }
 | 
	
		
			
			| 531 | 511 |                  break;
 | 
	
		
			
			| 532 | 512 |              case FileStorage:
 | 
	
		
			
			|  | 513 | +                ResponseBody responseBody = resp.body();
 | 
	
		
			
			|  | 514 | +
 | 
	
		
			
			| 533 | 515 |                  try {
 | 
	
		
			
			| 534 | 516 |                      // In order to write response data to `destPath` we have to invoke this method.
 | 
	
		
			
			| 535 | 517 |                      // It uses customized response body which is able to report download progress
 | 
	
		
			
			| 536 | 518 |                      // and write response data to destination path.
 | 
	
		
			
			| 537 |  | -                    resp.body().bytes();
 | 
	
		
			
			|  | 519 | +                    responseBody.bytes();
 | 
	
		
			
			| 538 | 520 |                  } catch (Exception ignored) {
 | 
	
		
			
			| 539 | 521 |  //                    ignored.printStackTrace();
 | 
	
		
			
			| 540 | 522 |                  }
 | 
	
		
			
			| 541 |  | -                this.destPath = this.destPath.replace("?append=true", "");
 | 
	
		
			
			| 542 |  | -                callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
 | 
	
		
			
			|  | 523 | +
 | 
	
		
			
			|  | 524 | +                RNFetchBlobFileResp rnFetchBlobFileResp = (RNFetchBlobFileResp) responseBody;
 | 
	
		
			
			|  | 525 | +
 | 
	
		
			
			|  | 526 | +                if(rnFetchBlobFileResp != null && rnFetchBlobFileResp.isDownloadComplete() == false){
 | 
	
		
			
			|  | 527 | +                    callback.invoke("RNFetchBlob failed. Download interrupted.", null);
 | 
	
		
			
			|  | 528 | +                }
 | 
	
		
			
			|  | 529 | +                else {
 | 
	
		
			
			|  | 530 | +                    this.destPath = this.destPath.replace("?append=true", "");
 | 
	
		
			
			|  | 531 | +                    callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
 | 
	
		
			
			|  | 532 | +                }
 | 
	
		
			
			| 543 | 533 |                  break;
 | 
	
		
			
			| 544 | 534 |              default:
 | 
	
		
			
			| 545 | 535 |                  try {
 | 
	
	
		
			
			|  | @@ -666,30 +656,40 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
 | 
	
		
			
			| 666 | 656 |                  DownloadManager dm = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
 | 
	
		
			
			| 667 | 657 |                  dm.query(query);
 | 
	
		
			
			| 668 | 658 |                  Cursor c = dm.query(query);
 | 
	
		
			
			| 669 |  | -
 | 
	
		
			
			|  | 659 | +                // #236 unhandled null check for DownloadManager.query() return value
 | 
	
		
			
			|  | 660 | +                if (c == null) {
 | 
	
		
			
			|  | 661 | +                    this.callback.invoke("Download manager failed to download from  " + this.url + ". Query was unsuccessful ", null, null);
 | 
	
		
			
			|  | 662 | +                    return;
 | 
	
		
			
			|  | 663 | +                }
 | 
	
		
			
			| 670 | 664 |  
 | 
	
		
			
			| 671 | 665 |                  String filePath = null;
 | 
	
		
			
			| 672 |  | -                // the file exists in media content database
 | 
	
		
			
			| 673 |  | -                if (c.moveToFirst()) {
 | 
	
		
			
			| 674 |  | -                    // #297 handle failed request
 | 
	
		
			
			| 675 |  | -                    int statusCode = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
 | 
	
		
			
			| 676 |  | -                    if(statusCode == DownloadManager.STATUS_FAILED) {
 | 
	
		
			
			| 677 |  | -                        this.callback.invoke("Download manager failed to download from  " + this.url + ". Status Code = " + statusCode, null, null);
 | 
	
		
			
			| 678 |  | -                        return;
 | 
	
		
			
			| 679 |  | -                    }
 | 
	
		
			
			| 680 |  | -                    String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
 | 
	
		
			
			| 681 |  | -                    if ( contentUri != null &&
 | 
	
		
			
			| 682 |  | -                            options.addAndroidDownloads.hasKey("mime") &&
 | 
	
		
			
			| 683 |  | -                            options.addAndroidDownloads.getString("mime").contains("image")) {
 | 
	
		
			
			| 684 |  | -                        Uri uri = Uri.parse(contentUri);
 | 
	
		
			
			| 685 |  | -                        Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
 | 
	
		
			
			| 686 |  | -                        // use default destination of DownloadManager
 | 
	
		
			
			| 687 |  | -                        if (cursor != null) {
 | 
	
		
			
			| 688 |  | -                            cursor.moveToFirst();
 | 
	
		
			
			| 689 |  | -                            filePath = cursor.getString(0);
 | 
	
		
			
			| 690 |  | -                            cursor.close();
 | 
	
		
			
			|  | 666 | +                try {    
 | 
	
		
			
			|  | 667 | +                    // the file exists in media content database
 | 
	
		
			
			|  | 668 | +                    if (c.moveToFirst()) {
 | 
	
		
			
			|  | 669 | +                        // #297 handle failed request
 | 
	
		
			
			|  | 670 | +                        int statusCode = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
 | 
	
		
			
			|  | 671 | +                        if(statusCode == DownloadManager.STATUS_FAILED) {
 | 
	
		
			
			|  | 672 | +                            this.callback.invoke("Download manager failed to download from  " + this.url + ". Status Code = " + statusCode, null, null);
 | 
	
		
			
			|  | 673 | +                            return;
 | 
	
		
			
			|  | 674 | +                        }
 | 
	
		
			
			|  | 675 | +                        String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
 | 
	
		
			
			|  | 676 | +                        if ( contentUri != null &&
 | 
	
		
			
			|  | 677 | +                                options.addAndroidDownloads.hasKey("mime") &&
 | 
	
		
			
			|  | 678 | +                                options.addAndroidDownloads.getString("mime").contains("image")) {
 | 
	
		
			
			|  | 679 | +                            Uri uri = Uri.parse(contentUri);
 | 
	
		
			
			|  | 680 | +                            Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
 | 
	
		
			
			|  | 681 | +                            // use default destination of DownloadManager
 | 
	
		
			
			|  | 682 | +                            if (cursor != null) {
 | 
	
		
			
			|  | 683 | +                                cursor.moveToFirst();
 | 
	
		
			
			|  | 684 | +                                filePath = cursor.getString(0);
 | 
	
		
			
			|  | 685 | +                                cursor.close();
 | 
	
		
			
			|  | 686 | +                            }
 | 
	
		
			
			| 691 | 687 |                          }
 | 
	
		
			
			| 692 | 688 |                      }
 | 
	
		
			
			|  | 689 | +                } finally {
 | 
	
		
			
			|  | 690 | +                    if (c != null) {
 | 
	
		
			
			|  | 691 | +                        c.close();
 | 
	
		
			
			|  | 692 | +                    }
 | 
	
		
			
			| 693 | 693 |                  }
 | 
	
		
			
			| 694 | 694 |  
 | 
	
		
			
			| 695 | 695 |                  // When the file is not found in media content database, check if custom path exists
 |