Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using nanohttpd for server on localhost, how to serve the static HTML code in the whole directory?

I can't make nanohttpd work. It seems not be able to find the www directory in app's root.

My code is at https://github.com/tlkahn/neonx

My code at MainActivity.java:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        BottomNavigationView navView = findViewById(R.id.nav_view);
        mWebView = findViewById(R.id.webkit);
        navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        webSettings.setDomStorageEnabled(true);
        mWebView.getSettings().setLoadsImagesAutomatically(true);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                return false;
            }
        });
        if (!haveNetworkConnection()) {
            new AlertDialog.Builder(this)
                .setTitle("You are not connected to internet.")
                .setMessage("Are you sure you want to exit?")
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finishAffinity();
                        System.exit(0);
                    }
                }).setNegativeButton("No", null).show();
        }
        startLocalServer(3000, "www", true, true );
    }

  public void startLocalServer(int port, String root, Boolean localhost, Boolean keepAlive) {
      try {
          File www_root = new File(root);
          server = new WebServer("localhost", port, www_root.getAbsoluteFile());
          server.start();
          printIp();
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

When I tried to visit localhost:3000, I got the error: given path is not a directory. The error seems to come from this line: https://git.io/fjS3f

I guess the way I initialize the rootDir is wrong (this line: https://git.io/fjS3v). But how can I make this work? I mean to serve the whole directory, which means all CSS/JS/hypyerlinks should work, once nanohttpd starts serving...

like image 414
lkahtz Avatar asked Jul 29 '19 14:07

lkahtz


People also ask

What is NanoHttpd web server?

Introduction NanoHTTPD is an open-source, lightweight, web server written in Java. In this tutorial, we'll create a few REST APIs to explore its features. 2. Project Setup To create a simple server, we need to extend NanoHTTPD and override its serve method:

What is a “static” server?

While developing applications, learning to use a library or just testing out something quick, you might encounter the need to host your files in a “static” server-meaning that you just need an HTTP server to serve files as-is from a directory - .

How does the staticserve function work on localhost?

This code handles all requests to the address localhost:8080. Even for non-root paths like localhost:8080/some/url/path you'll still get the same response. So every request received by the server is handled by the staticServe function, which is where the bulk of our static server logic will be.

How do I use echo with NanoHttpd?

A small standard echo example is included as org.nanohttpd.samples.echo.DebugWebSocketServer. You can use it as a starting point to implement your own services. For a more classic approach, perhaps to just create a HTTP server serving mostly service files from your disk, you can use the module with artifactId nanohttpd-webserver.


1 Answers

The problem is that you cannot access files in the assets folder as if they were local files. You have to extend NanoHTTPD and override serve(IHTTPSession) in order to serve assets. Here is an example in Kotlin. Let me know if you cannot read it and I will port it to Java.

class FileServer(private val context: Context, port: Int) : NanoHTTPD(port) {
override fun serve(session: IHTTPSession): Response {
    val uri = session.uri.removePrefix("/").ifEmpty { "index.html" }
    println("Loading $uri")
    try {
        val mime = when (uri.substringAfterLast(".")) {
            "ico" -> "image/x-icon"
            "css" -> "text/css"
            "htm" -> "text/html"
            "html" -> "text/html"
            else -> "application/javascript"
        }

        return NanoHTTPD.newChunkedResponse(
            Response.Status.OK,
            mime,
            context.assets.open("www/$uri") // prefix with www because your files are not in the root folder in assets
        )
    } catch (e: Exception) {
        val message = "Failed to load asset $uri because $e"
        println(message)
        e.printStackTrace()
        return NanoHTTPD.newFixedLengthResponse(message)
    }
}
like image 152
Yuriy Kulikov Avatar answered Sep 22 '22 10:09

Yuriy Kulikov