Skip to content

Commit

Permalink
Fix HttpEndpointMiddleware to return 404 when workflow not found
Browse files Browse the repository at this point in the history
Fixes #1253
  • Loading branch information
sfmskywalker committed Jul 14, 2021
1 parent dbb91a8 commit 2635115
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ public static class ApplicationBuilderExtensions
{
public static IApplicationBuilder UseHttpActivities(this IApplicationBuilder app)
{
var options = app.ApplicationServices.GetRequiredService<IOptions<HttpActivityOptions>>().Value;
var basePath = options.BasePath;

return basePath != null
? app.Map(basePath.Value, branch => branch.UseMiddleware<HttpEndpointMiddleware>())
: app.UseMiddleware<HttpEndpointMiddleware>();
return app.UseMiddleware<HttpEndpointMiddleware>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
using Elsa.Activities.Http.Bookmarks;
using Elsa.Activities.Http.Extensions;
using Elsa.Activities.Http.Models;
using Elsa.Activities.Http.Options;
using Elsa.Activities.Http.Parsers.Request;
using Elsa.Activities.Http.Services;
using Elsa.Persistence;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Open.Linq.AsyncExtensions;

Expand All @@ -28,16 +30,31 @@ public class HttpEndpointMiddleware

public async Task InvokeAsync(
HttpContext httpContext,
IOptions<HttpActivityOptions> options,
IWorkflowLaunchpad workflowLaunchpad,
IWorkflowInstanceStore workflowInstanceStore,
IWorkflowRegistry workflowRegistry,
IWorkflowBlueprintReflector workflowBlueprintReflector,
IEnumerable<IHttpRequestBodyParser> contentParsers)
{
var basePath = options.Value.BasePath;
var request = httpContext.Request;

// If a base path was configured, try to match against that first.
if (basePath != null)
{
// If no match, continue with the next middleware in the pipeline.
if (!request.Path.StartsWithSegments(basePath.Value))
{
await _next(httpContext);
return;
}
}

var cancellationToken = CancellationToken.None; // Prevent half-way request abortion (which also happens when WriteHttpResponse writes to the response).
var path = httpContext.Request.Path.Value.ToLowerInvariant();
var method = httpContext.Request.Method!.ToLowerInvariant();
var request = httpContext.Request;

request.TryGetCorrelationId(out var correlationId);

const string activityType = nameof(HttpEndpoint);
Expand All @@ -47,14 +64,23 @@ public class HttpEndpointMiddleware

if (!pendingWorkflows.Any())
{
// If a base path was configured, we are sure the requester tried to execute a workflow that doesn't exist.
// Therefore, sending a 404 response seems appropriate instead of continuing with any subsequent middlewares.
if (basePath != null)
{
httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
return;
}

// If no base path was configured on the other hand, the request could be targeting anything else and should be handled by subsequent middlewares.
await _next(httpContext);
return;
}

if (pendingWorkflows.Count > 1)
{
httpContext.Response.ContentType = "application/json";
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
httpContext.Response.StatusCode = (int) HttpStatusCode.InternalServerError;

var responseContent = JsonConvert.SerializeObject(new
{
Expand All @@ -67,7 +93,7 @@ public class HttpEndpointMiddleware
}

var pendingWorkflow = pendingWorkflows.Single();
var pendingWorkflowInstance = await workflowInstanceStore.FindByIdAsync(pendingWorkflow.WorkflowInstanceId);
var pendingWorkflowInstance = await workflowInstanceStore.FindByIdAsync(pendingWorkflow.WorkflowInstanceId, cancellationToken);
if (pendingWorkflowInstance is null)
{
await _next(httpContext);
Expand Down Expand Up @@ -108,7 +134,7 @@ public class HttpEndpointMiddleware
await workflowLaunchpad.DispatchPendingWorkflowAsync(pendingWorkflow, inputModel, cancellationToken);

httpContext.Response.ContentType = "application/json";
httpContext.Response.StatusCode = (int)HttpStatusCode.Accepted;
httpContext.Response.StatusCode = (int) HttpStatusCode.Accepted;
await httpContext.Response.WriteAsync(JsonConvert.SerializeObject(pendingWorkflows), cancellationToken);
}
else
Expand All @@ -121,7 +147,7 @@ public class HttpEndpointMiddleware
&& !httpContext.Response.HasStarted)
{
httpContext.Response.ContentType = "application/json";
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
httpContext.Response.StatusCode = (int) HttpStatusCode.InternalServerError;

var faultedResponse = JsonConvert.SerializeObject(new
{
Expand Down

0 comments on commit 2635115

Please sign in to comment.