예제 #1
0
        /// <summary>
        /// Waits for the current upload request to finish.</summary>
        /// <remarks>
        /// <para>
        /// If the UploadHttpModule is being used for the current request, this method will not return until the
        /// module has received and processed the entire request.  If the UploadHttpModule is not being used for
        /// the current request, this method will return immediately.  Note: the UploadHttpModule is only used if
        /// it has been added in the httpModules section of the Web.config, the neatUpload section's
        /// useHttpModule attribute is "true" for the page being requested (which is the default), and the
        /// request has a content type of multipart/form-data.</para>
        /// </remarks>
        public static void WaitForUploadToComplete()
        {
            // If the original request hasn't been parsed (and any upload received) by now,
            // we force parsing to ensure that the upload is received.
            FilteringWorkerRequest worker
                = GetCurrentWorkerRequest() as FilteringWorkerRequest;

            if (worker != null)
            {
                worker.ParseMultipart();
            }
        }
예제 #2
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);
                }
            }
        }