public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "UrlRedirect/{shortUrl}")] HttpRequestMessage req, [Table("urls")] CloudTable inputTable, string shortUrl, TraceWriter log)
        {
            log.Info($"C# HTTP trigger function processed a request for shortUrl {shortUrl}");

            var redirectUrl = FALLBACK_URL;

            if (!String.IsNullOrWhiteSpace(shortUrl))
            {
                shortUrl = shortUrl.Trim().ToLower();

                var partitionKey = $"{shortUrl.First()}";

                log.Info($"Searching for partition key {partitionKey} and row {shortUrl}.");

                var startTime = DateTime.UtcNow;
                var timer     = System.Diagnostics.Stopwatch.StartNew();

                TableOperation operation = TableOperation.Retrieve <ShortUrl>(partitionKey, shortUrl);
                TableResult    result    = inputTable.ExecuteAsync(operation).Result;

                telemetry.TrackDependency("AzureTableStorage", "Retrieve", startTime, timer.Elapsed, result.Result != null);

                ShortUrl fullUrl = result.Result as ShortUrl;
                if (fullUrl != null)
                {
                    log.Info($"Found it: {fullUrl.Url}");
                    redirectUrl = WebUtility.UrlDecode(fullUrl.Url);
                    telemetry.TrackPageView(redirectUrl);
                    if (!string.IsNullOrWhiteSpace(fullUrl.Medium))
                    {
                        telemetry.TrackEvent(fullUrl.Medium);
                    }
                }
            }
            else
            {
                telemetry.TrackEvent("Bad Link");
            }

            var res = req.CreateResponse(HttpStatusCode.Redirect);

            res.Headers.Add("Location", redirectUrl);
            return(res);
        }
Example #2
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestMessage req, [Table("urls", "1", "KEY")] NextId keyTable,
                                                           [Table("urls")] CloudTable tableOut, TraceWriter log)
        {
            log.Info($"C# manually triggered function called with req: {req}");

            if (req == null)
            {
                return(req.CreateResponse(HttpStatusCode.NotFound));
            }

            Request input = await req.Content.ReadAsAsync <Request>();

            if (input == null)
            {
                return(req.CreateResponse(HttpStatusCode.NotFound));
            }

            var  result     = new List <Result>();
            var  url        = input.Input;
            bool tagMediums = input.TagMediums.HasValue ? input.TagMediums.Value : true;
            bool tagSource  = (input.TagSource.HasValue ? input.TagSource.Value : true) || tagMediums;

            log.Info($"URL: {url} Tag Source? {tagSource} Tag Mediums? {tagMediums}");

            if (String.IsNullOrWhiteSpace(url))
            {
                throw new Exception("Need a URL to shorten!");
            }

            if (keyTable == null)
            {
                keyTable = new NextId
                {
                    PartitionKey = "1",
                    RowKey       = "KEY",
                    Id           = 1024
                };
                var keyAdd = TableOperation.Insert(keyTable);
                await tableOut.ExecuteAsync(keyAdd);
            }

            log.Info($"Current key: {keyTable.Id}");

            if (tagSource)
            {
                url = $"{url}?utm_source={UTM_SOURCE}";
            }

            if (tagMediums)
            {
                foreach (var medium in UTM_MEDIUMS)
                {
                    var mediumUrl = $"{url}&utm_medium={medium}";
                    var shortUrl  = Encode(keyTable.Id++);
                    log.Info($"Short URL for {mediumUrl} is {shortUrl}");
                    var newUrl = new ShortUrl
                    {
                        PartitionKey = $"{shortUrl.First()}",
                        RowKey       = $"{shortUrl}",
                        Medium       = medium,
                        Url          = mediumUrl
                    };
                    var multiAdd = TableOperation.Insert(newUrl);
                    await tableOut.ExecuteAsync(multiAdd);

                    result.Add(new Result
                    {
                        ShortUrl = $"{SHORTENER_URL}{newUrl.RowKey}",
                        LongUrl  = WebUtility.UrlDecode(newUrl.Url)
                    });
                }
            }
            else
            {
                var shortUrl = Encode(keyTable.Id++);
                log.Info($"Short URL for {url} is {shortUrl}");
                var newUrl = new ShortUrl
                {
                    PartitionKey = $"{shortUrl.First()}",
                    RowKey       = $"{shortUrl}",
                    Url          = url
                };
                var singleAdd = TableOperation.Insert(newUrl);
                await tableOut.ExecuteAsync(singleAdd);

                result.Add(new Result
                {
                    ShortUrl = $"{SHORTENER_URL}{newUrl.RowKey}",
                    LongUrl  = WebUtility.UrlDecode(newUrl.Url)
                });
            }

            var operation = TableOperation.Replace(keyTable);
            await tableOut.ExecuteAsync(operation);

            log.Info($"Done.");
            // until https://github.com/Azure/azure-webjobs-sdk/issues/1492 is resolved
            // return req.CreateResponse(HttpStatusCode.OK, result);

            return(new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(result))
            });
        }