htmlspark-javaspark-framework

Why does Html Audio control fails in html if served rather than treated as a regular file


I have a Java application that can run as a regular java Swing application but creates a standard html5 report that opens in a webbrowser.

e.g

Browser Url is:

file:///C:/Users/Paul/AppData/Roaming/SongKong/Reports/FixSongsReport00574/FixSongsReport00574.html

As part of that it uses a audio tag to allow the song to be played in the browser

    <h5>
        <audio controls="controls">
            <source src="file:/E:/Test4/test.WAV">
        </audio>
    </h5>

and that works fine.

But the application can also run with a Html User Interface, it then runs a webserver using Java Spark on port 4567, if I then serve the exact same report (yes i am actually serving files the same files on the disk) to the same computer so the audio file is local to the computer it will no longer play the song.

This would be the Browser Url

http://localhost:4567/FixSongsReport00574/FixSongsReport00574.html

So why is this, since I am specifying the full path in the source element and therefore I dont see why it would be affected by factors such as where static files are served from.

But in case relevant this is the java-spark start method

    CustomJettyServerFactory customJettyServerFactory = new CustomJettyServerFactory();
    EmbeddedServers.add(
            EmbeddedServers.Identifiers.JETTY,
            new EmbeddedJettyFactory(customJettyServerFactory));

    staticFiles.externalLocation(Platform.getPlatformReportFolder().getPath());
    staticFiles.location("");
    staticFiles.expireTime(600);

    SongKong.songKong.setRemote(true);

    StartPage.recreateIndexPage();
    init();
    configureWebEndPoints();
    configureApiWebEndPoints();

    before((request, response) -> {
      MainWindow.logger.severe(">>>>>"+request.uri());
    });

    listenForFinish();

The follow up question is that although I don't understand why it doesn't work on a local computer I can see that if was connecting via a remote browser then it would not work because the file url is relative to the server not the client machine, how would i make file playable in such a case.


Solution

  • You can't mix HTTP server and file protocols into one for security reasons. So what you need to do is below

    While serving any html file read its contents and replace file:/ by something like /localfile?url=

    And then you will need to create a /localfile endpoint in your embedded server code, which will read the url and then stream the file locally. Your server code will be able to access the local file and stream it.

    There used to be few techniques back in the days of FF11, but they are not valid anymore

    How do I view file:// images from http://localhost served pages in Firefox 11?