title: HTTP Proxy, Content-Length not adding up properly
body: <p>I am trying to write a simple HTTP proxy in java using sockets, basically just takes a request, reads it and forwards it to the server, reads the response and back to the browser. The issue I am having is in the response there is a Content-Length field which I parse, and I wrote a loop to read exactly that number of bytes to send back to the browser, but it gets to the end of the stream prior to reading the correct amount (read returns -1). I'll add the bare bones code of my proxy below - the main thread just spawns one of these classes when a connection is made. Does anyone have any ideas? It would be very helpful.</p>
  
  <pre><code>public class ProxyClient implements Runnable {
  
  Socket clientSocket;
  Socket netflixSocket;
  
  InputStream isClient = null;
  OutputStream osClient = null;
  BufferedReader brClient = null;
  
  InputStream isNetflix = null;
  OutputStream osNetflix = null;
  BufferedReader brNetflix = null;
  boolean connectedNetflix = false;
  
  String meta = "";   //header data
  
  public ProxyClient(Socket connectionSocket){
      this.clientSocket = connectionSocket;
  
      try {
          isClient = clientSocket.getInputStream();
          osClient = clientSocket.getOutputStream();
          brClient = new BufferedReader(new InputStreamReader(isClient));
      } catch (IOException e1) {
          e1.printStackTrace();
      }
  
  }
  
  @Override
  public void run() {
  
  
      String host = "";
  
      String temp;        // temp read line from buffer
      String getRequest;
      int contentLength;  //holder for reading bytes.
      int bytesRead;      // Total number of bytes read during consecutive reads
      int numRead;        // Number of bytes read in a single read.
  
  
      byte[] dataBuffer = new byte[2000000];
  
  
      while(true){
  
          try {
  
  
              // reading client HTTP request / connecting
              host = "";
              meta = "";
              contentLength = 0;
              getRequest = "";
              while((temp = brClient.readLine()).length() &gt; 0){
                      meta += temp + "\r\n";
  
                      //connect to server
                      if(!connectedNetflix &amp;&amp; temp.startsWith("Host")){
  
                          // extract the host to connect to
                          host = temp.substring(temp.indexOf(':') + 2);
  
                          //connect to the host
                          try {
                              netflixSocket = new Socket(host, 80);
                              osNetflix = netflixSocket.getOutputStream();
                              isNetflix = netflixSocket.getInputStream();
                              brNetflix = new BufferedReader(new InputStreamReader(isNetflix));
                          } catch (UnknownHostException e) {
                              e.printStackTrace();
                          } catch (IOException e) {
                              e.printStackTrace();
                          }
  
                          connectedNetflix = true;
  
                      }
                      else if (temp.startsWith("Content-Length:")) {
                          contentLength = Integer.parseInt(temp.substring(temp.indexOf(':') + 2));
                      }
  
              }
              meta += "\r\n"; // add blank line
  
  
              //read request content, if any
              if(contentLength &gt; 0){
                  numRead = 0;
                  bytesRead = 0;
                  while(bytesRead != contentLength){
                      numRead = isNetflix.read(dataBuffer, bytesRead, contentLength-bytesRead);
                      if(numRead &gt;0){
                          bytesRead += numRead;
                      }
                  }
              }
  
  
              //send to server
              osNetflix.write(meta.getBytes());
              if(contentLength &gt; 0){
                  osClient.write(dataBuffer, 0, contentLength);
              }
              osNetflix.flush();
  
  
              //Read response from server
              contentLength = 0;
              meta = "";
              while((temp = brNetflix.readLine()).length() &gt; 0){
                  meta += temp + "\r\n";
  
                  if (temp.startsWith("Content-Length:")) {
                      contentLength = Integer.parseInt(temp.substring(temp.indexOf(':') + 2));
                  }
  
              }               
              meta += "\r\n"; // add blank line
  
  
              //read Netflix content
              if(contentLength &gt; 0){
                  numRead = 0;
                  bytesRead = 0;
                  while(bytesRead != contentLength){
                      numRead = isNetflix.read(dataBuffer, bytesRead, contentLength-bytesRead);
                      if(numRead &gt;0){
                          bytesRead += numRead;
                      }
  
                  }
  
              }               
  
  
              // write back to browser/client
              osClient.write(meta.getBytes());
              if(contentLength &gt; 0){
                  osClient.write(dataBuffer, 0, contentLength);
              }
              osClient.flush();
  
          } catch (IOException e) {
              e.printStackTrace();
          }
  
  
  
      }
  
  
  }
  }
  </code></pre>
  
  <p>Here is a sample response header:</p>
  
  <pre><code>HTTP/1.1 200 OK
  Server: Apache
  Accept-Ranges: bytes
  Content-Type: text/plain
  Content-Type: application/octet-stream
  Access-Control-Allow-Origin: *
  Content-Type: application/octet-stream
  Last-Modified: Fri, 17 Jun 2011 07:52:37 GMT
  ETag: "0d6a07a1c0e6772459e73f7c0c4fd899:1308297157"
  Date: Thu, 31 May 2012 01:54:10 GMT
  Content-Length: 294183
  Connection: close
  Cache-Control: no-store
  </code></pre>