Spark: Static files delivered by externalStaticFileLocation are only accessible with 1 service started after 2.5.1

Created on 30 Mar 2017  路  8Comments  路  Source: perwendel/spark

Hello!

This issue affects all versions after 2.5.1 (before the security fix...).
Consider the following code:

        Service server1 = Service.ignite().port(8080);
        Service server2 = Service.ignite().port(8181);

        server1.externalStaticFileLocation(Paths.get("folder1").toAbsolutePath().toString());
        server2.externalStaticFileLocation(Paths.get("folder2").toAbsolutePath().toString());

with inside folder1 and folder2 a file "image.jpg".

If you visit http://localhost:8080/image.jpg (server1) => 404
If you visit http://localhost:8181/image.jpg (server2) => 200

If you put in comment the server2, the image from server1 is now accessible!

If you want something to quickly test it, I made a Github repository with my examples:
https://github.com/sandronm/sparkjava_example

What's wrong?

Most helpful comment

Hello guy's,
I found the origin of the bug in your code: the class StaticFilesFolder

public class StaticFilesFolder {
    private static final Logger LOG = LoggerFactory.getLogger(StaticFilesFolder.class);

    private **static** volatile String local;
    private **static** volatile String external;

    public **static** final void localConfiguredTo(String folder) {

        local = removeLeadingAndTrailingSlashesFrom(folder);
    }

    public **static** final void externalConfiguredTo(String folder) {

        String unixLikeFolder = Paths.get(folder).toAbsolutePath().toString().replace("\\", "/");
        LOG.warn("Registering external static files folder [{}] as [{}].", folder, unixLikeFolder);
        external = removeLeadingAndTrailingSlashesFrom(unixLikeFolder);
    }

    public **static** final String local() {
        return local;
    }

    public **static** final String external() {
        return external;
    }

}

The class should not use static variables and methods because if you do that, you can only define 1 external static files path by JVM and not by Service as expected.

You should instead create a single instance of StaticFileFolder by Service (Singleton pattern).

All 8 comments

727

Hello guy's,
I found the origin of the bug in your code: the class StaticFilesFolder

public class StaticFilesFolder {
    private static final Logger LOG = LoggerFactory.getLogger(StaticFilesFolder.class);

    private **static** volatile String local;
    private **static** volatile String external;

    public **static** final void localConfiguredTo(String folder) {

        local = removeLeadingAndTrailingSlashesFrom(folder);
    }

    public **static** final void externalConfiguredTo(String folder) {

        String unixLikeFolder = Paths.get(folder).toAbsolutePath().toString().replace("\\", "/");
        LOG.warn("Registering external static files folder [{}] as [{}].", folder, unixLikeFolder);
        external = removeLeadingAndTrailingSlashesFrom(unixLikeFolder);
    }

    public **static** final String local() {
        return local;
    }

    public **static** final String external() {
        return external;
    }

}

The class should not use static variables and methods because if you do that, you can only define 1 external static files path by JVM and not by Service as expected.

You should instead create a single instance of StaticFileFolder by Service (Singleton pattern).

I'm taking a look at this, but I'm not quite getting what's the deal with all the statics - seems like running from servlet, stuff is supposed to be static and otherwise not. This seems to be the case with routes as well. @perwendel | @tipsy am I on the right track here, is this by design?

am I on the right track here, is this by design?

Spark used to be entirely static (no instance api), so it might just be legacy code.

this is still the case at 2.7.1

    Service s1 = Service.ignite().port(4568).staticFileLocation("/s1");
    Service s2 = Service.ignite().port(4569).staticFileLocation("/s2");

    s1.init();
    s2.init();

curl -v http://localhost:4568/s1.txt ends up being 400 bad request (after creating resources/s1/s1.txt and resources/s2/s2.txt of course)

I got the same issue here. Is it possible to fix this? I guess removing the 'static' should fix this?
Its still reproduce able in version 2.7.2

Best regards and thanks a lot for your amazing work!

@sdmimaye version 2.8.0 is the latest version and has the fix to this issue (I believe)

Man i cannot express how helpful that one single line of text was!
Thank you so much. you are absolutely right, it is fixed in 2.8.0

Thanks again!

Was this page helpful?
0 / 5 - 0 ratings