namespace G2OAzureStorage
{
using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.WindowsAzure.Storage;
using G2O;
[Export]
[Authorize]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class CdnController : ApiController
{
[Import]
public G2OProxyConfiguration G2OConfiguration { get; set; }
///
/// Returns a 302 Redirect into Azure Blob Storage.
///
///
///
[HttpGet]
public IHttpActionResult Get(string segments)
{
return GetRedirect(segments);
}
/////
///// Fetches the data from Blob Storage and returns a Stream.
/////
/////
/////
//[HttpGet]
//public Task GetAsync(string segments)
//{
// return GetDataAsync(segments);
//}
#region Implementation
private IHttpActionResult GetRedirect(string segments)
{
string[] pathSegments = segments.Split(new[] { "/" }, StringSplitOptions.None);
string alias = pathSegments[0];
string containerName = pathSegments[1];
string path = string.Join("/", pathSegments.Skip(2));
// var userId = this.User.Identity.Name; // Akamai
var nonce = ((ClaimsIdentity)this.User.Identity).Claims.First(claim => claim.Type == G2OClaimTypes.Nonce);
Trace.TraceInformation(string.Format("Logged in via nonce {0}", nonce));
var storage = this.G2OConfiguration.Storage.FirstOrDefault(_ => _.Alias == alias);
if (storage == null) { return NotFound(); }
if (!storage.Containers.Any(_ => _ == containerName)) { return NotFound(); }
var blobClient = storage.CloudStorageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName);
// var sasAdHocUri = ContainerUtils.GetSASAdHoc(container, path, validity: TimeSpan.FromMinutes(55));
var sasPolicyUri = ContainerUtils.GetSASUsingPolicy(container, path, validity: TimeSpan.FromDays(31));
bool enforceProtocolEquality = storage.CloudStorageAccount != CloudStorageAccount.DevelopmentStorageAccount;
var redirectUri = enforceProtocolEquality
? new UriBuilder(sasPolicyUri) { Scheme = this.Request.RequestUri.Scheme, Port = -1 }.Uri // redirect scheme must be equal to inbound protocol
: sasPolicyUri;
Trace.TraceInformation(string.Format("Redirecting to {0}", redirectUri.AbsoluteUri));
return Redirect(redirectUri);
}
private async Task GetDataAsync(string segments)
{
string[] pathSegments = segments.Split(new[] { "/" }, StringSplitOptions.None);
string alias = pathSegments[0];
string containerName = pathSegments[1];
string path = string.Join("/", pathSegments.Skip(2));
var storage = this.G2OConfiguration.Storage.FirstOrDefault(_ => _.Alias == alias);
if (storage == null) { return new HttpResponseMessage(HttpStatusCode.NotFound); }
if (!storage.Containers.Any(_ => _ == containerName)) { return new HttpResponseMessage(HttpStatusCode.NotFound); }
var blobClient = storage.CloudStorageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName);
var blob = container.GetBlockBlobReference(path);
if (!await blob.ExistsAsync()) { return new HttpResponseMessage(HttpStatusCode.NotFound); }
Stream blobStream = await blob.OpenReadAsync();
var message = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(blobStream)
};
message.Content.Headers.ContentLength = blob.Properties.Length;
if (!string.IsNullOrEmpty(blob.Properties.ContentType)) { message.Content.Headers.ContentType = new MediaTypeHeaderValue(blob.Properties.ContentType); }
if (!string.IsNullOrEmpty(blob.Properties.ContentEncoding)) { message.Content.Headers.ContentEncoding.Add(blob.Properties.ContentEncoding); }
if (!string.IsNullOrEmpty(blob.Properties.CacheControl)) { message.Headers.CacheControl = CacheControlHeaderValue.Parse(blob.Properties.CacheControl); }
return message;
}
#endregion
}
}