1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How To Use Amazon S3 To Serve Private Membership Site Content

Discussion in 'Membership Sites' started by TechnicalSergio, May 15, 2010.

  1. TechnicalSergio

    TechnicalSergio Newbie

    Joined:
    Jan 19, 2010
    Messages:
    32
    Likes Received:
    80
    Occupation:
    Stackin' Paper
    Location:
    San Jose
    Home Page:
    Would you like to use Amazon's S3 servers to take care of your private membership site content?

    I'd been looking for a way to do this and no one could give me a straight answer, so I spent a few hours the other day and have finally got it working.

    I know a lot of you could benefit from this info, so here goes...

    1. Upload your content to S3 -- I use the Firefox plugin "S3 Organizer". The security settings should be private by default.

    2. Create a php file on your web server with the following code. Make sure you replace YOUR-KEY and YOUR-OTHER-KEY with your correct Amazon keys:

    Code:
    <?php
      // grab this with "pear install --onlyreqdeps Crypt_HMAC"
    require_once('Crypt/HMAC.php');
    
    // Amazon S3 credentials
    define('S3_ACCESS_KEY_ID', 'YOUR-KEY');
    define('S3_SECRET_ACCESS_KEY', 'YOUR-OTHER-KEY');
    
    /**
    * Generate a link to download a file from Amazon S3 using query string
    * authentication. This link is only valid for a limited amount of time.
    *
    * @param $bucket The name of the bucket in which the file is stored.
    * @param $filekey The key of the file, excluding the leading slash.
    * @param $expires The amount of time the link is valid (in seconds).
    * @param $operation The type of HTTP operation. Either GET or HEAD.
    */
    
    function mymodule_get_s3_auth_link($bucket, $filekey, $expires = 3000, $operation = 'GET') {
    $expire_time = time() + $expires;
    $filekey = rawurlencode($filekey);
    $filekey = str_replace('%2F', '/', $filekey);
    $path = $bucket .'/'. $filekey;
    
    /**
    * StringToSign = HTTP-VERB + "\n" +
    * Content-MD5 + "\n" +
    * Content-Type + "\n" +
    * Expires + "\n" +
    * CanonicalizedAmzHeaders +
    * CanonicalizedResource;
    */
    
    $stringtosign =
    $operation ."\n". // type of HTTP request (GET/HEAD)
    "\n". // Content-MD5 is meaningless for GET
    "\n". // Content-Type is meaningless for GET
    $expire_time ."\n". // set the expire date of this link
    "/$path"; // full path (incl bucket), starting with a /
    
    $signature = urlencode(mymodule_constructSig($stringtosign));
    
    $url = sprintf('http://%s.s3.amazonaws.com/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s', $bucket, $filekey, S3_ACCESS_KEY_ID, $expire_time, $signature);
    
    return $url;
    }
    
    function mymodule_hex2b64($str) {
    $raw = '';
    for ($i=0; $i < strlen($str); $i+=2) {
     $raw .= chr(hexdec(substr($str, $i, 2)));
    }
    return base64_encode($raw);
    }
    
    function mymodule_constructSig($str) {
    $hasher =& new Crypt_HMAC(S3_SECRET_ACCESS_KEY, 'sha1');
    $signature = mymodule_hex2b64($hasher->hash($str));
    return $signature;
    }
    ?>
    3. Now to access a file hosted on S3, use this code. Again make sure to replace YOUR-S3-CODE.php with the name of the file you created above, YOUR-BUCKET-NAME with your Amazon bucket name, and YOU_PATH_TO_FILE with the path of the ile within your bucket:

    Code:
    <?php
      // grab this with "pear install --onlyreqdeps Crypt_HMAC"
    require_once('YOUR-S3-CODE.php');
    
    echo mymodule_get_s3_auth_link('YOUR-BUCKET-NAME', 'YOUR_PATH_TO_FILE');
    
    ?> 
    For example, if you wanted to link to a mov file in your members area you'd do somethig like this:

    Code:
    <a href="<?php echo mymodule_get_s3_auth_link('my-bucket', 'movie.mov');?>">Download Mov File</a>
    You could do the same thing to embed a streaming flv from S3.

     
    • Thanks Thanks x 3
  2. pipwaves

    pipwaves Newbie

    Joined:
    Nov 12, 2009
    Messages:
    33
    Likes Received:
    7
    Location:
    Australia
    very handy.. thanks
     
    • Thanks Thanks x 1