Skip to content
This repository has been archived by the owner on Nov 22, 2018. It is now read-only.

Static files returning 404 #65

Closed
CoskunSunali opened this issue Jul 16, 2015 · 8 comments
Closed

Static files returning 404 #65

CoskunSunali opened this issue Jul 16, 2015 · 8 comments
Labels

Comments

@CoskunSunali
Copy link

Here is the scenario;

  • Application uses the StaticFiles middleware.
  • StaticFiles has StaticFilesOptions where FileProvider property is set to a custom provider (EmbeddedFileProvider). EmbeddedFileProvider accepts a PhysicalFileProvider instance which is used to check if the file physically exists. If it does, EmbeddedFileProvider just uses the PhysicalFileProvider to return the requested file, otherwise it checks embedded resources.
// Add static files to the request pipeline.
app.UseStaticFiles(new StaticFileOptions()
{
    FileProvider = new EmbeddedFileProvider(new PhysicalFileProvider(hostingEnvironment.WebRootPath))
});
  • Run the website using IIS/IIS Express - everything works as expected. The first request hits the homepage (HomeController), Startup methods get called without any issues, etc.
  • Restart IIS/IIS Express - Do NOT request the HomeController (/Home) but instead, make a request to a static file (that can be either a physical file or an embedded file, does not matter at all). If it is a physical file, the file returns correctly. If it is an embedded file, it returns 404 already. Either case breaks the rest of the process.
  • Now request the HomeController which has references to static files using <script> tags for Javascript files and <link> tags for stylesheet files. The Home view returns correctly but none of the static files do. They return 404 instead.
  • Restarting the IIS/IIS Express and making the first request to a valid MVC Controller and then requesting the static files fixes the issue but everytime the first request hits a static file, the StaticFiles middleware breaks.
@Tratcher
Copy link
Member

Can you push your repro app to github so we can clone and try it?

@CoskunSunali
Copy link
Author

Here is a sample repo: https://github.com/csunali/StaticFiles404

Clear steps to reproduce the issue are below.

Working scenario:

  • Set the "Launch Browser" property of the web project to "empty" and hit F5. Homepage should appear correctly at http://localhost:41002/. Keep the project running.
  • Visit http://localhost:41002/lib/foo.js. The embedded javascript should appear correctly - so that the embedded file provider works just fine.

Non-working scenario 1:

  • Set the "Launch Browser" property of the web project to lib/jquery/jquery.js (this is NOT an embedded file) and hit F5. jquery.js file should appear correctly at http://localhost:41002/lib/jquery/jquery.js
  • Visit homepage at http://localhost:41002/. The homepage should be working correctly.
  • Visit http://localhost:41002/lib/foo.js. The foo.js returns a 404 response.

Non-working scenario 2:

  • Set the "Launch Browser" property of the web project to lib/foo.js (this is an embedded file) and hit F5. foo.js file return a 404 response at http://localhost:41002/lib/foo.js
  • Visit homepage at http://localhost:41002/. The homepage should be working correctly.
  • Visit http://localhost:41002/lib/foo.js. The foo.js returns a 404 response.

As you can see, you don't need to hit an embedded file initially in order to break the functionality. Hitting even a physically existing file (jquery.js in this case) breaks it.

What I understand is that, as long as you hit a static file first, the custom file provider breaks for the rest of the process until you restart the web server. If you hit a regular MVC controller first, everything keeps working. I have also seen times when the static file provider broke later on, after some amount of time. That happened under IIS. I found an issue regarding that but it was not of any help as it was closed without any action being taken. That issue can be found at #59.

@Tratcher
Copy link
Member

Repro'd. This is an IIS/Express integration bug, not a bug with the static file middleware. It does not repro with WebListener.

Here's what I think is happing:
A) Working scenario:

  • First request arrivies, pointing to "/"
  • IIS boots the managed pipeline, Startup runs, everything is set up, then the request is served.
  • Subsequent requests for "/lib/foo.js" are executed via the managed pipeline and static file middleware.

B) Broken scenario:

  • First request arrives, pointing to "/lib/foo.js"
  • IIS sees the ".js" extension and skips directly to the native static file module. The managed pipeline is not booted, Startup does not run, etc..
  • No such file exists so a 404 is returned.
  • A subsequent request to "/" causes the managed pipeline to boot and run Startup.
  • Another request to "/lib/foo.js" still fails because it's being directly routed to the native static file module. (???)

#59 could also be caused by this because IIS can shut down your application if it does not receive any requests for a given period of time. Then when the next request arrives your back in the initial boot up mode.

We need to verify if this also happens in full IIS.

@Tratcher
Copy link
Member

Some additional details:

  • The contents of your app do not matter, only the repro steps themselves. I was able to repro it with just the empty template.
  • IIS appears to give priority to whichever module was loaded first.
  • The problem exists in both full IIS and IIS Express.

Workaround: Add the following to your web.config after publishing

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer> 

@CoskunSunali
Copy link
Author

Glad you were able to repro.

Should I take any additional actions on this matter or you will take care of the rest? I mean, shall I create an additional issue on another repo where it suits better for IIS integration issues? If so, where?

@CoskunSunali
Copy link
Author

Thank you for the workaround by the way.

@Tratcher
Copy link
Member

We'll take care of it, thanks.

@Tratcher
Copy link
Member

This issue was moved to aspnet/Helios#188

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

No branches or pull requests

2 participants