Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why images and style files couldn't found on NanoHTTPD

PROBLEM : I'm using NanoHTTPD . It's working great but it's not serving .js files, images and others.

DETAILED EXPLANATION : i have a pages folder inside of assets folder. This folder containing index.html, css files, images and others. I'm using NanoHTTPD like this, but when i browse with my browser, there aren't any styles or images. Server can't found images and other files. There is only index.html file's content. Activity :

MyHTTPD server = null;
        try {
            server = new MyHTTPD(getApplicationContext());
            try
               {
                   server.start();
               }
               catch( IOException ioe )
               {
                   System.err.println( "Couldn't start server:\n" + ioe );
                   System.exit( -1 );
               }
               System.out.println( "Listening on port 8080. Hit Enter to stop.\n" );
               try { System.in.read(); } catch( Throwable t ) {
                   System.out.println("read error");
               };
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

MyHTTPD class

public Context ctx = null;
    /**
    * Constructs an HTTP server on given port.
    */
   public MyHTTPD(Context ctx) throws IOException {
       super(8080);
       this.ctx = ctx;
   }


@Override
   public Response serve( String uri, Method method,
           Map<String, String> header, Map<String, String> parms,
           Map<String, String> files )
           {
            String html = null;
            InputStream is = null;
            try {
                is = ctx.getAssets().open("pages/index.html");
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            byte[] b;
            try {
                b = new byte[is.available()];
                is.read(b);
                html = new String(b);
            } catch (IOException e) { // TODO Auto-generated catch block
                e.printStackTrace();
            }
               return new NanoHTTPD.Response(html);
           }

NOTE : I've read this questions (and answers) : Using NanoHTTPD in Android file uploading error nanohttpd How to create nanohttpd server in android?

like image 803
Eray Avatar asked Dec 02 '22 19:12

Eray


1 Answers

in my serve() method it looks like this:

                 @Override
            public Response serve(String uri, String method, Properties header, Properties parms, Properties files) {
                       Log.d(TAG,"SERVE ::  URI "+uri);
              final StringBuilder buf = new StringBuilder();
              for (Entry<Object, Object> kv : header.entrySet())
                buf.append(kv.getKey() + " : " + kv.getValue() + "\n");
              InputStream mbuffer = null;



                            try { 
                                    if(uri!=null){

                                       if(uri.contains(".js")){
                                               mbuffer = mContext.getAssets().open(uri.substring(1));
                                               return new NanoHTTPD.Response(HTTP_OK, MIME_JS, mbuffer);
                                       }else if(uri.contains(".css")){
                                               mbuffer = mContext.getAssets().open(uri.substring(1));
                                               return new NanoHTTPD.Response(HTTP_OK, MIME_CSS, mbuffer);

                                       }else if(uri.contains(".png")){
                                               mbuffer = mContext.getAssets().open(uri.substring(1));      
                                               // HTTP_OK = "200 OK" or HTTP_OK = Status.OK;(check comments)
                                               return new NanoHTTPD.Response(HTTP_OK, MIME_PNG, mbuffer);
                                       }else if (uri.contains("/mnt/sdcard")){
                                               Log.d(TAG,"request for media on sdCard "+uri);
                                               File request = new File(uri);
                                               mbuffer = new FileInputStream(request);
                                               FileNameMap fileNameMap = URLConnection.getFileNameMap();
                                               String mimeType = fileNameMap.getContentTypeFor(uri);

                                               Response streamResponse = new Response(HTTP_OK, mimeType, mbuffer);
                                               Random rnd = new Random();
                                String etag = Integer.toHexString( rnd.nextInt() );
                                streamResponse.addHeader( "ETag", etag);
                                               streamResponse.addHeader( "Connection", "Keep-alive");






                                               return streamResponse;
                                       }else{
                                               mbuffer = mContext.getAssets().open("index.html");
                                               return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, mbuffer);
                                       }
                                    }

                            } catch (IOException e) {
                                    Log.d(TAG,"Error opening file"+uri.substring(1));
                                    e.printStackTrace();
                            }

                      return null;

            }

There is some not so clean solution with mime types. Validation should be done with something like this Getting A File's Mime Type In Java, I my simple project I am just checking few kinds of mime.
Reference mime types are static fields in NanoHTTPD class:

       /**
     * Common mime types for dynamic content
     */
    public static final String
            MIME_PLAINTEXT = "text/plain",
            MIME_HTML = "text/html",
            MIME_JS = "application/javascript",
            MIME_CSS = "text/css",
            MIME_PNG = "image/png",
            MIME_DEFAULT_BINARY = "application/octet-stream",
            MIME_XML = "text/xml";

With this implementation I was able to read files from assets as well as from external memory.

like image 165
MP23 Avatar answered Dec 10 '22 12:12

MP23