Bug 12190 - HttpHandler path matching is incorrect under FastCGI
Summary: HttpHandler path matching is incorrect under FastCGI
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.Web ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-05-10 08:08 UTC by June Rhodes
Modified: 2013-05-11 03:10 UTC (History)
1 user (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description June Rhodes 2013-05-10 08:08:11 UTC
I am running Mono:

    Mono JIT compiler version 3.0.7 (tarball Wed Apr 17 05:59:11 UTC 2013)
    Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
            TLS:           __thread
            SIGSEGV:       altstack
            Notifications: epoll
            Architecture:  amd64
            Disabled:      none
            Misc:          softdebug 
            LLVM:          supported, not enabled.
            GC:            Included Boehm (with typed GC and Parallel Mark)

I believe the code located under 'mono/mcs/class/System.Web/System.Web.Configuration_2.0/HttpHandlerAction.cs' may have incorrect logic for determining the correct HTTP handler under fastcgi-mono-server4.

If I specify a Web.config file that contains:

    <httpHandlers>
      <add path="cassette.axd" verb="*" type="Cassette.Aspnet.CassetteHttpHandler, Cassette.Aspnet" />
    </httpHandlers>

This will not match for a request such as:

    http://www.tychaia.com/cassette.axd/script/oz4BBh-gK6gJkhB5S64l3mXseFQ=/Scripts

even though under both normal XSP and Microsoft's stack it will.

I believe the offending code is most likely related to line 211, where it attempts to determine the virtual path.  From what I can see, it seems likely that this might behave differently between XSP and FastCGI, but as I don't really have this set up in a debuggable environment, I can't be sure.

When running in a site that also has MVC it's even worse.  It seems that a rule like:

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

won't actually match a URL like "http://www.tychaia.com/cassette.axd", even though again under XSP and Microsoft's stack it does, and when MVC isn't included, this URL will actually fall through to the HTTP handler.  It's likely that whatever path matching code the HttpHandlerAction's PathMatches function is using is probably re-used or similar in MVC to match it's routes, thus why it's not picking up path URLs correctly.  Interestingly though, the MVC default routing for mapping onto controllers and actions appears to work fine.

The code for the site that we're attempting to run is located at "https://github.com/hach-que/Tychaia/tree/master/Tychaia.Website".  Running this under Mono 3.0.7 and 3.0.10 FastCGI exhibits the problem.

The invocation for the FastCGI server is:

    /usr/bin/mono /usr/lib/mono/4.5/fastcgi-mono-server4.exe /applications=makemeaworld.com:/:/srv/www/tychaia.com/mmaw/MakeMeAWorld,www.makemeaworld.com:/:/srv/www/tychaia.com/mmaw/MakeMeAWorld,tychaia.com:/:/srv/www/tychaia.com/mmaw/Tychaia.Website,www.tychaia.com:/:/srv/www/tychaia.com/mmaw/Tychaia.Website /socket=unix:/tmp/mono-makemeaworld.com.sock /printlog=True /loglevels=debug /verbose=True
Comment 1 June Rhodes 2013-05-10 08:29:03 UTC
Well I've checked both those values using reflection under FastCGI and XSP, and they appear to be the same.

I'm now running FastCGI at:

    http://www.tychaia.com/

and XSP4 at:

    http://www.tychaia.com:12345/

These are both running using the same applications setup.  You can see the difference between responses when hitting URLs such as:

http://www.tychaia.com:12345/cassette.axd/stylesheet/nDvbK5eAxf6miyaRa_J0vl7YdxA=/Content
Comment 2 June Rhodes 2013-05-10 08:35:40 UTC
I've also put up a HttpHandler that outputs the state of some variables:

http://www.tychaia.com/test.axd
http://www.tychaia.com:12345/test.axd

They are in order:

  * context.Request.ApplicationPath
  * context.Request.Path
  * context.Request.PathInfo
  * context.Request.PhysicalApplicationPath
  * context.Request.PhysicalPath
  * HttpContext.Current
  * HttpContext.Current.Request
  * HttpContext.Current.Request.BaseVirtualDir (via reflection)
  * HttpRuntime.AppDomainAppVirtualPath

As you can see, all of these variables are identical between FastCGI and XSP4.
Comment 3 June Rhodes 2013-05-11 01:43:24 UTC
So I've done some tracing by adding Console.Write commands to the PathMatches command and it seems that this caused by my particular setup, in which:

Front-end Nginx -> Back-end Nginx -> FastCGI Mono

where a request pipes through the front-end nginx and is reverse proxied into a back-end nginx, which then passes it off to FastCGI.

Under normal XSP, or just straight Nginx -> FastCGI Mono, the results when hitting the cassette.axd handler is:

PathMatches invoked with /cassette.axd.
Original path to match is /cassette.axd
Path to match is /cassette.axd
>> Handler path is cassette.axd
>> Handler path matches exactly.

Under my double Nginx setup, this is the result:

PathMatches invoked with /cassette.axd/script/oz4BBh-gK6gJkhB5S64l3mXseFQ=/Scripts.
Original path to match is /cassette.axd/script/oz4BBh-gK6gJkhB5S64l3mXseFQ=/Scripts
Path to match is /Scripts
(more lines where it tries to match the handler against /Scripts).

I'm investigating as to whether it's the reverse proxy causing weirdness in the path being passed back, or whether FastCGI isn't picking up the request properly.
Comment 4 June Rhodes 2013-05-11 02:52:16 UTC
I have verified that the FastCGI parameters that are being passed in my environment and on the production server are identical (except for the HTTP_* parameters), yet it still drops to the StaticFileHandler in production and works correctly on my local machine (even when getting production into a single Nginx to FastCGI setup):

james@james-pc:~/Projects/Redpoint/Tychaia/Tychaia.Website> fastcgi-mono-server4 --applications localhost:/:/home/james/Projects/Redpoint/Tychaia/Tychaia.Website/ --socket tcp:127.0.0.1:9456 --loglevels=Debug --printlog=True
[2013-05-11 16:47:19Z] Debug   fastcgi-mono-server4
[2013-05-11 16:47:19Z] Debug   Listening on port: 127.0.0.1
[2013-05-11 16:47:19Z] Debug   Listening on address: 9456
[2013-05-11 16:47:19Z] Debug   Root directory: /home/james/Projects/Redpoint/Tychaia/Tychaia.Website
[2013-05-11 16:47:19Z] Debug   Max connections: 1024
[2013-05-11 16:47:19Z] Debug   Max requests: 1024
[2013-05-11 16:47:19Z] Debug   Multiplex connections: False
[2013-05-11 16:47:22Z] Debug   Accepting an incoming connection.
[2013-05-11 16:47:22Z] Debug   Record received. (Type: BeginRequest, ID: 1, Length: 8)
[2013-05-11 16:47:22Z] Debug   Record received. (Type: Params, ID: 1, Length: 1123)
[2013-05-11 16:47:22Z] Debug   Record received. (Type: Params, ID: 1, Length: 0)
[2013-05-11 16:47:22Z] Debug   Read parameter. (SCRIPT_FILENAME = /scripts/cassette.axd/stylesheet/nDvbK5eAxf6miyaRa_J0vl7YdxA=/Content)
[2013-05-11 16:47:22Z] Debug   Read parameter. (QUERY_STRING = )
[2013-05-11 16:47:22Z] Debug   Read parameter. (REQUEST_METHOD = GET)
[2013-05-11 16:47:22Z] Debug   Read parameter. (CONTENT_TYPE = )
[2013-05-11 16:47:22Z] Debug   Read parameter. (CONTENT_LENGTH = )
[2013-05-11 16:47:22Z] Debug   Read parameter. (SCRIPT_NAME = /cassette.axd/stylesheet/nDvbK5eAxf6miyaRa_J0vl7YdxA=/Content)
[2013-05-11 16:47:22Z] Debug   Read parameter. (REQUEST_URI = /cassette.axd/stylesheet/nDvbK5eAxf6miyaRa_J0vl7YdxA=/Content)
[2013-05-11 16:47:22Z] Debug   Read parameter. (DOCUMENT_URI = /cassette.axd/stylesheet/nDvbK5eAxf6miyaRa_J0vl7YdxA=/Content)
[2013-05-11 16:47:22Z] Debug   Read parameter. (DOCUMENT_ROOT = /usr//html)
[2013-05-11 16:47:22Z] Debug   Read parameter. (SERVER_PROTOCOL = HTTP/1.1)
[2013-05-11 16:47:22Z] Debug   Read parameter. (GATEWAY_INTERFACE = CGI/1.1)
[2013-05-11 16:47:22Z] Debug   Read parameter. (SERVER_SOFTWARE = nginx/1.2.6)
[2013-05-11 16:47:22Z] Debug   Read parameter. (REMOTE_ADDR = 127.0.0.1)
[2013-05-11 16:47:22Z] Debug   Read parameter. (REMOTE_PORT = 60527)
[2013-05-11 16:47:22Z] Debug   Read parameter. (SERVER_ADDR = 127.0.0.1)
[2013-05-11 16:47:22Z] Debug   Read parameter. (SERVER_PORT = 80)
[2013-05-11 16:47:22Z] Debug   Read parameter. (SERVER_NAME = localhost)
[2013-05-11 16:47:22Z] Debug   Read parameter. (REDIRECT_STATUS = 200)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_HOST = localhost)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_CONNECTION = keep-alive)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_CACHE_CONTROL = max-age=0)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_ACCEPT = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_USER_AGENT = Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_ACCEPT_ENCODING = gzip,deflate,sdch)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_ACCEPT_LANGUAGE = en-US,en;q=0.8,en-AU;q=0.6)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_ACCEPT_CHARSET = ISO-8859-1,utf-8;q=0.7,*;q=0.3)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_COOKIE = ASP.NET_SessionId=BEC035EBF3BF078DFEBF90A7)
[2013-05-11 16:47:22Z] Debug   Read parameter. (HTTP_IF_NONE_MATCH = "9c3bdb2b9780c5fea68b26916bf274be5ed87710")

Both are using TCP sockets to connect FastCGI; the production box is hardcoded to pass these parameters and the binaries are identical (tracked under the same Git commit, with Git storing the binaries that are being used).  The code and setup is now literally identical and I have no idea what else could possibly be causing the difference in the way it's operating.
Comment 5 June Rhodes 2013-05-11 02:55:50 UTC
Well.  I think I just solved my issue.

Under OpenSUSE, XSP/FastCGI and Mono are packaged seperately.  So even though I had Mono 3.0.10 installed, I still had XSP 2.10.2.0 installed on production, where locally I had 2.11.0.0.  Once installing the correct version of XSP/FastCGI the issue appears to be resolved under basic tests, although now I have to reconfigure production before I really know.
Comment 6 June Rhodes 2013-05-11 03:10:14 UTC
Confirmed that upgrading to 2.11.0.0 resolves the issue.