简体   繁体   中英

Rackspace Cloud Files (OpenStack Swift) TempUrl Example in vb.net

Can anyone provide an example for rackspace cloud files tempurl function in .net (c# or vb.net)?

There is documentation at the RackSpace site at: http://docs.rackspacecloud.com/files/api/v1/cf-devguide/cf-devguide-20121130.pdf starting on page 52.

There are examples in Ruby and Python but I'm having trouble porting them. I need to:

  • Set the account Temp URL Metadata Key
    • Create the HMAC-SHA1 (RFC 2104)
    • Create the temp url

The following will generate a temporary URL with C#:

        var account = new CF_Account(conn, client);

        string tempUrlKey = account.Metadata["temp-url-key"];

        //Set the link to expire after 60 seconds (in epoch time)
        int epochExpire = ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds) + 60;

        //The path to the cloud file
        string path = string.Format("{0}/{1}/{2}", account.StorageUrl.AbsolutePath, containerName, fileName);

        string hmacBody = string.Format("GET\n{0}\n{1}", epochExpire.ToString(), path);

        byte[] hashSaltBytes = Encoding.ASCII.GetBytes(tempUrlKey);

        string sig = null;

        using (HMACSHA1 myhmacMd5 = new HMACSHA1(hashSaltBytes))
        {
            byte[] ticketBytes = Encoding.ASCII.GetBytes(hmacBody);
            byte[] checksum = myhmacMd5.ComputeHash(ticketBytes);

            StringBuilder hexaHash = new StringBuilder();

            foreach (byte b in checksum)
            {
                hexaHash.Append(String.Format("{0:x2}", b));
            }

            sig = hexaHash.ToString();
        }

        string cloudFileUrl = string.Format("https://{0}{1}", account.StorageUrl.Host, path);

        //Compile the temporary URL
        string tempUrl = string.Format("{0}?temp_url_sig={1}&temp_url_expires={2}", cloudFileUrl, sig, epochExpire);

Athlectual's reply doesn't seem to apply to the current openstack.net NuGet package, but I've managed to get it working with the latest version (1.1.2.1) through trial and error. Hopefully this will help others

In my case it seems I didn't have to set the Temp URL Metadata Key as one was already set, must be randomly generated when the account was created. So the code to get the temp URL that works is as follows.

Nb I've used Username and APIKey to authenticate. I guess you can use Password instead. APIKey can be found under your account details in the Rackspace Cloud Control Panel website.

private static string GetCloudFilesTempUrl(Uri storageUrl, string username, string apiKey, string containerName, string filename)
{
    var cloudIdentity = new CloudIdentity()
        {
            Username = username,
            APIKey = apiKey
        };

    var provider = new CloudFilesProvider(cloudIdentity);

    var accountMetaData = provider.GetAccountMetaData();
    var tempUrlKey = accountMetaData["Temp-Url-Key"];

    //Set the link to expire after 60 seconds (in epoch time)
    var epochExpire = ((int) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds) + 60;

    //The path to the cloud file
    var path = string.Format("{0}/{1}/{2}", storageUrl.AbsolutePath, containerName, filename);

    var hmacBody = string.Format("GET\n{0}\n{1}", epochExpire, path);

    var hashSaltBytes = Encoding.ASCII.GetBytes(tempUrlKey);

    string sig;

    using (var myhmacMd5 = new HMACSHA1(hashSaltBytes))
    {
        var ticketBytes = Encoding.ASCII.GetBytes(hmacBody);
        var checksum = myhmacMd5.ComputeHash(ticketBytes);

        var hexaHash = new StringBuilder();

        foreach (var b in checksum)
        {
            hexaHash.Append(String.Format("{0:x2}", b));
        }

        sig = hexaHash.ToString();
    }

    var cloudFileUrl = string.Format("https://{0}{1}", storageUrl.Host, path);

    //Compile the temporary URL
    return string.Format("{0}?temp_url_sig={1}&temp_url_expires={2}", cloudFileUrl, sig, epochExpire);
}

I'm not sure how you're meant to get the storage URL, but through more trial and error I managed this:

private static string GetCloudFilesStorageUrl(string username, string apiKey)
{
    var cloudIdentity = new CloudIdentity()
    {
        Username = username,
        APIKey = apiKey
    };

    var identityProvider = new CloudIdentityProvider(cloudIdentity);

    return identityProvider.GetUserAccess(cloudIdentity)
                            .ServiceCatalog
                            .Single(x => x.Name == "cloudFiles")
                            .Endpoints[0].PublicURL;
}

As mentioned I didn't have to set the Temp URL Key, and I'm probably not going to try in case I break something that's working! If you need to though I'd guess that the following should do the trick:

private static void SetCloudFilesTempUrlKey(string username, string apiKey, string tempUrlKey)
{
    var cloudIdentity = new CloudIdentity()
        {
            Username = username,
            APIKey = apiKey
        };

    var provider = new CloudFilesProvider(cloudIdentity);

    provider.UpdateAccountMetadata(new Metadata
        {
            { "Temp-Url-Key", tempUrlKey }
        });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM