By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,105 Members | 2,541 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,105 IT Pros & Developers. It's quick & easy.

How to avoid EOFException while using readFully() in java

P: 3
I am doing a project for internet control using Java,PHP and MySql.All sites
should go through the proxy server only.We are giving access rights as allow or
deny to the sites.If we type the url,first it will ask for authentication.After
giving username and password,the authentication will be confirmed and if the
site has access right as allow,the website will open else a page will be
displayed.There we can send request mail to the administrator to give access
rights to open the site.This is the brief description of my project.
Here java is used as server(back-end) and php is used as front-end.The php files are used to store the values in the database.In the java proxy,i have specified the port,server-ip and apache-port.I am using j2sdk1.4.2_13 and Apache2 versions and working in Windows2000.

The sites which have no access rights are restricted properly.
But there is some problem in accessing sites which have access rights.
For example,rediff.com,sify.com are loading completely and msn.com,microsoft.com are loading partially and yahoo.com,gmail.com are not loading.

Refer the code mentioned below:


Expand|Select|Wrap|Line Numbers
  1.  import java.net.*; 
  2. import java.io.*;
  3. import java.util.*;
  4.  
  5. /* Stream reader for HTTP requests.The start line contains the whole URL (http://host/file) to retrieve. */
  6.  
  7. public class HTTPRequestReader extends HTTPMessageReader {
  8.  
  9. /* The method, eg. GET, POST, etc. */
  10. String command;
  11.  
  12. /* The host concerned in the request */
  13. String host;
  14.  
  15. /* The file (with full path) concerned in the request */
  16. String file;
  17.  
  18. /* The whole start line */
  19. String startLine;
  20.  
  21. /* The Basic authorization parameter */
  22. String auth;
  23.  
  24. /* Retrieves a HTTP request message from the connection stream.*/
  25. public HTTPRequestReader(InputStream istream) 
  26.      throws IOException, NoSuchElementException {
  27.     DataInputStream distream = new DataInputStream(istream);
  28.     this.contentLength = 0;
  29.     retrieveHeader(distream);
  30.  
  31.     // We've got the header, let's parse it. 
  32.     StringTokenizer st = 
  33.      new StringTokenizer(new String(HTTPMessageReader.toArray(header)));
  34.     command = st.nextToken();
  35.     URL url = new URL(st.nextToken());
  36.     host = url.getHost();
  37.     file = url.getFile();
  38.     versionProtocol = st.nextToken();
  39.  
  40.     startLine = new String(command + " " + url + " " + versionProtocol);
  41.  
  42.     // Parses, within the remaining header lines, the fields we want control:
  43.     String s;
  44.     while (st.hasMoreTokens()) 
  45.     {
  46.      s = st.nextToken();
  47.  
  48.      if (s.equals("Content-Length:"))
  49.          contentLength = Integer.parseInt(st.nextToken());
  50.  
  51.      if (s.equals("Connection:"))
  52.      {
  53.      connection = new String(st.nextToken());
  54. if (connection.equals("keep-alive")) mustCloseConnection = false;
  55.      }
  56.  
  57.      if (s.equals("Authorization:")) 
  58.      {
  59.          s = st.nextToken();
  60.          if (s.equals("Basic")) 
  61.          auth = new String(st.nextToken());
  62.      }
  63.     }
  64.  
  65.     retrieveBody(distream);
  66. }
  67. }
  68.  
  69.  
  70. --------------------------------------------------------------------------------
  71.  
  72.  
  73. import java.net.*;
  74. import java.io.*;
  75. import java.util.*;
  76.  
  77.  
  78. /**
  79. * Stream reader for HTTP responses.
  80. */
  81. public class HTTPResponseReader extends HTTPMessageReader {
  82.  
  83. /** Status line: The status code, eg. 200, 404, etc. */
  84. String statusCode;
  85.  
  86.  
  87. /**
  88. * Retrieves a HTTP response message from the connection stream.
  89. * @param istream the stream
  90. */
  91. public HTTPResponseReader(InputStream istream) 
  92.      throws IOException, NoSuchElementException {
  93.     DataInputStream distream = new DataInputStream(istream);
  94.  
  95.     retrieveHeader(distream);
  96.  
  97.     // We've got the header, let's parse it
  98.  
  99.     // Parses the status line
  100.     StringTokenizer st = 
  101.      new StringTokenizer(new String(HTTPMessageReader.toArray(header)));
  102.  
  103.     versionProtocol = st.nextToken();
  104.     statusCode = st.nextToken();
  105.  
  106.     String s;
  107.     while (st.hasMoreTokens()) 
  108.     {
  109.      s = st.nextToken();
  110.  
  111. if (s.equals("Content-Length:"))
  112.      contentLength = Integer.parseInt(st.nextToken());
  113.  
  114.  
  115.      if (s.equals("Connection:")) 
  116.      {
  117.      connection = new String(st.nextToken());
  118.      if (connection.equals("keep-alive")) mustCloseConnection = false;
  119.      }
  120.     }
  121.  
  122.     retrieveBody(distream);    
  123. }
  124.  
  125. }
  126.  
  127.  
  128.  
  129. --------------------------------------------------------------------------------
  130.  
  131.  
  132.  
  133. import java.net.*;
  134. import java.io.*;
  135. import java.util.*;
  136.  
  137.  
  138. /**
  139. * Stream reader for HTTP messages (requests and responses).
  140. */
  141. public abstract class HTTPMessageReader {
  142.  
  143. /** The header of the message (blank line included) */
  144. protected ArrayList header;
  145.  
  146. /** The body of the message */
  147. protected ArrayList body;
  148.  
  149. /** The whole message obtained from the stream */
  150. protected byte[] message;
  151.  
  152. /** Start/Status line: The version of HTTP protocol, eg. HTTP/1.1 */
  153. String versionProtocol;
  154.  
  155. /** Header field: The length of message body */
  156. protected int contentLength = -1;
  157.  
  158. /** Position of body in the message */
  159. protected int offset;
  160.  
  161. /** Header field: Connection */
  162. protected String connection;
  163.  
  164. /** Flag that informs whether the connection must be closed or not */
  165. protected boolean mustCloseConnection = true;
  166.  
  167.  
  168. /**
  169. * Reads inside the stream until the "\r\n" couple that
  170. * separes header from body message.
  171. * @param distream the stream of connection
  172. */
  173. protected void retrieveHeader(DataInputStream distream) throws IOException 
  174. {
  175.     header = new ArrayList();
  176.     byte data;
  177.     offset = 0;
  178.     while (true) {
  179.      data = (byte) distream.read();
  180.      if (data == '\r') {
  181.         header.add(new Byte(data));
  182.         data = (byte) distream.read();
  183.         if (data == '\n') {
  184.          header.add(new Byte(data));
  185.          data = (byte) distream.read();
  186.          if (data == '\r') {
  187.             header.add(new Byte(data));
  188.             data = (byte) distream.read();
  189.             if (data == '\n') {
  190.              header.add(new Byte(data));
  191.              break;
  192.             }
  193.          }
  194.         }
  195.      }
  196.      header.add(new Byte(data));
  197.     }
  198.  
  199.     if (ProxyMain.TRACEON_MSGS)
  200.      System.out.print(new String(toArray(header)));
  201. }
  202.  
  203.  
  204.  
  205. /**
  206. * Receives the body of the message (if exists) from the stream.
  207. * @param distream the stream of connection 
  208. */
  209.  
  210. protected void retrieveBody(DataInputStream distream) throws IOException {
  211.     /* HTTP/1.0 compliant: sets a buffer enough large for the data.
  212.      HTTP/1.0 marks the end of a message by closing the connection
  213.      (no keep-alive), thus does not need a Content-Length header
  214.      which is obligatory in HTTP/1.1
  215.     */ 
  216.  
  217.  
  218.     if (contentLength == -1) contentLength = 1024 *1024 ;
  219.  
  220. byte[] bbody = new byte[contentLength];
  221.  
  222. distream.readFully(bbody, 0, contentLength);
  223.     //distream.skipBytes(contentLength);
  224.  
  225. body = new ArrayList();
  226.     for (int i = 0; i < contentLength; i++) 
  227.  
  228.      body.add(new Byte(bbody[i]));
  229.  
  230.     if (ProxyMain.TRACEON_FULLMSGS)
  231.      System.out.println(new String(toArray(body)) + "\n");
  232.     else if (ProxyMain.TRACEON_MSGS)
  233.      System.out.println("[" + body.size() + " bytes of data body]\n");
  234.  
  235.     concatenateHeaderBody();
  236. }
  237.  
  238.  
  239. /**
  240. * Concatenates the header and the body in a whole message.
  241. */
  242. private void concatenateHeaderBody() {
  243.     message = new byte[header.size() + body.size()];
  244.     int c = 0;
  245.     for (int c1 = 0; c1 < header.size(); c1++)
  246.      message[c++] = ((Byte) header.get(c1)).byteValue();
  247.     for (int c2 = 0; c2 < body.size(); c2++)
  248.      message[c++] = ((Byte) body.get(c2)).byteValue();
  249. }
  250.  
  251.  
  252. /**
  253. * Converts an ArrayList of Bytes into an array of bytes.
  254. * @param arraylist an ArrayList
  255. * @return an array of bytes
  256. */ 
  257. public static byte[] toArray(ArrayList arraylist) {
  258.     byte[] array = new byte[arraylist.size()];
  259.     for (int i = 0; i < arraylist.size(); i++) 
  260.      array[i] = ((Byte) arraylist.get(i)).byteValue();
  261.     return array;
  262. }
  263.  
  264. /**
  265. * Erases from the header the line containing a command.
  266. * @param cmd the command that identifies the line
  267. * @param nbrParam the number of parameter to erase after the command cmd
  268. */
  269. public void eraseCommand(String cmd, int nbrParam) {
  270.     String string; 
  271.     byte[] bytes;
  272.     ArrayList sal = new ArrayList();
  273.     StringTokenizer st = 
  274.      new StringTokenizer(new String(toArray(header)), "\n", true);
  275.     while (st.hasMoreTokens()) {
  276.      string = new String(st.nextToken());
  277.      if (string.equals(cmd)) {
  278.         for (int i=0; i<nbrParam; i++) st.nextToken();
  279.      }
  280.      else {
  281.         bytes = string.getBytes();
  282.         for (int i = 0; i < bytes.length; i++) 
  283.          sal.add(new Byte(bytes[i]));
  284.      }
  285.     }
  286.     header = sal;
  287.  
  288.     concatenateHeaderBody();
  289. }
  290.  
  291.  
  292. --------------------------------------------------------------------------------
  293.  
  294.  
If the sites have Content-Length,there is no problem in accessing the sites.ie.,the readFully method reads from the file completely upto the
Content-Length.

But if the sites don't have Content-Length,it wil become -1 andwe set some default value as 1024*1024 for that.At that time,the readFully method cannot read from the file upto 1024*1024 bytes.It reaches the end of the file before reading completely,ie,an EOFException is thrown.So the sites are not loading or partially loading.

To avoid this problem,we used a similar method called skipBytes.If we use
that,the sites which were accessed for example,rediff.com,sify.com itselves are
not loading.

Then we made some changes in the code to read until EOF on an InputStream.But the response was the site was on loading and the page was not opened.

I tried my level best to solve this problem.But i cant find a solution.

Can anybody help me to find a solution.

I will be thankful to you.

By,
T.VeeraLakshmi
Mar 26 '07 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.