Question

Je veux créer un service sur Google App Engine (Python) qui recevra une URL d'une image et la stocker sur Google Storage. J'ai réussi à télécharger à partir d'un fichier local en utilisant boto ou ligne de commande gsutil, mais pas en récupérant le fichier via l'URL. J'ai essayé de le faire en utilisant les demandes HTTP (PUT) et je reçois des réponses d'erreur pour les signatures fausses. Il est évident que je fais quelque chose de mal, mais malheureusement, je ne sais pas où.

Alors ma question est: Comment puis-je récupérer un fichier à partir d'une URL et le stocker sur Google Storage en utilisant Python pour Google App Angine

Voici ce que je l'ai fait (en utilisant un autre réponse ):

class ImportPhoto(webapp.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        srow = self.response.out.write
        url = self.request.get('url')
        srow('URL: %s\n' % (url))
        image_response = urlfetch.fetch(url)
        m = md5.md5()
        m.update(image_response.content)
        hash = m.hexdigest()
        time = "%s" % datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT")
        str_to_sig = "PUT\n" + hash + "\n\n" + 
                      time + "\nx-goog-acl:public-read\n/lipis/8418.png"
        sig = base64.b64encode(hmac.new(
                                  config_credentials.GS_SECRET_ACCESS_KEY,
                                  str_to_sig, hashlib.sha1).digest())
        total = len(image_response.content) 
        srow('Size: %d bytes\n' % (total))

        header = {"Date": time,
                  "x-goog-acl": "public-read",
                  "Content-MD5": hash,
                  'Content-Length': total,
                  'Authorization': "GOOG1 %s:%s" % 
                                    (config_credentials.GS_ACCESS_KEY_ID, sig)}

        conn = httplib.HTTPConnection("lipis.commondatastorage.googleapis.com")
        conn.set_debuglevel(2)

        conn.putrequest('PUT', "/8418.png")
        for h in header:
            conn.putheader(h, header[h])
        conn.endheaders()
        conn.send(image_response.content + '\r\n')
        res = conn.getresponse()

        srow('\n\n%d: %s\n' % (res.status, res.reason))
        data = res.read()
        srow(data)
        conn.close()

Et je deviens comme réponse:

URL: https://stackoverflow.com/users/flair/8418.png
Size: 9605 bytes

400: Bad Request
<?xml version='1.0' encoding='UTF-8'?><Error><Code>BadDigest</Code><Message>The Content-MD5 you specified did not match what we received.</Message><Details>lipis/hello.jpg</Details></Error>
Était-ce utile?

La solution

Avez-vous lu la documentation sur comment signer les demandes ? La chaîne de signe doit inclure les en-têtes Content-MD5, Content-Type et Date, en plus des en-têtes et le chemin des ressources.

Autres conseils

Content-MD5 tête est facultatif pour les . Essayez de laisser cela pour un test.

En outre, les en-têtes nécessaires sont Authorization, Date et Host. Il semble que votre demande est absente en-tête de Host.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top