如何使用http响应Java

时间:2019-03-07 20:11:28

标签: java http

我正在尝试制作Java TCP Multithread Server,该服务器允许您制作“ GET”和“ HEAD”。问题是即使正确发送HEAD,发送的文件也不会加载到浏览器上。

Js代码:

ServerTCP.java

package ServerTCP;

import java.net.*;
import java.io.*;


public class ServerTCP{
    public static void main(String argv[]) throws IOException {
        if (argv.length != 1) {
            System.err.println("Format: ServerTCP <port>");
            System.exit(-1);
        }
        Socket connectionSocket = null;
        try{
            // Create a server socket
            int port = Integer.parseInt(argv[0]);
            ServerSocket server = new ServerSocket(port);
            // Set a timeout of 300 secs
            server.setSoTimeout(300000);
            while(true){
                // Esperamos posibles conexiones
                connectionSocket = server.accept();
                // Creamos un objeto ThreadServidor, pasándole la nueva conexión
                ThreadServer handler = new ThreadServer(connectionSocket);
                // Iniciamos su ejecución con el método start()
                handler.start();
            }
        }catch(SocketTimeoutException e){
            System.err.println("Nothing received in 300 secs");
        }catch(IOException | NumberFormatException e){
            System.err.println("Error: " + e.getMessage());
        }finally{
            if(connectionSocket != null)
                connectionSocket.close();
        }
    }
} 

ThreadServer.java

package ServerTCP;

import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.time.format.DateTimeFormatter;  
import java.time.LocalDateTime;  
import java.time.ZoneId;


public class ThreadServer extends Thread {
    Socket socket;
    public ThreadServer(Socket s) {
        // Almacenamos el socket de la conexión
        this.socket = s;
    }
    @SuppressWarnings("override")
    public void run() {
        try {
            // Establecemos el canal de entrada
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // Establecemos el canal de salida
            DataOutputStream writer = new DataOutputStream(socket.getOutputStream());
            reply(reader,writer);

            // Cerramos los flujos
        } catch (SocketTimeoutException e) {
            System.err.println("300 segs sin recibir nada");
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
        } finally {
            try {
                // Cerramos el socket
                this.socket.close();
            } catch (IOException ex) {
                Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }


    public void reply(BufferedReader input, DataOutputStream output){
        // Recibimos el mensaje del cliente
        String requestLine = null;
        try {
            requestLine = input.readLine();
        } catch (IOException ex) {
            Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        String[] splittedHead = requestLine.split(" ",3);
        String reqMethod = splittedHead[0];
        String reqResource = "./" + checkFileRequested(splittedHead[1]);
        String reqProtocol = splittedHead[2];
        System.out.println(reqResource);
        String resStateLine = reqProtocol;
        String statusCode;
        int fileType=0;

        if("GET".equals(reqMethod) || "get".equals(reqMethod) || "HEAD".equals(reqMethod) || "head".equals(reqMethod)){
            statusCode = "200 OK";
            System.out.println(resStateLine);
        }else{
            statusCode = "400 Not Implemented";
            try {
                output.writeBytes(createHead(reqProtocol,statusCode,-1,0));
            } catch (IOException ex) {
                Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        File f = new File(reqResource);
        if(!f.exists() || f.isDirectory()){
            statusCode = "404 Not Found";
            try {
                output.writeBytes(createHead(reqProtocol,statusCode,-1,0));
            } catch (IOException ex) {
                Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }else{
            FileInputStream file = null;
            try {
                file = new FileInputStream(reqResource);
            } catch (FileNotFoundException ex) {
                Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
            }

            if(reqResource.toLowerCase().endsWith(".html")){
                fileType = 1;
            }
            if(reqResource.toLowerCase().endsWith(".txt")){
                fileType = 2;
            }
            if(reqResource.toLowerCase().endsWith(".gif")){
                fileType = 3;
            }
            if(reqResource.toLowerCase().endsWith(".png")){
                fileType = 4;
            }
            try {
                output.writeBytes(createHead(reqProtocol,statusCode,fileType,f.length()));
            } catch (IOException ex) {
                Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
            }

            if("GET".equals(reqMethod)){
                try{                   
                    while(true){
                        int b = file.read();                      
                        if(b == -1){
                            break;
                        }
                        output.write(b);
                    }
                }catch(IOException e){
                    System.err.println(e);
                    System.err.println("No se pudo enviar el contenido de la respuesta correctamente");
                }
            }
        }
    }
    public String checkFileRequested(String reqResource){
        String[] resource = reqResource.split("/",2);
        if(resource.length == 0){
          return reqResource;  
        }else{
            return resource[1];
        }
    }
    public String createHead(String protocol,String statusCode,int fileType, long fileSize){
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss z").withZone(ZoneId.systemDefault());
        LocalDateTime now = LocalDateTime.now();
        String currentTime = "Date: " + now.format(dtf);
        String serverMessage = "Server: Node.js/v10.15.0 (Raspbian)";
        String contentLength = "Content-Length: " + fileSize;
        String contentType = null;


        switch(fileType){
            default:
            case -1:
                contentType = "Content-Type: application/octet-stream";
                break;
            case 1:
                contentType = "Content-Type: text/html";
                break;
            case 2:
                contentType = "Content-Type: text/plain";
                break;
            case 3:
                contentType = "Content-Type: image/gif";
                break;
            case 4:
                contentType = "Content-Type: image/png";
                break;
        }
        String head = protocol + " " + statusCode + System.lineSeparator() + 
            currentTime + System.lineSeparator() + 
            serverMessage + System.lineSeparator() + 
            contentLength + System.lineSeparator() +
            contentType + System.lineSeparator();

        return head;
    }
}

我要测试的是使用netcat,先在端口2100上运行服务器,然后在 nc localhost 上运行,然后仅使用 get localhost / fic.png http / 1.1

我从netcat收到的答案如下:

get localhost/fic.png http/1.0
http/1.0 200 OK
Date: jue, 7 mar 2019 18:44:57 CET
Server: Node.js/v10.15.0 (Raspbian)
Content-Length: 13320
Content-Type: image/png

一切正常,如果文件不存在,它将给出404,如果它是未定义的方法,它将返回400。但是正如我之前在浏览器中所说,我看不到文档(仅适用于txt,这太奇怪了,因为我不认为MIME有任何问题。希望所有必要的信息都在帖子中。

非常感谢您:D

1 个答案:

答案 0 :(得分:0)

解决了,如评论中所述,我对HTTP协议有误解。当我不得不离开2个行间距符时,我在内容和HEAD之间留下了1个行分隔符。