I had been using Google Cloud CDN for caching content from a GCS bucket for months. Until yesterday (2019/09/19), I noticed that I cannot access an object with white spaces in its name. Usually, I apply encodeURIComponent
to the object's name before signing the whole URL, which had been working fine until yesterday.
Here's what I've tried so far with gcloud
utility:
Sign the URL without URL-encoding the file's name:
$ gcloud compute sign-url --key-name my-key --key-file my-key --expires-in 15m "https://cdn.example.com/file-with-white space.txt"
I then accessed the URL with and without
%20
. The result is 403, shown in the picture.Sign the URL with the URL-encoded file's name (this is what I'd been doing for months, and it worked fine):
$ gcloud compute sign-url --key-name my-key --key-file my-key --expires-in 15m "https://cdn.example.com/file-with-white%20space.txt"
The result is also 403 but with different message:
Anonymous caller does not have storage.objects.get access to bucket/file name
I have also tried using the Go code from this link. The results are the same.
Please note that files without white spaces in its name can still be accessed successfully through the CDN.
Update
- To clarify, I think the CDN's behavior has changed.
- I have granted the CDN access to the GCS bucket. That's why the CDN worked without problems earlier. I actually have just run
gsutil iam ch serviceAccount:service-PROJECT_NUM@cloud-cdn-fill.iam.gserviceaccount.com:objectViewer gs://[BUCKET]
twice to ensure this. - I have tried signing GCS URLs using
gsutil
directly without using the CDN, and the signed URL worked.
Update 2
I have tried out the --validate
option. This is what I got:
$ gcloud compute sign-url --key-name cdn-signing-key \
--key-file cdn-signing-key --expires-in 15m \
--validate "https://cdn.domain.com/file%20with%20space"
signedUrl: https://cdn.domain.com/file%20with%20space?Expires=1569075302&KeyName=cdn-signing-key&Signature=e3SANudKHIT5txHWVlO1oijItXw=
validationResponseCode: 200
And yet, I still received 403 when accessing the "signedUrl" through a browser. The result is an XML page with <Code>AccessDenied</Code>
.