0

I have tried everything. It works well for GET AND PUT requests. But with POST (to initiate multipart request) it throws various error like 405 Method not allowed or Signature Mismatch error. Any help is appreciated and welcome. Please if anyone have any idea throw some hints.

If anyone can edit this python code to get it working i would really appreciate that. Thanks in advance.

import sys, os, base64, datetime, hashlib, hmac
import requests # pip install requests


method = 'POST'
service = 's3'
host = 'freemedianews.s3.amazonaws.com'
region = 'ap-southeast-1'
endpoint = 'https://freemedianews.s3-ap-southeast-1.amazonaws.com'
request_parameters = ''


def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'aws4_request')
    return kSigning


access_key = '*******'
secret_key = '*******'
if access_key is None or secret_key is None:
    print 'No access key is available.'
    sys.exit()


t = datetime.datetime.utcnow()
amzdate = '20180621T151517Z'
datestamp = '20180621' # Date w/o time, used in credential scope


request.html


canonical_uri = '/a/message/1200/1200.png'
content_type = "multipart/form-data"



request_parameters variable.
canonical_querystring = request_parameters



payload_hash = hashlib.sha256('').hexdigest()
canonical_headers ='content-type:' + content_type + '\n' + 'host:' + host + '\n' + 'x-amz-content-sha256:' + payload_hash + '\n' + 'x-amz-date:' + amzdate + '\n'


signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date'



canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash



algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp  + "/" + region + '/' + service + '/' + 'aws4_request'
credential_scope_final = access_key  + "/"  + datestamp + "/" + region + '/' + service + '/' + 'aws4_request'
string_to_sign = algorithm  + '\n' +  amzdate + '\n' + credential_scope + '\n' +  hashlib.sha256(canonical_request).hexdigest()




signing_key = getSignatureKey(secret_key, datestamp, region, service)

print "signing_key -----" + signing_key



signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
print "signature -----" + signature

authorization_header = algorithm + ' ' + 'Credential='  + credential_scope_final + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature



headers = {'Content-Type': content_type, 'Host': host, 'X-Amz-Content-Sha256': payload_hash, 'X-Amz-Date':amzdate, 'Authorization':authorization_header}
print authorization_header + "---this"


request_url = endpoint + canonical_uri 





r = requests.post(request_url, data=request_parameters, headers=headers)
print r

print '\nRESPONSE++++++++++++++++++++++++++++++++++++'
print 'Response code: %d\n' % r.status_code
print r.text
Sahil Deswal
  • 66
  • 2
  • 6
  • *"I think they are doing this deliberately so that people can pay for their other services."* Well, that's a baseless assertion. If you are trying to initiate a multipart upload, you `POST /my/object/key?uploads`, [as documented](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html). Additionally, you would not use `multipart/form-data` for a multipart upload. You use the actual content type of the object. Also, you would not use one hostname for the endpoint and a different one for the `Host` header. Correct these things and post an example request and the error. – Michael - sqlbot Jun 21 '18 at 19:24
  • Thank you Michael for your hint. You actually solved my problem. You should write this as the answer. And sorry for my baseless assertion, It was out of frustration of being stuck at this silly thing for 2 days. Genius. – Sahil Deswal Jun 21 '18 at 21:06

0 Answers0