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); }
void IUploadModule.CancelPostBack(string postBackID) { UploadState uploadState = UploadStateStore.OpenReadWrite(postBackID); if (uploadState.Status == UploadStatus.Unknown) { return; } uploadState.Status = UploadStatus.Cancelled; UploadStateStore.Close(uploadState); }
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; } }
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); } } }