KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freecs > content > HTTPRequest


1 /**
2  * Copyright (C) 2003 Manfred Andres
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */

18 package freecs.content;
19
20 import freecs.*;
21 import freecs.core.*;
22 import freecs.util.CookieGenerator;
23 import freecs.util.EntityDecoder;
24 import freecs.interfaces.*;
25
26 import java.util.Properties JavaDoc;
27 import java.util.Enumeration JavaDoc;
28 import java.nio.ByteBuffer JavaDoc;
29 import java.nio.CharBuffer JavaDoc;
30 import java.nio.channels.SelectionKey JavaDoc;
31 import java.nio.charset.Charset JavaDoc;
32 import java.nio.charset.CharacterCodingException JavaDoc;
33 import java.nio.charset.CharsetDecoder JavaDoc;
34 import java.nio.charset.MalformedInputException JavaDoc;
35 import java.net.InetAddress JavaDoc;
36 import java.net.URLDecoder JavaDoc;
37 import java.net.UnknownHostException JavaDoc;
38
39 /**
40  * implementation of a HTTP-Request
41  * parses the http-header and stores the neccesary data
42  * as properties which may be accessed by the getProperty-Method
43  */

44 public class HTTPRequest implements IRequest {
45     private final SelectionKey JavaDoc key;
46     private String JavaDoc request;
47     private Properties JavaDoc props;
48     private byte method;
49     private String JavaDoc action, cookie, userAgent;
50     private boolean isHTTP11;
51     private final ConnectionBuffer cb;
52     private Properties JavaDoc cookies = null;
53
54     private Connection conn;
55
56    public HTTPRequest (ByteBuffer JavaDoc buf, ConnectionBuffer cb) throws CharacterCodingException JavaDoc {
57       this.cb = cb;
58       this.key = cb.getKey ();
59       try {
60           Charset JavaDoc c = Charset.forName("iso-8859-1");
61           CharsetDecoder JavaDoc ce = c.newDecoder();
62           CharBuffer JavaDoc cbuf = ce.decode(buf);
63           this.request = cbuf.toString();
64           // this.request = Charset.forName ().newDecoder ().decode (buf).toString();
65
} catch (MalformedInputException JavaDoc mie) {
66           this.request = new String JavaDoc(buf.array());
67       }
68       if (Server.TRACE_CREATE_AND_FINALIZE)
69           Server.log (this, "++++++++++++++++++++++++++++++++++++++++CREATE", Server.MSG_STATE, Server.LVL_VERY_VERBOSE);
70    }
71
72    public ConnectionBuffer getConnectionBuffer () {
73       return cb;
74    }
75
76    /**
77     * parses the HTTP request
78     */

79    public void parse () throws Exception JavaDoc {
80        if (!CentralSelector.isSkValid(key)) {
81            throw new Exception JavaDoc ("Key isn't valid anymore");
82        }
83       props = new Properties JavaDoc ();
84
85       String JavaDoc parts[] = request.split ("\r\n\r\n");
86       String JavaDoc hf[] = parts[0].split ("\r\n");
87
88       String JavaDoc values[] = hf[0].split (" ");
89       if ("GET".equals(values[0])) {
90           method=METHOD_GET;
91       } else if ("POST".equals(values[0])) {
92           method=METHOD_POST;
93       }
94       action=parseAction(values[1]);
95       isHTTP11 = values[2].equals ("HTTP/1.1") && Server.srv.USE_HTTP11;
96       if (!isHTTP11 && parts.length > 1 && parts[1].substring (parts[1].length () - 2).equals ("\r\n")) {
97          // it looks like http/1.0 has an extra \r\n after the values of a post-request (not included in content length)
98
parts[1] = parts[1].substring (0, parts[1].length () - 2);
99       }
100
101       int pos = action.indexOf ("?");
102       if (pos > -1) {
103          String JavaDoc rest = action.substring (pos + 1);
104          action = action.substring (0, pos);
105          String JavaDoc prt[] = rest.split("&");
106          for (int i = 0; i < prt.length; i++) {
107             String JavaDoc keyval[] = prt[i].split ("=");
108             if (keyval.length < 2) continue;
109             keyval[0] = URLDecoder.decode(keyval[0], "UTF-8");
110             keyval[1] = URLDecoder.decode(keyval[1].trim (), Server.srv.DEFAULT_CHARSET);
111
112             StringBuffer JavaDoc tsb = new StringBuffer JavaDoc ("v_").append (keyval[0].trim ());
113             props.setProperty (tsb.toString (), keyval[1]);
114          }
115       }
116       boolean refererFound = false, isProxyConnection = false;
117       String JavaDoc[] fwChain = null;
118       String JavaDoc realIp = null;
119       for (int i = 1; i < hf.length; i++) {
120          int dp = hf[i].indexOf (":");
121          if (dp == -1) continue;
122          String JavaDoc key = hf[i].substring (0, dp).trim ().toLowerCase();
123          String JavaDoc value = hf[i].substring (dp +1).trim ();
124          if (key.equals ("host")) {
125             String JavaDoc hst = value.split (":")[0];
126             InetAddress JavaDoc ia;
127             try {
128                 ia = InetAddress.getByName (hst);
129             } catch (UnknownHostException JavaDoc uhe) {
130                 Server.log (this, "Unable to lookup host specified in host-http-field a client claimed to get a resource from: '" + hst + "'", Server.MSG_ERROR, Server.LVL_MAJOR);
131                 throw uhe;
132             }
133             if (!"localhost".equalsIgnoreCase(hst) && Server.srv.STRICT_HOST_BINDING) {
134                 if (Server.srv.SERVER_NAME != null && !hst.equalsIgnoreCase(Server.srv.SERVER_NAME)) {
135                     StringBuffer JavaDoc tsb = new StringBuffer JavaDoc ("Recieved request specifying a different Host than specifiec inside configuration of this server. Recieved: ");
136                     tsb.append (hst);
137                     tsb.append (" Configured: ");
138                     tsb.append (Server.srv.SERVER_NAME);
139                     throw new Exception JavaDoc (tsb.toString());
140                 }
141                 if (!ia.equals (Server.srv.lh) && !hst.equalsIgnoreCase(Server.srv.SERVER_NAME)) {
142                     StringBuffer JavaDoc tsb = new StringBuffer JavaDoc ("Recieved request specifying a host, which doesn't resolve to the host of this chat-server. Recieved: ");
143                     tsb.append (hst);
144                     // StringBuffer tsb = new StringBuffer ("Illegal HTTP/1.1-request (Host-entity doesn't match localhost(").append (ia.toString ()).append (" != ").append (Server.srv.lh.toString ()).append ("))");
145
throw new Exception JavaDoc (tsb.toString ());
146                 }
147                 if (Server.srv.COOKIE_DOMAIN != null && !hst.endsWith (Server.srv.COOKIE_DOMAIN)) {
148                     throw new Exception JavaDoc ("Wrong adress used: " + hst + " instead of something ending with " + Server.srv.COOKIE_DOMAIN);
149                 }
150             }
151         } else if (!Server.srv.ALLOW_EXTERNAL && key.equals ("referer")) {
152             value = value.substring(7);
153             int pos1=value.indexOf (":");
154             int pos2= value.indexOf ("/");
155             if (pos1 > 0)
156                 pos2 = pos1;
157             if (pos2 > 0)
158                value = value.substring (0,pos2);
159                 
160             for (Enumeration JavaDoc e = Server.srv.allowedLoginHosts.elements (); e.hasMoreElements (); ) {
161                InetAddress JavaDoc ia = InetAddress.getByName (value);
162                if (((InetAddress JavaDoc) e.nextElement ()).equals (ia)) {
163                   refererFound = true;
164  
165                   break;
166                }
167             }
168             if (!refererFound)
169                 Server.log("Referer ",value +" not found", Server.MSG_TRAFFIC, Server.LVL_VERBOSE);
170          } else if (key.equals ("cookie")) {
171             String JavaDoc cookiePair[] = value.split (";");
172             for (int j = 0; j < cookiePair.length; j++) {
173                 String JavaDoc cp[] = cookiePair[j].trim().split ("=");
174                 if (cp.length < 2)
175                     continue;
176                 if (!cookiePair[j].trim ().startsWith("FreeCSSession")) {
177                     props.put("c_" + cp[0], cp[1]);
178                     continue;
179                 }
180                cookie = cp[1].trim ();
181                if (!CookieGenerator.checkValidity(cookie)) {
182                   cookie = null;
183                }
184             }
185          } else if (key.equalsIgnoreCase ("x-forwarded-for")) {
186             isProxyConnection = true;
187             fwChain = value.split(",");
188          } else if (key.equalsIgnoreCase ("via")) {
189             isProxyConnection = true;
190          } else if (key.equalsIgnoreCase ("client-ip")) {
191             isProxyConnection = true;
192             realIp = value;
193          } else if (key.equals("user-agent")) {
194             userAgent = value;
195          } else {
196             props.setProperty (key, value);
197          }
198       }
199       conn = new Connection (this.key, fwChain, !isProxyConnection);
200       if (realIp != null) try {
201          InetAddress JavaDoc realAddress = InetAddress.getByName(realIp);
202          conn.clientAddress = realAddress;
203          conn.clientIp = realIp;
204       } catch (UnknownHostException JavaDoc uhe) {
205          Server.debug (this, "parse: Headerfield client-IP contains an UnknownHost", uhe, Server.MSG_STATE, Server.LVL_MINOR);
206       }
207       if (parts.length < 2 || (!Server.srv.ALLOW_EXTERNAL && !refererFound)) return;
208       hf = parts[1].split ("&");
209       for (int i = 0; i < hf.length; i++) {
210          String JavaDoc pair[] = hf[i].split ("=");
211          if (pair.length < 2) continue;
212          pair[0] = EntityDecoder.entityToChar (pair[0]);
213          if (pair[0].equalsIgnoreCase ("message"))
214             pair[1] = EntityDecoder.entityToHtml (pair[1].trim ());
215          else
216             pair[1] = EntityDecoder.entityToChar (pair[1].trim ());
217          StringBuffer JavaDoc tsb = new StringBuffer JavaDoc ("v_").append (pair[0]);
218          props.setProperty (tsb.toString (), pair[1]);
219       }
220    }
221
222    /**
223     * get properties of this request
224     * @param key the name of this property
225     * @return the value of the property identified by this key
226     */

227    public String JavaDoc getProperty (String JavaDoc key) {
228       return props.getProperty (key);
229    }
230    
231    public String JavaDoc getValue (String JavaDoc key) {
232        return getProperty ("v_" + key);
233    }
234    
235    private String JavaDoc parseAction (String JavaDoc rawAction) {
236        if (rawAction.length() < 1
237                || !rawAction.startsWith("http://"))
238            return rawAction;
239        int idx = rawAction.indexOf("/", 7);
240        return rawAction.substring(idx);
241    }
242    
243    public String JavaDoc getCookie (String JavaDoc key) {
244        return getProperty ("c_");
245    }
246
247    public byte getMethod () {
248       return method;
249    }
250    public String JavaDoc getAction () {
251       return action;
252    }
253    public boolean isHTTP11 () {
254       return isHTTP11;
255    }
256    public String JavaDoc getCookie () {
257       return cookie;
258    }
259    public String JavaDoc getUserAgent() {
260       return userAgent;
261    }
262    public String JavaDoc getProtokol () {
263       return isHTTP11 ? "HTTP/1.1" : "HTTP/1.0";
264    }
265
266     public Connection getConnectionObject() {
267         return conn;
268     }
269     
270
271    public SelectionKey JavaDoc getKey () {
272       return key;
273    }
274    
275    public String JavaDoc toString () {
276        return "HTTP: " + action;
277    }
278    
279 /* public String toString () {
280         StringBuffer sb = new StringBuffer("[HTTPRequest: ");
281         sb.append (method);
282         sb.append (" ");
283         sb.append (action);
284         sb.append (" (");
285         sb.append (cookie);
286         sb.append (")@");
287         if (conn != null)
288             sb.append (conn.toString());
289         else
290             sb.append ("unspeciefied");
291         sb.append ("]");
292         return sb.toString();
293     } */

294
295     public void finalize() {
296         if (Server.TRACE_CREATE_AND_FINALIZE)
297             Server.log(this, "----------------------------------------FINALIZED", Server.MSG_STATE, Server.LVL_VERY_VERBOSE);
298     }
299 }
Popular Tags