/// <summary> /// /// </summary> /// <param name="requestFilter"></param> internal MimeParser(RequestFilter requestFilter) { _RequestFilter = requestFilter; //iInstanceCount++; }
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 } }