private void OnAsyncCompletion(IAsyncResult readAsyncResult)
        {
            if (readAsyncResult.CompletedSynchronously)
            {
                return;
            }
            HttpAsyncResult httpAsyncResult = readAsyncResult.AsyncState as HttpAsyncResult;
            Exception       error           = null;

            try {
                int    bytesRead = _inputStream.EndRead(readAsyncResult);
                byte[] buffer    = _app.EntityBuffer;
                // loop to prevent recursive calls and potential stack overflow when it completes synchronously
                while (bytesRead != 0)
                {
                    readAsyncResult = _inputStream.BeginRead(buffer, 0, buffer.Length, _callback, httpAsyncResult);
                    if (!readAsyncResult.CompletedSynchronously)
                    {
                        return;
                    }
                    bytesRead = _inputStream.EndRead(readAsyncResult);
                }
            }
            catch (Exception e) {
                error = e;
            }
            httpAsyncResult.Complete(false, null, error);
        }
        private IAsyncResult OnEnter(Object sender, EventArgs e, AsyncCallback cb, Object state) {
            Debug.Assert(_inputStream == null);
            _app = (HttpApplication)sender;
            HttpContext context = _app.Context;
            HttpRequest request = context.Request;
            HttpWorkerRequest wr = context.WorkerRequest;
            HttpAsyncResult httpAsyncResult = new HttpAsyncResult(cb, state);
            AsyncPreloadModeFlags asyncPreloadMode = context.AsyncPreloadMode;
            int contentLength;
            bool isForm = false;
            bool isFormMultiPart = false;

            if (asyncPreloadMode == AsyncPreloadModeFlags.None
                || request.ReadEntityBodyMode != ReadEntityBodyMode.None
                || wr == null
                || !wr.SupportsAsyncRead
                || !wr.HasEntityBody()
                || wr.IsEntireEntityBodyIsPreloaded()
                || context.Handler == null
                || context.Handler is TransferRequestHandler
                || context.Handler is DefaultHttpHandler
                || (contentLength = request.ContentLength) > RuntimeConfig.GetConfig(context).HttpRuntime.MaxRequestLengthBytes
                || ((isForm = StringUtil.StringStartsWithIgnoreCase(request.ContentType, "application/x-www-form-urlencoded"))
                    && (asyncPreloadMode & AsyncPreloadModeFlags.Form) != AsyncPreloadModeFlags.Form)
                || ((isFormMultiPart = StringUtil.StringStartsWithIgnoreCase(request.ContentType, "multipart/form-data"))
                    && (asyncPreloadMode & AsyncPreloadModeFlags.FormMultiPart) != AsyncPreloadModeFlags.FormMultiPart)
                || !isForm && !isFormMultiPart && (asyncPreloadMode & AsyncPreloadModeFlags.NonForm) != AsyncPreloadModeFlags.NonForm
                ) {
                Debug.Trace("AsyncPreload", " *** AsyncPreload skipped *** ");
                httpAsyncResult.Complete(true, null, null);
                return httpAsyncResult;
            }

            Debug.Trace("AsyncPreload", " *** AsyncPreload started *** ");
            try {
                if (_callback == null) {
                    _callback = new AsyncCallback(OnAsyncCompletion);
                }
                _inputStream = request.GetBufferedInputStream();
                byte[] buffer = _app.EntityBuffer;
                int bytesRead = 0;
                // loop to prevent recursive calls and potential stack overflow if/when it completes synchronously
                do {
                    IAsyncResult readAsyncResult = _inputStream.BeginRead(buffer, 0, buffer.Length, _callback, httpAsyncResult);
                    if (!readAsyncResult.CompletedSynchronously) {
                        return httpAsyncResult;
                    }
                    bytesRead = _inputStream.EndRead(readAsyncResult);
                } while (bytesRead != 0);
            }
            catch {
                Reset();
                throw;
            }
            httpAsyncResult.Complete(true, null, null);
            return httpAsyncResult;
        }
		IAsyncResult OnBeginAcquireState (object o, EventArgs args, AsyncCallback cb, object data)
		{
			HttpApplication application = (HttpApplication) o;
			HttpContext context = application.Context;

			bool required = (context.Handler is IRequiresSessionState);
			
			// This is a hack. Sites that use Session in global.asax event handling code
			// are not supposed to get a Session object for static files, but seems that
			// IIS handles those files before getting there and thus they are served without
			// error.
			// As a workaround, setting MONO_XSP_STATIC_SESSION variable make this work
			// on mono, but you lose performance when serving static files.
			if (sessionForStaticFiles && context.Handler is StaticFileHandler)
				required = true;
			// hack end

			bool read_only = (context.Handler is IReadOnlySessionState);
			
			bool isNew = false;
			HttpSessionState session = null;
			if (handler != null)
				session = handler.UpdateContext (context, this, required, read_only, ref isNew);

			if (session != null) {
				if (isNew)
					session.SetNewSession (true);

				if (read_only)
					session = session.Clone ();
					
				context.SetSession (session);

				if (isNew && config.CookieLess) {
					string id = context.Session.SessionID;
					context.Request.SetHeader (HeaderName, id);
					context.Response.Redirect (UrlUtils.InsertSessionId (id,
								   context.Request.FilePath));
				} else if (isNew) {
					string id = context.Session.SessionID;
					HttpCookie cookie = new HttpCookie (CookieName, id);
					cookie.Path = UrlUtils.GetDirectory (context.Request.ApplicationPath);
					context.Response.AppendCookie (cookie);
				}
			}
			
			// In the future, we might want to move the Async stuff down to
			// the interface level, if we're going to support other than
			// InProc, we might actually want to do things async, now we
			// simply fake it.
			HttpAsyncResult result=new HttpAsyncResult (cb,this);
			result.Complete (true, o, null);
			if (isNew && Start != null)
				Start (this, args);

			return result;
		}
		IAsyncResult OnBeginRequestCache (object o, EventArgs args, AsyncCallback cb, object data)
		{
			HttpApplication app = (HttpApplication) o;
			HttpContext context = app.Context;
			
			string vary_key = context.Request.FilePath;
			CachedVaryBy varyby = context.Cache [vary_key] as CachedVaryBy;
			string key;
			CachedRawResponse c;

			if (varyby == null)
				goto leave;

			key = varyby.CreateKey (vary_key, context);
			c = context.Cache [key] as CachedRawResponse;
			
			if (c != null) {
				
				context.Response.ClearContent ();
				context.Response.BinaryWrite (c.GetData (), 0, c.ContentLength);

				context.Response.ClearHeaders ();
				c.DateHeader.Value = TimeUtil.ToUtcTimeString (DateTime.Now);
				context.Response.SetCachedHeaders (c.Headers);

				context.Response.StatusCode = c.StatusCode;
				context.Response.StatusDescription = c.StatusDescription;
				
				app.CompleteRequest ();
			} 

		leave:
			HttpAsyncResult result = new HttpAsyncResult (cb,this);
			result.Complete (true, o, null);
			
			return result;
		}
		IAsyncResult OnBeginUpdateCache (object o, EventArgs args, AsyncCallback cb, object data)
		{
			HttpApplication app = (HttpApplication) o;
			HttpContext context = app.Context;
			HttpAsyncResult result;

			if (context.Response.IsCached && context.Response.StatusCode == 200 && 
			    !context.Trace.IsEnabled)
				DoCacheInsert (context);

			result = new HttpAsyncResult (cb, this);
			result.Complete (true, o, null);
			return result;
		}
Ejemplo n.º 6
0
    internal /*public*/ IAsyncResult BeginAspCompatExecution(AsyncCallback cb, object extraData) {
        SynchronizationContextUtil.ValidateModeForAspCompat();

        if (IsInAspCompatMode) {
            // already in AspCompatMode -- execute synchronously
            bool sync = true;
            Exception error = _app.ExecuteStep(this, ref sync);
            _ar = new HttpAsyncResult(cb, extraData, true, null, error);
            _syncCaller = true;
        }
        else {
            _ar = new HttpAsyncResult(cb, extraData);
            _syncCaller = (cb == null);
            _rootedThis = GCHandle.Alloc(this);

            // send requests from the same session to the same STA thread
            bool sharedActivity = (_sessionId != null);
            int    activityHash = sharedActivity ? _sessionId.GetHashCode() : 0;

            if (UnsafeNativeMethods.AspCompatProcessRequest(_execCallback, this, sharedActivity, activityHash) != 1) {
                // failed to queue up the execution in ASP compat mode
                _rootedThis.Free();
                _ar.Complete(true, null, new HttpException(SR.GetString(SR.Cannot_access_AspCompat)));
            }
        }

        return _ar;
    }
        private IAsyncResult OnEnter(Object sender, EventArgs e, AsyncCallback cb, Object state)
        {
            Debug.Assert(_inputStream == null);
            _app = (HttpApplication)sender;
            HttpContext           context          = _app.Context;
            HttpRequest           request          = context.Request;
            HttpWorkerRequest     wr               = context.WorkerRequest;
            HttpAsyncResult       httpAsyncResult  = new HttpAsyncResult(cb, state);
            AsyncPreloadModeFlags asyncPreloadMode = context.AsyncPreloadMode;
            int  contentLength;
            bool isForm          = false;
            bool isFormMultiPart = false;

            if (asyncPreloadMode == AsyncPreloadModeFlags.None ||
                request.ReadEntityBodyMode != ReadEntityBodyMode.None ||
                wr == null ||
                !wr.SupportsAsyncRead ||
                !wr.HasEntityBody() ||
                wr.IsEntireEntityBodyIsPreloaded() ||
                context.Handler == null ||
                context.Handler is TransferRequestHandler ||
                context.Handler is DefaultHttpHandler ||
                (contentLength = request.ContentLength) > RuntimeConfig.GetConfig(context).HttpRuntime.MaxRequestLengthBytes ||
                ((isForm = StringUtil.StringStartsWithIgnoreCase(request.ContentType, "application/x-www-form-urlencoded")) &&
                 (asyncPreloadMode & AsyncPreloadModeFlags.Form) != AsyncPreloadModeFlags.Form) ||
                ((isFormMultiPart = StringUtil.StringStartsWithIgnoreCase(request.ContentType, "multipart/form-data")) &&
                 (asyncPreloadMode & AsyncPreloadModeFlags.FormMultiPart) != AsyncPreloadModeFlags.FormMultiPart) ||
                !isForm && !isFormMultiPart && (asyncPreloadMode & AsyncPreloadModeFlags.NonForm) != AsyncPreloadModeFlags.NonForm
                )
            {
                Debug.Trace("AsyncPreload", " *** AsyncPreload skipped *** ");
                httpAsyncResult.Complete(true, null, null);
                return(httpAsyncResult);
            }

            Debug.Trace("AsyncPreload", " *** AsyncPreload started *** ");
            try {
                if (_callback == null)
                {
                    _callback = new AsyncCallback(OnAsyncCompletion);
                }
                _inputStream = request.GetBufferedInputStream();
                byte[] buffer    = _app.EntityBuffer;
                int    bytesRead = 0;
                // loop to prevent recursive calls and potential stack overflow if/when it completes synchronously
                do
                {
                    IAsyncResult readAsyncResult = _inputStream.BeginRead(buffer, 0, buffer.Length, _callback, httpAsyncResult);
                    if (!readAsyncResult.CompletedSynchronously)
                    {
                        return(httpAsyncResult);
                    }
                    bytesRead = _inputStream.EndRead(readAsyncResult);
                } while (bytesRead != 0);
            }
            catch {
                Reset();
                throw;
            }
            httpAsyncResult.Complete(true, null, null);
            return(httpAsyncResult);
        }