Rebol > S3

S3

Table of contents
No headers

Simple tools to upload a file and download a file from Amazon S3.

Uses the modified http protocol on this site.

Rebol [
	file: %s3.r
	author: [ "Graham Chiu" "Maarten Koopmans" "Gregg Irwin" ]
	date: 23-Nov-2008
	license: 'BSD
	purpose: {
		basic retrieve and upload of files to Amazon S3.
	}
]


; custom http prot - fetch from http://rebol.wik.is/Protocols/Http
do %/d/rebol-sdk-276/source/prot-http.r

now-gmt: has [t] [
    t: now  
    t: t - t/zone  
    t/zone: none  
    t
]

hmac-sha1: func [val key] [checksum/method/key val 'sha1 key]

make-sig: func [
    {Encodes the given string with the aws_secret_access_key, by taking the
    hmac-sha1 sum, and then base64 encoding it.}
    data       [string!]
    secret-key [string!]
    /for-url   "Make encoded string usable as a query string parameter"
    /local res
] [
    res: enbase/base hmac-sha1 data secret-key 64
    either for-url [url-encode res] [res]
]

Comment {
StringToSign = HTTP-Verb + "\n" +
	Content-MD5 + "\n" +
	Content-Type + "\n" +
	Date + "\n" +
	CanonicalizedAmzHeaders +
	CanonicalizedResource;

}

create-string-to-sign: func [ verb md5 [none! string!] type  url [url!]
	/local obj bucket resource s
][	
	obj: make object! [path: target: port-id: host: none]
	net-utils/URL-Parser/parse-url obj url
	probe obj	
	parse obj/host [ copy bucket to ".s3.amazonaws.com" ]
	resource: rejoin [ "/" bucket "/" any [ obj/path copy "" ] url-encode obj/target ]
	s: rejoin [ verb newline
		any [ md5 copy "" ] newline
		any [ type copy "" ] newline
		to-http-date newline
		resource
	]	
]

to-http-date: func [ 
	/local d
][
	d: now-gmt
	rejoin [ 
		copy/part pick system/locale/days d/weekday 3 
		", " next form 100 + d/day " " 
		copy/part pick system/locale/months d/month 3 
		" " d/year " " 
		next form 100:00 + d/time " +0000" 
	]
]

Get-s3object: func [ url [url!] accesskey secretkey
	/info
	/local err signature result verb
][
	verb: either info [ 'HEAD ][ 'GET ]
	data: create-string-to-sign verb none none url 
	signature: make-sig data secretkey 
	if error? set/any 'err try [
		result: read/custom/binary url compose/deep [ 
			(verb) "" 
			[ 	
				Date: (to-http-date)
				Authorization: (rejoin [ "AWS " accesskey ":" signature ]) 
				Pragma: "no-cache"
				Cache-Control: "no-cache"
			
			]
		]
		return result
	][
		probe mold disarm err
		return none
	]
]

Put-s3object: func [ url [url!] file [file!] accesskey secretkey
	/local err signature result content-type 
][
	content-type: form switch/default suffix? file [
		%.html [ 'text/html ]
		%.jpg [ 'image/jpeg ]
		%.jpeg [ 'image/jpeg ]
		%.png [ 'image/png ]
		%.tiff [ 'image/tiff ]
		%.tif [ 'image/tiff ]
		%.pdf [ 'application/pdf ]
		%.txt [ 'text/plain ]
		%.xml [ 'application/xml ]
		%.mpeg [ 'video/mpeg ]
	][	'application/octet-stream ]
	
	data: create-string-to-sign "PUT" none content-type url 
	signature: make-sig data secretkey 
	if error? set/any 'err try [
		result: read/custom url reduce compose/deep [ 
			'PUT file
			[ 	
				Date: (to-http-date)
				Authorization: (rejoin [ "AWS " accesskey ":" signature ]) 
				Content-type: (content-type)
			]
		]
		return result
	][
		probe mold disarm err
		return none
	]
]

; as used in the examples at http://docs.amazonwebservices.com/AmazonS3/2006-03-01/
AWSAccessKeyId: "0PN5J17HBGZHT7JJ3X82" AWSSecretAccessKey: "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"

; my secret keys
;;; ;============removed! ===============

shouldbe: {
GET /photos/puppy.jpg HTTP/1.1
Host: johnsmith.s3.amazonaws.com
Date: Tue, 27 Mar 2007 19:36:42 +0000
Authorization: AWS 0PN5J17HBGZHT7JJ3X82:xXjDGYUmKxnwqr5KXNPGldn5LbA=
}

; url: http://johnsmith.s3.amazonaws.com/photos/puppy.jpg
url: http://comet.s3.amazonaws.com/CIMG0396.JPG

result: get-s3object AWSAccessKeyId AWSSecretAccessKey 
result: put-s3object http://comet.s3.amazonaws.com/zonal.tiff %zonal.tif AWSAccessKeyId AWSSecretAccessKey

Retrieved from "http://rebol.wik.is/S3"

Tag page
You must login to post a comment.
wik.is