Example #1
0
        internal void ReportCanceled()
        {
#if (TRACE)
            ThreadLog.WriteLine("Upload canceled");
#endif

            _EndDate        = DateTime.UtcNow;
            _ProgressStatus = UploadProgressStatus.Canceled;

            if (HttpContext.Current != null) //Support for unit tests
            {
                //System.Diagnostics.Debug.Assert(((UploadData)HttpContext.Current.Cache.Get(UploadMonitor.UPLOAD_DATA_PREFIX + _UploadId)).ContentPosition == contentPosition);
                System.Diagnostics.Debug.Assert(((UploadData)HttpContext.Current.Cache.Get(UploadMonitor.UPLOAD_DATA_PREFIX + _UploadId)).ProgressStatus == UploadProgressStatus.Canceled);
            }

            HealthMonitoringManager.LogErrorEvent(
                Resources.ExceptionRequestCanceled,
                this,
                UploadRequestErrorEvent.RuntimeErrorRequestAbort,
                null);
        }
Example #2
0
        private void DeleteUploadFiles(IList <UploadFile> uploadFiles)
        {
            if (uploadFiles == null)
            {
                return;
            }

            try
            {
                foreach (UploadFile objUploadFile in uploadFiles)
                {
                    FileStorage.DeleteFile(objUploadFile.ProviderFileKey);
                    objUploadFile.IsComplete = false;
                }
            }
            catch (Exception Ex)
            {
                HealthMonitoringManager.LogErrorEvent(
                    Resources.ExceptionUnhandled,
                    null, //<-- no upload data here
                    UploadRequestErrorEvent.RuntimeErrorExceptionUnhandled,
                    Ex);
            }
        }
Example #3
0
        private void OnPreRequestHandlerExecute(object sender, EventArgs e)
        {
            HttpApplication objHttpApplication = sender as HttpApplication;

            System.Diagnostics.Debug.Assert(objHttpApplication != null);
            HttpRequest objHttpRequest = objHttpApplication.Request;

            System.Diagnostics.Debug.Assert(objHttpRequest != null);

            if (objHttpRequest != null && UploadHttpModule.IsUploadRequest(objHttpRequest))
            {
#if (TRACE)
                ThreadLog.WriteLine("Entered OnPreRequestHandlerExecute for an upload request");
#endif

                HttpContext objHttpContext = objHttpApplication.Context;
                System.Diagnostics.Debug.Assert(objHttpContext != null);

                HttpWorkerRequest objHttpWorkerRequest = UploadHttpModule.GetWorkerRequest(objHttpContext);
                System.Diagnostics.Debug.Assert(objHttpWorkerRequest != null);

                if (objHttpWorkerRequest != null)
                {
                    //long lContentLength = objHttpRequest.ContentLength;
                    long lContentLength = long.Parse(objHttpWorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength), CultureInfo.InvariantCulture);

                    if (lContentLength <= 0) //This is for Flash 8 FileReference which tests an empty post before sending a large upload
                    {
#if (TRACE)
                        ThreadLog.WriteLine("No content, maybe Flash");
#endif

                        HealthMonitoringManager.LogSucessEvent(
                            Resources.ExceptionZeroContentLength,
                            null, //<- no upload data yet
                            UploadRequestSuccessEvent.RuntimeUploadSuccessZeroContentLength);

                        objHttpApplication.Response.StatusCode = 200; //OK
                        objHttpApplication.CompleteRequest();
                        //See: http://support.microsoft.com/kb/312629
                        //objHttpApplication.Response.End();
                        return;
                    }

                    //Initialize an upload monitor
                    string sUploadID = UploadHttpModule.GetUploadID(objHttpRequest);
                    if (String.IsNullOrEmpty(sUploadID))
                    {
#if (TRACE)
                        ThreadLog.WriteLine("No upload ID");
#endif

                        HttpException objHttpException = new HttpException(400, Resources.ExceptionNullOrEmptyUploadId);

                        HealthMonitoringManager.LogErrorEvent(
                            Resources.ExceptionNullOrEmptyUploadId,
                            null, //<- no upload data yet
                            UploadRequestErrorEvent.RuntimeErrorMissingUploadID,
                            objHttpException);

                        UploadHttpModule.CloseConnectionAfterError(objHttpApplication.Response);
                        throw objHttpException;

                        //See comment in relation with MaxRequestLength here below
                        //objHttpApplication.Response.StatusCode = 400; //Bad request
                        //objHttpApplication.Response.StatusDescription = Resources.ExceptionNullOrEmptyUploadId;
                        //objHttpApplication.Response.Write(String.Format(Resources.Culture, Resources.ErrorPage, 400, Resources.ExceptionNullOrEmptyUploadId));
                        //objHttpApplication.CompleteRequest();
                        //See: http://support.microsoft.com/kb/312629
                        //objHttpApplication.Response.End();
                    }

                    UploadData objUploadData = UploadMonitor.SetUploadData(objHttpContext, sUploadID);
                    System.Diagnostics.Debug.Assert(objUploadData != null);

                    //Check whether we should read MaxRequestLength from httpRuntime section of web.config (true)
                    bool bMaximizeRequestLength = UploadHttpModule.GetForceHttpMaxRequestLength(objHttpRequest);
                    //Check the upload size and end request if file is too big
                    long lMaxRequestLength = UploadHttpModule.GetMaxRequestLengthBytes(objHttpContext, bMaximizeRequestLength);
                    if ((lMaxRequestLength >= 0) && (lContentLength > lMaxRequestLength))
                    {
#if (TRACE)
                        ThreadLog.WriteLine("Post request is too large");
#endif

                        HttpException objHttpException = new HttpException(413, Resources.ExceptionPostTooLarge);

                        HealthMonitoringManager.LogErrorEvent(
                            Resources.ExceptionPostTooLarge,
                            objUploadData,
                            UploadRequestErrorEvent.RuntimeErrorPostTooLarge,
                            objHttpException);

                        objUploadData.ReportFailed(objHttpException);

                        UploadHttpModule.CloseConnectionAfterError(objHttpApplication.Response);
                        throw objHttpException;

                        //There are 3 possible options
                        //1) Do nothing and let httpRuntime/maxRequestlength do its job
                        //2) Do something like
                        //      objHttpApplication.Response.StatusCode = 413;
                        //      objHttpApplication.Response.StatusDescription = Resources.ExceptionPostTooLarge;
                        //      objHttpApplication.Response.Write(String.Format(Resources.Culture, Resources.ErrorPage, 413, Resources.ExceptionPostTooLarge));
                        //      objHttpApplication.CompleteRequest();
                        //      See: http://support.microsoft.com/kb/312629
                        //      //objHttpApplication.Response.End();
                        //      return;
                        //3) Raise an HttpException

                        //Option 1 is no more an option since we have implemented uploadRuntime

                        //Option 2 sometimes aborts and closes the connection with an IE error page,
                        //sometimes displays a blank page. When the IE page appears, we get
                        //an ERROR_INTERNET_CONNECTION_ABORTED, when the blank page is displayed
                        //the post returns a 413 status code. To get some content we would need
                        //to write to the response _Input using something like objHttpApplication.Response.Write

                        //HttpRequest.GetEntireRawContent implements option 3). Actually it triggers
                        //throw new HttpException(SR.GetString("Max_request_length_exceeded"), null, 0xbbc);
                        //after calling HttpResponse.CloseConnectionAfterError(). In this case an unhdandled
                        //exception is thrown abd we can rely on Application_Error and Custom Errors which
                        //is the best option.
                    }

#if (TRACE)
                    ThreadLog.WriteLine("Start parsing upload _Input");
#endif

                    Encoding objEncoding = objHttpRequest.ContentEncoding;

                    string sContentType = objHttpRequest.ContentType;
                    int    iPos         = sContentType.ToLowerInvariant().IndexOf(Constants.MultiPartBoundary);
                    if (iPos < 0)
                    {
#if (TRACE)
                        ThreadLog.WriteLine("Bad request");
#endif

                        HttpException objHttpException = new HttpException(400, Resources.ExceptionMalformedContentType);

                        HealthMonitoringManager.LogErrorEvent(
                            Resources.ExceptionMalformedContentType,
                            objUploadData,
                            UploadRequestErrorEvent.RuntimeErrorMalformedContentType,
                            objHttpException
                            );

                        objUploadData.ReportFailed(objHttpException);

                        UploadHttpModule.CloseConnectionAfterError(objHttpApplication.Response);
                        throw objHttpException;

                        //See comment in relation with MaxRequestLength here above
                        //objHttpApplication.Response.StatusCode = 400; //Bad request
                        //objHttpApplication.Response.StatusDescription = Resources.ExceptionMultipartBoundaryNotFound;
                        //objHttpApplication.Response.Write(String.Format(Resources.Culture, Resources.ErrorPage, 400, Resources.ExceptionMultipartBoundaryNotFound));
                        //objHttpApplication.CompleteRequest();
                        //See: http://support.microsoft.com/kb/312629
                        //objHttpApplication.Response.End();
                        //return;
                    }
                    string sMultiPartBoundary = Constants.BoundaryPrefix + sContentType.Substring(iPos + Constants.MultiPartBoundary.Length);
#if (TRACE)
                    ThreadLog.WriteLine("Identified boundary = " + sMultiPartBoundary);
#endif

                    RequestStream objRequestStream = null;
                    RequestFilter objRequestFilter = null;

                    try
                    {
                        HashAlgorithm objHashAlgorithm = CryptoConfig.CreateFromName(Constants.HashAlgorithmName) as HashAlgorithm;
                        //objHashAlgorithm.Initialize(); Done in RequestFilter
                        objRequestStream = new RequestStream(objHttpWorkerRequest);
                        objRequestFilter = new RequestFilter(objRequestStream, objHashAlgorithm, lContentLength, objEncoding, sMultiPartBoundary, objUploadData);

#if (TRACE)
                        ThreadLog.WriteLine("Started parsing");
#endif

                        //Parse the request to filter input files
                        MimeParser objMimeParser = new MimeParser(objRequestFilter);
                        objMimeParser.Parse();
                        //Get the filtered request
                        byte[] arrFilteredRequest = objRequestFilter.Encoding.GetBytes(objRequestFilter.FilteredRequest);
                        //Redirect the filtered request
                        RedirectFilteredRequest(objHttpApplication, objHttpWorkerRequest, arrFilteredRequest);

#if (TRACE)
                        ThreadLog.WriteLine("Filtered request redirected");
#endif

                        HealthMonitoringManager.LogSucessEvent(
                            Resources.MessageUploadCompleted,
                            objUploadData,
                            UploadRequestSuccessEvent.RuntimeUploadSuccessCompleted
                            );
                    }
                    catch (Exception Ex)
                    {
#if (TRACE)
                        ThreadLog.WriteLine("Parsing error");
#endif
                        HealthMonitoringManager.LogErrorEvent(
                            Resources.ExceptionUnhandled + "\r\n" + objHttpWorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderUserAgent),
                            objUploadData,
                            UploadRequestErrorEvent.RuntimeErrorExceptionUnhandled,
                            Ex);

                        objUploadData.ReportFailed(Ex);

                        UploadHttpModule.CloseConnectionAfterError(objHttpApplication.Response);
                        if ((Ex is HttpException) || (Ex is System.Net.WebException))
                        {
                            throw;
                        }
                        else
                        {
                            throw new HttpException(500, Resources.ExceptionUnhandled, Ex);
                        }

                        //objHttpApplication.Response.StatusCode = 500; //Error
                        //objHttpApplication.Response.StatusDescription = Resources.ExceptionUnhandled;
                        //objHttpApplication.Response.Write(String.Format(Resources.Culture, Resources.ErrorPage, 500, Ex.Message));
                        //objHttpApplication.CompleteRequest();
                        //See: http://support.microsoft.com/kb/312629
                        //objHttpApplication.Response.End();
                    }
                    finally
                    {
#if (TRACE)
                        ThreadLog.WriteLine("Disposing of resources");
#endif

                        if (objRequestFilter != null)
                        {
                            objRequestFilter.Dispose();
                        }
                        if (objRequestStream != null)
                        {
                            objRequestStream.Dispose();
                        }

                        if (objUploadData != null)
                        {
                            if (objUploadData.ProgressStatus != UploadProgressStatus.Completed)
                            {
                                this.DeleteUploadFiles(objUploadData.UploadFiles);
                            }

                            //Too soon to release here: let sliding expiration work for us
                            //UploadMonitor.Release(objHttpContext, objUploadData.UploadId);
                        }
                    }
                }
#if (TRACE)
                ThreadLog.WriteLine("Exit OnPreRequestHandlerExecute");
#endif
            }
        }