androidangularinputstreamnanohttpd

Serve font/images with Nanohttpd from Android


I'm trying to host an Angular app with nanohttpd, so I put the files into a dist/ folder inside the assets folder of the android app. Now I want to serve the angular files but I keep getting this kind of errors in console (it only appears when trying to request fonts and images):

GET http://hostname/font.woff2 200 (OK)

This is the code that I use to serve the files:

public Response serve(IHTTPSession session) {
    String filepath = getFilepath(session.getUri()); // Get filepath depending on the requested url
    String mimeType = getMimeType(filepath); // Get mimetype depending on the extension of the filepath (font/woff, font/woff2, font/ttf, image/x-icon, text/html, application/javascript)
    String content;
    byte[] buffer;
    Response res;
    InputStream is;
    try {
        is = this.assetManager.open("dist/" + filepath);
        int size = is.available();

        buffer = new byte[size];
        is.read(buffer);
        is.close();

        content = new String(buffer);
        content = content.replace("old string", "new string");

        if (typeText(mimeType)) { // If mimeType is text/html or application/json
            res = newFixedLengthResponse(content);
        }else{ // This is when I try to serve fonts or images
            res = newFixedLengthResponse(Response.Status.OK, mimeType, is, size); // Not working
        }

    }catch(IOException e) {
        res = newFixedLengthResponse("Error!");
    }
    return res;
}

I think that maybe the font files are getting compressed, or the size is not the real size of the InputStream. Also when loading the page, vendor.js takes a lot to download, and after that, it stops downloading the rest of the files.

I also get this error on the logcat:

Communication with the client broken, or an bug in the handler code

Solution

  • I fixed it like this:

    public Response serve(IHTTPSession session) {
        String filepath = getFilepath(session.getUri()); // Get filepath depending on the requested url
        String mimeType = getMimeType(filepath); // Get mimetype depending on the extension of the filepath (font/woff, font/woff2, font/ttf, image/x-icon, text/html, application/javascript)
        String content;
        byte[] buffer;
        Response res;
        InputStream is;
        try {
            is = this.assetManager.open("dist/" + filepath);
            if (!typeText(mimeType)) { // If mimeType is font/<something> or image/<something>
                return newFixedLengthResponse(Response.Status.OK, mimeType, is, -1);
            }
            int size = is.available();
            buffer = new byte[size];
            is.read(buffer);
            is.close();
            content = new String(buffer);
            content = content.replace("old string", "new string");
        }catch(IOException e) {
            content = "Error!";
        }
        return newFixedLengthResponse(content);
    }
    

    I really don't know what happend, but it works really well this way. It seems to me that is.available() was not returning the right file size.