Search code examples
javahttpserversimplehttpserver

Why can't my web client accept an image from my web server?


I this is my java HTTP server:

public class WebServer implements Runnable {
    public static final int PORT = 80;
    @Override
    public void run() {
        HttpServer $server;
        try {
            $server = HttpServer.create(new InetSocketAddress(80), 0);
        } catch (IOException _e) {
            throw new RuntimeException(_e);
        }
        $server.createContext("/", _httpExchange ->
        {
            String $uri = _httpExchange.getRequestURI().toString();
            $uri = $uri.startsWith("/") ? $uri.replaceFirst("/", "") : $uri;
            if ($uri.equals("")) {
                sendFile("test.html", _httpExchange);
            }
            else if ($uri.matches(".*\\.[^/.]+")) {
                sendFile($uri, _httpExchange);
            }
            else {
                sendFile($uri + ".html", _httpExchange);
            }
        });
        $server.start();
        System.out.println("Server started at " + getPrivateIp() + " on port " + PORT);
    }


    private static String getPrivateIp() {
        try (final DatagramSocket datagramSocket = new DatagramSocket()) {
            datagramSocket.connect(InetAddress.getByName("8.8.8.8"), 12345);
            return datagramSocket.getLocalAddress().getHostAddress();
        } catch (UnknownHostException | SocketException _e) {
            throw new RuntimeException(_e);
        }
    }
    public static void sendFile(String _name, HttpExchange _exchange) throws IOException {
        try {
            InputStream $stream = WebServer.class.getResourceAsStream(_name);
            if ($stream == null) {
                _exchange.sendResponseHeaders(404, 0);
                _exchange.close();
                return;
            }
            Scanner $scanner = new Scanner($stream).useDelimiter("\\A");
            String $response = $scanner.next();
            _exchange.getResponseBody();
            _exchange.sendResponseHeaders(200, $response.getBytes().length);
            _exchange.getResponseBody().write($response.getBytes());
            _exchange.close();
        } catch (Exception _ex) {
            throw new RuntimeException(_ex);
        }
    }
}

When I run it, and then open my website, everything is ok, but I cannot see any images. In the network tab, it says that the image was accepted, but it's not shown. I tried using Files.copy() in sendFile() method, but it didn't work - it didn't show the website, nor the image! (Not even when I did localhost/image.jpg).

In the network tab, it also shows that the MIME type is img/jpeg, which is correct, so it's not because of that...

Using wget, I get a normal looking .jpg file, but if I open it, it's corrupted...

Does someone know how to fix this? Thanks.


Solution

  • Solved it!

    You just check if the request wants .png or .jpg file (or you can just check the MIME type), and if it does, then you have to use ImageIO class

    public static void sendFile(String _name, HttpExchange _exchange) {
            try {
                InputStream $stream = WebServer.class.getResourceAsStream(_name);
                if ($stream == null) {
                    _exchange.sendResponseHeaders(404, 0);
                    _exchange.close();
                    return;
                }
                if (_name.matches(".*?\\.(png|PNG|jpg|JPG|jpeg|JPEG)")) {
                    BufferedImage $image = ImageIO.read($stream);
                    if (_name.toLowerCase().endsWith("png")) {
                        _exchange.sendResponseHeaders(200, getImageSize($image, "png"));
                        ImageIO.write($image, "png", _exchange.getResponseBody());
                    }
                    else {
                        _exchange.sendResponseHeaders(200, getImageSize($image,"jpeg"));
                        ImageIO.write($image, "jpeg", _exchange.getResponseBody());
                    }
                    $stream.close();
                    _exchange.close();
                    return;
                }
                Scanner $scanner = new Scanner($stream).useDelimiter("$");
                String $response = $scanner.next();
                _exchange.getResponseBody();
                _exchange.sendResponseHeaders(200, $response.length());
                _exchange.getResponseBody().write($response.getBytes());
                _exchange.close();
            } catch (Exception _ex) {
                throw new RuntimeException(_ex);
            }
        }