private int ReadOrigEntityBody(byte[] destBuf, int count) { // If the upload was cancelled, return a 204 error code which tells the client that it // "SHOULD NOT change its document view from that which caused the request to be sent" (RFC 2616 10.2.5) if (UploadState != null && UploadState.Status == UploadStatus.Cancelled) { throw new HttpException(204, "Upload cancelled by user"); } double secsToWait = 0; if (UploadState != null && Config.Current.MaxUploadRate > 0 && UploadState.TimeElapsed != TimeSpan.MinValue) { double desiredSecs = ((double)UploadState.BytesRead) / Config.Current.MaxUploadRate; secsToWait = Math.Max(0, desiredSecs - UploadState.TimeElapsed.TotalSeconds); } // NOTE: if secsToWait = 0, this will simply yield to other threads so that the progress bar // has a chance to update. System.Threading.Thread.Sleep((int)(1000 * secsToWait)); int totalRead = 0; if (origPreloadedBody != null) { int read = Math.Min(count, origPreloadedBody.Length - origPreloadedBodyPos); if (read > 0) { Buffer.BlockCopy(origPreloadedBody, origPreloadedBodyPos, destBuf, totalRead, read); } origPreloadedBodyPos += read; if (read < count) { origPreloadedBody = null; } count -= read; totalRead += read; } if (count > 0) { byte[] localBuffer = new byte[count]; int read = OrigWorker.ReadEntityBody(localBuffer, count); if (Config.Current.DebugDirectory != null) { LogEntityBodyStream.Write(localBuffer, 0, read); LogEntityBodySizesStream.WriteLine(read); } if (read > 0) { Buffer.BlockCopy(localBuffer, 0, destBuf, totalRead, read); } totalRead += read; } return(totalRead); }
internal void ParseMultipart() { if (isParsed) { return; } isParsed = true; try { bool readEntireRequest = ParseOrThrow(); if (!readEntireRequest) { // Wait 5 seconds to see if the user cancelled the request. System.Threading.Thread.Sleep(5000); // Setting the status to Failed will force a MergeAndSave which // will change the status to Cancelled if the user cancelled // the request. UploadState.Status = UploadStatus.Failed; // If the user did cancel the request, then stop all further // processing of the request so that no exceptions are logged. if (UploadState.Status == UploadStatus.Cancelled) { // Make sure that all the files associated // with a cancelled multi-request upload get disposed. if (MultiRequestControlID != null) { RegisterFilesForDisposal(MultiRequestControlID); UploadStorage.DisposeAtEndOfRequest(uploadedFile); } HttpContext.Current.ApplicationInstance.CompleteRequest(); return; } bool isClientConnected = false; try { isClientConnected = OrigWorker.IsClientConnected(); } catch (Exception) { // Mono throws an exception if the client is no longer connected. } if (isClientConnected) { throw new HttpException(400, String.Format("Data length ({0}) is shorter than Content-Length ({1}) and client is still connected after {2} secs.", grandTotalBytesRead, origContentLength, Math.Round(UploadState.TimeElapsed.TotalSeconds))); } else { throw new HttpException(400, String.Format("Client disconnected after receiving {0} of {1} bytes in {2} secs -- user probably cancelled upload.", grandTotalBytesRead, origContentLength, Math.Round(UploadState.TimeElapsed.TotalSeconds))); } } } catch (Exception ex) { if (UploadState != null) { // We need to remember the exception here because the // FormsAuthenticationHttpModule in ASP.NET 1.1 will eat any exception we throw and // the UploadHttpModule's RememberError handler will not get called. this.Exception = ex; if (ex is UploadException) { UploadState.Rejection = (UploadException)ex; UploadState.Status = UploadStatus.Rejected; // Wait 5 seconds to give the client a chance to stop the request. If the client // stops the request, the user will see the original form instead of an error page. // Regardless, the progress display will show the error so the user knows what went wrong. System.Threading.Thread.Sleep(5000); } else if (UploadState.Status != UploadStatus.Cancelled) { UploadState.Failure = ex; UploadState.Status = UploadStatus.Failed; } // If an error occurs during the upload of one file during // a multi-request upload, make sure that all the files associated // with that upload get disposed. if (MultiRequestControlID != null) { RegisterFilesForDisposal(MultiRequestControlID); UploadStorage.DisposeAtEndOfRequest(uploadedFile); } } try { byte[] buffer = new byte[4096]; while (0 < OrigWorker.ReadEntityBody(buffer, buffer.Length)) { ; // Ignore the remaining body } } catch (Exception) { // Ignore any errors that occur in the process. } log.Error("Rethrowing exception", ex); throw; } finally { if (fileStream != null) { fileStream.Close(); } if (preloadedEntityBodyStream != null) { preloadedEntityBodyStream.Close(); } if (LogEntityBodyStream != null) { LogEntityBodyStream.Close(); } if (LogEntityBodySizesStream != null) { LogEntityBodySizesStream.Close(); } } }