示例#1
0
        private static async Task <bool> InvokeAsync(ContextAdapter context, ProtocolMethodHandler methodHandler)
        {
            var response = context.Response;

            if (!(methodHandler is OptionsHandler))
            {
                var tusResumable = context.Request.Headers.ContainsKey(HeaderConstants.TusResumable)
                    ? context.Request.Headers[HeaderConstants.TusResumable].FirstOrDefault()
                    : null;

                if (tusResumable == null)
                {
                    return(false);
                }

                if (tusResumable != HeaderConstants.TusResumableValue)
                {
                    response.SetHeader(HeaderConstants.TusResumable, HeaderConstants.TusResumableValue);
                    response.SetHeader(HeaderConstants.TusVersion, HeaderConstants.TusResumableValue);
                    return(await response.Error(HttpStatusCode.PreconditionFailed,
                                                $"Tus version {tusResumable} is not supported. Supported versions: {HeaderConstants.TusResumableValue}"));
                }
            }

            InMemoryFileLock fileLock = null;

            if (methodHandler.RequiresLock)
            {
                fileLock = new InMemoryFileLock(context.GetFileId());

                var hasLock = fileLock.Lock();
                if (!hasLock)
                {
                    return(await response.Error(HttpStatusCode.Conflict,
                                                $"File {context.GetFileId()} is currently being updated. Please try again later"));
                }
            }

            try
            {
                if (!await methodHandler.Validate(context))
                {
                    return(true);
                }

                return(await methodHandler.Handle(context));
            }
            catch (TusStoreException storeException)
            {
                await context.Response.Error(HttpStatusCode.BadRequest, storeException.Message);

                return(true);
            }
            finally
            {
                fileLock?.ReleaseIfHeld();
            }
        }
示例#2
0
        public void LockAsync_Can_Lock_Successfully()
        {
            const string fileId    = "testfile1";
            var          fileLock1 = new InMemoryFileLock(fileId);

            fileLock1.Lock().ShouldBeTrue();

            var fileLock2 = new InMemoryFileLock(fileId);

            fileLock2.Lock().ShouldBeFalse();

            fileLock1.Lock().ShouldBeTrue();

            fileLock1.ReleaseIfHeld();

            fileLock2.Lock().ShouldBeTrue();
        }
示例#3
0
        public async Task ReleaseIfHeld_Relases_Lock_Successfully()
        {
            const string fileId    = "testfile2";
            var          fileLock1 = new InMemoryFileLock(fileId);

            (await fileLock1.Lock()).ShouldBeTrue();

            var fileLock2 = new InMemoryFileLock(fileId);

            (await fileLock2.Lock()).ShouldBeFalse();

            (await fileLock1.Lock()).ShouldBeTrue();

            await fileLock1.ReleaseIfHeld();

            (await fileLock2.Lock()).ShouldBeTrue();
        }
示例#4
0
        public void ReleaseIfHeld_Does_Nothing_If_Lock_Was_Not_Held()
        {
            const string fileId    = "testfile3";
            var          fileLock1 = new InMemoryFileLock(fileId);

            fileLock1.Lock().ShouldBeTrue();

            var fileLock2 = new InMemoryFileLock(fileId);

            fileLock2.Lock().ShouldBeFalse();

            fileLock2.ReleaseIfHeld();

            var fileLock3 = new InMemoryFileLock(fileId);

            fileLock3.ReleaseIfHeld();
            fileLock3.Lock().ShouldBeFalse();
        }
示例#5
0
        public static async Task <ResultType> Invoke(ContextAdapter context)
        {
            context.Configuration.Validate();

            var intentHandler = IntentAnalyzer.DetermineIntent(context);

            if (intentHandler == IntentHandler.NotApplicable)
            {
                return(ResultType.ContinueExecution);
            }

            var onAuhorizeResult = await EventHelper.Validate <AuthorizeContext>(context, ctx =>
            {
                ctx.Intent            = intentHandler.Intent;
                ctx.FileConcatenation = GetFileConcatenationFromIntentHandler(intentHandler);
            });

            if (onAuhorizeResult == ResultType.StopExecution)
            {
                return(ResultType.StopExecution);
            }

            if (await VerifyTusVersionIfApplicable(context, intentHandler) == ResultType.StopExecution)
            {
                return(ResultType.StopExecution);
            }

            InMemoryFileLock fileLock = null;

            if (intentHandler.LockType == LockType.RequiresLock)
            {
                fileLock = new InMemoryFileLock(context.Request.FileId);

                var hasLock = fileLock.Lock();
                if (!hasLock)
                {
                    await context.Response.Error(HttpStatusCode.Conflict, $"File {context.Request.FileId} is currently being updated. Please try again later");

                    return(ResultType.StopExecution);
                }
            }

            try
            {
                if (!await intentHandler.Validate())
                {
                    return(ResultType.StopExecution);
                }

                await intentHandler.Invoke();

                return(ResultType.StopExecution);
            }
            catch (TusStoreException storeException)
            {
                await context.Response.Error(HttpStatusCode.BadRequest, storeException.Message);

                return(ResultType.StopExecution);
            }
            finally
            {
                fileLock?.ReleaseIfHeld();
            }
        }