This is a follow up to garnaat's answer from Apr 6 '12.
I am generating a signed URL server side, where I have credentials, and I pass it to a client such that a client can directly upload content. I trust the client far enough to allow it to upload arbitrary sized files, but not enough to give it security tokens. I wanted to avoid having the client tell the server how large its content would be as part of the request. Hence my follow up answer.
I was able to get the signed url for the PUT method working without specifying content length in the headers or specifying force_http=True.
Using Boto 2.31.1:
as in garnaat's answere:
>>> import boto
>>> c =boto.connect_s3()
then instead I used:
>>> temp_url = c.generate_url(seconds_available, 'PUT', bucket_name, s3_key)
this produced a url in the following form:
https://s3_location/bucket_name/s3_key?Signature=Ew407JMktSIcFln%2FZe00VroCmTU%3D&Expires=1405647669&AWSAccessKeyId=kM__pEQo2AEVd_Juz4Qq
I was then able to use curl to post a file:
>>> os.system('curl --request PUT --upload-file true_measure/test_files/test_file_w_content.txt "'+temp_url+'"')
I did have a very difficult time figuring this out because I usually use python requests to write tests and debug; however I get an authentication failure when I try to use it to put a file to one of these boto generated signed urls using requests. I haven't fully debugged this, but I suspect it is because requests is adding a few additional headers as compared to what curl produces.
I hope this follow up answer spares someone else the debugging pain I went through.