0

I am trying to generate the presigned url for uploading files to buckets in GCS. But am having the following error when trying to open the link in the browser. Following is my code

package test;
import com.google.auth.Credentials;
import com.google.auth.ServiceAccountSigner;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.HttpMethod;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageException;
import com.google.cloud.storage.StorageOptions;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class TestGcs {
    public static void main(String args[]) throws FileNotFoundException, IOException {
        String extracted = extracted();
        System.out.println(extracted);
        
        
    }

    private static String extracted() throws IOException, FileNotFoundException, UnsupportedEncodingException {
        Credentials credentials = getCreds();
        Storage storage = StorageOptions.newBuilder()
                .setCredentials(credentials)
                .setProjectId("<<project ID>>")
                .build()
                .getService();

        BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of("<<bucketname>>", "<<object Nmae>>")).build();

// Generate Signed URL
Map<String, String> extensionHeaders = new HashMap<>();
extensionHeaders.put("Content-Type", "application/octet-stream");

URL url = storage.signUrl(blobInfo, 1, TimeUnit.HOURS,
Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
Storage.SignUrlOption.signWith((ServiceAccountSigner) getCreds()),
Storage.SignUrlOption.withExtHeaders(extensionHeaders),
Storage.SignUrlOption.withV4Signature());
return URLDecoder.decode(url.toString(), StandardCharsets.UTF_8.name());
    }

    private static Credentials getCreds() throws IOException, FileNotFoundException {
        Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("<<Json service account key path>>"));
        return credentials;
    }

}

I get the following error when accesing through browser. The service account role has storage admin role.

<Error>
<Code>MalformedSecurityHeader</Code>
<Message>Your request has a malformed header.</Message>
<ParameterName>content-type</ParameterName>
<Details>Header was included in signedheaders, but not in the request.</Details>
</Error>
user846445
  • 221
  • 1
  • 3
  • 14
  • What did you enter in the browser? Note the error message **Header was included in signedheaders, but not in the request**. Did you include the same header **Content-Type: application/octet-stream**? Use **curl** to test and post the command and the result in your question. – John Hanley Mar 29 '22 at 10:15
  • @JohnHanley: I entered the url generated from above code which the value of "extracted". I used the folowing command curl -X PUT --upload-file helo.txt <> and got an error which is too large to display here – user846445 Mar 29 '22 at 10:32
  • How did you specify the header **Content-Type: application/octet-stream**? Put these details in your question. There is plenty of room. – John Hanley Mar 29 '22 at 16:48
  • @JohnHanley In the above code in the extension headers map, i put the content-type. – user846445 Mar 29 '22 at 19:33
  • 1
    You must also put the same headers in the request when using the signed URL. Reread the error message. For testing, remove the header when signing to see how everything works. – John Hanley Mar 29 '22 at 19:36
  • 1
    Hi, I found this [stackoverflow thread](https://stackoverflow.com/a/55291055/15774177), can you please try to use content-type in the curl command the way he has used it, it will be like this ``` curl -X PUT -H 'Content-Type: application/octet-stream' " --upload-file my-file 'signedURL’```, and tell us what you get. – Zeenath S N Mar 30 '22 at 09:08
  • @ZeenathSN : works with curl. But am facing issue with cors.I am not upload from browser through js code. I am getting the following error Acess to XmlHttpRequest from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. – user846445 Mar 30 '22 at 09:34
  • Have you configured the CORS on the bucket as shown in [this](https://stackoverflow.com/a/67568665/15774177)? – Zeenath S N Mar 30 '22 at 12:53

0 Answers0