Example #1
0
        void IUploadModule.BindProgressState(string postBackID, string controlUniqueID, IUploadProgressState progressState)
        {
            UploadState uploadState = UploadStateStore.OpenReadOnly(postBackID);

            if (uploadState == null)
            {
                progressState.Status = UploadStatus.Unknown;
                return;
            }

            progressState.Status = uploadState.Status;
            if (uploadState.Status == UploadStatus.Unknown)
            {
                return;
            }
            progressState.BytesRead     = uploadState.BytesRead;
            progressState.BytesTotal    = uploadState.BytesTotal;
            progressState.BytesPerSec   = uploadState.BytesPerSec;
            progressState.FileBytesRead = uploadState.FileBytesRead;
            progressState.FractionComplete
                = (uploadState.BytesTotal <= 0 || uploadState.FileBytesRead <= 0)
                ? 0
                : ((double)uploadState.BytesRead / uploadState.BytesTotal);
            progressState.CurrentFileName = uploadState.CurrentFileName;
            progressState.Files           = uploadState.Files.GetReadOnlyCopy();
            progressState.Failure         = uploadState.Failure;
            progressState.Rejection       = uploadState.Rejection;
            if (controlUniqueID != null)
            {
                progressState.ProcessingState = uploadState.ProcessingStateDict[controlUniqueID];
            }
            progressState.TimeElapsed = uploadState.TimeElapsed;
            if (uploadState.BytesRead == 0 || uploadState.BytesTotal < 0)
            {
                // If the upload is in progress but we haven't received any bytes yet,
                // pretend that the upload hasn't started yet because there is no way
                // to estimate TimeRemaining.  This situation occurs during a Flash-upload
                // or other upload where the postBackID is passed in the query string.
                // Note that we don't want to lie about the upload status if the status is
                // something other than NormalInProgress.  For example, if the status is
                // Rejected then pretending the upload hasn't started would hide the rejection
                // message.
                if (uploadState.Status == UploadStatus.NormalInProgress)
                {
                    progressState.Status = UploadStatus.Unknown;
                }
                progressState.TimeRemaining = TimeSpan.MaxValue;
            }
            else
            {
                double bytesRemaining = ((double)(uploadState.BytesTotal - uploadState.BytesRead));
                double ticksRemaining = bytesRemaining * uploadState.TimeElapsed.Ticks;
                progressState.TimeRemaining = new TimeSpan((long)(ticksRemaining / uploadState.BytesRead));
            }
            UploadStateStore.Close(uploadState);
        }
Example #2
0
        void IUploadModule.CancelPostBack(string postBackID)
        {
            UploadState uploadState = UploadStateStore.OpenReadWrite(postBackID);

            if (uploadState.Status == UploadStatus.Unknown)
            {
                return;
            }
            uploadState.Status = UploadStatus.Cancelled;
            UploadStateStore.Close(uploadState);
        }
Example #3
0
        private void Application_EndRequest(object sender, EventArgs e)
        {
            if (!IsInited)
            {
                return;
            }
            if (log.IsDebugEnabled)
            {
                log.Debug("In Application_EndRequest");
            }
            if (!Config.Current.UseHttpModule)
            {
                return;
            }

            HttpApplication app = sender as HttpApplication;

            if (RememberErrorHandler != null)
            {
                app.Error -= RememberErrorHandler;
            }

            HttpContext ctx = HttpContext.Current;
            // Get the list of files to dispose to the current context if one hasn't been added yet
            ArrayList filesToDispose = ctx.Items["NeatUpload_FilesToDispose"] as ArrayList;

            if (filesToDispose != null)
            {
                foreach (UploadedFile file in filesToDispose)
                {
                    file.Dispose();
                }
            }

            // Get CurrentUploadState only if it has already been set to
            // avoid deadlocks.
            UploadState uploadState = null;

            if (HttpContext.Current != null)
            {
                uploadState = (UploadState)HttpContext.Current.Items["NeatUpload_UploadState"];
            }
            if (uploadState != null)
            {
                if (CurrentMultiRequestControlID == null &&
                    uploadState.Status != UploadStatus.Failed && uploadState.Status != UploadStatus.Rejected)
                {
                    uploadState.Status = UploadStatus.Completed;
                }
                UploadStateStore.Close(CurrentUploadState);
                CurrentUploadState = null;
            }
        }
Example #4
0
        private void Application_BeginRequest(object sender, EventArgs e)
        {
            if (log.IsDebugEnabled)
            {
                log.Debug("In Application_BeginRequest");
            }
            // When tracing is enabled at the application level ASP.NET reads the entire request before
            // BeginRequest is fired.  So, we should not use our module at all.  We can't do this
            // check from Init() when using Integrated Pipeline Mode because the following line
            // will throw an exception if tracing is enabled.
            lock (StaticSync)
            {
                _isInited = !HttpContext.Current.Trace.IsEnabled;
                if (!IsInited)
                {
                    return;
                }
            }

            HttpApplication app = sender as HttpApplication;

            // Restore the cookies for the MultiRequestUploadModule.UploadPath page.
            HttpWorkerRequest wr       = GetCurrentWorkerRequest();
            string            filePath = wr.GetFilePath().ToLower();
            string            multiRequestUploadPath = MultiRequestUploadModule.UploadPath;

            multiRequestUploadPath = app.Response.ApplyAppPathModifier(multiRequestUploadPath);
            if (log.IsDebugEnabled)
            {
                log.DebugFormat("filePath={0}", filePath);
            }
            string qs = wr.GetQueryString();

            if (filePath.StartsWith(multiRequestUploadPath.ToLower()))
            {
                // The module should always be used for the multi-request upload handler
                // Note that for compatibility reasons we can't set useHttpModule="true"
                // in the NeatUpload folder's Web.config because we can't be sure where
                // the app put the top-level <neatUpload> section and if guess wrong we
                // won't inherit the top-level settings (e.g. validationKey and
                // encryptionKey)
                HttpContext.Current.Items["NeatUpload_UseHttpModule"] = true;
                if (qs != null)
                {
                    HttpCookieCollection cookies = UploadHttpModule.GetCookiesFromQueryString(qs);
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("cookies={0}", cookies);
                    }
                    if (cookies != null)
                    {
                        foreach (string k in cookies.AllKeys)
                        {
                            HttpCookie c = cookies[k];
                            if (log.IsDebugEnabled)
                            {
                                log.DebugFormat("Calling SetCookie({0}, {1})", c.Name, c.Value);
                            }
                            SetCookie(c.Name, c.Value);
                        }
                    }
                }
            }

            if (!Config.Current.UseHttpModule)
            {
                return;
            }

            HttpWorkerRequest origWorker = GetCurrentWorkerRequest();

            if (origWorker == null)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("origWorker = null");
                }
                return;
            }

            if (log.IsDebugEnabled)
            {
                log.Debug(origWorker.GetType() + " for " + origWorker.GetRawUrl() + " with AspFilterSessionId = " + origWorker.GetUnknownRequestHeader("AspFilterSessionId"));
            }
            string rawUrl = app.Context.Request.RawUrl;

            log4net.ThreadContext.Properties["url"] = rawUrl;

            if (origWorker is DecoratedWorkerRequest)
            {
                // If an unhandled error occurs, we want to remember it so that we can rethrow it
                // in the original context.
                if (RememberErrorHandler != null)
                {
                    app.Error += RememberErrorHandler;
                }
                // Save a reference to the original HttpContext in the subrequest context so that
                // AppendToLog() can use it.
                DecoratedWorkerRequest decoratedWorkerRequest = origWorker as DecoratedWorkerRequest;
                if (decoratedWorkerRequest.OrigContext != null)
                {
                    HttpContext.Current.Items["NeatUpload_origContext"] = decoratedWorkerRequest.OrigContext;
                }
                // Ignore the subrequests to avoid infinite recursion...
                return;
            }

            // Get the Content-Length header and parse it if we find it.  If it's not present we might
            // still be OK.
            long   contentLength       = 0;
            string contentLengthHeader = origWorker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);

            if (contentLengthHeader != null)
            {
                try
                {
                    contentLength = Int64.Parse(contentLengthHeader);
                }
                catch (Exception ex)
                {
                    throw new HttpException(400, "Bad Request", ex);
                }
            }

            DecoratedWorkerRequest subWorker = null;

            // Create a subrequest for each request.  For multipart/form-data requests, we use a
            // FilteringWorkerRequest which filters the file parts into temp files.  For all other
            // requests that could contain a body, we use a SizeLimitingWorkerRequest to ensure that the
            // size of the request is within
            // the user configured limit.  We need the SizeLimitingWorkerRequest, because httpRuntime's
            // maxRequestLength attribute needs to be set to a large value to allow large file upload request
            // to get to this module at all.  That means that large normal requests will also get to this
            // module.  SizeLimitingWorkerRequest ensures that normal requests which are too large are
            // rejected.
            string contentTypeHeader      = origWorker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);
            string transferEncodingHeader = origWorker.GetKnownRequestHeader(HttpWorkerRequest.HeaderTransferEncoding);

            if (contentTypeHeader != null && contentTypeHeader.ToLower().StartsWith("multipart/form-data"))
            {
                // If this is a multi-request upload get the post-back ID from the query string
                if (qs != null && UploadHttpModule.GetMultiRequestControlIDFromQueryString(qs) != null)
                {
                    CurrentUploadState = UploadStateStore.OpenReadWriteOrCreate(UploadHttpModule.GetPostBackIDFromQueryString(qs));
                    if (transferEncodingHeader != "chunked")
                    {
                        CurrentUploadState.Status = UploadStatus.NormalInProgress;
                    }
                    else
                    {
                        CurrentUploadState.Status = UploadStatus.ChunkedInProgress;
                    }
                }
                subWorker = new FilteringWorkerRequest(origWorker);
            }
            else
            {
                // If the client-specified content length is too large, we reject the request
                // immediately.  If it's not, the client could be lying so we need to use
                // SizeLimitingWorkerRequest to actually count the bytes.
                if (contentLength > MaxNormalRequestLength)
                {
                    throw new HttpException(413, "Request Entity Too Large");
                }

                // Only requests which match the following criteria could contain a body.
                if ((transferEncodingHeader != null && transferEncodingHeader != "identity") ||
                    (contentLengthHeader != null && contentLengthHeader != "0") ||
                    (contentTypeHeader != null && contentTypeHeader.StartsWith("multipart/byteranges")))
                {
                    subWorker = new SizeLimitingWorkerRequest(origWorker, MaxNormalRequestLength);
                }
                else
                {
                    if (origWorker.HasEntityBody())
                    {
                        throw new HttpException(400, "Unexpected body in request for " + rawUrl);
                    }
                }
            }

            if (subWorker != null)
            {
                if (!ReplaceWorkerRequest(app, subWorker))
                {
                    MakeChildRequest(app, subWorker);
                }
            }
        }