Browser Uploads to S3 using HTML POST Forms @suz_lab Saturday, December 17, 11
Browser Uploads to S3 using HTML POST Forms
@suz_lab
Saturday, December 17, 11
AWSで負荷分散が容易に!
Saturday, December 17, 11
(Upload)ファイル分散問題
•nfs?
•SPOF対策が面倒...
•s3fs?
•Heavyに利用すると嫌な思い出が...
•...
Saturday, December 17, 11
As-Is と To-Be
Saturday, December 17, 11
シーケンス
Saturday, December 17, 11
<form action="http://www.suz-lab.com.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="key" value="${filename}"/> <input type="hidden" name="AWSAccessKeyId" value="AAAAAAAAAAAAAAAAAAAA"/> <input type="hidden" name="acl" value="private"/> <input type="hidden" name="success_action_redirect" value="http://www.suz-lab.com/"/> <input type="hidden" name="policy" value="pppppppppppppppppppppppppppp"/> <input type="hidden" name="signature" value="ssssssssssssssssssssssssssss"/> <input type="hidden" name="Content-Type" value="text/plain"/> <input type="file" name="file"/> <input type="submit" name="button" value="Upload"/> </form>
Saturday, December 17, 11
<form action="http://www.suz-lab.com.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="key" value="${filename}"/> <input type="hidden" name="AWSAccessKeyId" value="AAAAAAAAAAAAAAAAAAAA"/> <input type="hidden" name="acl" value="private"/> <input type="hidden" name="success_action_redirect" value="http://www.suz-lab.com/"/> <input type="hidden" name="policy" value="pppppppppppppppppppppppppppp"/> <input type="hidden" name="signature" value="ssssssssssssssssssssssssssss"/> <input type="hidden" name="Content-Type" value="text/plain"/> <input type="file" name="file"/> <input type="submit" name="button" value="Upload"/> </form>
Saturday, December 17, 11
action
•バケット名.s3.amazonaws.comを指定
•http/httpsが指定可能
•www.suz-lab.comのようなドット区切りのバケット名は証明書エラー
•証明書が*.s3.amazonaws.comだから
Saturday, December 17, 11
<form action="http://www.suz-lab.com.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="key" value="${filename}"/> <input type="hidden" name="AWSAccessKeyId" value="AAAAAAAAAAAAAAAAAAAA"/> <input type="hidden" name="acl" value="private"/> <input type="hidden" name="success_action_redirect" value="http://www.suz-lab.com/"/> <input type="hidden" name="policy" value="pppppppppppppppppppppppppppp"/> <input type="hidden" name="signature" value="ssssssssssssssssssssssssssss"/> <input type="hidden" name="Content-Type" value="text/plain"/> <input type="file" name="file"/> <input type="submit" name="button" value="Upload"/> </form>
Saturday, December 17, 11
key
•S3にアップロードされるオブジェクト(ファイル)名を指定
•${filename}にするとアップロードするファイル名が利用される
Saturday, December 17, 11
<form action="http://www.suz-lab.com.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="key" value="${filename}"/> <input type="hidden" name="AWSAccessKeyId" value="AAAAAAAAAAAAAAAAAAAA"/> <input type="hidden" name="acl" value="private"/> <input type="hidden" name="success_action_redirect" value="http://www.suz-lab.com/"/> <input type="hidden" name="policy" value="pppppppppppppppppppppppppppp"/> <input type="hidden" name="signature" value="ssssssssssssssssssssssssssss"/> <input type="hidden" name="Content-Type" value="text/plain"/> <input type="file" name="file"/> <input type="submit" name="button" value="Upload"/> </form>
Saturday, December 17, 11
acl
•private
•public-read
•public-read-write
•authenticated-read
•bucket-owner-read
•bucket-owner-full-control
Saturday, December 17, 11
<form action="http://www.suz-lab.com.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="key" value="${filename}"/> <input type="hidden" name="AWSAccessKeyId" value="AAAAAAAAAAAAAAAAAAAA"/> <input type="hidden" name="acl" value="private"/> <input type="hidden" name="success_action_redirect" value="http://www.suz-lab.com/"/> <input type="hidden" name="policy" value="pppppppppppppppppppppppppppp"/> <input type="hidden" name="signature" value="ssssssssssssssssssssssssssss"/> <input type="hidden" name="Content-Type" value="text/plain"/> <input type="file" name="file"/> <input type="submit" name="button" value="Upload"/> </form>
Saturday, December 17, 11
success_action_redirect
•アップロード完了後のリダイレクト先
•http://www.suz-lab.com/
?bucket=www.suz-lab.com
&key=upload.txt
&etag=%22...%22
Saturday, December 17, 11
<form action="http://www.suz-lab.com.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="key" value="${filename}"/> <input type="hidden" name="AWSAccessKeyId" value="AAAAAAAAAAAAAAAAAAAA"/> <input type="hidden" name="acl" value="private"/> <input type="hidden" name="success_action_redirect" value="http://www.suz-lab.com/"/> <input type="hidden" name="policy" value="pppppppppppppppppppppppppppp"/> <input type="hidden" name="signature" value="ssssssssssssssssssssssssssss"/> <input type="hidden" name="Content-Type" value="text/plain"/> <input type="file" name="file"/> <input type="submit" name="button" value="Upload"/> </form>
Saturday, December 17, 11
policy
•JSONで記述されたポリシーをBase64でエンコードしたもの
•ポリシーには有効期限やフォームのinputタグに記載された内容の条件などを記述
Saturday, December 17, 11
require 'base64'
json = <<"EOS"{ "expiration": "2012-01-01T00:00:00Z", "conditions": [ {"bucket": "www.suz-lab.com"}, ["starts-with", "$key", ""], {"acl": "private"}, {"success_action_redirect": "http://www.suz-lab.com/"}, ["starts-with", "$Content-Type", ""], ["content-length-range", 0, 1048576] ]}EOS
policy = Base64.encode64(json).gsub("\n","")
Saturday, December 17, 11
<form action="http://www.suz-lab.com.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="key" value="${filename}"/> <input type="hidden" name="AWSAccessKeyId" value="AAAAAAAAAAAAAAAAAAAA"/> <input type="hidden" name="acl" value="private"/> <input type="hidden" name="success_action_redirect" value="http://www.suz-lab.com/"/> <input type="hidden" name="policy" value="pppppppppppppppppppppppppppp"/> <input type="hidden" name="signature" value="ssssssssssssssssssssssssssss"/> <input type="hidden" name="Content-Type" value="text/plain"/> <input type="file" name="file"/> <input type="submit" name="button" value="Upload"/> </form>
Saturday, December 17, 11
signature
•Base64でエンコードされたポリシーをHMAC/SHA-1を使ってシークレットキーでサインして、さらにBase64でエンコードしたもの
Saturday, December 17, 11
require 'base64'require 'openssl'require 'digest/sha1'
...
signature = Base64.encode64(OpenSSL::HMAC.digest( OpenSSL::Digest::Digest.new('sha1'), "SECRET_KEY", policy)).gsub("\n","")
Saturday, December 17, 11
まとめ
•負荷分散によるアップロードファイル分散問題
•直接S3にファイルアップロードすることで解決
•S3の耐久性と可用性をダイレクトに利用できるので負荷や障害にも強いシステムに!
Saturday, December 17, 11
参考資料
• Browser-Based Uploads Using POST
http://docs.amazonwebservices.com/AmazonS3/2006-03-01/dev/UsingHTTPPOST.html
• Browser Uploads to S3 using HTML POST Forms
http://aws.amazon.com/articles/1434
• Amazon Simple Storage Service: Browser-Based Uploads using POST Proposal
http://doc.s3.amazonaws.com/proposals/post.html
Saturday, December 17, 11
cloudpack
Saturday, December 17, 11