Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

At random intervals ocelot fails to copy RouteValues from source #1579

Closed
okolvik-avento opened this issue May 28, 2022 · 1 comment
Closed

Comments

@okolvik-avento
Copy link

okolvik-avento commented May 28, 2022

At random intervals (between 6-24 hours) Ocelot fails to copy RouteValues from the source request.
It only happens once, subsequent requests or parallel requests succeeds.
I don't know if this is a Ocelot bug or a framework bug.

Error message:

2022-05-28 19:06:36.363 +02:00 [INF] Request starting HTTP/1.1 GET http://xx/api/language?fields=custObj - -
2022-05-28 19:06:36.363 +02:00 [INF] Remote ip is: xx
2022-05-28 19:06:36.363 +02:00 [INF] Checking ip whitelist for xx
2022-05-28 19:06:36.363 +02:00 [INF] xx - xx/8: False
2022-05-28 19:06:36.363 +02:00 [INF] xx- xx/12: False
2022-05-28 19:06:36.363 +02:00 [INF] xx - xx/16: False
2022-05-28 19:06:36.363 +02:00 [INF] xx - xx/24: True
2022-05-28 19:06:36.363 +02:00 [INF] xx whitelisted
2022-05-28 19:06:36.363 +02:00 [INF] Parsed hostname xx
2022-05-28 19:06:36.365 +02:00 [INF] Api hostname: xx, Api version: 3.0, Url version: 3
2022-05-28 19:06:36.857 +02:00 [ERR] requestId: 80013433-0000-ed00-b63f-84710c7967bb, previousRequestId: no previous request id, message: Exception caught in global error handler, exception message: Object reference not set to an instance of an object., exception stack:    at Microsoft.AspNetCore.Http.DefaultHttpRequest.get_RouteValues()
   at Ocelot.Multiplexer.MultiplexingMiddleware.Copy(HttpContext source)
   at Ocelot.Multiplexer.MultiplexingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.MiddlewareAnalysis.AnalysisMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.MiddlewareAnalysis.AnalysisMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.Responder.Middleware.ResponderMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.MiddlewareAnalysis.AnalysisMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.MiddlewareAnalysis.AnalysisMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.Errors.Middleware.ExceptionHandlerMiddleware.Invoke(HttpContext httpContext) RequestId: 80013433-0000-ed00-b63f-84710c7967bb
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.AspNetCore.Http.DefaultHttpRequest.get_RouteValues()
   at Ocelot.Multiplexer.MultiplexingMiddleware.Copy(HttpContext source)
   at Ocelot.Multiplexer.MultiplexingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.MiddlewareAnalysis.AnalysisMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.MiddlewareAnalysis.AnalysisMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.Responder.Middleware.ResponderMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.MiddlewareAnalysis.AnalysisMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.MiddlewareAnalysis.AnalysisMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.Errors.Middleware.ExceptionHandlerMiddleware.Invoke(HttpContext httpContext)
2022-05-28 19:06:36.888 +02:00 [INF] Request finished HTTP/1.1 GET http://xx/api/language?fields=custObj - - - 500 - - 525.3485ms

ocelot.config:

{
  "Routes": [
    {
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 62212
        }
      ],
      "DownstreamPathTemplate": "/{url}",
      "DownstreamScheme": "http",
      "UpstreamHttpMethod": [ "Get", "Post", "Delete" ],
      "UpstreamPathTemplate": "/{url}",
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "BasicAuthentication",
        "AllowedScopes": []
      },
      "AddHeadersToRequest": {
        "X-xx-Api-Hostname": "Claims[xxHostname] > value"
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://localhost:44364/",
    "RequestIdKey": "OcRequestId"
  }
}

ocelot.development.json:

{
  "Routes": [
    {
      "DownstreamHostAndPorts": [
        {
          "Host": "192.168.197.13",
          "Port": 80
        },
        {
          "Host": "192.168.197.14",
          "Port": 80
        }
      ],
      "LoadBalancerOptions": {
        "Type": "LeastConnection"
      },
      "DownstreamPathTemplate": "/v{apiVersion}-development/{url}",
      "DownstreamScheme": "http",
      "ChangeDownstreamPathTemplate": {
        "apiVersion": "Claims[xxUrlVersion] > value"
      },
      "UpstreamHttpMethod": [ "Get", "Post", "Delete" ],
      "UpstreamPathTemplate": "/{url}",
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "BasicAuthentication",
        "AllowedScopes": []
      },
      "AddHeadersToRequest": {
        "X-xx-Api-Hostname": "Claims[xxHostname] > value",
        "X-xx-Api-Version": "Claims[xxVersion] > value"
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://xxx"
  }
}

Claims:

Version apiVersion = new Version(1,0);
int urlVersion = 2;
if(Request.Headers.ContainsKey("xx-Api-Version"))
{
	Version v;
	if(Version.TryParse(Request.Headers["xx-Api-Version"].ToString(), out v))
	{
		urlVersion = v.Major > 1 ? v.Major : 2;
		apiVersion = v;
	}
}
Logger.LogInformation(string.Format("Api hostname: {0}, Api version: {1}, Url version: {2}", account.ApiHost, apiVersion, urlVersion));

var name = string.IsNullOrEmpty(account.Username) ? account.ApiHost : account.Username;

var claims = new[] {
	new Claim(ClaimTypes.NameIdentifier, account.Id.ToString()),
	new Claim(ClaimTypes.Name, name),
	new Claim("xxHostname", account.ApiHost),
	new Claim("xxUrlVersion", urlVersion.ToString()),
	new Claim("xxVersion", apiVersion.ToString())
};
var identity = new ClaimsIdentity(claims, Scheme.Name);
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, Scheme.Name);

return AuthenticateResult.Success(ticket)
  • Version: 18.0.0
  • Platform: .NET 6
@okolvik-avento
Copy link
Author

Fixed in dotnet/SqlClient#1637

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant