public WorkflowState Provider(WorkflowContinuation <ContextWrapper> workflowContinuation, ContextWrapper wrapper) { Session session; IPAddress endpointAddress = wrapper.Context.EndpointAddress(); if (!sessionMap.TryGetValue(endpointAddress, out session)) { session = new Session(endpointAddress); session[CsrfTokenName] = Guid.NewGuid().ToString(); sessionMap[endpointAddress] = session; } else { // If the session exists, set the expired flag before we update the last connection date/time. // Once set, stays set until explicitly cleared. session.Expired |= session.IsExpired(ExpireInSeconds); } wrapper.Session = session; session.UpdateLastConnectionTime(); WorkflowState ret = CheckExpirationAndAuthorization(workflowContinuation, wrapper, session); return(ret); }
protected WorkflowState CheckExpirationAndAuthorization(WorkflowContinuation <ContextWrapper> workflowContinuation, ContextWrapper wrapper, Session session) { // Inspect the route to see if we should do session expiration and/or session authorization checks. WorkflowState ret = WorkflowState.Continue; RouteEntry entry = null; PathParams parms = null; if (routeTable.TryGetRouteEntry(wrapper.Context.Verb(), wrapper.Context.Path(), out entry, out parms)) { if (entry.SessionExpirationHandler != null) { ret = entry.SessionExpirationHandler(workflowContinuation, wrapper, session, parms); } if (ret == WorkflowState.Continue) { if (entry.AuthorizationHandler != null) { ret = entry.AuthorizationHandler(workflowContinuation, wrapper, session, parms); } } } return(ret); }
/// <summary> /// A workflow item implementing the ContextWrapper handler. /// </summary> public WorkflowState Process(WorkflowContinuation <ContextWrapper> workflowContinuation, ContextWrapper context) { // Create a workflow context and queue it. requests.Enqueue(new WorkflowContext(workflowContinuation, context)); semQueue.Release(); return(WorkflowState.Defer); }
/// <summary> /// A workflow item implementing the HttpListenerContext handler. /// </summary> public WorkflowState Process(WorkflowContinuation <HttpListenerContext> workflowContinuation, HttpListenerContext context) { // Create a workflow context and queue it. requests.Enqueue(new WorkflowContext(workflowContinuation, context)); semQueue.Release(); return(WorkflowState.Defer); }
/// <summary> /// Continue a deferred workflow, unless it is aborted. /// </summary> public void Continue(WorkflowContinuation <T> wc, T data) { if (!wc.Abort) { wc.Defer = false; InternalContinue(wc, data); } }
/// <summary> /// Continue a deferred workflow, unless it is aborted. /// </summary> public void Continue(WorkflowContinuation <T> wc, T data) { // TODO: Throw exception instead? if ((!wc.Abort) && (!wc.Done)) { wc.Defer = false; InternalContinue(wc, data); } }
/// <summary> /// Route the request. If no route exists, the workflow continues, otherwise, we return the route handler's continuation state. /// </summary> public WorkflowState Route(WorkflowContinuation <HttpListenerContext> workflowContinuation, HttpListenerContext context) { WorkflowState ret = WorkflowState.Continue; RouteEntry entry = null; if (routeTable.TryGetRouteEntry(context.Verb(), context.Path(), out entry)) { if (entry.RouteProvider != null) { ret = entry.RouteProvider(workflowContinuation, context); } } return(ret); }
/// <summary> /// Internally, we execute workflow steps until: /// 1. we reach the end of the workflow chain /// 2. we are instructed to abort the workflow /// 3. we are instructed to defer execution until later. /// </summary> protected void InternalContinue(WorkflowContinuation <T> wc, T data) { while ((wc.WorkflowStep < items.Count) && !wc.Abort && !wc.Defer && !wc.Done) { try { WorkflowState state = items[wc.WorkflowStep++].Execute(wc, data); switch (state) { case WorkflowState.Abort: wc.Abort = true; wc.Workflow.AbortHandler(data); break; case WorkflowState.Defer: wc.Defer = true; break; case WorkflowState.Done: wc.Done = true; break; } } catch (Exception ex) { // Yes, the user's exception handler could itself through an exception // from which we need to protect ourselves. try { wc.Workflow.ExceptionHandler(data, ex); } catch { /* Now what? */ } // TODO: Should we use a different flag, like "Exception"? Can't be Abort, as this invokes an app-specific handler. wc.Done = true; } } if (wc.Defer) { // Synchronization, we're done with this loop and the workflow can now continue on another thread. wc.Deferred = true; } }
/// <summary> /// Route the request. If no route exists, the workflow continues, otherwise, we return the route handler's continuation state. /// </summary> public WorkflowState Route(WorkflowContinuation <ContextWrapper> workflowContinuation, ContextWrapper wrapper) { WorkflowState ret = WorkflowState.Continue; RouteEntry entry = null; Session session = sessionManager != null ? sessionManager[wrapper.Context] : null; PathParams parms = null; // Makes debugging easier to declare these variable here. string verb = wrapper.Context.Verb(); string path = wrapper.Context.Path(); if (routeTable.TryGetRouteEntry(verb, path, wrapper.Context.Request.ContentType, out entry, out parms)) { if (entry.RouteHandler != null) { ret = entry.RouteHandler(workflowContinuation, wrapper, session, parms); } } return(ret); }
public WorkflowState GetContent(WorkflowContinuation <ContextWrapper> workflowContinuation, ContextWrapper wrapper) { // Only try to get the file if we DO NOT have a pending page response that some route handler or other workflow step created. if (wrapper.PendingResponse == null) { // Get the request. HttpListenerRequest request = wrapper.Context.Request; HttpListenerResponse response = wrapper.Context.Response; // Get the path, everything up to the first ? and excluding the leading "/" string path = wrapper.Context.Path(); string ext = wrapper.Context.Extension(); // Console.WriteLine(path); // Default to index.html if only the URL is provided with no additional page information. if (String.IsNullOrEmpty(path)) { path = "index.html"; ext = "html"; } if (String.IsNullOrEmpty(ext)) { path = path + ".html"; } path = websitePath + "\\" + path; FileExtensionHandler extHandler; if (extensionLoaderMap.TryGetValue(ext, out extHandler)) { extHandler.Loader(wrapper, path, ext); wrapper.PendingResponse.MimeType = extHandler.ContentType; } } return(WorkflowState.Continue); }
public WorkflowState GetContent(WorkflowContinuation <HttpListenerContext> workflowContinuation, HttpListenerContext context) { // Get the request. HttpListenerRequest request = context.Request; HttpListenerResponse response = context.Response; // Get the path, everything up to the first ? and excluding the leading "/" string path = context.Path(); string ext = context.Extension(); // Default to index.html if only the URL is provided with no additional page information. if (String.IsNullOrEmpty(path)) { path = "index.html"; ext = "html"; } if (String.IsNullOrEmpty(ext)) { path = path + ".html"; } path = websitePath + "\\" + path; FileExtensionHandler extHandler; if (extensionLoaderMap.TryGetValue(ext, out extHandler)) { byte[] data = extHandler.Loader(context, path, ext); response.ContentEncoding = Encoding.UTF8; context.Response.ContentType = extHandler.ContentType; context.Response.ContentLength64 = data.Length; context.Response.OutputStream.Write(data, 0, data.Length); response.StatusCode = 200; // OK response.OutputStream.Close(); } return(WorkflowState.Done); }
protected WorkflowState CheckExpirationAndAuthorization(WorkflowContinuation <HttpListenerContext> workflowContinuation, HttpListenerContext context, Session session) { // Inspect the route to see if we should do session expiration and/or session authorization checks. WorkflowState ret = WorkflowState.Continue; RouteEntry entry = null; if (routeTable.TryGetRouteEntry(context.Verb(), context.Path(), out entry)) { if (entry.SessionExpirationProvider != null) { ret = entry.SessionExpirationProvider(workflowContinuation, context, session); } if (ret == WorkflowState.Continue) { if (entry.AuthorizationProvider != null) { ret = entry.AuthorizationProvider(workflowContinuation, context, session); } } } return(ret); }
public WorkflowContext(WorkflowContinuation <ContextWrapper> workflowContinuation, ContextWrapper context) { this.workflowContinuation = workflowContinuation; this.context = context; }
/// <summary> /// Execute the workflow item method. /// </summary> public WorkflowState Execute(WorkflowContinuation <T> workflowContinuation, T data) { return(doWork(workflowContinuation, data)); }
public WorkflowContext(WorkflowContinuation <HttpListenerContext> workflowContinuation, HttpListenerContext context) { this.workflowContinuation = workflowContinuation; this.context = context; }
/// <summary> /// Execute the workflow from the beginning. /// </summary> public void Execute(T data) { WorkflowContinuation <T> continuation = new WorkflowContinuation <T>(this); InternalContinue(continuation, data); }