0

I learn the code from the first example of .

here is the index.html

<html>
  <head>
    <title>Welcome to BrainySoftware</title>
  </head>
  <body>
    <img src="./images/logo.gif">
    <br>
    Welcome to BrainySoftware.
  </body>
</html>

I know there will be 2 GET request. First is the html,the second is the img. But I do receive the third request sometimes. The third request is empty, I can get nothing from the request.

ServerSocket serverSocket = null;
int port = 8080;
try {
  serverSocket =  new ServerSocket(port, 1,    InetAddress.getByName("127.0.0.1"));
}
catch (IOException e) {
  e.printStackTrace();
  System.exit(1);
}
while (!shutdown) {
      Socket socket = null;
      InputStream input = null;
      OutputStream output = null;
      try {
        socket = serverSocket.accept();
        input = socket.getInputStream();
        output = socket.getOutputStream();

        // create Request object and parse
        Request request = new Request(input);
        request.parse();

        // create Response object
        Response response = new Response(output);
        response.setRequest(request);
        response.sendStaticResource();

        // Close the socket
        socket.close();

        //check if the previous URI is a shutdown command
        shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
      }
      catch (Exception e) {
        e.printStackTrace();
        continue;
      }
    }

When the third request comes, the method sendStaticResource throw an exception:
java.lang.NullPointerException because request.getUri() is null. My jdk version is 1.7,when I change the InetAddress from 127.0.0.1 to 192.168.50.132,the third request disappeared. I have no idea why not 2 requests, please help me.

Ataur Rahman Munna
  • 3,887
  • 1
  • 23
  • 34
  • 1
    Have you tried setting a breakpoint in a debugger and inspect what's coming in? It might be a HEAD instead of a GET request, checking for the server's capabilities or about other properties of a file - e.g. the "last change time". – Olaf Kock May 03 '16 at 06:00
  • Yes, I tried.It has request 3 times: ①GET /index.html HTTP/1.1 ②"" ③GET /images/logo.gif HTTP/1.1 –  May 03 '16 at 06:13
  • @TomEast I doubt it could be some [browser prefetching](https://developers.google.com/speed/articles/prefetching) optimization that is resulting in extra request. What is the browser you are using? Can you try with different browser. – Madhusudana Reddy Sunnapu May 03 '16 at 06:17
  • Yes, I tried.It has request 3 times: ①GET /index.html HTTP/1.1 ②"" ③GET /images/logo.gif HTTP/1.1 sometimes, the ② becomes GET /favicon.ico HTTP/1.1, then the code works well.It won't throw any exception. I got really confused. –  May 03 '16 at 06:20
  • @TomEast favicon is a shortcut fir favorite icon as described in https://en.wikipedia.org/wiki/Favicon. Browsers try to get the favicon and so we are seeing the third request but not sure why it is empty sometimes. Maybe we need to check if getUri is null before proceeding. – Madhusudana Reddy Sunnapu May 03 '16 at 06:33
  • Hi Reddy,you're right.I tried chrome and IE10. I clear two browser's cache first,and then use them request the server respectively. They both request 3 times. After that, I refresh the browser,IE request only once, chrome still request 3 times and one of the requests is empty,so the server throw a null exception.I don't know whether it is a bug in chrome. –  May 03 '16 at 07:21
  • I suggest the problem is the *second*, empty request, which could mean you aren't parsing the *first* request correctly, for example not consuming the final blank line after the headers. You need a good knowledge of RFC 2616 if you're going to implement HTTP, especially the parts about Content-length and connection lifetime. In any case a null pointer exception is certainly nobody's fault but your own. – user207421 May 04 '16 at 06:52

1 Answers1

1

If you accept connections from the world, there's no way you can blame the connecting browser to "have a bug". Even if it has: It's your responsibility to deal with whatever data you receive from outside. There might be exceptions thrown while handling these requests, but you better catch and handle them. If anything, your code must deal with anything that gets thrown to it.

The code you post seems to do so - but as it's overly simplistic it doesn't handle any nonexpected results gracefully. Instead, it just blasts out stacktraces - giving the impression that something went horribly wrong. I understand that you're not going to implement yet another handler for HTTP - that would be well covered territory - but rather are interested in testing out the concepts.

Coming back to what actually causes those requests: It's hard to say from a distance, without executing this code and doing everything here as well. As I'm saying in a comment, you should inspect the questionable request and the data that comes with it in a debugger. And keep in mind that HTTP seems very simple at first glance, but the spec contains a lot of details that you are completely omitting in this very simple connection handler - connection-keep-alive comes to my mind: One physical connection can carry multiple virtual connections (read: HTTP requests).

Olaf Kock
  • 46,930
  • 8
  • 59
  • 90