1 18 package freecs.core; 19 20 import freecs.*; 21 import freecs.content.*; 22 import freecs.interfaces.*; 23 import freecs.util.ObjectBuffer; 24 import java.nio.ByteBuffer ; 25 import java.nio.channels.SelectionKey ; 26 import java.nio.channels.SocketChannel ; 27 import freecs.util.TrafficMonitor; 28 import java.net.InetAddress ; 29 30 36 public class ConnectionBuffer { 37 private volatile User u; 38 private int src; 39 private ByteBuffer buf; 40 private ByteBuffer tBuf = null; 41 public ByteBuffer rBuf = ByteBuffer.allocate (Server.srv.READBUFFER_SIZE); 42 private SelectionKey sk; 43 private String ts; 44 private ObjectBuffer writeBuffer = new ObjectBuffer (Server.srv.INITIAL_RESPONSE_QUEUE); 45 private volatile boolean valid=true; 46 public Connection conn; 47 48 private StringBuffer lsb = new StringBuffer (); 49 50 private static final int GET = 1; 51 private static final int POST= 2; 52 53 private int reqType = 0; 54 private int so = 0; 55 private int cStart = -1; 56 private int cLength = -1; 57 public volatile IRequest currentRequest; 58 private boolean reading=false; 59 60 private volatile long closeWhen=System.currentTimeMillis() + Server.srv.KEEP_ALIVE_TIMEOUT; 61 62 63 public ConnectionBuffer (int src) { 64 this.src = src; 65 buf = ByteBuffer.allocate(Server.srv.READBUFFER_SIZE); 66 if (Server.TRACE_CREATE_AND_FINALIZE) 67 Server.log (this, "++++++++++++++++++++++++++++++++++++++++CREATE", Server.MSG_STATE, Server.LVL_VERY_VERBOSE); 68 } 69 70 77 public IRequest append () throws Exception { 78 boolean parse = false; 79 synchronized (this) { 80 reading=true; 81 rBuf.flip(); 82 if (this.buf.remaining () < rBuf.remaining ()) { 83 ByteBuffer tbuf = ByteBuffer.allocate (this.buf.position () + rBuf.remaining ()); 84 this.buf.flip (); 85 tbuf.put(this.buf); 86 this.buf = tbuf; 87 } 88 this.buf.put(rBuf); 89 rBuf.clear (); 90 if (reqType == 0 && this.buf.position () > 4) { 91 if (this.buf.get(0) == 'P' && this.buf.get(1) == 'O' && this.buf.get(2) == 'S' && this.buf.get(3) == 'T') { 92 reqType = POST; 93 } else if (this.buf.get(0) == 'G' && this.buf.get(1) == 'E' && this.buf.get(2) == 'T') { 94 reqType = GET; 95 } else { 96 this.addLog("HEADER-INVALID"); 97 this.invalidate(); 98 reading=false; 99 return null; 100 } 101 } 102 if (reqType == GET) { 103 if (this.buf.position() > 4096) { 104 this.addLog("HEADER>4096bytes"); 105 this.invalidate(); 106 reading=false; 107 return null; 108 } 109 if (this.buf.position () > 10 110 && this.buf.get (this.buf.position () - 4) == '\r' 111 && this.buf.get (this.buf.position () - 3) == '\n' 112 && this.buf.get (this.buf.position () - 2) == '\r' 113 && this.buf.get (this.buf.position () - 1) == '\n') { 114 parse = true; 115 } 116 } else if (reqType == POST) { 117 if (cLength == -1) { 118 for (; so < this.buf.position () - 15; so++) { 119 if (so > 4096 120 || (this.buf.get(so) == '\r' 121 && this.buf.get(so+1) == '\n' 122 && this.buf.get(so+2) == '\r' 123 && this.buf.get(so+3) == '\n')) { 124 this.addLog("HEADER-INVALID"); 125 this.invalidate(); 126 reading=false; 127 return null; 128 } 129 if (this.buf.get(so) == 'C' && this.buf.get(so+1) == 'o' 130 && this.buf.get(so+2) == 'n' && this.buf.get(so+3) == 't' 131 && this.buf.get(so+4) == 'e' && this.buf.get(so+5) == 'n' 132 && this.buf.get(so+6) == 't' && this.buf.get(so+7) == '-' 133 && (this.buf.get(so+8) == 'L' || this.buf.get(so+8) == 'l') 134 && this.buf.get(so+9) == 'e' && this.buf.get(so+10) == 'n' 135 && this.buf.get(so+11) == 'g' && this.buf.get(so+12) == 't' 136 && this.buf.get(so+13) == 'h' && this.buf.get(so+14) == ':') { 137 int cso = so + 14; 138 if (cso >= this.buf.capacity ()) return null; 139 while ((this.buf.get(cso) < 48 || this.buf.get(cso) > 57)) { 140 if (cso >= this.buf.capacity ()) return null; 141 cso++; 142 } 143 StringBuffer sb = new StringBuffer (); 144 while (this.buf.get(cso) >= 48 && this.buf.get(cso) <= 57) { 145 if (cso >= this.buf.capacity ()) return null; 146 sb.append ((char) this.buf.get(cso)); 147 cso++; 148 } 149 so = cso; 150 cLength = Integer.parseInt (sb.toString ()); 151 break; 152 } 153 } 154 } 155 if (cLength != -1) { 156 for (; cStart == -1 && so < this.buf.position () - 4; so++) { 157 if (so > 4096) { 158 this.addLog("HEADER>4096bytes"); 159 this.invalidate(); 160 reading=false; 161 return null; 162 } 163 if (this.buf.get(so) == '\r' 164 && this.buf.get(so+1) == '\n' 165 && this.buf.get(so+2) == '\r' 166 && this.buf.get(so+3) == '\n') { 167 cStart = so + 4; 168 break; 169 } 170 } 171 if (cStart != -1) { 172 if ((this.buf.position () - cStart) > cLength) { 173 int diff = this.buf.position () - cStart - cLength; 174 tBuf = ByteBuffer.allocate (diff); 175 for (int pos = this.buf.position () - diff; pos < this.buf.position (); pos++) { 176 tBuf.put (this.buf.get (pos)); 177 } 178 this.buf.position(cStart + cLength); 179 parse=true; 180 } else if ((this.buf.position () - cStart) == cLength) { 181 parse=true; 182 } 183 } 184 } 185 } 186 } 187 if (parse) 188 return parse(); 189 return null; 190 } 191 192 196 public IRequest parse () throws Exception { 197 IRequest req = null; 199 synchronized (this) { 200 this.buf.flip (); 201 try { 202 req = new HTTPRequest(buf, this); 203 } catch (Exception e) { 204 reset(); 205 throw e; 206 } 207 reading=false; 208 } 209 try { 210 req.parse (); 211 Connection conn = req.getConnectionObject(); 212 if (!conn.isDirectlyConnected) { 213 InetAddress ia = ((SocketChannel ) sk.channel ()).socket().getInetAddress (); 214 if (ia != null) { 215 TrafficMonitor.tm.markAsProxy (ia); 216 } 217 } 218 221 } finally { 222 reset (); 223 } 224 return req; 225 } 226 227 private synchronized void reset () { 228 if (buf.capacity () != Server.srv.READBUFFER_SIZE) { 229 buf = ByteBuffer.allocate (Server.srv.READBUFFER_SIZE); 230 } else { 231 buf.clear (); 232 } 233 if (tBuf != null) { 234 buf.put (tBuf); 235 tBuf = null; 236 } 237 cStart = -1; 238 cLength= -1; 239 reqType= 0; 240 so = 0; 241 valid=true; 242 reading=false; 243 } 244 245 public void setTemplateSet (String ts) { 246 this.ts = ts; 247 } 248 249 public String getTemplateSet () { 250 return ts; 251 } 252 253 public void setUser (User u) { 254 this.u = u; 255 } 256 257 public User getUser () { 258 return u; 259 } 260 261 264 public SelectionKey getKey () { 265 return sk; 266 } 267 268 public void setKey (SelectionKey sk) { 269 if (!CentralSelector.isSkValid(sk)) { 270 Server.log(this, "setKey: tryed to set invalid key", Server.MSG_STATE, Server.LVL_VERBOSE); 271 return; 272 } 273 this.sk=sk; 274 conn = new Connection (sk); 275 } 276 277 public void addToWrite (Object ic) { 278 if (!CentralSelector.isSkValid(sk)) { 279 Server.log (this, "addToWrite: selection-key isn't valid anymore", Server.MSG_STATE, Server.LVL_VERBOSE); 280 return; 281 } 282 synchronized (this) { 283 if (writeBuffer.isFull ()) { 284 int newSize = writeBuffer.capacity () + Server.srv.INITIAL_RESPONSE_QUEUE; 285 if (newSize > Server.srv.MAX_RESPONSE_QUEUE) { 286 Server.log(this, "addToWrite: write-queue would be bigger than specified for " + toString(), Server.MSG_STATE, Server.LVL_MINOR); 287 return; 288 } 289 Server.log(this, "addToWrite: Expanding write-queue for " + toString(), Server.MSG_STATE, Server.LVL_MINOR); 290 writeBuffer.resizeTo(newSize); 291 } 292 writeBuffer.put(ic); 293 } 294 writeToLog(); 295 Responder.res.addToWrite((SocketChannel ) sk.channel(), this); 296 } 297 298 public ObjectBuffer getWriteQueue () { 299 return writeBuffer; 300 } 301 302 public void updateKeepAliveTimeout () { 303 if (isMessageFrame) 304 return; 305 closeWhen = System.currentTimeMillis() + Server.srv.KEEP_ALIVE_TIMEOUT; 306 } 307 308 public long getKeepAliveTimeout(long ts) { 309 if (isMessageFrame || reading) 310 return -1; 311 return closeWhen; 312 } 313 314 public void invalidate() { 315 valid=false; 316 } 317 318 public boolean isValid() { 319 return valid; 320 } 321 322 private volatile boolean isMessageFrame = false; 323 public void setIsMessageFrame(boolean b) { 324 isMessageFrame=b; 326 } 327 328 public void addLog (String str) { 329 lsb.append (" "); 330 lsb.append (str); 331 } 332 333 public void writeToLog () { 334 if (lsb.length() < 1) 335 return; 336 if (conn!=null && conn.peerAddress != null) 337 lsb.insert(0, conn.peerAddress.getHostAddress()); 338 else if (conn != null) 339 lsb.insert(0, conn.toString()); 340 else 341 lsb.insert(0, "undefined"); 342 Server.log ("OK", lsb.toString (), Server.MSG_TRAFFIC, Server.LVL_MINOR); 343 lsb = new StringBuffer (); 344 } 345 346 public void logError (String reason) { 347 lsb.append (" REASON: "); 348 lsb.append (reason); 349 if (conn != null && conn.peerAddress != null) 350 lsb.insert (0, conn.peerAddress.getHostAddress()); 351 else if (conn != null) 352 lsb.insert (0, conn.toString()); 353 else 354 lsb.insert (0, "undefined"); 355 Server.log ("FAILED", lsb.toString (), Server.MSG_TRAFFIC, Server.LVL_MAJOR); 356 lsb = new StringBuffer (); 357 } 358 359 public void finalize() { 360 if (Server.TRACE_CREATE_AND_FINALIZE) 361 Server.log(this, "----------------------------------------FINALIZED", Server.MSG_STATE, Server.LVL_VERY_VERBOSE); 362 } 363 } | Popular Tags |