1 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 ; 27 import java.util.Enumeration ; 28 import java.nio.ByteBuffer ; 29 import java.nio.CharBuffer ; 30 import java.nio.channels.SelectionKey ; 31 import java.nio.charset.Charset ; 32 import java.nio.charset.CharacterCodingException ; 33 import java.nio.charset.CharsetDecoder ; 34 import java.nio.charset.MalformedInputException ; 35 import java.net.InetAddress ; 36 import java.net.URLDecoder ; 37 import java.net.UnknownHostException ; 38 39 44 public class HTTPRequest implements IRequest { 45 private final SelectionKey key; 46 private String request; 47 private Properties props; 48 private byte method; 49 private String action, cookie, userAgent; 50 private boolean isHTTP11; 51 private final ConnectionBuffer cb; 52 private Properties cookies = null; 53 54 private Connection conn; 55 56 public HTTPRequest (ByteBuffer buf, ConnectionBuffer cb) throws CharacterCodingException { 57 this.cb = cb; 58 this.key = cb.getKey (); 59 try { 60 Charset c = Charset.forName("iso-8859-1"); 61 CharsetDecoder ce = c.newDecoder(); 62 CharBuffer cbuf = ce.decode(buf); 63 this.request = cbuf.toString(); 64 } catch (MalformedInputException mie) { 66 this.request = new String (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 79 public void parse () throws Exception { 80 if (!CentralSelector.isSkValid(key)) { 81 throw new Exception ("Key isn't valid anymore"); 82 } 83 props = new Properties (); 84 85 String parts[] = request.split ("\r\n\r\n"); 86 String hf[] = parts[0].split ("\r\n"); 87 88 String 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 parts[1] = parts[1].substring (0, parts[1].length () - 2); 99 } 100 101 int pos = action.indexOf ("?"); 102 if (pos > -1) { 103 String rest = action.substring (pos + 1); 104 action = action.substring (0, pos); 105 String prt[] = rest.split("&"); 106 for (int i = 0; i < prt.length; i++) { 107 String 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 tsb = new StringBuffer ("v_").append (keyval[0].trim ()); 113 props.setProperty (tsb.toString (), keyval[1]); 114 } 115 } 116 boolean refererFound = false, isProxyConnection = false; 117 String [] fwChain = null; 118 String realIp = null; 119 for (int i = 1; i < hf.length; i++) { 120 int dp = hf[i].indexOf (":"); 121 if (dp == -1) continue; 122 String key = hf[i].substring (0, dp).trim ().toLowerCase(); 123 String value = hf[i].substring (dp +1).trim (); 124 if (key.equals ("host")) { 125 String hst = value.split (":")[0]; 126 InetAddress ia; 127 try { 128 ia = InetAddress.getByName (hst); 129 } catch (UnknownHostException 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 tsb = new StringBuffer ("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 (tsb.toString()); 140 } 141 if (!ia.equals (Server.srv.lh) && !hst.equalsIgnoreCase(Server.srv.SERVER_NAME)) { 142 StringBuffer tsb = new StringBuffer ("Recieved request specifying a host, which doesn't resolve to the host of this chat-server. Recieved: "); 143 tsb.append (hst); 144 throw new Exception (tsb.toString ()); 146 } 147 if (Server.srv.COOKIE_DOMAIN != null && !hst.endsWith (Server.srv.COOKIE_DOMAIN)) { 148 throw new Exception ("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 e = Server.srv.allowedLoginHosts.elements (); e.hasMoreElements (); ) { 161 InetAddress ia = InetAddress.getByName (value); 162 if (((InetAddress ) 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 cookiePair[] = value.split (";"); 172 for (int j = 0; j < cookiePair.length; j++) { 173 String 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 realAddress = InetAddress.getByName(realIp); 202 conn.clientAddress = realAddress; 203 conn.clientIp = realIp; 204 } catch (UnknownHostException 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 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 tsb = new StringBuffer ("v_").append (pair[0]); 218 props.setProperty (tsb.toString (), pair[1]); 219 } 220 } 221 222 227 public String getProperty (String key) { 228 return props.getProperty (key); 229 } 230 231 public String getValue (String key) { 232 return getProperty ("v_" + key); 233 } 234 235 private String parseAction (String 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 getCookie (String key) { 244 return getProperty ("c_"); 245 } 246 247 public byte getMethod () { 248 return method; 249 } 250 public String getAction () { 251 return action; 252 } 253 public boolean isHTTP11 () { 254 return isHTTP11; 255 } 256 public String getCookie () { 257 return cookie; 258 } 259 public String getUserAgent() { 260 return userAgent; 261 } 262 public String 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 getKey () { 272 return key; 273 } 274 275 public String toString () { 276 return "HTTP: " + action; 277 } 278 279 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 |