Reputation: 917
I'd like users of a site to be able to upload files to google cloud storage
without using the web app servers resources so signed urls seem like the way to go.
When a user selects a file to upload jquery
sends a GET
request to django
for a signed url. The url is generated using gsutil signurl
command. Django
then returns the signed url to the template and on submit a jquery PUT
request is sent with the signed url.
However:
Are there required headers that must be sent with the PUT request?
gsutil command (assuming user selected file 'map.html')...
gsutil signurl -p notasecret -m PUT -d 10m /path/to/.p12 gs://bucket_name/map.html
jquery PUT code...
$.ajax( {
url: g_url,
type: 'PUT',
crossDomain: true,
success: console.log('success'),
error: function(XMLHttpRequest, textStatus, errorThrown){
alert('status:' + XMLHttpRequest.status + ', status text: ' + XMLHttpRequest.statusText);
},
data: file,
} );
g_url looks like...
https://storage.googleapis.com/bucket_name/map.html?GoogleAccessId=__retracted__&Expires=1408889274&Signature=rDJAZQG4MIyMupy0M8HJ17r8rkEJcAbYSWpcq084SdzRh%2BnZavTfuWl4Q%2F6ytkSkN2c2%2B4b4pPRF5eWOEOL1InRxlB5pEBedPFZPpgDrRvR9tFybtH%2BkesKLhIZ3WjJ0utzAwhl%2BgAlQY6ulvO0Djib20zcG5fkHOigpRf1xBUk%3D
Upvotes: 5
Views: 1349
Reputation: 917
Turns out my problem was related to CORS. In order to get this to work on Django 1.6
, I had to do the following:
django-cors-headers
and follow configuration instructions https://github.com/ottoyiu/django-cors-headersGCS
bucket with the appropriate verbs and to accept requests from my domain https://developers.google.com/storage/docs/cross-originjquery
code provided in the Django docs to my template https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-it-works With that PUT
and DELETE
requests started working. The only other issue I ran into was incompatible content-headers. So you my need to set your content-type in the signed url and before sending the request.
gsutil command would look like
gsutil signurl -p notasecret -m PUT -d 10m -c 'multipart/formdata; charset=UTF-8' /path/to/.p12 gs://bucket_name/map.html
add beforeSend to jquery request
beforeSend: function (request){
request.setRequestHeader("Content-Type", 'multipart/formdata; charset=UTF-8')
;},
Upvotes: 1