Example #1
0
        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);
        }
Example #2
0
        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();
                }
            }
        }