Exemple #1
0
        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);
        }
Exemple #2
0
        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();
        }
Exemple #4
0
        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();
        }
Exemple #5
0
        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));
            }
        }