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

fileserver: Fix try_files for directories, windows fix #3684

Merged
merged 4 commits into from
Sep 17, 2020

Conversation

francislavoie
Copy link
Member

Discussion: https://caddy.community/t/file-not-file-testing-question/9564

The gist of it is that the trailing / was being stripped by path.Clean, so the condition in strictFileExists expecting a trailing / indicating a directory expected wasn't working because it would never have a / once it got there.

But on top of this, sanitizedPathJoin had this issue as well, because filepath.Join also cleans the path. I updated that code to re-add the path separator as well.

I refactored the common lines between all the try policies that set up suffix and fullpath into a closure for obvious reasons.

And finally, strictFileExists was checking specifically for a trailing / which did not work on Windows, so I changed that to use the filepath.Separator constant to work on Windows (I wrote and tested these changes on Windows).

Note that sanitizedPathJoin is used in file_server browse but path.Join is called before on the path, so no trailing slash should exist, so the behaviour should stay the same for that code path.

@francislavoie francislavoie added the bug 🐞 Something isn't working label Aug 25, 2020
@francislavoie francislavoie added this to the v2.3.0 milestone Aug 25, 2020
@francislavoie francislavoie requested a review from mholt August 25, 2020 07:02
@francislavoie
Copy link
Member Author

francislavoie commented Sep 2, 2020

FYI @mholt I added a new feature in the second commit in here (because it doesn't super make sense to be in a new PR since it sorta depends on these changes).

I added a new placeholder {http.matchers.file.type} which can be set to either file or directory based on what's matched. That can be useful for chaining into another matcher (i.e. expression matcher) which can do things based on whether a file or directory was matched.

Also did some refactoring to make this a bit simpler, and to centralize the placeholder setup in the file matcher. It could be simplified further probably, and you'll probably tell me to move the closure out... but 🤷‍♂️ this is what I felt like doing for now! I can clean it up further if you think this is ok.

I can drop that 2nd commit if you don't want it, but I think it's useful.

Some discussion here: https://caddy.community/t/how-to-determine-if-a-path-is-a-directory-or-a-file/9643/2

Also I kinda think this should go in 2.2, since it's a pretty good bug fix.

@francislavoie francislavoie modified the milestones: v2.3.0, v2.2.0 Sep 2, 2020
@mholt mholt added the under review 🧐 Review is pending before merging label Sep 8, 2020
@mholt
Copy link
Member

mholt commented Sep 16, 2020

Thanks, will look at this closer soon. Working though my backlog. 😃

I added a new placeholder {http.matchers.file.type} which can be set to either file or directory based on what's matched. That can be useful for chaining into another matcher (i.e. expression matcher) which can do things based on whether a file or directory was matched.

If I recall correctly, file matchers are designed to match either a directory or a file based solely on whether a separator (I used / but I guess on windows we need \ as you noted) suffixed the path: if so, match only directories; if not, match only files. How useful is the placeholder if there is no variance in the file matching?

@francislavoie
Copy link
Member Author

This PR specifically fixes file matching so that if you use {path}/, it will match a directory. It wouldn't at all before. So because of that, that placeholder becomes useful.

@mholt
Copy link
Member

mholt commented Sep 16, 2020

Okay, cool. But {path}/ would never match anything other than a directory, so why do we need a placeholder to say whether it matched a directory or a regular file?

@francislavoie
Copy link
Member Author

francislavoie commented Sep 16, 2020

Because you can do file {path} {path}/. In which case, which one did it match? That lets you find out.

Basically, things down the line might need to know whether the rewritten thing was a directory or a file, and behave differently based on that. That's the crux of the question in https://caddy.community/t/how-to-determine-if-a-path-is-a-directory-or-a-file/9643

Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been looking at this most of the afternoon and I think I finally understand what is going on... it's a big change!

Thanks for the tests. I'm glad there are some. 😅

modules/caddyhttp/fileserver/matcher.go Outdated Show resolved Hide resolved
modules/caddyhttp/fileserver/matcher.go Outdated Show resolved Hide resolved
Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, we're almost there I think.

modules/caddyhttp/fileserver/matcher.go Outdated Show resolved Hide resolved
Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, let's rock and roll.

Thanks for working so diligently on this!

@mholt mholt removed the under review 🧐 Review is pending before merging label Sep 17, 2020
@mholt mholt merged commit b95b873 into caddyserver:master Sep 17, 2020
@francislavoie francislavoie deleted the try-files-directories branch September 17, 2020 00:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants