mjpclab / go-http-file-server

Simple command line based HTTP file server to share local file system
MIT License
379 stars 55 forks source link

Option to specify URL base-path #19

Closed SubhashBose closed 2 years ago

SubhashBose commented 2 years ago

It will be nice to have an option to specify the base-path for the URL. E.g. I want to serve at "HTTP://IP:PORT/base-path/" instead of the URL root.

This is needed when using a reverse proxy (like NGNIX).

marjune163 commented 2 years ago

The file list page is always using relative path. I don't think there are path issues for nginx reverse proxy.

SubhashBose commented 2 years ago

It is not an issue as long as NGNIX root URL's path is the same as GHFS root URL's path.

Suppose I have a web server running at HTTP://localhost:8080 and GHFS running at HTTP://localhost:9000. Now, I configure NGNIX (running at port 80) to reverse proxy both servers on different paths. e.g., NGNIX reverse proxy is mapped like this HTTP://localhost/ -> HTTP://localhost:8080 HTTP://localhost/fileserver -> HTTP://localhost:9000

So visitors coming to HTTP://localhost/, HTTP://localhost/bla-bla/.. etc will be served by the webserver, whereas HTTP://localhost/fileserver will be served by GHFS.

In the above example, GHFS will not serve the correct filesystem directory, as it expects the root URL to be "/" to list the filesystem root (specified by -r argument). So when NGNIX proxies HTTP://localhost/fileserver to GHFS, the later will try to serve "./fileserver" from filesystem root, which may not exist.

Well, this is just one use case for serving a fileserver at a different base-url. There can be many other use cases as well. You may also look at Filebrowser server, it provides a base-url option which required in the above example.

So, all that is needed, is an option to specify "base-url", such that "HTTP://localhost:9000/base-url/" will list the root of the filesystem (specified by -r argument).

marjune163 commented 2 years ago

here is the nginx example, ensure to add tailing / to location and proxy_pass target:

location /fileserver/ {
    proxy_pass http://localhost:9000/;
}
SubhashBose commented 2 years ago

Your ngnix example is correct, but this will not give the expected output. I just tested it. It will give 404 error because here GHFS will try to list "./fileserver/" path of the filesystem instead of "./" .

SubhashBose commented 2 years ago

Ok, I did a fresh ngnix configuration with only this and now it works.

SubhashBose commented 2 years ago

Actually, I am trying to use CloudFlare Access tunneling to use as a proxy. My initial thought was it works the same as Ngnix, but now I see Couldfare handles proxying differently. Ngnix does URL rewriting when passing the URL to proxy, so it works. While CloudFlare does not do any URL rewriting, it passes the raw URL to the proxy, so it is not working.

Here is a screenshot of Cloudflare interface to set up proxy. GHFS is running on port 9090 locally and I want to serve it at HTTP://domain.com/fileserver/.

image Also note that the service URL can only be domain:port without any path so 127.0.0.1:9090 is allowed but not with trailing slash '/'

The only solution it seems is if the file server uses a base-url.

I don't know if there are other proxy server implementations that deal proxy similarly. I was looking at other types of server programs and I see many of those provide this option of base-url - like TTYD, Filebrowser, gohttpserver. It will be nice if such an option is available in GHFS too, it will be useful to deal with such scenarios.

SubhashBose commented 2 years ago

Thanks that's a good trick to try actually (your deleted suggestion to use alias ghfs --empty-root --alias :/fileserver:path_to_root_dir). Now It partly works, When visiting the proxy URL (HTTP://domain/fileserver/) the file listing is done from the correct directory. But the page styling is broken because it tries to load "../?asset=index.css", "../?asset=index.js", etc., but '../' url is no more served by GHFS.

Also it seems GHFS assets are served from any sub-directory, its does not need to be from the root URL. If the theme HTML only just points it's assets like "?asset=index.css" it will probably work.

SubhashBose commented 2 years ago

I edited https://github.com/mjpclab/go-http-file-server/blob/main/src/tpl/frontend/index.html to remove {{.RootRelPath}} from all assets and now it works fine - both when proxied and un-proxied. It seems {{.RootRelPath}} is not required. You can check if this doesn't cause some other side-effect, then you may consider applying this in the next release.

However, using the alias trick may not be the perfect solution, because "/" in breadcrumb navigation and also '../' in file-list navigated to domain root which is outside the proxy. But this is something I can probably live with and apart from this everything works as expected.

marjune163 commented 2 years ago

Please try the dev branch with option --prefix /fileserver https://github.com/mjpclab/go-http-file-server/tree/dev

SubhashBose commented 2 years ago

Thanks! now it works perfectly.

marjune163 commented 2 years ago

Feature released in 1.14.0.