Uploaded image for project: 'jclouds'
  1. jclouds
  2. JCLOUDS-1632

GCP BlobStore fails to put a blob if blob name contains non ASCII characters

    XMLWordPrintableJSON

Details

    Description

      Steps to reproduce:

      1. Configure blob store using `google-cloud-storage`
      2. Try to put a blob with name containing any Unicode character
      3. The error occurred something like below
      SEVERE: error after writing 389/409 bytes to https://www.googleapis.com/upload/storage/v1/b/gcp-dev/o?uploadType=multipart
      java.io.IOException: too many bytes written
      	at java.base/sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.write(HttpURLConnection.java:3812)
      	at com.google.common.io.CountingOutputStream.write(CountingOutputStream.java:54)
      	at org.jclouds.io.ByteStreams2.copy(ByteStreams2.java:73)
      	at org.jclouds.http.internal.JavaUrlHttpCommandExecutorService.writePayloadToConnection(JavaUrlHttpCommandExecutorService.java:302)
      	at org.jclouds.http.internal.JavaUrlHttpCommandExecutorService.convert(JavaUrlHttpCommandExecutorService.java:175)
      	at org.jclouds.http.internal.JavaUrlHttpCommandExecutorService.convert(JavaUrlHttpCommandExecutorService.java:66)
      	at org.jclouds.http.internal.BaseHttpCommandExecutorService.invoke(BaseHttpCommandExecutorService.java:97)
      	at org.jclouds.rest.internal.InvokeHttpMethod.invoke(InvokeHttpMethod.java:91)
      	at org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:74)
      	at org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:45)
      	at org.jclouds.reflect.FunctionalReflection$FunctionalInvocationHandler.handleInvocation(FunctionalReflection.java:117)
      	at com.google.common.reflect.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:87)
      	at jdk.proxy3/jdk.proxy3.$Proxy86.multipartUpload(Unknown Source)
      	at org.jclouds.googlecloudstorage.blobstore.GoogleCloudStorageBlobStore.putBlob(GoogleCloudStorageBlobStore.java:235)
      	at org.jclouds.googlecloudstorage.blobstore.GoogleCloudStorageBlobStore.putBlob(GoogleCloudStorageBlobStore.java:207)
      	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
      	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
      	at com.google.inject.internal.DelegatingInvocationHandler.invoke(DelegatingInvocationHandler.java:50)
      	at jdk.proxy3/jdk.proxy3.$Proxy78.putBlob(Unknown Source)
      

      Root cause

      The constructor org.jclouds.io.payloads.MultipartForm#MultipartForm(java.lang.String, java.lang.Iterable<? extends org.jclouds.io.payloads.Part>) doesn't calculate content's length properly.

      Specifically the constructor counts the length of org.jclouds.io.payloads.MultipartForm#createHeaders string instead of byte array length of that string to UTF-8

      AS a result a wrong content length is assigned to output stream causing the error above.

      Solution

      Use the length of a byte array instead of string length obtained from the method org.jclouds.io.payloads.MultipartForm#createHeaders

      See the PR https://github.com/apache/jclouds/pull/201

      Attachments

        Activity

          People

            gaul Andrew Gaul
            astsiapanay Aliaksandr
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 0.5h
                0.5h