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

FOS is not compatible with IIS #10

Open
mikdav opened this issue May 16, 2018 · 3 comments
Open

FOS is not compatible with IIS #10

mikdav opened this issue May 16, 2018 · 3 comments

Comments

@mikdav
Copy link

mikdav commented May 16, 2018

IIS has two options for FastCGI - named pipes and TCP. FOS supports unix named pipes and TCP. However, the way that IIS uses TCP is not compatible with the way that FOS uses TCP.

In the case of named pipes, IIS creates a named pipe and passes it to the FastCGI process as StdIn. The FastCGI process is then expected to duplicate the handle and use the pipe for reading/writing.

In the case of TCP, IIS opens a transient port and then passes a handle to the FastCGI process also as StdIn. The FastCGI process is then expected to duplicate the handle and use it for read/writing. IIS will not connect to a FastCGI process listening on a specific port.

A possible fix would be to add a BindToIisStdIn method to SocketListener that would pull the correct handle/socket from StdIn in order to communicate with IIS.

@mzabani
Copy link
Owner

mzabani commented May 18, 2018

I once searched for ways to make Fos/FastCgi work with IIS, but I honestly can't remember finding any good info on this; you seem to be much more aware of how it works. Do you have any links to some good reading material on this?

@mikdav
Copy link
Author

mikdav commented May 18, 2018

I have been working on this one for the last couple of days since our organization generally prefers IIS. We're a mostly Windows shop so nginx/mono isn't really our thing, though I currently have my changes working with nginx. We have an external component that is not thread-safe and needs to be used in a web application. So unfortunately ASP.NET doesn't work for us--which is how I landed on your project.

It appears the best way to do this in C# is to P/Invoke to get the handle from StdIn and use that to open a FileSteam because unfortunately the .Net Socket API doesn't allow creating sockets from a handle. I see the .net core team has a work item to allow this, but it hasn't moved for a while. So I've been reading through the Fos/FastCGI code trying to decide what the most surgical change would be to support this. However, the approaches I have tried so far I do not like because they will require a lot of code churn. There are two problems:

  1. The Fos/FastCGI code is very socket oriented. It appears to expect to accept connections for each new record. It maintains a dictionary of open sockets to records and reads them all in a loop. A FileStream would not have this mapping of connections to records.

  2. A FileStream would be a continuous stream and would require logic to split the incoming records from each other.

@mzabani
Copy link
Owner

mzabani commented May 21, 2018

Wow, IIS seems really strange! However, I'd certainly love to get it working with Fos.
The main difference - and you said it yourself - is that Fos does one Socket per Request (that's how the servers I worked with do it anyways), while with IIS we'd have to multiplex connections over a single communication channel.

Before we delve into this we must really understand how IIS does this, because if multiple requests are multiplexed over a single channel, any FastCGI record may come in anytime, so we'd have to parse incoming FastCGI records and index our Requests by their Ids.
This should probably work with Sockets as well, with just one possible exception: Maybe data comes through the sockets in chunks so small (or so fragmented) that it's not even possible to obtain the RequestId of the next Record, so we don't know which request it belongs to, leading to a big problem.

This problem is most likely the reason (although I can't remember for sure) why I indexed Requests per Socket. I believe I even have unit tests that feed the main loop byte per byte to test if this works.

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

2 participants