title: Error with Java HTTP Server: Unexpected end of file from server
body: <p><strong>java.net.SocketException: Unexpected end of file from server</strong></p>
  
  <p>The client sends a query to the server by using an URL. I have a HTTPServer that parses info from the URL. Using that info, the server does some work and then returns the response to the client.</p>
  
  <p>Let's say the URL is:</p>
  
  <pre><code>http://localhost:9090/find?term=healthy&amp;term=cooking&amp;count=3
  </code></pre>
  
  <p>This works fine. But when count is greater or equal to 4, I get java.net.SocketException.
  To debug the error, I print out the URL. System.out.println(input);
  When count>=4, the URL gets printed two times in the console. Please help.</p>
  
  <pre><code>private final HttpServer server;
  public Server(int port){
    server = HttpServer.create(new InetSocketAddress(port), MAX_BACKLOG);
    server.createContext("/isbn", new ISBNHandler());
    server.createContext("/find", new TitleHandler());
  }
  
  static class TitleHandler implements HttpHandler {
    public void handle(HttpExchange t) throws IOException {
      int count=5;
      String input=t.getRequestURI().toASCIIString();//get the URL
      System.out.println(input);
      //using info from URL to do some work
      String response = builder.toString();//StringBuilder
      // System.out.println(response);
      t.sendResponseHeaders(200, response.getBytes().length);
      OutputStream os = t.getResponseBody();
      os.write(response.getBytes());
      os.close();
    }
  }
  </code></pre>
  
  <p><strong>Exception</strong></p>
  
  <blockquote>
    <p>java.net.SocketException: Unexpected end of file from server at
    sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source) at
    sun.net.www.http.HttpClient.parseHTTP(Unknown Source) at
    sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source) at
    sun.net.www.http.HttpClient.parseHTTP(Unknown Source) at
    sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
    Source) at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at TestHarness.assertJSONResponse(TestHarness.java:101) at
    TestHarness.testServer(TestHarness.java:38) at
    TestHarness.main(TestHarness.java:25)</p>
  </blockquote>
  
  <p><strong>TestHarness</strong></p>
  
  <pre><code> import java.io.*;
      import java.net.HttpURLConnection;
       import java.net.URL;
      import java.util.*;
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;
  
  /**
   * Sample main method with initial acceptance tests to help you along
   */
  public class TestHarness {
      private static Pattern MAP_PATTERN = Pattern.compile("(['\"])(.*?)\\1:\\s*(['\"])(.*?)\\3");
      private static Pattern LIST_PATTERN = Pattern.compile("\\{(.*?)\\}");
  
      public static void main(String[] args) throws IOException {
          /*
          if (args.length &lt; 1) {
              System.out.println("The test harness requires a single parameter: the location of the CSV file to parse");
          }
          */
          BookServer server = new BookServer(9090, new File("books.csv"));
          server.start();
          testServer();
          server.stop();
      }
  
      /**
       * Run initial acceptance tests
       */
      @SuppressWarnings("unchecked")
      private static void testServer() {
          assertJSONResponse("Book Test", "http://localhost:9090/isbn/9780470052327",
                  createMap("isbn", "9780470052327", "title", "Techniques of Healthy Cooking", "author", "Mary Dierdre Donovan", "publisher", "Wiley", "publishedYear", "2007"));
          assertJSONResponse("Book Test", "http://localhost:9090/isbn/9780451169525",
                          createMap("isbn", "9780451169525", "title", "Misery", "author", "Stephen King", "publisher", "Signet", "publishedYear", "1987"));
          assertJSONResponse("Query Test", "http://localhost:9090/find?term=healthy&amp;term=cooking&amp;count=4",
                          Arrays.asList(createMap("isbn", "9780470052327", "title", "Techniques of Healthy Cooking", "author", "Mary Dierdre Donovan", "publisher", "Wiley", "publishedYear", "2007")));
  
      }
  
      /**
       * Helper method to convert the vararg parameters into a Map. Assumes alternating key, value, key, value... and calls
       * toString on all args
       *
       * @param args the parameters to put in the map, alternating key ancd value
       * @return Map of String representations of the parameters
       */
      private static Map&lt;String, String&gt; createMap(Object ... args) {
          Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
          for (int i=0; i &lt; args.length; i+=2) {
              map.put(args[i].toString(), args[i+1].toString());
          }
          return map;
      }
  
      /**
       * Parses a JSON list of maps
       * NOTE: assumes all keys and values in the nested maps are quoted
       *
       * @param content the JSON representation
       * @return a list of parsed Map content
       */
      private static List&lt;Map&lt;String, String&gt;&gt; parseJSONList(CharSequence content) {
          List&lt;Map&lt;String, String&gt;&gt; list = new ArrayList&lt;Map&lt;String, String&gt;&gt;();
          Matcher m = LIST_PATTERN.matcher(content);
          while(m.find()) {
              list.add(parseJSONMap(m.group(1)));
          }
          return list;
      }
  
      /**
       * Parse JSON encoded content into a Java Map.
       * NOTE: Assumes that all elements in the map are quoted
       *
       * @param content the JSON representation to be parsed
       * @return A map of parsed content
       */
      private static Map&lt;String, String&gt; parseJSONMap(CharSequence content) {
          Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
          Matcher m = MAP_PATTERN.matcher(content);
          while (m.find()) {
              map.put(m.group(2), m.group(4));
          }
          return map;
      }
  
      /**
       * Retrieve content from a test URL and assert that its content is the expected. Results will be printed to System.out for convenience
       *
       * @param testName Name of the test, to be used simply for labelling
       * @param urlString The URL to test
       * @param expected The content expected at that URL
       */
      private static void assertJSONResponse(String testName, String urlString, Object expected) {
          try {
              URL url = new URL(urlString);
              HttpURLConnection con = ((HttpURLConnection)url.openConnection());
              if (!assertTest(testName + " - response code", con.getResponseCode(), 200)) return;
  
              StringBuilder b = new StringBuilder();
              BufferedReader r = new BufferedReader(new InputStreamReader(con.getInputStream()));
              String line;
              while((line = r.readLine()) != null) b.append(line);
              String result = b.toString();
              assertTest(testName + " - content retrieved", !result.isEmpty(), true);
  
              Object parsed = result.trim().startsWith("[") ? parseJSONList(result) : parseJSONMap(result);
              assertTest(testName + " - parsed content match", parsed, expected);
          } catch (Exception e) {
              System.out.println(testName + ": &lt;&lt;&lt;FAILED with Exception&gt;&gt;&gt;");
              e.printStackTrace(System.out);
          }
      }
  
      /**
       * Log the results of a test assertion
       *
       * @param testName Name of the test, to be used simply for labelling
       * @param result The result of the operation under test
       * @param expected The expected content that the result will be compared against
       * @return whether the test was successful
       */
      private static boolean assertTest(String testName, Object result, Object expected) {
          boolean passed = result.equals(expected);
          System.out.println(testName + (passed ? ": &lt;&lt;&lt;PASSED&gt;&gt;&gt;" : String.format(": &lt;&lt;&lt;FAILED&gt;&gt;&gt; expected '%s' but was '%s'", expected, result)));
          return passed;
  
  
        }
      }
  </code></pre>