Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: raining/protocol/http/HttpOKResponse.java


1   /*
2    * $Author: rahul_kumar $
3    * $Id: HttpOKResponse.java,v 1.1 2003/10/20 18:09:56 rahul_kumar Exp rahul $
4    */
5    
6   package raining.protocol.http;
7   import raining.core.*;
8   import raining.util.*;
9   import java.util.*;
10  import java.text.SimpleDateFormat;
11  
12  /**
13   * Interface for Response, including response header creation.
14   * TODO:Remember that headers need to cached as does data.
15   * I suggest if not found in cache, we can store these contents using
16   * getContent. Else we just send the content as a whole without coming
17   * here.
18   * What about when file is updated. We need the header to be generated.
19   *
20   * Acco to RFC 2616 a server SHOULD send a "Date:" header, with the
21   * closest approximation of the time. THis means we have to keep
22   * updating this header and store it separately. However, the RFC states
23   * that if we cant give an accurate time, then we SHOULD not. XXX
24   *
25   * XXX i have begun passing in the request object, for logging etc.
26   * However, when the cacher precreates a header, or updates it there
27   * wont be a request. so logging cant really happen here.
28   */
29  
30  public class HttpOKResponse implements Response {
31  
32      ///// static variables ////////////////////////////////
33      static byte[] header = null;
34      static String sheader = null;
35  
36      public final static String HTTP_VERSION = "HTTP/1.1";
37      public final static String CRLF = "\r\n";
38      public final static String CRLF2 = "\r\n\r\n";
39      public final static String contentType = "text/html";
40      public final static int LAST_MODIFIED_HEADER_SIZE = "Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT".length();
41      public final static byte[] LAST_MODIFIED = "Last-Modified: ".getBytes();
42      public final static int DATE_SIZE = 29; // fixed size of date as per RFC 822
43  
44      static {
45          sheader = HTTP_VERSION + " 200 OK"+ CRLF +
46              "Content-Type: "+ contentType + CRLF +
47              "Connection: close"+ CRLF +
48              "Content-Length: ";
49          header = sheader.getBytes();
50      }
51      ///// instance variables ////////////////////////////////
52      byte[] content = null;
53      StringBuffer sb = null;
54      /** constructor taking a byte array. This would be the preferred
55       * constructor.
56       * <pre>next line takes 263ms for 100,000 iterations
57          byte[] blen = new byte[]{(byte)'1',(byte)'6'};
58       * next line takes 1020ms for 100,000 iterations
59          byte[] blen = (Integer.toString(incoming.length)).getBytes();
60       * next line takes 285ms for 100,000 iterations
61          byte[] blen = int2byte (incoming.length);
62          </pre>
63       */
64      public HttpOKResponse (Request request, byte[] incoming, long fileupdatetime){
65          // Need to find a more decent way of doing this withuot
66          // getting into Strings and other voracious objects.
67          // NEXT LINE IS VERY FAST, THE INTEGER THING SLOWS IT DOWN
68          //byte[] blen = new byte[]{(byte)'1',(byte)'6'};
69          //byte[] blen = (Integer.toString(incoming.length)).getBytes();
70          byte[] blen = NioUtil.int2byte (incoming.length);
71  
72          // 8 for 4 CRLFs 
73          this.content = new byte[incoming.length+header.length+8+blen.length+ 2 + LAST_MODIFIED_HEADER_SIZE];
74          System.arraycopy(header, 0, content, 0, header.length);
75  
76          // print length of document
77          int j = header.length;
78          for( int i = 0; i < blen.length; i++ , j++){ 
79              content[j]=blen[i];
80  
81          }
82          content[j++] = (byte)'\r';
83          content[j++] = (byte)'\n';
84  
85          System.arraycopy(LAST_MODIFIED, 0, content, j, LAST_MODIFIED.length);
86          j+= LAST_MODIFIED.length;
87  
88          SimpleDateFormat fo =
89              new SimpleDateFormat ("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
90          fo.setTimeZone(TimeZone.getTimeZone("GMT"));
91  
92          byte[] tmpdate = (fo.format(new java.util.Date(fileupdatetime))).getBytes();
93          System.arraycopy(tmpdate, 0, content, j, DATE_SIZE);
94          j+= DATE_SIZE;
95  
96          // header is over
97          content[j++] = (byte)'\r';
98          content[j++] = (byte)'\n';
99          content[j++] = (byte)'\r';
100         content[j++] = (byte)'\n';
101         System.arraycopy(incoming, 0, content, j, incoming.length);
102         j+= incoming.length;
103         content[j++] = (byte)'\r';
104         content[j++] = (byte)'\n';
105         content[j++] = (byte)'\r';
106         content[j++] = (byte)'\n';
107             
108     }
109     public HttpOKResponse (Request request, String incoming){
110         sb = new StringBuffer(sheader).append(incoming.length())
111             .append(CRLF2).append(incoming).append(CRLF2);
112         //this.content = new byte[incoming.length()+header.length+8+10];
113         //System.arraycopy(header, 0, content, 0, header.length);
114         //System.arraycopy(sb.toString().getBytes(), 0, content, header.length , sb.length());
115     }
116 
117     /** return as a stream of bytes.
118      * preferred since we can use bytes
119      * throughout and avoid costly string to byte conversions.
120      */
121     public byte[] getBytes(){
122         if (this.content == null)
123             this.content = sb.toString().getBytes();
124         return this.content;
125     }
126     /** return content as a String.
127      * to start with we use this. this does a conversion 3 times, so
128      * avoid. */
129     public String getString(){
130         if (sb == null)
131             return new String(content);
132         return sb.toString();
133     }
134     public static final String P="HttpOKResponse";
135 
136     public static void main (String args[]){ 
137 
138         System.out.println(  "--string cons--------");
139         HttpOKResponse ok = new HttpOKResponse(null, "Hello There Boys");
140         System.out.println(  ok.getString());
141         String s1 = ok.getString();
142         System.out.println(  "-As Bytes:");
143         System.out.println(  ok.getBytes());
144         byte[] b1 = ok.getBytes();
145         System.out.println(  "----------");
146         System.out.println(  "-- byte cons--------");
147         ok = new HttpOKResponse(null, "Hello There Boys".getBytes(), 0);
148         System.out.println(  ok.getString());
149         String s2 = ok.getString();
150         System.out.println(  "-As Bytes:");
151         System.out.println(  ok.getBytes());
152         byte[] b2 = ok.getBytes();
153         System.out.println(  "s2 eq s1:"+s2.equals(s1));
154             System.out.println(  "Length:"+s1.length()+","+s2.length());
155             System.out.println(  "BLength:"+b1.length+","+b2.length);
156         if (!s2.equals(s1)){
157             System.out.println(  ">>>>:"+s2.compareTo(s1));
158             for( int i = 0; i < s1.length(); i++ ){ 
159                 if (s1.charAt(i) != s2.charAt(i)){ System.out.print(  i+" not equal!");
160                     System.out.println(  "["+s1.charAt(i) + "]:["+ s2.charAt(i)+ "]" );
161                 }
162             }
163             System.out.println(  "---");
164 
165         }
166         for( int i = 0; i < s1.length(); i++ ){ 
167             if (b1[i] != b2[i]) System.out.println(  i+" not equal!");
168         }
169         long start = System.currentTimeMillis();
170         for( int j = 0; j < 100000; j++ ){ 
171             ok = new HttpOKResponse(null, "Hello There Boys");
172         }
173         long finish = System.currentTimeMillis();
174         System.out.println(  "time:"+ (finish-start));
175 
176         start = System.currentTimeMillis();
177         byte b3[] = "Hello There Boys".getBytes();
178         for( int j = 0; j < 100000; j++ ){ 
179             ok = new HttpOKResponse(null, b3, 0);
180         }
181         finish = System.currentTimeMillis();
182         System.out.println(  "time:"+ (finish-start));
183 
184     }
185 
186 
187 } // end of class