Exemplo n.º 1
0
        /// <summary>
        /// Helper method that returns the redirect url or null
        /// </summary>
        /// <param name="path">The path to get the redirect url for</param>
        /// <returns>The target url, or <c>null</c></returns>
        public async Task <string> GetRedirecLinkAsync(string path)
        {
            if (!FoundCache.TryGetValue(path, out var le))
            {
                var notFound = await NotFoundCache.TryGetUnlessAsync(path, (a, b) => b < DateTime.Now);

                if (notFound.Key)
                {
                    return(null);
                }

                le = await DB.RunInTransactionAsync(db => db.SelectSingle <LinkEntry>(x => x.Match == path));

                if (le == null)
                {
                    await NotFoundCache.AddOrReplaceAsync(path, DateTime.Now.Add(ExpireTimeout));
                }
                else
                {
                    await FoundCache.AddOrReplaceAsync(path, le);
                }
            }

            if (le != null && le.Enabled && le.IsActive)
            {
                return(le.TargetUrl);
            }
            return(null);
        }
Exemplo n.º 2
0
        public async Task <IResult> Get(
            [Parameter(ParameterSource.Url)]
            string id,

            [Parameter(ParameterSource.Query, required: false, name: "w")]
            int w = 0,
            [Parameter(ParameterSource.Query, required: false, name: "h")]
            int h = 0
            )
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                return(NotFound);
            }

            // Clamp the values
            w = Math.Min(Math.Max(0, w), MAX_DIMENSIONS);
            h = Math.Min(Math.Max(0, h), MAX_DIMENSIONS);

            var mapentry = await DB.RunInTransactionAsync(db => db.SelectItemById <Database.ImageMap>(id));

            if (mapentry == null)
            {
                return(NotFound);
            }

            var resp = Context.Response;

            if (w == 0 && h == 0)
            {
                if (!string.IsNullOrWhiteSpace(mapentry.Sha256) && string.Equals(mapentry.Sha256, Context.Request.Headers["If-None-Match"]))
                {
                    return(Status(HttpStatusCode.NotModified));
                }

                var fi = new FileInfo(mapentry.Path);
                if (!fi.Exists)
                {
                    return(NotFound);
                }

                resp.ContentLength = fi.Length;
                if (!string.IsNullOrWhiteSpace(mapentry.ContentType))
                {
                    resp.ContentType = mapentry.ContentType;
                }

                resp.StatusCode = HttpStatusCode.OK;
                resp.SetExpires(TimeSpan.FromHours(6));
                if (!string.IsNullOrWhiteSpace(mapentry.Sha256))
                {
                    resp.AddHeader("ETag", mapentry.Sha256);
                }

                await resp.FlushHeadersAsync();

                using (var s = File.OpenRead(mapentry.Path))
                    using (var rs = resp.GetResponseStream())
                        await s.CopyToAsync(rs);

                return(null);
            }

            var url = SyntheticUrl(id, w, h);

            if (!m_resizecache.TryGetValue(url, out var data))
            {
                using (var img = Image.Load(mapentry.Path, out var format))
                    using (var ms = new MemoryStream())
                        using (var sha256 = System.Security.Cryptography.SHA256.Create())
                        {
                            var enc = GetEncoder(format.Name);

                            img.Mutate(x => x.Resize(w, h));
                            img.Metadata.ExifProfile = null;
                            img.Save(ms, enc);

                            var bytes = ms.ToArray();
                            data = new KeyValuePair <string, byte[]>(Convert.ToBase64String(sha256.ComputeHash(bytes)), bytes);
                        }

                await m_resizecache.AddOrReplaceAsync(url, data);
            }
            else
            {
                if (string.Equals(data.Key, Context.Request.Headers["If-None-Match"]))
                {
                    return(Status(HttpStatusCode.NotModified));
                }
            }

            resp.ContentLength = data.Value.Length;
            if (!string.IsNullOrWhiteSpace(mapentry.ContentType))
            {
                resp.ContentType = mapentry.ContentType;
            }

            resp.StatusCode = HttpStatusCode.OK;
            resp.SetExpires(TimeSpan.FromHours(6));
            resp.AddHeader("ETag", data.Key);

            await resp.FlushHeadersAsync();

            using (var rs = resp.GetResponseStream())
                await rs.WriteAsync(data.Value, 0, data.Value.Length);

            return(null);
        }