简体   繁体   中英

Correct way for responding resources from http server

I have this index.html page:

   <html>
    <head>
     <title>My Site</title>
     <link rel="stylesheet" type="text/css" href="css/example.css" />
    </head>
    <body>
     <h2>Hello world</h2>
     <p>Image:</p>
     <img src="someimage.jpg" alt="W3Schools.com" width="104" height="142">
    </body>
   </html>

And I wrote a simple java Http server. This server handles the request, load index.html from the resources folder and responses to the client(browser). The client sees index.html but without resources(images, CSS, js). Because browser after loading index.html tries to load all resources included to this page. But resources in the server. I Wrote a new handler with path like /assets/ and tried to replace all links to resources in index.html like this:

<img src="someimage.jpg" width="104" height="142">

to

<img src="/assets/someimage.jpg" width="104" height="142">

After that in /assets/ handler, I cut the first part of URI ( /assets/ ) and try load from resources second part of URI( someimage.jpg );

It works, but I can not load CSS. Because I replace pageAsString.replace("src=\\"", "/assets/"); but CSS in href="css/example.css"

Maybe I doing something wrong and this approach is bad? How can I return index.html to the client and give the ability for loading resources from the server?

Made quick single-class project based on your question. Made IMG and SCRIPT tags work:

package test.server;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.URI;

public class MyHandler implements HttpHandler {
    public void handle(HttpExchange t) throws IOException, IOException {
        InputStream is = t.getRequestBody();

        InputStreamReader isReader = new InputStreamReader(is);
        BufferedReader reader = new BufferedReader(isReader);
        StringBuffer sb = new StringBuffer();
        String str;
        while((str = reader.readLine())!= null){
            sb.append(str);
        }

        String response = "<html>\n" +
                "\n" +
                "<head>\n" +
                "    <title>My Site</title>\n" +
                "    <link rel=\"stylesheet\" type=\"text/css\" href=\"css/example.css\" />\n" +
                "</head>\n" +
                "\n" +
                "<body>\n" +
                "    <h2>Hello world</h2>\n" +
                "    <p>Image:</p>\n" +
                "    <img src=\"/assets/cat.jpg\" alt=\"W3Schools.com\" width=\"104\" height=\"142\">\n" +
                "    <script src=\"/assets/alert.js\"></script>\n" +
                "</body>\n" +
                "\n" +
                "</html>";

        t.sendResponseHeaders(200, response.length());
        OutputStream os = t.getResponseBody();
        os.write(response.getBytes());
        os.close();
    }

    public static void main(String[] args) {

        InetSocketAddress cd = new InetSocketAddress(8080);
        HttpServer server = null;
        try {
            server = HttpServer.create(cd, 8080);
        } catch (IOException e) {
            e.printStackTrace();
        }

        server.createContext("/main", new MyHandler());

        server.createContext("/assets/", new HttpHandler() {
            @Override
            public void handle(HttpExchange httpExchange) throws IOException {
                String root = "!!! YOUR SITE ROOT IN FILE SYSTEM !!!";
                URI uri = httpExchange.getRequestURI();
                File file = new File(root + uri.getPath()).getCanonicalFile();
                if (!file.getPath().startsWith(root)) {
                    // Suspected path traversal attack: reject with 403 error.
                    String response = "403 (Forbidden)\n";
                    httpExchange.sendResponseHeaders(403, response.length());
                    OutputStream os = httpExchange.getResponseBody();
                    os.write(response.getBytes());
                    os.close();
                } else if (!file.isFile()) {
                    // Object does not exist or is not a file: reject with 404 error.
                    String response = "404 (Not Found)\n";
                    httpExchange.sendResponseHeaders(404, response.length());
                    OutputStream os = httpExchange.getResponseBody();
                    os.write(response.getBytes());
                    os.close();
                } else {
                    // Object exists and is a file: accept with response code 200.
                    httpExchange.sendResponseHeaders(200, 0);
                    OutputStream os = httpExchange.getResponseBody();
                    FileInputStream fs = new FileInputStream(file);
                    final byte[] buffer = new byte[0x10000];
                    int count = 0;
                    while ((count = fs.read(buffer)) >= 0) {
                        os.write(buffer,0,count);
                    }
                    fs.close();
                    os.close();
                }
            }
        });
        server.setExecutor(null); // creates a default executor
        server.start();
    }
}

alert.js can be like

alert("I'm from inner file!");
console.log("I'm from inner file!");

image is any jpg image

project structure (for us there are src and assets folders):

在此处输入图片说明

Run main method and go to http://localhost:8080/main

Everything should work correct.

NOTE One thing in java code you should change - path in your file system.

PS based on http://www.microhowto.info/howto/serve_web_pages_using_an_embedded_http_server_in_java.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM