Ошибка возврата файла с Java WebServer - PullRequest
0 голосов
/ 21 февраля 2012

У меня проблемы с этим базовым, простым веб-сервером, который я написал на Java. По какой-то причине вместо того, чтобы отправлять «200 OK» или «404 Not Found» исключительно в браузер, они записываются в любой извлекаемый файл. Например, если я пытаюсь получить файл index.html, мне возвращается:

example

.... а не браузер, пытающийся скомпилировать HTML. Еще хуже при попытке получить изображение, так как файл поврежден с сервера, пытающегося добавить к нему «200 OK» и тип контента. Может кто-нибудь предложить какие-либо идеи о том, как отправить строку состояния и тип содержимого отдельно от фактического файла HTML / JPG? Ошибка полностью исчезает, когда я закомментирую «os.writeBytes (statusLine)» и т. Д., Но я все еще хочу отправить эти сообщения в браузер ... только не объединенные с файлом. Любая помощь будет принята с благодарностью.

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

final class HttpRequest implements Runnable {
    final static String CRLF = "\r\n";
    Socket socket;

    // Constructor
    public HttpRequest(Socket socket) throws Exception {
        this.socket = socket;
    }

    // Implement the run() method of the Runnable interface.
    public void run() {
        try {
            processRequest();
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    private static void sendBytes(FileInputStream fis, OutputStream os) 
    throws Exception {
    // Construct a 1K buffer to hold bytes on their way to the socket.
    byte[] buffer = new byte[1024];
    int bytes = 0;

    // Copy requested file into the socket's output stream.
    while((bytes = fis.read(buffer)) != -1 ) {
        os.write(buffer, 0, bytes);
        }
    }

    private static String contentType(String fileName) {
    if(fileName.endsWith(".htm") || fileName.endsWith(".html")) {
        return "text/html";
    }
    if(fileName.endsWith(".jpeg") || fileName.endsWith(".jpg")) {
    return "image/jpeg";
    }
    if(fileName.endsWith(".gif")) {
    return "image/gif";
    }
    return "application/octet-stream";
    }

    private void processRequest() throws Exception {
        // Get a reference to the socket's input and output streams.
        InputStream is = socket.getInputStream();
        DataOutputStream os = new DataOutputStream(socket.getOutputStream());

        // Set up input stream filters.
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        // Get the request line of the HTTP request message.
        String requestLine = new String(br.readLine());

        // Display the request line.
        System.out.println();
        System.out.println(requestLine);

        // Get and display the header lines.
        String headerLine = null;
        while ((headerLine = br.readLine()).length() != 0) {
            System.out.println(headerLine);
        }

    // Extract the filename from the request line.
    StringTokenizer tokens = new StringTokenizer(requestLine);
    tokens.nextToken(); // skip over the method, which should be "GET"
    String fileName = tokens.nextToken();
    // Prepend a "." so that file request is within the current directory.
    fileName = "." + fileName;

    // Open the requested file.
    FileInputStream fis = null;
    boolean fileExists = true;
    try {
    fis = new FileInputStream(fileName);
    } catch (FileNotFoundException e) {
    fileExists = false;
    }

    // Construct the response message.
    String statusLine = null;
    String contentTypeLine = null;
    String entityBody = null;
    if (fileExists) {
    statusLine = "200 OK" + CRLF;
    contentTypeLine = "Content-type: " + 
        contentType( fileName ) + CRLF;
    } else {
    statusLine = "404 NOT FOUND" + CRLF;
    contentTypeLine = "Content Not Found!" + CRLF;
    entityBody = "<HTML>" + 
        "<HEAD><TITLE>Not Found</TITLE></HEAD>" +
        "<BODY>Not Found</BODY></HTML>";
    }

    // Send the status line.
    os.writeBytes(statusLine);

    // Send the content type line.
    os.writeBytes(contentTypeLine);

    // Send a blank line to indicate the end of the header lines.
    os.writeBytes(CRLF);

    // Send the entity body.
    if (fileExists) {
    sendBytes(fis, os);
    fis.close();
    } else {
    os.writeBytes("File DNE: Content Not Found!");
    }

        // Close streams and socket.
        os.close();
        br.close();
        socket.close();
    }
    public static void main(String[] args) throws Exception {
        final ServerSocket ss = new ServerSocket(6789);
        while (true)
            new HttpRequest(ss.accept()).run();
    }
}

Ответы [ 2 ]

2 голосов
/ 21 февраля 2012

Я полагаю, вам не хватает CRLF. Разве нет необходимости в дополнительном, в конце строки состояния

200 ОК Тип контента: хххх

Конечно, вы можете прочитать спецификацию HTTP или выполнить трассировку Wireshark:)

Обновление: да, у вас много проблем. Прочитайте Easy Http для простого Резюме.

Но в любом случае вам нужно сказать «HTTP / 1.0 200 OK», например

http://www.somehost.com/path/file.html

сначала откройте сокет для хоста www.somehost.com, порт 80 (используйте порт по умолчанию, равный 80, поскольку ни один из них не указан в URL). Затем отправьте что-то вроде следующего через сокет:

GET /path/file.html HTTP/1.0
From: someuser@jmarshall.com
User-Agent: HTTPTool/1.0
[blank line here]

Сервер должен ответить примерно следующим образом, отправленным обратно через тот же сокет:

HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Content-Type: text/html
Content-Length: 1354

<html>
<body>
<h1>Happy New Millennium!</h1>
(more file contents)
  .
  .
  .
</body>
</html>
0 голосов
/ 23 декабря 2014

На statusLine = "200 ОК" + CRLF;

У вас нет правильного запроса, вам не хватает HTTP / 1.1

правильный код:

if (fileExists) {
    statusLine = "HTTP/1.1 200 OK" + CRLF;
    contentTypeLine = "Content-type: " + 
        contentType( fileName ) + CRLF + CRLF;
    } else {
    statusLine = "404 NOT FOUND" + CRLF;
    contentTypeLine = "Content Not Found!" + CRLF;
    entityBody = "<HTML>" + 
        "<HEAD><TITLE>Not Found</TITLE></HEAD>" +
        "<BODY>Not Found</BODY></HTML>";
    }
...