1 18 19 22 package freecs.content; 23 24 import freecs.*; 25 import freecs.interfaces.*; 26 import freecs.layout.*; 27 import freecs.util.HttpDateParser; 28 29 import java.nio.charset.Charset ; 30 import java.nio.charset.CharacterCodingException ; 31 import java.nio.ByteBuffer ; 32 import java.nio.CharBuffer ; 33 34 35 public class ContentContainer implements IResponseHeaders, IContainer { 36 private ByteBuffer buf; 37 private TemplateSet ts; 38 private String tName; 39 private Template tpl; 40 private String cookie, 41 contentType="text/html"; 42 43 private String eTag; 44 private boolean notModified=false; 45 46 private volatile boolean chunkedHdr, 47 nocache=false, 48 nostore=false, 49 keepAlive = false, 50 isMessages = false, 51 isRedirect, 52 isHTTP11=true; 53 54 private short resCode = 200; 55 56 public ContentContainer () { 57 if (Server.TRACE_CREATE_AND_FINALIZE) 58 Server.log (this, "++++++++++++++++++++++++++++++++++++++++CREATE", Server.MSG_STATE, Server.LVL_VERY_VERBOSE); 59 } 60 61 65 public void wrap (String cntnt) { 66 wrap(cntnt, null); 67 } 68 public void wrap (String cntnt, String eTag) { 69 StringBuffer sb = new StringBuffer (); 70 sb.append (isHTTP11 ? "HTTP/1.1" : "HTTP/1.0"); 71 switch (resCode) { 72 case OK_CODE: 73 sb.append (OK_HDR); 74 break; 75 case REDIRECT_CODE: 76 setRedirectTo (cntnt); 77 break; 78 case NOCONTENT_CODE: 79 sb.append (NOCONTENT_HDR); 80 prepareForSending (CharBuffer.wrap(sb.toString())); 81 return; 82 case AUTHENTICATE_CODE: 83 sb.append (AUTHENTICATE_HDR); 84 contentType="text/html"; 85 break; 86 case NOTFOUND_CODE: 87 sb.append (NOTFOUND_HDR); 88 contentType="text/html"; 89 break; 90 } 91 sb.append ("Content-Type: "); 92 sb.append (contentType); 93 sb.append ("; charset="); 94 sb.append (Server.srv.DEFAULT_CHARSET); 95 if (nocache) { 96 sb.append ("\r\nPragma: no-cache\r\nCache-Control: no-cache"); 97 sb.append ("\r\nExpires: Thu, 01 Dec 1994 16:00:00 GMT"); 98 } 99 if (nostore) { 100 sb.append ("\r\nCache-Control: no-store"); 101 } 102 if (eTag != null) { 103 sb.append ("\r\nETag: \"").append(eTag).append("\""); 104 } 106 107 sb = appendCookie (sb); 108 109 if (!isHTTP11 || !keepAlive || isMessages) { 110 sb.append ("\r\nConnection: close\r\nProxy-Connection: close"); 111 } else { 112 sb.append ("\r\nConnection: Keep-Alive\r\nProxy-Connection: Keep-Alive"); 113 if (!chunkedHdr) { 114 sb.append("\r\nContent-Length: "); 115 sb.append (cntnt.length ()); 116 } 117 } 118 if (chunkedHdr) { 119 sb.append ("\r\nTransfer-Encoding: chunked\r\n\r\n"); 120 sb.append (Integer.toHexString (cntnt.length ())); 121 sb.append ("\r\n"); 122 sb.append (cntnt); 123 sb.append ("\r\n"); 124 prepareForSending(CharBuffer.wrap (sb.toString())); 125 return; 126 } 127 sb.append ("\r\n\r\n"); 128 if ("iso-8859-1".equals(Server.srv.DEFAULT_CHARSET)) { 129 sb.append(cntnt); 130 prepareForSending(CharBuffer.wrap(sb.toString())); 131 } else { 132 CharBuffer hdrChar = CharBuffer.wrap(sb.toString()); 133 prepareForSending(hdrChar, CharBuffer.wrap (cntnt)); 134 } 135 } 136 137 141 public void setResCode (short code) { 142 resCode=code; 143 } 144 145 150 public StringBuffer appendCookie (StringBuffer sb) { 151 if (cookie == null) return sb; 152 sb.append ("\r\n"); 153 sb.append ("Set-Cookie: FreeCSSession="); 154 sb.append (cookie); 155 sb.append ("; path=/;"); 156 if (Server.srv.COOKIE_DOMAIN != null) { 157 sb.append (" Domain="); 158 sb.append (Server.srv.COOKIE_DOMAIN); 159 } 160 return sb; 161 } 162 163 167 public void useTemplateSet (TemplateSet ts) { 168 this.ts = ts; 169 } 170 171 175 public void setTemplate (String tName) { 176 this.tName = tName; 177 } 178 179 182 public void renderTemplate (IRequest req) { 183 if (tpl == null) { 184 if (this.ts == null) 185 ts = Server.srv.templatemanager.getTemplateSet ("default"); 186 tpl = ts.getTemplate (tName); 187 if (tpl == null) 188 tpl = ts.getTemplate ("not_found"); 189 } 190 if (tpl.isRedirect ()) { 191 this.setRedirectTo(tpl.getDestination ()); 192 return; 193 } 194 if (!nocache && !nostore && 195 !tpl.hasToBeRendered(req.getProperty("if-none-match"), 196 HttpDateParser.parseDate(req.getProperty("if-modified-since")))) { 197 StringBuffer sb = new StringBuffer (); 198 sb.append (isHTTP11 ? "HTTP/1.1" : "HTTP/1.0"); 199 sb.append (IResponseHeaders.NOT_MODIFIED); 200 prepareForSending(CharBuffer.wrap (sb.toString())); 201 return; 202 } 203 String cntnt = tpl.render (req); 204 if (cntnt==null || cntnt.length () < 1) { 205 Server.log (this, "renderTemplate: rendered template has no content", Server.MSG_STATE, Server.LVL_MAJOR); 206 resCode=NOCONTENT_CODE; 207 StringBuffer sb = new StringBuffer (); 208 sb.append ("<html><body><b>The requested page could not be displayed!<br><br>Reason:</b> "); 209 if (tpl == null) { 210 sb.append ("No template given"); 211 } else { 212 sb.append ("Template '"); 213 sb.append (tpl.getName()); 214 sb.append ("' has not been found on this server."); 215 } 216 sb.append ("</body></html>"); 217 wrap (sb.toString()); 218 return; 219 } 220 nocache=tpl.notCacheable(); 221 wrap (cntnt, tpl.getEtag()); 224 } 225 226 230 public void useChunkedHeader () { 231 chunkedHdr = true; 232 keepAlive = true; 233 } 234 235 239 public void setKeepAlive (boolean b) { 240 keepAlive = b; 241 } 242 243 247 public void setHTTP11 (boolean b) { 248 isHTTP11 = b; 249 keepAlive = true; 250 } 251 252 256 public boolean isHttp11 () { 257 return isHTTP11; 258 } 259 260 264 public void setCookie (String cookie) { 265 this.cookie = cookie; 266 } 267 268 271 public ByteBuffer getByteBuffer () { 272 return buf; 273 } 274 275 278 public String getContentType() { 279 return contentType; 280 } 281 282 285 public void setContentType(String contentType) { 286 this.contentType = contentType; 287 } 288 289 295 public void prepareForSending (CharBuffer cb) { 296 if (cb == null || cb.length() < 1) 297 return; 298 try { 299 buf = Charset.forName ("iso-8859-1").newEncoder().encode(cb); 300 return; 301 } catch (CharacterCodingException cce) { 302 Server.debug (this, "prepareForSending: ", cce, Server.MSG_ERROR, Server.LVL_MINOR); 303 } 304 } 305 306 public void prepareForSending (CharBuffer hdr, CharBuffer cntnt) { 307 if (hdr == null || hdr.capacity() < 1) 308 return; 309 try { 310 ByteBuffer hdrBytes = Charset.forName("iso-8859-1").newEncoder().encode(hdr); 311 ByteBuffer cntntBytes = Charset.forName (Server.srv.DEFAULT_CHARSET).newEncoder().encode(cntnt); 312 buf = ByteBuffer.allocate(hdrBytes.capacity() + cntntBytes.capacity()); 313 buf.put(hdrBytes); 314 buf.put(cntntBytes); 315 buf.flip(); 316 } catch (Exception e) { 317 Server.debug (this, "Exception during prepareForSending(hdr/cntnt)", e, Server.MSG_ERROR, Server.LVL_MAJOR); 318 } 319 } 320 321 322 public boolean prepareForSending (IRequest req) { 323 if (tName != null || tpl != null) 324 renderTemplate (req); 325 if (buf == null) 326 return false; 327 return true; 328 } 329 330 public void setContent (byte[] cntnt) throws Exception { 331 StringBuffer sb = new StringBuffer (); 332 sb.append (isHTTP11 ? "HTTP/1.1" : "HTTP/1.0"); 333 sb.append (OK_HDR); 334 sb.append ("Content-Type: "); 335 sb.append (contentType); 336 if (!isHTTP11 || !keepAlive || isMessages) { 337 sb.append ("\r\nConnection: close\r\nProxy-Connection: close"); 338 } else { 339 sb.append ("\r\nConnection: Keep-Alive\r\nProxy-Connection: Keep-Alive"); 340 sb.append("\r\nContent-Length: "); 341 sb.append (cntnt.length); 342 } 343 sb.append ("\r\n\r\n"); 344 CharBuffer cb = CharBuffer.wrap (sb.toString()); 345 ByteBuffer tempBuffer; 346 try { 347 tempBuffer = Charset.forName ("iso-8859-1").newEncoder().encode(cb); 348 } catch (CharacterCodingException cce) { 349 Server.debug (this, "prepareForSending: ", cce, Server.MSG_ERROR, Server.LVL_MINOR); 350 try { 351 tempBuffer = ByteBuffer.wrap (cb.toString().getBytes(Server.srv.DEFAULT_CHARSET)); 352 } catch (Exception e) { 353 Server.debug (this, "prepareForSending: ", e, Server.MSG_ERROR, Server.LVL_MAJOR); 354 throw e; 355 } 356 } 357 this.buf = ByteBuffer.allocate(tempBuffer.capacity() + cntnt.length); 358 this.buf.put(tempBuffer.array()); 359 this.buf.put(cntnt); 360 this.buf.flip(); 361 } 362 363 public boolean hasContent () { 364 return (buf != null); 365 } 366 367 public boolean closeSocket () { 368 return (!isHTTP11 || !keepAlive) && !isMessages; 369 } 370 public void setIsMessages () { 371 this.isMessages = true; 372 } 373 public void setNoCache () { 374 nocache = true; 375 } 376 public void setNoStore () { 377 nostore = true; 378 } 379 380 385 public void setRedirectTo(String dest) { 386 StringBuffer cntnt = new StringBuffer (); 387 cntnt.append("<html><head><title>redirection</title><head><body>Redirected to <a HREF=\""); 388 cntnt.append(dest); 389 cntnt.append("\">"); 390 cntnt.append(dest); 391 cntnt.append("</a>"); 392 cntnt.append("</body></html>"); 393 int len = cntnt.length(); 394 StringBuffer sb = new StringBuffer (); 395 sb.append(isHTTP11 ? "HTTP/1.1" : "HTTP/1.0"); 396 sb.append(REDIRECT_HDR); 397 sb.append(Server.srv.DEFAULT_CHARSET); 398 sb.append("\r\nLocation: "); 399 sb.append(dest); 400 sb.append("\r\nContent-Length: "); 401 sb.append(len); 402 sb = appendCookie(sb); 403 sb.append("\r\n\r\n"); 404 if ("iso-8859-1".equals(Server.srv.DEFAULT_CHARSET)) { 405 sb.append(cntnt); 406 prepareForSending(CharBuffer.wrap(sb.toString())); 407 } else { 408 CharBuffer hdrChar = CharBuffer.wrap(sb.toString()); 409 prepareForSending(hdrChar, CharBuffer.wrap(cntnt)); 410 } 411 isRedirect = true; 412 } 413 414 public void finalize() { 415 if (Server.TRACE_CREATE_AND_FINALIZE) 416 Server.log(this, "----------------------------------------FINALIZED", Server.MSG_STATE, Server.LVL_VERY_VERBOSE); 417 } 418 } | Popular Tags |