geank / google-api-java-client

Automatically exported from code.google.com/p/google-api-java-client
0 stars 0 forks source link

Unable to resuming an interrupted upload #897

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
google-api-java-client-1.18.0-rc
google-api-services-drive-v2-rev135-1.18.0-rc

Java environment: Android 443

Describe the problem.

It seems that MediaHttpUploader.upload() did not handle resume upload well. 
The reason is that "1) Request the upload status." mentioned in "Google Drive 
SDK, Upload Files" always fail to get "Content-Range".
https://developers.google.com/drive/web/manage-uploads#resumable

My test step is try to disconnect WiFi/connect to another WiFi during upload, 
and then upload the same file again, but it always upload the file from 
beginning.

Code(cannot resume an interrupted upload):

insert = getDriveService().files().insert(fileMetadata, mediaContent);
MediaHttpUploader mediaUploader = insert.getMediaHttpUploader();
mediaUploader.setDirectUploadEnabled(false);
mediaUploader.setProgressListener(mUploadFileProgressListener);
mediaUploader.setChunkSize(MediaHttpUploader.MINIMUM_CHUNK_SIZE);
mediaUploader.upload(insert.buildHttpRequestUrl());

How would you expect it to be fixed?

1) Google drive server should respond "Content-Range" with "HTTP/1.1 308 Resume 
Incomplete"
2) If server is allow to NOT response "Content-Range", the way to solve it is 
polling "Content-Range" all the time during upload. Thus, it able to resuming 
an interrupted upload by "Resume the upload from the point where it left off."

Original issue reported on code.google.com by kaifu.c...@gmail.com on 15 Aug 2014 at 8:18

GoogleCodeExporter commented 9 years ago
Thanks for your feedback. We're looking into your issue. Please stay tuned for 
updates.

Original comment by wonder...@google.com on 22 Aug 2014 at 6:03

GoogleCodeExporter commented 9 years ago
Hi, to help us debugging, can you provide an uploadId? It will be a query 
parameter on additional resumable upload requests beyond the first one.

Original comment by wonder...@google.com on 28 Aug 2014 at 11:51

GoogleCodeExporter commented 9 years ago
Hello, 

Sine the issue happen rate is 100%, I suggest you to get upload ID by yourself.
Or you can get upload ID based on below method:

    private String getUploadID(Uri fileUri, String token) {         
        Log.d(LOG_TAG, "[sendResumableHttpRequest] +++");

        String upload_id = "";

        java.io.File fileContent = new java.io.File(fileUri.getPath());
        String fileName = fileContent.getName();
        String contentLength = String.valueOf(fileContent.length());
        String mimeType = getMimeFromURI(fileUri);

        Log.d(LOG_TAG, "[sendResumableHttpRequest] fileName : " + fileName);
        Log.d(LOG_TAG, "[sendResumableHttpRequest] contentLength : " + contentLength);
        Log.d(LOG_TAG, "[sendResumableHttpRequest] mimeType : " + mimeType);

        try {
            String url = "https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable";
            URL obj = new URL(url);
            HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

            //add reuqest header
            con.setRequestMethod("POST");
            con.setRequestProperty("Authorization", "Bearer " + token);
            con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            con.setRequestProperty("X-Upload-Content-Type", mimeType);
            con.setRequestProperty("X-Upload-Content-Length", contentLength);       

            JSONObject jobj = new JSONObject();
            jobj.put("title", fileName);
            byte[] postData = jobj.toString().getBytes();           

            // Send post request
            con.setDoOutput(true);
            DataOutputStream wr = new DataOutputStream(con.getOutputStream());
            wr.write(postData);
            wr.flush();
            wr.close();

            int responseCode = con.getResponseCode();
            String location = con.getHeaderField("Location");
            if (location.contains("upload_id")) {
                String[] uploadParameters = location.split("upload_id");
                upload_id = uploadParameters[1].replace("=", "");
            }

            Log.d(LOG_TAG, "[sendResumableHttpRequest] Response Code : " + responseCode);
            Log.d(LOG_TAG, "[sendResumableHttpRequest] Response Location : " + location);
            Log.d(LOG_TAG, "[sendResumableHttpRequest] Response uploadID : " + upload_id);

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();            
        }               

        Log.d(LOG_TAG, "[sendResumableHttpRequest] ---");

        return upload_id;
    }

Original comment by kaifu.c...@gmail.com on 29 Aug 2014 at 9:17