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

StaticFiles extension serving truncated file for symbolic link #202

Closed
colindembovsky opened this Issue Jun 13, 2017 · 6 comments

Comments

Projects
None yet
3 participants
@colindembovsky

colindembovsky commented Jun 13, 2017

(Moving from this issue)
I have a SPA app that uses an config.json file with the following contents:

{
   "api": {
     "baseUri": "http://192.168.1.27:30081/api"
   }
}

In the Startup.cs file I configure StaticFiles:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
      ...

      app.UseDefaultFiles();
      app.UseStaticFiles();
    }

I'm deploying the app in a docker container (FROM microsoft/aspnetcore:1.1) using Kubernetes. In the Kubernetes Pod I map a configMap volume to override the config file. Kubernetes creates a symlink in the contianer and the file contents are correct within the container:

host ~> kubectl exec -it $podname -c frontend /bin/bash
container:/app# ls -l wwwroot/config/config.json
lrwxrwxrwx 1 root root 18 Jun 13 15:30 wwwroot/config/config.json -> ..data/config.json
container:/app# cat wwwroot/config/config.json
{
    "api": {
        "baseUri": "http://kubernetes-value:30081/api"
    }
}

However, doing a curl only returns 18 bytes:

host ~> curl http://192.168.1.160:30080/config/config.json
{
    "api": {
host ~>

I think that the StaticFile is seeing the file length as 18 (the length for the symlink, which is the length of the path to the physical file: in this case, ../data/config.json which is 18 chars) and only serving that length even though the file proper is longer.

I don't think this is expected behavior - but perhaps there is some other setting that I should use for StaticFiles?

@Tratcher

This comment has been minimized.

Show comment
Hide comment
@Tratcher

Tratcher Jun 13, 2017

Member

I doubt StaticFiles is doing any special here. I'd bet you could repro the issue using IFileProvider directly. See IHostingEnvironment.WebRootFileProvider and see if you can read your file as expected.

Member

Tratcher commented Jun 13, 2017

I doubt StaticFiles is doing any special here. I'd bet you could repro the issue using IFileProvider directly. See IHostingEnvironment.WebRootFileProvider and see if you can read your file as expected.

@colindembovsky

This comment has been minimized.

Show comment
Hide comment
@colindembovsky

colindembovsky Jun 13, 2017

Thanks @Tratcher - I'm busy digging in now. The FileProvider is providing the length field and StaticFiles is returning 0 - length bytes in the response. I suspect that the length property is being set incorrectly for symlinks. Tracking down the point in the clr where the length is read from the OS to see if there's a workaround.

colindembovsky commented Jun 13, 2017

Thanks @Tratcher - I'm busy digging in now. The FileProvider is providing the length field and StaticFiles is returning 0 - length bytes in the response. I suspect that the length property is being set incorrectly for symlinks. Tracking down the point in the clr where the length is read from the OS to see if there's a workaround.

@colindembovsky

This comment has been minimized.

Show comment
Hide comment
@colindembovsky

colindembovsky Jun 13, 2017

Yep @Tratcher , I've confirmed it. If you do

var fi = new FileInfo("path/to/symLink");

then fi.Length is the length of the symlink (as described above), not the lenght of the file! I think this is a bug on the FileInfo object for Unix.

colindembovsky commented Jun 13, 2017

Yep @Tratcher , I've confirmed it. If you do

var fi = new FileInfo("path/to/symLink");

then fi.Length is the length of the symlink (as described above), not the lenght of the file! I think this is a bug on the FileInfo object for Unix.

@BrennanConroy

This comment has been minimized.

Show comment
Hide comment
@BrennanConroy

BrennanConroy Jun 14, 2017

Contributor

Here is the change that made unix FileInfo not follow symlinks and a comment about why dotnet/corefx#5020 (comment)

TLDR;
FileInfo behavior on Unix matches Windows behavior for symlinks.

Contributor

BrennanConroy commented Jun 14, 2017

Here is the change that made unix FileInfo not follow symlinks and a comment about why dotnet/corefx#5020 (comment)

TLDR;
FileInfo behavior on Unix matches Windows behavior for symlinks.

@colindembovsky

This comment has been minimized.

Show comment
Hide comment
@colindembovsky

colindembovsky Jun 14, 2017

Thanks @BrennanConroy. So is there an IFileProvider that uses Stat for symlinks so that I get the expected length? I could roll my own if there isn't one, but was hoping you might know of one before I start hacking ☺️!

colindembovsky commented Jun 14, 2017

Thanks @BrennanConroy. So is there an IFileProvider that uses Stat for symlinks so that I get the expected length? I could roll my own if there isn't one, but was hoping you might know of one before I start hacking ☺️!

@colindembovsky

This comment has been minimized.

Show comment
Hide comment
@colindembovsky

colindembovsky Jun 14, 2017

Turns out it was pretty easy to write my own IFileProvider to work around the symlink length issue.

Once that was in place, I just changed Startup.cs:

      app.UseStaticFiles(new StaticFileOptions()
      {
          FileProvider = new SymlinkFileProvider(env.WebRootPath)
      });

Now all is well!

colindembovsky commented Jun 14, 2017

Turns out it was pretty easy to write my own IFileProvider to work around the symlink length issue.

Once that was in place, I just changed Startup.cs:

      app.UseStaticFiles(new StaticFileOptions()
      {
          FileProvider = new SymlinkFileProvider(env.WebRootPath)
      });

Now all is well!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment