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

UseStaticFiles should provide a case insensitive option in StaticFileOptions #35128

Open
mchandler-manticore opened this issue Apr 16, 2020 · 28 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-Extensions-FileSystem
Milestone

Comments

@mchandler-manticore
Copy link

Is your feature request related to a problem? Please describe.

My team ran into an issue where we develop on windows with case insensitive file system and returning static files using lower case links but when deploying on linux (case sensitive file system) in docker the same links no longer worked as the files had camel case on disk

Describe the solution you'd like

Add a boolean value to StaticFileOptions to enable static files to resolve files on disk ignoring file system case thus having the same behavior on windows and linux.

Additional context

Example file: /wwwroot/MyTestFile.txt
Link http://localhost/mytestfile.txt works on windows doesnt work on linux

@Tratcher
Copy link
Member

Tratcher commented Apr 16, 2020

The file lookup is managed by the IFileProvider implemented by PhysicalFileProvider in this example.
https://github.com/dotnet/runtime/blob/master/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs

Case in-sensitivity isn't something StaticFiles can fake from the top down, you'd need this option on the underlying file APIs first.

Recommend transferring this to Runtime.

@analogrelay
Copy link
Contributor

Transferring this to runtime. The change that would be needed here is to have a case-insensitive mode to file providers.

Having said that, we already know there are case-sensitive file systems in use (Linux, as you noted) and making the file providers case-insensitive even when on a case-sensitive file system is very tricky and disruptive.

@analogrelay analogrelay transferred this issue from dotnet/aspnetcore Apr 17, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Apr 17, 2020
@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't figure out the best area label to add to this issue. Please help me learn by adding exactly one area label.

@maryamariyan maryamariyan added this to the 6.0.0 milestone Jul 9, 2020
@maryamariyan maryamariyan removed the untriaged New issue has not been triaged by the area owner label Jul 9, 2020
@maryamariyan maryamariyan modified the milestones: 6.0.0, Future Jul 9, 2020
@ericstj
Copy link
Member

ericstj commented Jul 9, 2020

It's not clear what the API request is here. Can you make a formal API request?

Also, keep in mind that even on windows you can now make the file system case-sensitive so the value of such a feature here might be diminished.

@ericstj ericstj added api-suggestion Early API idea and discussion, it is NOT ready for implementation needs more info labels Jul 9, 2020
@jhudsoncedaron
Copy link

I'm not going to back this at all, but in fact this is to my eyes a very clear item. API surface is something like bool ForceCaseInsensitive {get;set;} = false; Trying to provide case insensitive APIs in general is very hard for lots of obvious reasons, but it's easy enough to do on a pure reader. Or maybe ForceLowerCase is better; hard to tell.

@maryamariyan
Copy link
Member

We have issues tracking this request on dotnet/runtime repo already: #23871, #14321, #17873

@Tratcher what is the underlying API that would end up calling a new API that allows for checking case sensitivity?

@Tratcher
Copy link
Member

Here:

public IFileInfo GetFileInfo(string subpath)
{
if (string.IsNullOrEmpty(subpath) || PathUtils.HasInvalidPathChars(subpath))
{
return new NotFoundFileInfo(subpath);
}
// Relative paths starting with leading slashes are okay
subpath = subpath.TrimStart(_pathSeparators);
// Absolute paths not permitted.
if (Path.IsPathRooted(subpath))
{
return new NotFoundFileInfo(subpath);
}
string fullPath = GetFullPath(subpath);
if (fullPath == null)
{
return new NotFoundFileInfo(subpath);
}
var fileInfo = new FileInfo(fullPath);

Case sensitivity would be a new option on the PhysicalFileProvider, and it would use that when creating a new FileInfo.

Also here when listing the contents of directories:

return new PhysicalDirectoryContents(fullPath, _filters);

@maryamariyan
Copy link
Member

Seems like a new API addition for System.IO.

cc: @carlossanlop @jozkee

@DamianGuth
Copy link

Any new information here?

@MarvinKlein1508
Copy link

We came across this in our application as well. Any update on this would be appreciated

@0x6DD8
Copy link

0x6DD8 commented Jul 29, 2022

Yeah, any update on this would help a lot...

@jhudsoncedaron
Copy link

@MarvinKlein1508 , @0x6DD8 An implementation of static file provider is about 600 lines of mostly boilerplate code; maybe less in truly modern C#.

@7702244
Copy link

7702244 commented Feb 10, 2023

After 3 years, there is still no solution for linux?

@davidfowl
Copy link
Member

Is there a proposal?

@jhudsoncedaron
Copy link

@davidfowl : That's trivial.

@davidfowl
Copy link
Member

@jhudsoncedaron Did you send a pull request with the solution?

@jhudsoncedaron
Copy link

jhudsoncedaron commented Feb 10, 2023

@davidfowl That's a different question. I'm not going to lift a finger unless it's approved first. A proposal is trivial. Getting a PR approved for a request that isn't approved first is not.

@davidfowl
Copy link
Member

I guess I missed the proposal. I re-read this a couple of times and I see this suggestion but I don't know what the end to end proposal is for this feature. How would it work?

@jhudsoncedaron
Copy link

It's pretty clear that OP wants to develop on Windows and run the output on Linux. So you run the directory descent piecewise matching case insensitive by matching the output of directory enumeration. It would be easier if I could use my own libraries because System.IO.Directory is pretty bad; but that's a different problem.

@davidfowl
Copy link
Member

So the file provider enumerates the entire directory tree up front? If not, what happens in GetFileInfo?

@jhudsoncedaron
Copy link

jhudsoncedaron commented Feb 10, 2023

"So the file provider enumerates the entire directory tree up front?"

If it were my codebase that's how I'd do it; but that's because I know I can just not handle updates to the tree while running. If that's not going to work out for you gotta do the piecewise descent and resolve in GetFileInfo. This isn't too expensive on the server. samba gets away with it all the time.

Now that you know what a proposal looks like you can decide whether you want it or not.

@davidfowl
Copy link
Member

I'm just trying to understand your idea, so I'm trying to piece it together from the clues you are dropping. So the idea is the enumerate and cache the files in a case insensitive set? Did I miss something? What about file changes?

@jhudsoncedaron
Copy link

jhudsoncedaron commented Feb 10, 2023

I think you missed nothing.

"What about file changes?" If you have to handle this you can't cache. I simply don't have the toolset to know. I solved this problem by case normalization at build time and I am already using my own provider due to a bug that was closed wontfix so there it will remain.

Case insensitive file open is an exercise that should take an hour to solve.

@davidfowl
Copy link
Member

OK, I'll leave this open, and I'm still confused as to what your concrete proposal is for this.

@Tratcher
Copy link
Member

It sounds like we'd have to recursively enumerate directories along the path and do a manual case-insensitive search at each level for a match. That can get very expensive per request, especially if the folder structure is deep or folders contain many files. Performance wise this seems untenable for more than a few files without cache + refresh.

For what it's worth, this whole solution could be built into a custom version of PhysicalFileProvider, it wouldn't require any changes from StaticFiles.

@Jaykul
Copy link

Jaykul commented Mar 2, 2023

What if, instead of "case insensitive" you made it transform everything to lowercase?
That is: the files needs to all be lowercase (but that's something "we" control).
Then the client/user can use any case they want in the URL, and you just transform it to lowercase before doing a file lookup?

@kevin-osborne
Copy link

I was able to solve for this issue using https://github.com/XiaoFaye/CaseInsensitiveStaticFile

@urza
Copy link

urza commented Oct 24, 2023

I run into this issue as well, dockerizing asp.net core app that was previously running on Windows Server IIS, now having issues with case sensitive paths in static files, I would welcome some bool option to treat paths for static files as case insensitive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-Extensions-FileSystem
Projects
None yet
Development

No branches or pull requests