Add S3 vocab
							parent
							
								
									4d4da7ac23
								
							
						
					
					
						commit
						88afb451ba
					
				| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Chris Double
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,149 @@
 | 
			
		|||
! Copyright (C) 2009 Chris Double. All Rights Reserved.
 | 
			
		||||
! See http://factorcode.org/license.txt for BSD license.
 | 
			
		||||
USING:
 | 
			
		||||
    accessors
 | 
			
		||||
    assocs
 | 
			
		||||
    base64
 | 
			
		||||
    calendar
 | 
			
		||||
    calendar.format
 | 
			
		||||
    checksums.hmac
 | 
			
		||||
    checksums.sha
 | 
			
		||||
    combinators
 | 
			
		||||
    http
 | 
			
		||||
    http.client
 | 
			
		||||
    kernel
 | 
			
		||||
    make
 | 
			
		||||
    math.order
 | 
			
		||||
    namespaces
 | 
			
		||||
    sequences
 | 
			
		||||
    sorting
 | 
			
		||||
    strings
 | 
			
		||||
    xml
 | 
			
		||||
    xml.traversal
 | 
			
		||||
;
 | 
			
		||||
IN: s3
 | 
			
		||||
 | 
			
		||||
SYMBOL: key-id
 | 
			
		||||
SYMBOL: secret-key
 | 
			
		||||
 | 
			
		||||
TUPLE: s3-request path mime-type date method headers  bucket data ;
 | 
			
		||||
 | 
			
		||||
: hashtable>headers ( hashtable -- seq )
 | 
			
		||||
    [
 | 
			
		||||
        [ swap % ":" % % "\n" % ] "" make
 | 
			
		||||
    ] { } assoc>map [ <=> ] sort ;
 | 
			
		||||
 | 
			
		||||
: signature ( s3-request -- string )
 | 
			
		||||
    [
 | 
			
		||||
        { 
 | 
			
		||||
            [ method>> % "\n" % "\n" % ]
 | 
			
		||||
            [ mime-type>> % "\n" % ]
 | 
			
		||||
            [ date>> timestamp>rfc822 % "\n" % ]
 | 
			
		||||
            [ headers>> [ hashtable>headers [ % ] each ] when* ]
 | 
			
		||||
            [ bucket>> [ "/" % % ] when* ]
 | 
			
		||||
            [ path>> % ]
 | 
			
		||||
        } cleave
 | 
			
		||||
    ] "" make ;
 | 
			
		||||
 | 
			
		||||
: sign ( s3-request -- string )
 | 
			
		||||
    [
 | 
			
		||||
        "AWS " %
 | 
			
		||||
        key-id get %
 | 
			
		||||
        ":" %
 | 
			
		||||
        signature secret-key get sha1 hmac-bytes >base64 %
 | 
			
		||||
    ] "" make ;
 | 
			
		||||
  
 | 
			
		||||
: s3-url ( s3-request -- string )
 | 
			
		||||
    [ 
 | 
			
		||||
        "http://" % 
 | 
			
		||||
        dup bucket>> [ % "." % ] when* 
 | 
			
		||||
        "s3.amazonaws.com" %  
 | 
			
		||||
        path>> %
 | 
			
		||||
    ] "" make ;
 | 
			
		||||
 | 
			
		||||
: <s3-request> ( bucket path headers method -- request )
 | 
			
		||||
    s3-request new
 | 
			
		||||
        swap >>method
 | 
			
		||||
        swap >>headers
 | 
			
		||||
        swap >>path
 | 
			
		||||
        swap >>bucket
 | 
			
		||||
        now >>date ;
 | 
			
		||||
 | 
			
		||||
: sign-http-request ( s3-request http-request -- request )
 | 
			
		||||
    over date>> timestamp>rfc822 "Date" set-header
 | 
			
		||||
    swap sign "Authorization" set-header ;
 | 
			
		||||
 | 
			
		||||
: s3-get ( bucket path headers -- request data )
 | 
			
		||||
    "GET" <s3-request> dup s3-url <get-request> 
 | 
			
		||||
    sign-http-request http-request ;
 | 
			
		||||
 | 
			
		||||
: s3-put ( data bucket path headers -- request data )
 | 
			
		||||
    "PUT" <s3-request> dup s3-url swapd <put-request> 
 | 
			
		||||
    sign-http-request http-request ;
 | 
			
		||||
 | 
			
		||||
TUPLE: bucket name date ;
 | 
			
		||||
 | 
			
		||||
: (buckets) ( xml -- seq )
 | 
			
		||||
    "Buckets" tag-named 
 | 
			
		||||
    "Bucket" tags-named [
 | 
			
		||||
        [ "Name" tag-named children>string ] 
 | 
			
		||||
        [ "CreationDate" tag-named children>string ] bi bucket boa
 | 
			
		||||
    ] map ;
 | 
			
		||||
 
 | 
			
		||||
: buckets ( -- seq )
 | 
			
		||||
    f "/" H{ } clone s3-get nip >string string>xml (buckets) ;
 | 
			
		||||
 | 
			
		||||
: bucket-url ( bucket -- string )
 | 
			
		||||
    [ "http://" % % ".s3.amazonaws.com/" % ] "" make ;
 | 
			
		||||
 | 
			
		||||
TUPLE: key name last-modified size ;
 | 
			
		||||
 | 
			
		||||
: (keys) ( xml -- seq )
 | 
			
		||||
    "Contents" tags-named [
 | 
			
		||||
      [ "Key" tag-named children>string ]
 | 
			
		||||
      [ "LastModified" tag-named children>string ]
 | 
			
		||||
      [ "Size" tag-named children>string ]
 | 
			
		||||
      tri key boa
 | 
			
		||||
  ] map ;
 | 
			
		||||
 
 | 
			
		||||
: keys ( bucket -- seq )
 | 
			
		||||
    "/" H{ } clone s3-get
 | 
			
		||||
    nip >string string>xml (keys) ;
 | 
			
		||||
 | 
			
		||||
: object-get ( bucket key -- response data )
 | 
			
		||||
    s3-request new
 | 
			
		||||
        swap "/" prepend >>path
 | 
			
		||||
        swap >>bucket
 | 
			
		||||
    s3-url http-get ;
 | 
			
		||||
 | 
			
		||||
: create-bucket ( bucket -- )
 | 
			
		||||
    "" swap "/" H{ } clone "PUT" <s3-request>
 | 
			
		||||
    "application/octet-stream" >>mime-type
 | 
			
		||||
    dup s3-url swapd <put-request>
 | 
			
		||||
    0 "content-length" set-header 
 | 
			
		||||
    sign-http-request
 | 
			
		||||
    http-request 2drop ;
 | 
			
		||||
 | 
			
		||||
: delete-bucket ( bucket -- )
 | 
			
		||||
    "/" H{ } clone "DELETE" <s3-request>
 | 
			
		||||
    dup s3-url <delete-request> sign-http-request http-request 2drop ;
 | 
			
		||||
 
 | 
			
		||||
: put-object ( object type bucket key headers -- )
 | 
			
		||||
    [ "/" prepend ] dip "PUT" <s3-request> 
 | 
			
		||||
    over >>mime-type
 | 
			
		||||
    [ <post-data> swap >>data ] dip
 | 
			
		||||
    dup s3-url swapd <put-request> 
 | 
			
		||||
    dup header>> pick headers>> assoc-union >>header
 | 
			
		||||
    sign-http-request 
 | 
			
		||||
    http-request 2drop ;
 | 
			
		||||
 | 
			
		||||
! "testbucket" create-bucket
 | 
			
		||||
! "testbucket" delete-bucket
 | 
			
		||||
! buckets
 | 
			
		||||
! "testbucket" keys 
 | 
			
		||||
! "hello world" binary encode "text/plain" "testbucket" "hello.txt" 
 | 
			
		||||
! H{ { "x-amz-acl" "public-read" } } put-object
 | 
			
		||||
! "hello.txt" <pathname> "text/plain" "testbucket" "hello.txt" 
 | 
			
		||||
! H{ { "x-amz-acl" "public-read" } } put-object
 | 
			
		||||
! "testbucket" "hello.txt" object-get
 | 
			
		||||
! Need to write docs...
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Amazon S3 Wrapper
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
web
 | 
			
		||||
		Loading…
	
		Reference in New Issue