1

I am using Backblaze and managed to upload files (images and videos) to my buckets in my iOS App (swift 5) but I am unable to do so in my java android app.

I receive the correct auth token, download url, upload url and API Url.

But when I try to post it to that url its not working and I receive the following error

W/OkHttpClient: A connection to https://googleads.g.doubleclick.net/ was leaked. Did you forget to close a response body?
D/yyyy enclosed: saveImgToStorage:     buffer(com.android.okhttp.internal.http.Http1xStream$FixedLengthSource@e5232ab).inputStream()
saveImgToStorage: 401
W/System.err: java.net.ProtocolException: cannot write request body after response has been read
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:264)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(Unknown Source:0)
    at com.flax.de.Helper.StorageService.saveImgToStorage(StorageService.java:192)
    at com.flax.de.Helper.StorageService.getUploadUrl(StorageService.java:142)
    at com.flax.de.Helper.StorageService.getAuthData(StorageService.java:95)
W/System.err:     at com.flax.de.Categories.NewPostFragment$3.run(NewPostFragment.java:341)
    at java.lang.Thread.run(Thread.java:764)

The function trying to post the data to the upload url is the following

   static private void saveImgToStorage(Context context, String id, String uploadUrl, String uploadAuthorizationToken
        , String downloadUrl, Uri imageUrl, String bucketName, Interfaces.OnSuccessHashMap onSuccess
        , Interfaces.OnError onError) throws IOException {

    String photoUrl = downloadUrl+"/file/"+bucketName+"/"+id;
    HashMap hashMap = new HashMap();
    hashMap.put(API.databaseStrings.URL, photoUrl);
    Bitmap bmp = MediaStore.Images.Media.getBitmap(context.getContentResolver(), imageUrl);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] fileData = baos.toByteArray();
    String contentType = "image/jpg";
    String sha1 = "do_not_verify";



    HttpURLConnection connection = null;
    try {
        URL url = new URL(uploadUrl);
        connection = (HttpURLConnection)url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Authorization", uploadAuthorizationToken);
        connection.setRequestProperty("Content-Type", contentType);
        connection.setRequestProperty("X-Bz-File-Name", id);
        connection.setRequestProperty("X-Bz-Content-Sha1", sha1);
        connection.setDoOutput(true);

        Log.d("yyyy enclosed", "saveImgToStorage: " + connection.getErrorStream().toString());
        Log.d("yyyy enclosed", "saveImgToStorage: " + connection.getResponseCode());

        DataOutputStream writer = new DataOutputStream(connection.getOutputStream());
        writer.write(fileData);
        String jsonResponse = myInputStreamReader(connection.getInputStream());
        JSONObject obj = new JSONObject(jsonResponse);


        System.out.println(jsonResponse);
    } catch (Exception e) {
        e.printStackTrace();
        onError.onError();
    } finally {
        connection.disconnect();
    }
}

Error code is as you see

401

I have no idea why its not working. As I said it is working perfectly fine on my iOS devices which uses basically the same code only written in swift (taken from the guide from back blaze) I personally think its not an issue from back blaze but rather that my request is wrong? Or the format of my bitmap?

Or maybe I have to do it asynchronously? I tried it with a thread before move it out from the main thread but it did not work either.

W/System.err: java.io.FileNotFoundException: https://pod-000-1070-11.backblaze.com/b2api/v2/b2_upload_file/afec4cd53b2f323f715a0c18/c000_v0001070_t0002
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:251)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(Unknown Source:0)

is what I receive if use this code

      String photoUrl = downloadUrl+"/file/"+bucketName+"/"+id;
    HashMap hashMap = new HashMap();
    hashMap.put(API.databaseStrings.URL, photoUrl);
    Bitmap bmp = MediaStore.Images.Media.getBitmap(context.getContentResolver(), imageUrl);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] fileData = baos.toByteArray();
    String contentType = "image/jpg";
    String sha1 = "do_not_verify";

    HttpURLConnection connection = null;
    String json = null;


    try {
        URL url = new URL(uploadUrl);
        connection = (HttpURLConnection)url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Authorization", uploadAuthorizationToken);
        connection.setRequestProperty("Content-Type", contentType);
        connection.setRequestProperty("X-Bz-File-Name", id);
        connection.setRequestProperty("X-Bz-Content-Sha1", sha1);
        connection.setDoOutput(true);
        DataOutputStream writer = new DataOutputStream(connection.getOutputStream());
        writer.write(fileData);
        String jsonResponse = myInputStreamReader(connection.getInputStream());
        System.out.println(jsonResponse);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        connection.disconnect();
    }
Zash__
  • 293
  • 4
  • 16
  • `Sending Bitmap to Server` You should not send bitmaps to your server but image files like .jpg or .png. – blackapps Oct 21 '20 at 12:59
  • I guess you did not read through my post. I made a byteArray out of my bitmap. – Zash__ Oct 21 '20 at 13:01
  • Yes i saw that. But that byte array contains the bytes for a .jpeg. It is not relevant that it comes from a bitmap. You are trying to upload jpeg bytes. You could have filled that byte arrray also from the bytes of a jpg file. Look at the subject of your post as it does not cover what you do. – blackapps Oct 21 '20 at 13:03
  • However, its not working anyway so I am looking for help to solve it – Zash__ Oct 21 '20 at 13:05
  • Sorry but i cannot give help for sending bitmaps to a server. ;-) – blackapps Oct 21 '20 at 13:08
  • The request does not work. Thats what I need to fix first – Zash__ Oct 21 '20 at 13:10
  • It makes no sense to fix your subject afterwards. – blackapps Oct 21 '20 at 13:16
  • My question is clear: I want to upload a selected bitmap to a server via a http request. There is no need to change my subject as it stays the same – Zash__ Oct 21 '20 at 13:27

1 Answers1

1

The issue in the first version of the function is these two lines:

Log.d("yyyy enclosed", "saveImgToStorage: " + connection.getErrorStream().toString());
Log.d("yyyy enclosed", "saveImgToStorage: " + connection.getResponseCode());

Both getErrorStream() and getResponseCode() cause the request to be sent, and the response to be read, since you've asked for the error response and response code from the server. connection.getOutputStream() throws an error because it's too late to send the request body.

You should remove these lines, or move them after the line:

writer.write(fileData);

HttpURLConnection is 'broken by design' in the way that it implicitly sends the request when you try to read the response.

metadaddy
  • 4,234
  • 1
  • 22
  • 46