private async Task Process(HttpContext context) { context.Response.ContentType = "binary/octet-stream"; context.Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + context.Server.UrlEncode(_id + "." + _version + ".nupkg") + "\""); string filename = context.Server.MapPath("~/packages/" + _id + "." + _version + ".nupkg"); await SynchronizationHelp.Enter(filename); Stream stream = null; if (!File.Exists(filename)) { try { NugetDownloader downloader = new NugetDownloader(MvcApplication.NugetSource + context.Request.Url.PathAndQuery); downloader.Progress += async(sender, buffer, length) => { if (stream == null) { stream = File.Open(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); } await stream.WriteAsync(buffer, 0, length); await context.Response.OutputStream.WriteAsync(buffer, 0, length); }; await downloader.Download(); if (downloader.StatusCode != HttpStatusCode.OK) { if (stream != null) { stream.Close(); stream.Dispose(); File.Delete(filename); } context.Response.StatusCode = (int)downloader.StatusCode; return; } else { stream.Close(); stream.Dispose(); } } finally { SynchronizationHelp.Exit(filename); } } else { SynchronizationHelp.Exit(filename); //context.Request.Headers["Range"] stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); await stream.CopyToAsync(context.Response.OutputStream); } }
private async Task Process(HttpContext context) { string path = context.Request.Url.PathAndQuery.ToLower(); await SynchronizationHelp.Enter(path); Page page; DataContext dataContext; try { dataContext = new DataContext(); page = dataContext.Page.SingleOrDefault(t => t.Path == path); } catch (Exception ex) { SynchronizationHelp.Exit(path); context.Response.StatusCode = 500; context.Response.Write(ex.Message); ExceptionLog(ex, context); return; } if (page == null) { page = dataContext.Page.Create(); page.Path = path; page.Id = Guid.NewGuid(); dataContext.Page.Add(page); } else { SynchronizationHelp.Exit(path); } byte[] pageContent = page.Content; if (page.ExpiredDate < DateTime.Now) { string key = path; bool download = true; if (pageContent != null) { key = "Download/" + path; download = await SynchronizationHelp.TryEnter(key); } if (download) { NugetDownloader downloader = new NugetDownloader(MvcApplication.NugetSource + context.Request.Url.PathAndQuery.Substring(7)); Task <Task> downloadTask = downloader.Download().ContinueWith(async t => { if (downloader.StatusCode == HttpStatusCode.OK) { var reader = new StreamReader(downloader.Stream); var content = await reader.ReadToEndAsync(); string replaceTo = context.Request.Url.Scheme + "://" + context.Request.Url.Host; if (context.Request.Url.Port != 80) { replaceTo += ":" + context.Request.Url.Port; } replaceTo += "/api/v2"; content = content.Replace(MvcApplication.UrlReplace, replaceTo); page.Content = Encoding.UTF8.GetBytes(content); page.ExpiredDate = DateTime.Now.AddSeconds(GetCacheTime(_action)); } else { if (pageContent == null) { page.Content = new byte[0]; } page.ExpiredDate = DateTime.Now.AddSeconds(10); } page.ContentType = downloader.ContentType; await dataContext.SaveChangesAsync(); }); if (pageContent == null) { try { await await downloadTask; } catch (Exception ex) { context.Response.StatusCode = 500; context.Response.Write(ex.Message); ExceptionLog(ex, context); return; } finally { SynchronizationHelp.Exit(key); } pageContent = page.Content; } if (page.Content == null || page.Content.Length == 0) { context.Response.StatusCode = 400; return; } } } context.Response.ContentType = page.ContentType; context.Response.Cache.SetExpires(page.ExpiredDate); if (pageContent.Length > 0) { await context.Response.OutputStream.WriteAsync(pageContent, 0, pageContent.Length); } await context.Response.OutputStream.FlushAsync(); }