public async Task TestInMemoryCacheObjectAsync() { var cache = new InMemoryCache("cache1", new TimeSpan(0, 2, 0)); int hits = 0; Func <Task <string> > getter = async() => { hits++; return(hits.ToString()); }; string result; result = await cache.GetAsync("key", getter); Assert.AreEqual(1, hits); Assert.AreEqual("1", result); result = await cache.GetAsync("key", getter); Assert.AreEqual(1, hits); Assert.AreEqual("1", result); }
private static async Task CacheDemoAsync() { Console.Write("Getting item... "); var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); await _cacheService.GetAsync( "LargeObjectKeyAsync", GetObjectFromSomewhereSlowlyAsync, 600); var detail = _cacheService.GetCacheItemDetail("LargeObjectKeyAsync"); if (detail != null) { Console.WriteLine("Item is set to expire on: {0}", detail.ExpiresOn); } Console.WriteLine("That took {0} milliseconds to get", stopWatch.ElapsedMilliseconds); Console.WriteLine(); }
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { using (var scope = app.ApplicationServices.GetRequiredService <IServiceScopeFactory>().CreateScope()) { scope.ServiceProvider.GetService <ApplicationDbContext>().Database.Migrate(); } var pipeline = new AggregatedFilterPipeline(); app .UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, KnownNetworks = { new IPNetwork(new IPAddress(new byte[] { 127, 0, 0, 1 }), 32) } }) .Use(async(context, next) => { var flareContext = new FlaggableFlareContext(new FlareContext() { request = new FlareRequest() { date = DateTimeOffset.Now, http_version = (int)(double.Parse(context.Request.Protocol.Substring(5)) * 10), identity = "-", ip = context.Connection.RemoteIpAddress.ToString(), method = context.Request.Method, path = context.Request.Path.Value, query_string = context.Request.QueryString.Value, userid = "-" }, response = null }); var domain = context.Request.Headers["host"]; // Flare CDN logic if (domain != "localhost:5000" && domain != "api.flare.wtf") { var db = context.RequestServices.GetRequiredService <ApplicationDbContext>(); var server = await db.servers .Where(a => a.proxy_active && a.domains.Any(b => b.domain == domain)) .FirstOrDefaultAsync(); if (server == null) { context.Response.StatusCode = 404; await context.Response.WriteAsync("The requested resource is not found. That's all we know."); return; } var ip = await context.RequestServices.GetRequiredService <GeoIpService>() .Query(flareContext.Context.request.ip); var db_request = new request { server_id = server.id, ip_id = ip.id, request_identity = flareContext.Context.request.identity, request_user_id = flareContext.Context.request.userid, request_date = flareContext.Context.request.date, request_method = flareContext.Context.request.method, request_path = flareContext.Context.request.path, request_query_string = flareContext.Context.request.query_string, request_http_version = flareContext.Context.request.http_version, // response_code = flareContext.Context.response?.status_code, // response_length = flareContext.Context.response?.bytes_sent, // flags = flareContext.Flags }; db.requests.Add(db_request); if (await pipeline.ProcessRequest(flareContext) && server.proxy_block_requests) { await db.SaveChangesAsync(); db_request.response_code = 418; db_request.flags = flareContext.Flags; await db.SaveChangesAsync(); var text = $"418 - I am a teapot. Your request #{db_request.id} is failed because of security checks. Contact the website owner with this number if you think this was a mistake."; db_request.response_length = text.Length; context.Response.StatusCode = 418; await context.Response.WriteAsync(text); return; } db_request.flags = flareContext.Flags; using (var httpClient = new HttpClient()) { httpClient.DefaultRequestHeaders.Clear(); foreach (var header in context.Request.Headers .Where(a => !a.Key.StartsWith("X-"))) { httpClient.DefaultRequestHeaders.Add(header.Key, header.Value.ToArray()); } httpClient.DefaultRequestHeaders.Add("X-Forwarded-For", context.Connection.RemoteIpAddress.ToString()); using (var _req = new HttpRequestMessage( context.Request.Method == "GET" ? HttpMethod.Get : context.Request.Method == "POST" ? HttpMethod.Post : context.Request.Method == "DELETE" ? HttpMethod.Delete : context.Request.Method == "PUT" ? HttpMethod.Put : context.Request.Method == "PATCH" ? HttpMethod.Patch : context.Request.Method == "TRACE" ? HttpMethod.Trace : context.Request.Method == "OPTIONS" ? HttpMethod.Options : throw new Exception("invalid method") , $"http://{server.origin_ip}{context.Request.Path}{context.Request.QueryString}")) { _req.Headers.Host = domain; using (var response = await httpClient.SendAsync(_req)) { db_request.response_code = context.Response.StatusCode = (int)response.StatusCode; foreach (var header in response.Headers .Where(a => a.Key != "Transfer-Encoding")) { context.Response.Headers.Add(header.Key, new StringValues(header.Value.ToArray())); } foreach (var header in response.Content.Headers) { context.Response.Headers.Add(header.Key, new StringValues(header.Value.ToArray())); } using (var streamWithProgess = new StreamWithProgress(context.Response.Body)) { await response.Content.CopyToAsync(streamWithProgess); await context.Response.Body.FlushAsync(); context.Response.Body.Close(); db_request.response_length = (int)streamWithProgess.bytesTotal; await db.SaveChangesAsync(); } } } } } else { if (await pipeline.ProcessRequest(flareContext)) { var text = $"418 - I am a teapot. Your request is failed because of security checks. If you think it was a mistake contact [email protected]"; context.Response.StatusCode = 418; await context.Response.WriteAsync(text); return; } await next(); } }) .UseCors(policy => policy.SetPreflightMaxAge(TimeSpan.FromMinutes(10)).AllowAnyMethod().AllowAnyOrigin().AllowAnyHeader()) .UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "../uploads")), RequestPath = new PathString("/uploads") }) .Use(async(context, next) => { IHttpBufferingFeature bufferingFeature = context.Features.Get <IHttpBufferingFeature>(); bufferingFeature?.DisableRequestBuffering(); bufferingFeature?.DisableResponseBuffering(); try { await next(); } catch (Exception e) { context.Response.StatusCode = e is NotImplementedException ? 404 : e is UnauthorizedAccessException || e is SecurityTokenValidationException ? 401 : e is ArgumentException ? 400 : 500; context.Response.ContentType = "application/json; charset=utf-8"; string message = ""; Exception x = e; do { message += x.Message + "\r\n\r\n"; } while ((x = x.InnerException) != null); await context.Response.WriteAsync(JsonConvert.SerializeObject(new { code = -1, message = message.Substring(0, message.Length - 4), stacktrace = e.StackTrace })); } }) .Use(async(context, next) => { Token token = null; string strToken = context.Request.Query["token"]; if (strToken == null) { string authorization = context.Request.Headers["Authorization"]; if (authorization != null) { if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { strToken = authorization.Substring("Bearer ".Length).Trim(); } else if (authorization.StartsWith("Basic ")) { var encoding = Encoding.UTF8.GetString(Convert.FromBase64String(authorization.Substring("Basic ".Length))).Split(':'); if (encoding.Length != 2) { throw new UnauthorizedAccessException(); } var username = encoding[0]; var password = encoding[1]; token = await personal_token_cache.GetAsync(username + ":" + password, async() => { var db = context.RequestServices.GetRequiredService <ApplicationDbContext>(); var _code = AccountController.StringToByteArrayFastest(username); var id = new Guid(_code.ToArray()); var app2 = await db.pacs .Include(a => a.user) .SingleOrDefaultAsync(b => b.id == id); if (app2 == null || app2.password_hash == null || !app2.password_hash.SequenceEqual( KeyDerivation.Pbkdf2( password: password, salt: app2.password_salt, iterationCount: 10000, numBytesRequested: 256 / 8, prf: KeyDerivationPrf.HMACSHA1 ) )) { throw new UnauthorizedAccessException(); } return(await token_cache.GetAsync(app2.user.id.ToString(), () => Task.FromResult <Token>(new UserToken(app2.user.id, app2.user.name, app2.user.type)), TimeSpan.FromDays(3))); }, TimeSpan.FromDays(3)); } } } if (strToken != null) { var a = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(); var claims = a.ValidateToken(strToken, new TokenValidationParameters { ValidateAudience = true, ValidIssuer = "Flare", ValidAudience = "Flare Users", IssuerSigningKey = _key }, out SecurityToken _); context.User = claims; var strID = context.User?.Claims?.FirstOrDefault(b => b.Type == "user_id")?.Value; if (Int32.TryParse(strID, out int dwID)) { token = await token_cache.GetAsync(strID, async() => { var db = context.RequestServices.GetRequiredService <ApplicationDbContext>(); var app2 = await db.users.SingleAsync(b => b.id == dwID); return(new UserToken(app2.id, app2.name, app2.type)); }, TimeSpan.FromDays(3)); } } context.AddScoped(() => { if (token == null) { throw new UnauthorizedAccessException(); } return(token); }); await next(); }) .UseMvc(); }
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { using (var scope = app.ApplicationServices.GetRequiredService <IServiceScopeFactory>().CreateScope()) { scope.ServiceProvider.GetService <ApplicationDbContext>().Database.Migrate(); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app .Use(async(context, next) => { try { await next(); } catch (Exception e) { context.Response.StatusCode = e is NotImplementedException ? 404 : e is UnauthorizedAccessException || e is SecurityTokenValidationException ? 401 : e is ArgumentException ? 400 : 500; context.Response.ContentType = "application/json; charset=utf-8"; string message = ""; Exception x = e; do { message += x.Message + "\r\n\r\n"; } while ((x = x.InnerException) != null); await context.Response.WriteAsync(JsonConvert.SerializeObject(new { code = -1, message = message.Substring(0, message.Length - 4), stacktrace = e.StackTrace })); } }) .UseCors(policy => policy.SetPreflightMaxAge(TimeSpan.FromMinutes(10)).AllowAnyMethod().AllowAnyOrigin().AllowAnyHeader()) .Use(async(context, next) => { Token token = null; string strToken = context.Request.Query["token"]; if (strToken == null) { string authorization = context.Request.Headers["Authorization"]; if (authorization != null) { if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { strToken = authorization.Substring("Bearer ".Length).Trim(); } else if (authorization.StartsWith("Basic ")) { var encoding = Encoding.UTF8.GetString(Convert.FromBase64String(authorization.Substring("Basic ".Length))).Split(':'); if (encoding.Length != 2) { throw new UnauthorizedAccessException(); } var username = encoding[0]; var password = encoding[1]; if (username.StartsWith("acc_")) { username = username.Substring(4); token = await personal_token_cache.GetAsync(username + ":" + password, async() => { var db = context.RequestServices.GetRequiredService <ApplicationDbContext>(); var _code = AccountController.StringToByteArrayFastest(username); var id = new Guid(_code.ToArray()); var app2 = await db.pacs .Include(a => a.user) .SingleOrDefaultAsync(b => b.id == id); if (app2 == null || app2.password_hash == null || !app2.password_hash.SequenceEqual( KeyDerivation.Pbkdf2( password: password, salt: app2.password_salt, iterationCount: 10000, numBytesRequested: 256 / 8, prf: KeyDerivationPrf.HMACSHA1 ) )) { throw new UnauthorizedAccessException(); } return(await token_cache.GetAsync(app2.user.id.ToString(), () => Task.FromResult <Token>(new UserToken(app2.user.id, app2.user.name, app2.user.type)), TimeSpan.FromDays(3))); }, TimeSpan.FromDays(3)); } else { throw new UnauthorizedAccessException(); } } } } if (strToken != null) { var a = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(); var claims = a.ValidateToken(strToken, new TokenValidationParameters { ValidateAudience = true, ValidIssuer = "Visa", ValidAudience = "Visa Users", IssuerSigningKey = _key }, out SecurityToken stoken); context.User = claims; var strID = context.User?.Claims?.FirstOrDefault(b => b.Type == "user_id")?.Value; if (Int32.TryParse(strID, out int dwID)) { token = await token_cache.GetAsync(strID, async() => { var db = context.RequestServices.GetRequiredService <ApplicationDbContext>(); var app2 = await db.users.SingleAsync(b => b.id == dwID); return(new UserToken(app2.id, app2.name, app2.type)); }, TimeSpan.FromDays(3)); } } context.AddScoped(() => { if (token == null) { throw new UnauthorizedAccessException(); } return(token); }); await next(); }) .UseMvc(); }
private async Task <HttpResponseMessage> RedirectRequest(HttpRequestMessage request, CancellationToken cancellationToken) { var localPath = request.RequestUri.LocalPath.Replace("/proxy", "/adfs"); var redirectLocation = ConfigurationManager.AppSettings["ida:RedirectLocation"]; string primaryCacheKey = request.RequestUri.ToString().ToLower(); bool responseIsCached = false; HttpResponseMessage responseFromCache = null; // first, before even looking at the cache: // The Cache-Control: no-cache HTTP/1.1 header field is also intended for use in requests made by the client. // It is a means for the browser to tell the server and any intermediate caches that it wants a // fresh version of the resource. if (request.Headers.CacheControl != null && request.Headers.CacheControl.NoCache && localPath != "/adfs/discovery/keys") { // Don't get from cache. Get from server. return(await HandleRedirectRequest(primaryCacheKey, request, localPath, redirectLocation, cancellationToken)); } // available in cache? var cacheEntry = await memoryCache.GetAsync <CacheEntry>(primaryCacheKey); if (cacheEntry != default(CacheEntry)) { // TODO: for all of these, check the varyby headers (secondary key). // An item is a match if secondary & primary keys both match! responseFromCache = new HttpResponseMessage(cacheEntry.StatusCode); responseFromCache.ReasonPhrase = cacheEntry.StatusDescription; responseFromCache.Version = cacheEntry.ProtocolVersion; responseFromCache.RequestMessage = request; responseIsCached = true; } if (responseIsCached) { // set the accompanying request message responseFromCache.RequestMessage = request; // Check conditions that might require us to revalidate/check // we must assume "the worst": get from server. bool mustRevalidate = HttpResponseHelpers.MustRevalidate(responseFromCache); if (mustRevalidate) { // we must revalidate - add headers to the request for validation. // // we add both ETag & IfModifiedSince for better interop with various // server-side caching handlers. // if (responseFromCache.Headers.ETag != null) { request.Headers.Add(Utils.Constants.HttpHeaderConstants.IfNoneMatch, responseFromCache.Headers.ETag.ToString()); } if (responseFromCache.Content.Headers.LastModified != null) { request.Headers.Add(Utils.Constants.HttpHeaderConstants.IfModifiedSince, responseFromCache.Content.Headers.LastModified.Value.ToString("r")); } // Don't get from cache. Get from server. return(await HandleRedirectRequest(primaryCacheKey, request, localPath, redirectLocation, cancellationToken)); } else { responseFromCache.Content = new StringContent(cacheEntry.Content, Encoding.UTF8, "application/json"); // response is allowed to be cached and there's // no need to revalidate: return the cached response return(responseFromCache); } } else { // Don't get from cache. Get from server. return(await HandleRedirectRequest(primaryCacheKey, request, localPath, redirectLocation, cancellationToken)); } }