On Apr 9, 4:38 pm, "Ryan Mulligan" <
r...@ryantm.com> wrote:
> I was going to say that you might be able to use S3 for storage, but that
> doesn't seem to be the case. They've locked down sockets and URLGet's fetch
> doesn't seem to be able to send files via multi-part POST.
Use a PUT request, not a POST request, to upload to S3. POST is much
more complex, and only really useful when you want to allow a user to
do a direct upload. Here's some code that works for me, though I've
not tested it much yet:
def _method2str(method):
if method == urlfetch.GET:
return "GET"
elif method == urlfetch.POST:
return "POST"
elif method == urlfetch.HEAD:
return "HEAD"
elif method == urlfetch.PUT:
return "PUT"
elif method == urlfetch.DELETE:
return "DELETE"
else:
raise ValueException("Unknown method %s" % str(method))
def s3fetch(bucket, path, payload = None, method = urlfetch.GET,
headers = None, allow_truncated = False):
FMT = '%a, %d %b %Y %H:%M:%S +0000'
if not headers:
headers = {}
headers = headers.copy()
headers['x-amz-date'] = datetime.datetime.utcnow().strftime(FMT)
cresource = "/%s%s" % (bucket, path)
canonheaders = {}
for key in headers:
canonheaders[key.lower()] = headers[key]
cheaders = ''
p = re.compile("^x-amz-")
chkeys = canonheaders.keys()
chkeys.sort()
for key in chkeys:
if p.match(key):
cheaders = "%s%s:%s\n" % (cheaders, key,
canonheaders[key])
ctype = canonheaders.get('content-type', '')
cmd5 = canonheaders.get('content-md5', '')
cdate = ''
cverb = _method2str(method)
stringtosign = cverb + "\n" + cmd5 + "\n" + ctype + "\n" + cdate +
"\n" + cheaders + cresource
hm =
hmac.new(S3_SECRET_KEY, stringtosign, hashlib.sha1)
hmac_b64 = base64.b64encode(hm.digest())
logging.info("stringtosign: {%s} hmac {%s}" % (stringtosign,
hmac_b64))
headers["Authorization"] = "AWS %s:%s" % (S3_ACCESS_KEY, hmac_b64)
url = "http://%
s.s3.amazonaws.com%s" % (bucket, path)
result = urlfetch.fetch(url, payload = payload, method = method,
headers = headers, allow_truncated = allow_truncated)
if (result.status_code >= 300) and (result.status_code != 404):
logging.error("Unexpected result from S3 (%d): {%s}" %
(result.status_code, result.content))
return HttpResponseServerError("Internal error")
logging.debug("s3 response ok, code={%d}" % result.status_code)
return result