Sunday, December 02, 2012

Add folders to rackspace cloud file container with php and cURL


We use rackspace cloudfile container to publish our css and javascript files to Akamai CDN. They (rackspace)  has a nice one click deployment of cloud files to the CDN. Assuming you are new to this, the recipe goes like
  • Access your rackspace cloud account
  • Create a new container in rackspace cloud files
  • Upload your files to that container
  • Select container and in the bottom panel - just select publish to CDN.
You can map a CNAME record in your DNS server to make the the long rackspace CDN URL manageable (or something that your application understands)

The css and javascript files refer to assets (logos/ sprites/ images and such) and we need to upload those as well to the CDN enabled container. However we do not want to do this manually and we wish to create and upload file + assets  bundle as part of build process (automatic and not manual)

Rackspace provides PHP libraries to make such tasks as creating a container and uploading files to them easier. However I planned to take the plain cURL route because 

  1. Number of files is not large
  2. The files themselves are not large 
  3. I was not in a mood to download and install yet another library and learn the API

So I just rolled my sleeve and wrote this PHP script that would take a local folder and upload its content in a pseudo_directory hierarchy to rackspace cloud file container. YMMV but sometimes we all need quick and dirty and then this script can come in handy. 

Relevant links





    error_reporting(-1);

    function do_upload($ch2,$auth,$fname) {

        $headers = array();
        $grab = array("X-Auth-Token");
        $host = $auth["X-Storage-Url"];

        foreach($auth as $name => $value) {
            if(in_array($name,$grab)) {
                array_push($headers, "$name: $value");
            }
        }


        // Content-Type
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mime = finfo_file($finfo, $fname);
        finfo_close($finfo);
        $etag = md5_file($fname);

        array_push($headers, "Content-Type: $mime");
        array_push($headers, "ETag: $etag");

        $fp = fopen($fname, "r");
        $fsize = filesize($fname);
        // asset is container name
        // upload in a pseudo_dir structure
        // /asset/css/...
        //
        $url = $host. "/asset/".$fname ;
        printf("HTTP PUT %s  to => %s \n",$fname,$url); 

         $options = array(
            CURLOPT_TIMEOUT => 60 ,
            CURLOPT_RETURNTRANSFER => 1 ,
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_URL => $url,
            CURLOPT_VERBOSE => false,
            CURLOPT_HEADER => 1,
            CURLOPT_PUT => 1 ,
            CURLOPT_INFILE => $fp,
            CURLOPT_INFILESIZE => $fsize);



        // print_r($headers); 
        // Do a PUT operation

        curl_setopt_array($ch2, $options);
        $response = curl_exec ($ch2);
    }


    function do_auth() {

        $ch = curl_init();

        $host = "https://identity.api.rackspacecloud.com/v1.0" ;
        $apiKey = "xxxxxxx" ;
        $user = "yyyyyyyyy" ;

        $headers = array(
            "X-Auth-Key: $apiKey " ,
            "X-Auth-User: $user");
           $options = array(
            CURLOPT_TIMEOUT => 60 ,
            CURLOPT_RETURNTRANSFER => 1 ,
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_URL => $host,
            CURLOPT_VERBOSE => false,
            CURLOPT_HEADER => 1);

        curl_setopt_array($ch, $options);
        $response = curl_exec ($ch);
        curl_close($ch);

        list($headers, $body) = explode("\r\n\r\n", $response, 2);

        $lines = explode("\n",$headers);
        $auth = array();
        $grab = array("X-Storage-Token", "X-Storage-Url","X-Auth-Token");

        foreach($lines as $line ) {
            $parts = explode(" ",$line);
            $name = $parts[0] ;
            $name = trim($name,": ");

            if(in_array($name,$grab)) {
                $auth[$name] = trim($parts[1]);
            }

        } 

        return $auth ;

    }


     $auth = do_auth();
    printf(" \n **** parsed auth headers for PUT **** \n");
    print_r($auth);

    $ch2 = curl_init();
    // get all files in css dir
    $files = array();

    // load everything from local css folder into
    // /asset/css/local-file-path
    foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator('css')) as $path) {
        $filename = sprintf("%s",$path);
        $pos = strrpos($filename,"/");
        if($pos !== false) {
            $last = substr($filename,$pos+1);
            if($last == '.' || $last == '..') {
                printf(" ignore file :: %s \n",$filename); 
            }else {
                array_push($files,$filename);
            }
        }
    }

    foreach($files as $file){
        do_upload($ch2,$auth,$file);
    }

    curl_close($ch2);


 
       



© Life of a third world developer
Maira Gall