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

Some clients can't connect as 'Route Not Found' due to PatternParser class behavior. #216

Closed
longlongago-k opened this issue Nov 4, 2020 · 9 comments
Labels
more-information-needed Needs more information before issue can be resolved

Comments

@longlongago-k
Copy link

I'm trying to connect to Grapevine server from two type clients.

  1. curl in linux is successfully connect.
  2. Network utility in the certain embedded device.

The client (2) can't connect due to URL filter in Grapevine RoutingTable.
As far as I investigated HttpRequest for two clients, I found some differences:

Request URL: http://192.168.14.3:8080/the_endpoint


  1. Request {Grapevine.Interfaces.Server.HttpRequest} of client 'curl'
  • Name "GET /the_endpoint"
  • PathInfo "/the_endpoint"
  • RawUrl "/the_endpoint"

  1. Request {Grapevine.Interfaces.Server.HttpRequest} of client 'embedded device'

I tried URL search pattern such as following:

[RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "the_endpoint/*.*")]
public IHttpContext Exec(IHttpContext context){}

But, current behavior of PatternParser used in RoutingTable, always insert ^ at the beginning of URL search pattern.
PathInfoPattern = "the_endpoint/." ---> "^the_endpoint/."

Could you please consider to user can change this adding '^' behavior?

@scottoffen
Copy link
Owner

@longlongago-k I'm more curious about why the HttpListener implementation on the embedded device puts the protocol, host and port in the RawUrl property. I don't have an embedded system to test this on. Is there an emulator you are aware of that I could use to do some testing with?

@scottoffen
Copy link
Owner

scottoffen commented Jan 4, 2021

The documentation for the RawUrl property of the HttpListenerRequest class states:

Gets the URL information (without the host and port) requested by the client.

The difference between the PathInfo property and the RawUrl property is that the latter includes the query string while the former does not. To calculate the PathInfo property, the RawUrl is split by the ? character and the first string in the returned array is assigned to the PathInfo.

Ergo, the problem you are experiencing has something to do with the fact that the RawUrl includes the host and port, which it should not. If you can provide me with a way to duplicate this issue on my end, I'd be happy to take another look, but until such time I am closing this issue.

@longlongago-k
Copy link
Author

longlongago-k commented Jan 5, 2021

@scottoffen
Hi, I investigated this issue internally.
My device expected server as role of both REST HTTP and Proxy server .
So that reason, request line included host address like http://192.168.14.3:8080/the_endpoint.
As the result, this issue was a wrong usage of Grapevine. I'm sorry for taking your times.

Just for the information, I resolved this issue by following ways:

  1. Modified Grapevine in my branch to support proxy style request.
  2. Added reverse proxy server between device and Grapevine REST server.

@scottoffen scottoffen reopened this Jan 11, 2021
@scottoffen
Copy link
Owner

Modified Grapevine in my branch to support proxy style request.

Tell me more about this....do you have code I can look at? I can think of a way to fix this, but it's hard to know for sure if I can't test it.

@scottoffen
Copy link
Owner

@longlongago-k do you have a code sample I can look at?

@scottoffen scottoffen added the more-information-needed Needs more information before issue can be resolved label Jan 16, 2021
@longlongago-k
Copy link
Author

Hi,
According to RFC2616(legacy) or 7235,
It sais "When making a request to a proxy, other than a CONNECT or server-wide OPTIONS request (as detailed below), a client MUST send the target URI in absolute-form as the request-target."

a) Normal client requests:
GET /the_endpoint HTTP/1.1
b) Clients with proxy requests: (this issue)
GET http://192.168.10.2:8080/the_endpoint HTTP/1.1

My device requests b) style (absolute-form).
For example, I used following PathInfo

[RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "/the_endpoint/*.*")]
public IHttpContext Exec(IHttpContext context){
}

But, "/the_endpoint/." was converted to "^/the_endpoint/." in Grapevie Routing table.
So, this regex pattern rejects proxy style request "GET http://192.168.10.2:8080/the_endpoint HTTP/1.1"
In this case, Grapevine outputs: "Route Not Found For GET http://192.168.10.2:8080/the_endpoint"
To resolve instantly, I modified following code;

[PatternParser.cs]
//old
//var pattern = new StringBuilder("^");
//modified
var pattern = new StringBuilder(""); // delete ^ char

@scottoffen You can simply test by following sample code.

async void Main()
{
  //Prepare:
  //  add route with your Grapevine server as [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "/the_endpoint/*.*")]
  var url = @"http://192.168.10.2:8080/the_endpoint";//Set your IP address. do not use localhost string, because Windows ignore proxy
  WebRequestHandler handler = new WebRequestHandler();
  //Add proxy
  handler.Proxy = new WebProxy("http://192.168.10.2:8080"); // do not use localhost, because Windows ignore proxy
  using (HttpClient client = new HttpClient(handler))
  {
    HttpResponseMessage response = client.GetAsync(url).Result;
    var str = await response.Content.ReadAsStringAsync();
    Console.WriteLine(str);
  }
}

This usage is very special case, and generally this case should be used with another (Reverse) proxy.

@scottoffen
Copy link
Owner

scottoffen commented Jan 26, 2021

Excellent, thank you. I'll take a look at this.

Edit: Using .NET 5.0 and the HttpRequestHandler does not duplicate this issue. Downloading the .NET Framework 4.8 SDK now so I can test it with the WebRequestHandler.

@scottoffen
Copy link
Owner

scottoffen commented Jan 26, 2021

I found the issue. It was already (unintentionally) fixed in Grapevine 5. I'll port that quick fix over to Grapevine 4 and publish a new version. (Because I don't use RawUrl in GV5)

@scottoffen
Copy link
Owner

The fix for this is in release 4.2.2, and has been uploaded to Nuget.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
more-information-needed Needs more information before issue can be resolved
Projects
None yet
Development

No branches or pull requests

2 participants