2

Below is my code. I copied the interoperable access keys.. The client and secret both from the same page. I used client key in the ClientAccess ID in the form and secret for hashing. But i get the error saying invalid argument.

Detail error being shown as "Cannot create buckets using a POST"

Below is the python code i used.

import webapp2
import cgi
import datetime
import urllib
import base64
import hmac, hashlib
import sha


policy_document = '''{"expiration": "2016-06-16T11:11:11Z",
                    "conditions": [
                        ["starts-with", "$key", "" ],
                        {"acl": "public-read" },
                    ]
                }'''


policy = base64.b64encode(policy_document).strip()
h = hmac.new('xxx', digestmod=sha.sha)
h.update(policy)
signature = base64.b64encode(h.digest())


class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('<html><body>')
        self.response.write('<form action="http://storage.googleapis.com/www.xyz.com" method="post" enctype="multipart/form-data">')
        self.response.write('<input type="text" name="key" value="">')
        self.response.write('<input type="hidden" name="bucket" value="www.xyz.com">')
        #self.response.write('<input type="hidden" name="Content-Type" value="image/jpeg">')
        self.response.write('<input type="hidden" name="GoogleAccessId" value="GOOGxxxxx">')
        self.response.write('<input type="hidden" name="acl" value="public-read">')
        self.response.write('<input type="hidden" name="success_action_redirect" value="http://www.linklip.com/storage.html">')
        self.response.write('<input type="hidden" name="policy" value="%s">' % policy )
        self.response.write('<input type="hidden" name="signature" value="%s">' % signature )
        self.response.write('<input name="file" type="file">')
        self.response.write('<input type="submit" value="Upload">')
        self.response.write('</form>')
        self.response.write('</body></html>')


app = webapp2.WSGIApplication([
    ('/', MainHandler)
    ], debug=True)
user2131868
  • 21
  • 1
  • 5

4 Answers4

10

I had the same issue, and after trying to be as close as possible to the documentation, I found that what was wrong is that my file input was the first child of the form instead of at the end.

Does not work:

<form action="https://***.storage.googleapis.com" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="hidden" name="signature" value="***" />
    <input type="hidden" name="key" value="test/alexis.png" />
    <input type="hidden" name="policy" value="***" />
    <input type="hidden" name="Content-Type" value="image/png" />
    <input type="hidden" name="GoogleAccessId" value="***@developer.gserviceaccount.com" />
    <input type="hidden" name="bucket" value="***" />
    <input type="hidden" name="success_action_status" value="201" />
    <input type="submit" value="Upload">
</form>

Works:

<form action="https://***.storage.googleapis.com" method="post" enctype="multipart/form-data">
    <input type="hidden" name="signature" value="***" />
    <input type="hidden" name="key" value="test/alexis.png" />
    <input type="hidden" name="policy" value="***" />
    <input type="hidden" name="Content-Type" value="image/png" />
    <input type="hidden" name="GoogleAccessId" value="***@developer.gserviceaccount.com" />
    <input type="hidden" name="bucket" value="***" />
    <input type="hidden" name="success_action_status" value="201" />
    <input type="file" name="file" />
    <input type="submit" value="Upload">
</form>

I'm still puzzled about why it works this way and not the other...

Alexis
  • 488
  • 4
  • 10
  • that is too crazy – lucemia Nov 24 '18 at 01:50
  • 2
    Man you saved me :) It is almost 6 months I have been trying to resolve this issue . Luckily I found your post . SO Happy :) – Bujji Jan 01 '19 at 03:15
  • This is also required if you are using async POST requests. You have to build your FormData object making sure to append the uploaded file at the end, after appending the other fields. – MajorScientist Jun 11 '20 at 16:36
0

To create a bucket, you need to perform an HTTP PUT:

https://developers.google.com/storage/docs/reference-methods#putbucket

Your form method is set to 'POST'.

rein
  • 32,967
  • 23
  • 82
  • 106
  • 1
    I want to upload the document to GCS using the HTML forms. I already created the bucket but i could not able to upload. I tried what is given in the document (https://developers.google.com/storage/docs/reference-methods#postobject)but still it is not working. – user2131868 May 05 '13 at 09:58
0

I found the answer for the above problem.

self.response.write('<input type="hidden" name="bucket" value="www.xyz.com">')

In the value, i tried value="Bucket/filename-i-want-to-put" and i was able to see file created in the bucket.

user2131868
  • 21
  • 1
  • 5
0

Solution for me was to add <input type="hidden" name="key" value="${filename}">.

<form action="http://container-name.storage.googleapis.com" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="acl" value="public-read">
    <input type="hidden" name="Content-Type" value="application/pdf">
    <input type="hidden" name="key" value="${filename}">
    <input type="hidden" name="bucket" value="container-name">
    <input type="hidden" name="GoogleAccessId" value="XXXXXXXXX">
    <input type="hidden" name="policy" value="XXXXXXXXXXXXXXXXXXXXXXX=">
    <input type="hidden" name="signature" value="XXXXXX==">
    <input type="file" name="file" />
    <input type="submit" value="Upload">
<form>

See Upload file using POST/PUT Object of Google Cloud Storage HTML Form.

Community
  • 1
  • 1
scottwernervt
  • 470
  • 3
  • 18