/// <summary> /// Called when a new request commences (but after authentication). /// Preloads the request header and initialises the form stream. /// /// We do this after authentication so that the file processor will /// have access to the security context if it is required. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event args.</param> void Context_AuthenticateRequest(object sender, EventArgs e) { HttpApplication app = sender as HttpApplication; HttpWorkerRequest worker = GetWorkerRequest(app.Context); int bufferSize; string boundary; string ct; bool statusPersisted = false; UploadManager.Instance.ModuleInstalled = true; bufferSize = UploadManager.Instance.BufferSize; ct = worker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType); // Is this a multi-part form which may contain file uploads? if (ct != null && string.Compare(ct, 0, C_MARKER, 0, C_MARKER.Length, true, CultureInfo.InvariantCulture) == 0) { // Get the content length from the header. Don't use Request.ContentLength as this is cached // and we don't want it to be calculated until we're done stripping out the files. long length = long.Parse(worker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength)); if (length > 0) { InitStatus(length); boundary = "--" + ct.Substring(ct.IndexOf(B_MARKER) + B_MARKER.Length); using (FormStream fs = new FormStream(GetProcessor(), boundary, app.Request.ContentEncoding)) { // Set up events fs.FileCompleted += new FileEventHandler(fs_FileCompleted); fs.FileCompletedError += new FileErrorEventHandler(fs_FileCompletedError); fs.FileStarted += new FileEventHandler(fs_FileStarted); byte[] data = null; int read = 0; int counter = 0; if (worker.GetPreloadedEntityBodyLength() > 0) { // Read the first portion of data from the client data = worker.GetPreloadedEntityBody(); fs.Write(data, 0, data.Length); if (!String.IsNullOrEmpty(fs.StatusKey)) { if (!statusPersisted) PersistStatus(fs.StatusKey, length, app, worker); statusPersisted = true; _status.UpdateBytes(data.Length, fs.Processor.GetFileName(), fs.Processor.GetIdentifier()); } counter = data.Length; } bool disconnected = false; // Read data while (counter < length && worker.IsClientConnected() && !disconnected) { // Let other threads work System.Threading.Thread.Sleep(0); if (counter + bufferSize > length) { bufferSize = (int)length - counter; } data = new byte[bufferSize]; read = worker.ReadEntityBody(data, bufferSize); if (read > 0) { counter += read; fs.Write(data, 0, read); if (!String.IsNullOrEmpty(fs.StatusKey)) { if (!statusPersisted) PersistStatus(fs.StatusKey, length, app, worker); statusPersisted = true; _status.UpdateBytes(counter, fs.Processor.GetFileName(), fs.Processor.GetIdentifier()); } } else { disconnected = true; } } if (!worker.IsClientConnected() || disconnected) { app.Context.Response.End(); return; } if (fs.ContentMinusFiles != null) { BindingFlags ba = BindingFlags.Instance | BindingFlags.NonPublic; // Replace the worker process with our own version using reflection UploadWorkerRequest wr = new UploadWorkerRequest(worker, fs.ContentMinusFiles); app.Context.Request.GetType().GetField("_wr", ba).SetValue(app.Context.Request, wr); } // Check that the query key is in the request app.Context.Items[UploadManager.STATUS_KEY] = fs.StatusKey; } } } }
/// <summary> /// Called when a new request commences (but after authentication). /// Preloads the request header and initialises the form stream. /// /// We do this after authentication so that the file processor will /// have access to the security context if it is required. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event args.</param> void Context_AuthenticateRequest(object sender, EventArgs e) { HttpApplication app = sender as HttpApplication; HttpWorkerRequest worker = GetWorkerRequest(app.Context); int bufferSize; string boundary; string ct; bool statusPersisted = false; UploadManager.Instance.ModuleInstalled = true; bufferSize = UploadManager.Instance.BufferSize; ct = worker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType); // Is this a multi-part form which may contain file uploads? if (ct != null && string.Compare(ct, 0, C_MARKER, 0, C_MARKER.Length, true, CultureInfo.InvariantCulture) == 0) { // Get the content length from the header. Don't use Request.ContentLength as this is cached // and we don't want it to be calculated until we're done stripping out the files. long length = long.Parse(worker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength)); if (length > 0) { InitStatus(length); boundary = "--" + ct.Substring(ct.IndexOf(B_MARKER) + B_MARKER.Length); using (FormStream fs = new FormStream(GetProcessor(), boundary, app.Request.ContentEncoding)) { // Set up events fs.FileCompleted += new FileEventHandler(fs_FileCompleted); fs.FileCompletedError += new FileErrorEventHandler(fs_FileCompletedError); fs.FileStarted += new FileEventHandler(fs_FileStarted); byte[] data = null; int read = 0; int counter = 0; if (worker.GetPreloadedEntityBodyLength() > 0) { // Read the first portion of data from the client data = worker.GetPreloadedEntityBody(); fs.Write(data, 0, data.Length); if (!String.IsNullOrEmpty(fs.StatusKey)) { if (!statusPersisted) { PersistStatus(fs.StatusKey, length, app, worker); } statusPersisted = true; _status.UpdateBytes(data.Length, fs.Processor.GetFileName(), fs.Processor.GetIdentifier()); } counter = data.Length; } bool disconnected = false; // Read data while (counter < length && worker.IsClientConnected() && !disconnected) { // Let other threads work System.Threading.Thread.Sleep(0); if (counter + bufferSize > length) { bufferSize = (int)length - counter; } data = new byte[bufferSize]; read = worker.ReadEntityBody(data, bufferSize); if (read > 0) { counter += read; fs.Write(data, 0, read); if (!String.IsNullOrEmpty(fs.StatusKey)) { if (!statusPersisted) { PersistStatus(fs.StatusKey, length, app, worker); } statusPersisted = true; _status.UpdateBytes(counter, fs.Processor.GetFileName(), fs.Processor.GetIdentifier()); } } else { disconnected = true; } } if (!worker.IsClientConnected() || disconnected) { app.Context.Response.End(); return; } if (fs.ContentMinusFiles != null) { BindingFlags ba = BindingFlags.Instance | BindingFlags.NonPublic; // Replace the worker process with our own version using reflection UploadWorkerRequest wr = new UploadWorkerRequest(worker, fs.ContentMinusFiles); app.Context.Request.GetType().GetField("_wr", ba).SetValue(app.Context.Request, wr); } // Check that the query key is in the request app.Context.Items[UploadManager.STATUS_KEY] = fs.StatusKey; } } } }