Rebol > S3
Was this page helpful?

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
    
    url-encode: func [
        "URL-encode a string" 
        data "String to encode" 
        /local new-data
    ] [
        new-data: make string! "" 
        normal-char: charset [
            #"A" - #"Z" #"a" - #"z" 
            #"@" #"." #"*" #"-" #"_" 
            #"0" - #"9"
        ] 
        if not string? data [return new-data] 
        forall data [
            append new-data either find normal-char first data [
                first data
            ] [
                rejoin ["%" to-string skip tail (to-hex to-integer first data) -2]
            ]
        ] 
        new-data
    ] 
    
    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 url AWSAccessKeyId AWSSecretAccessKey 
    result: put-s3object http://comet.s3.amazonaws.com/zonal.tiff %zonal.tif AWSAccessKeyId AWSSecretAccessKey
    Was this page helpful?
    Tag page (Edit tags)
    • No tags
    You must login to post a comment.
    Powered by MindTouch Core