public override int ReadEntityBody(byte[] buffer, int size) { if (log.IsDebugEnabled) { log.Debug("In ReadEntityBody() with size=" + size); } int bytesRead = OrigWorker.ReadEntityBody(buffer, size); totalBytesRead += bytesRead; byte[] preloadedEntityBody = OrigWorker.GetPreloadedEntityBody(); int bytesPreloaded = 0; if (preloadedEntityBody != null) { bytesPreloaded = preloadedEntityBody.Length; } if (totalBytesRead + bytesPreloaded > maxRequestLength) { IgnoreRemainingBodyAndThrow(new HttpException(413, "Request Entity Too Large")); } return(bytesRead); }
private bool ParseOrThrow() { origPreloadedBody = OrigWorker.GetPreloadedEntityBody(); string contentTypeHeader = OrigWorker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType); string contentLengthHeader = OrigWorker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength); string transferEncodingHeader = OrigWorker.GetKnownRequestHeader(HttpWorkerRequest.HeaderTransferEncoding); if (contentLengthHeader != null) { origContentLength = Int64.Parse(contentLengthHeader); } if (Config.Current.DebugDirectory != null) { string logEntityBodyBaseName = Path.Combine(Config.Current.DebugDirectory.FullName, DateTime.Now.Ticks.ToString()); LogEntityBodyStream = File.Create(logEntityBodyBaseName + ".body"); LogEntityBodySizesStream = File.CreateText(logEntityBodyBaseName + ".sizes"); LogEntityBodySizesStream.WriteLine(contentTypeHeader); LogEntityBodySizesStream.WriteLine(contentLengthHeader); if (origPreloadedBody != null) { LogEntityBodyStream.Write(origPreloadedBody, 0, origPreloadedBody.Length); LogEntityBodySizesStream.WriteLine(origPreloadedBody.Length); } else { LogEntityBodySizesStream.WriteLine(0); } } FieldNameTranslator translator = new FieldNameTranslator(); if (MultiRequestControlID == null && UploadState != null) { UploadState.BytesTotal += origContentLength; } if (log.IsDebugEnabled) { log.Debug("=" + contentLengthHeader + " -> " + origContentLength); } boundary = System.Text.Encoding.ASCII.GetBytes("--" + GetAttribute(contentTypeHeader, "boundary")); if (log.IsDebugEnabled) { log.Debug("boundary=" + System.Text.Encoding.ASCII.GetString(boundary)); } string charset = GetAttribute(contentTypeHeader, "charset"); if (charset != null) { try { System.Text.Encoding encoding = System.Text.Encoding.GetEncoding(charset); ContentEncoding = encoding; } catch (NotSupportedException) { if (log.IsDebugEnabled) { log.Debug("Ignoring unsupported charset " + charset + ". Using utf-8."); } } } else { ContentEncoding = HttpContext.Current.Response.ContentEncoding; } preloadedEntityBodyStream = new MemoryStream(); Hashtable storageConfigStreamTable = new Hashtable(); Stream postBackIDStream = null; outputStream = preloadedEntityBodyStream; readPos = writePos = parsePos = 0; while (CopyUntilBoundary()) { // If we were writing to a file, close it if (outputStream == fileStream && outputStream != null) { UploadState.Files.Add(controlID, uploadedFile); outputStream.Close(); } // If we were receiving the value generated by the HiddenPostBackID control, set the postback ID. if (postBackIDStream != null) { postBackIDStream.Seek(0, System.IO.SeekOrigin.Begin); StreamReader sr = new System.IO.StreamReader(postBackIDStream); translator.PostBackID = sr.ReadToEnd(); postBackIDStream = null; } // parse the headers string name = null, fileName = null, contentType = null; if (boundary[0] != (byte)'\r') { byte[] newBoundary = new byte[boundary.Length + 2]; Buffer.BlockCopy(boundary, 0, newBoundary, 2, boundary.Length); newBoundary[0] = (byte)'\r'; newBoundary[1] = (byte)'\n'; boundary = newBoundary; } else { GetLine(); // Blank line } GetLine(); // boundary line string header; while (null != (header = GetLine())) { if (log.IsDebugEnabled) { log.Debug("header=" + header); } int colonPos = header.IndexOf(':'); if (colonPos < 0) { break; } string headerName = header.Substring(0, colonPos); if (String.Compare(headerName, "Content-Disposition", true) == 0) { name = GetAttribute(header, "name"); fileName = GetAttribute(header, "filename"); } else if (String.Compare(headerName, "Content-Type", true) == 0) { contentType = header.Substring(colonPos + 1).Trim(); } } if (log.IsDebugEnabled) { log.Debug("name = " + name); } if (log.IsDebugEnabled) { log.Debug("fileName = " + fileName); } if (log.IsDebugEnabled) { log.DebugFormat("name = " + name); } if (log.IsDebugEnabled) { log.DebugFormat("fileName = " + fileName); } controlID = null; if (name == Config.Current.PostBackIDQueryParam && postBackIDStream == null) { postBackIDStream = outputStream = new System.IO.MemoryStream(); readPos = parsePos; // Skip past the boundary and headers } else if (name != null && null != (controlID = translator.ConfigFieldNameToControlID(name))) { storageConfigStreamTable[controlID] = outputStream = new System.IO.MemoryStream(); readPos = parsePos; // Skip past the boundary and headers } else if (name != null && null != (controlID = translator.FileFieldNameToControlID(name))) { if (log.IsDebugEnabled) { log.DebugFormat("name != null && controlID != null"); } if (UploadState == null) { UploadState = UploadStateStore.OpenReadWriteOrCreate(translator.FileFieldNameToPostBackID(name)); if (transferEncodingHeader != "chunked") { UploadState.Status = UploadStatus.NormalInProgress; } else { UploadState.Status = UploadStatus.ChunkedInProgress; } UploadState.BytesTotal += origContentLength; UploadState.BytesRead += grandTotalBytesRead; } UploadStorageConfig storageConfig = null; if (UploadState.MultiRequestObject != null) { string secureStorageConfigString = UploadState.MultiRequestObject as string; if (secureStorageConfigString != null) { storageConfig = UploadStorage.CreateUploadStorageConfig(); storageConfig.Unprotect(secureStorageConfigString); if (log.IsDebugEnabled) { log.DebugFormat("storageConfig[tempDirectory]={0}", storageConfig["tempDirectory"]); } } } string configID = translator.FileIDToConfigID(controlID); MemoryStream storageConfigStream = storageConfigStreamTable[configID] as MemoryStream; if (storageConfigStream != null) { storageConfigStream.Seek(0, System.IO.SeekOrigin.Begin); StreamReader sr = new System.IO.StreamReader(storageConfigStream); string secureStorageConfigString = sr.ReadToEnd(); if (log.IsDebugEnabled) { log.Debug("storageConfigStream = " + secureStorageConfigString); } storageConfig = UploadStorage.CreateUploadStorageConfig(); storageConfig.Unprotect(secureStorageConfigString); // Write out a part for the config hidden field if (log.IsDebugEnabled) { log.DebugFormat("Calling WriteReplacementFormField({0}, {1})", configID, secureStorageConfigString); } WriteReplacementFormField(configID, secureStorageConfigString); // Remove the stream from the table, so we don't write the replacement field again. storageConfigStreamTable.Remove(configID); } if (fileName != null) { if (log.IsDebugEnabled) { log.DebugFormat("filename != null"); } if (log.IsDebugEnabled) { log.Debug("Calling UploadContext.Current.CreateUploadedFile(" + controlID + "...)"); } UploadContext tempUploadContext = new UploadContext(); tempUploadContext._ContentLength = origContentLength; uploadedFile = UploadStorage.CreateUploadedFile(tempUploadContext, controlID, fileName, contentType, storageConfig); if (MultiRequestControlID == null) { UploadStorage.DisposeAtEndOfRequest(uploadedFile); } outputStream = fileStream = uploadedFile.CreateStream(); UploadState.CurrentFileName = uploadedFile.FileName; readPos = parsePos; // Skip past the boundary and headers // If the client-specified content length is too large, we set the status to // RejectedRequestTooLarge so that progress displays will stop. We do this after // having created the UploadedFile because that is necessary for the progress display // to find the uploadContext. if (origContentLength > UploadHttpModule.MaxRequestLength) { if (log.IsDebugEnabled) { log.Debug("contentLength > MaxRequestLength"); } throw new UploadTooLargeException(UploadHttpModule.MaxRequestLength, origContentLength); } // Write out a replacement part that just contains the filename as the value. WriteReplacementFormField(controlID, fileName); } else { if (log.IsDebugEnabled) { log.DebugFormat("filename == null"); } // Since filename==null this must just be a hidden field with a name that // looks like a file field. It is just an indication that when this request // ends, the associated uploaded files should be disposed. if (MultiRequestControlID == null) { if (log.IsDebugEnabled) { log.DebugFormat("MultiRequestControlID == null"); } RegisterFilesForDisposal(controlID); } outputStream = preloadedEntityBodyStream; } } else { outputStream = preloadedEntityBodyStream; } } if (log.IsDebugEnabled) { log.Debug("Done parsing."); } outputStream.WriteByte(10); outputStream.Close(); preloadedEntityBody = preloadedEntityBodyStream.ToArray(); preloadedEntityBodyStream = null; if (grandTotalBytesRead < origContentLength) { return(false); } return(true); }