1 4 5 9 10 package org.openlaszlo.cache; 11 12 import javax.servlet.http.*; 13 import java.io.InputStream ; 14 import java.io.IOException ; 15 import java.io.File ; 16 import java.io.Serializable ; 17 import java.io.OutputStream ; 18 import java.util.Properties ; 19 import java.net.MalformedURLException ; 20 import org.openlaszlo.data.*; 21 import org.openlaszlo.utils.LZHttpUtils; 22 import org.openlaszlo.utils.FileUtils; 23 import org.apache.log4j.*; 24 25 36 public abstract class RequestCache extends Cache { 37 38 39 private static Logger mLogger = Logger.getLogger(Cache.class); 40 41 42 protected Converter mConverter; 43 44 51 public RequestCache(String name, File cacheDirectory, Converter converter, 52 Properties props) 53 throws IOException { 54 55 super(name, cacheDirectory, props); 56 mConverter = converter; 57 } 58 59 62 public Serializable getKey(HttpServletRequest req) 63 throws MalformedURLException { 64 65 String enc = mConverter.chooseEncoding(req); 67 if (enc == null) 68 enc = ""; 69 StringBuffer key = new StringBuffer (); 70 key.append(DataSource.getURL(req)); 71 key.append(" "); 74 key.append(enc); 75 return key.toString(); 76 } 77 78 92 public void getAsSWF( 93 String app, 94 HttpServletRequest req, 95 HttpServletResponse res, 96 DataSource dataSource) 97 throws IOException , DataSourceException, ConversionException { 98 99 if (getMaxMemSize() == 0 && getMaxDiskSize() == 0) { 101 dataSource.getAsSWF(app, req, res, mConverter); 102 return; 103 } 104 105 StringBuffer kb = new StringBuffer (); 106 kb.append(dataSource.name()); 107 kb.append(" "); 108 String rk = getKey(req).toString(); 109 kb.append(rk); 110 String key = kb.toString(); 111 String enc = mConverter.chooseEncoding(req); 112 113 mLogger.info("requesting '" + rk + "'"); 114 if (enc != null) { 115 mLogger.debug("encoding " + enc); 116 } 117 118 Item item = null; 119 InputStream input = null; 120 OutputStream output = null; 121 try { 122 item = findItem(key, enc, true); 123 124 try { 126 input = getItemStreamAsSWF(item, app, req, res, dataSource); 127 } finally { 128 item.unlock(); 133 } 134 135 if (input != null) { 137 try { 138 output = res.getOutputStream(); 139 long n = FileUtils.sendToStream(input, output); 140 mLogger.info(n + " bytes sent"); 141 } catch (FileUtils.StreamWritingException e) { 142 mLogger.warn("StreamWritingException while responding: " 143 + e.getMessage()); 144 } 145 } else { 146 mLogger.info("Cache responding with NOT_MODIFIED"); 147 } 148 } finally { 149 FileUtils.close(output); 150 FileUtils.close(input); 151 152 if (item != null) { 154 updateCacheAndDeactivateItem(item); 155 } 156 } 157 } 158 159 171 public boolean isCacheable(HttpServletRequest req) { 172 String hds = req.getParameter("sendheaders"); 173 if (hds != null) { 174 if (hds.equals("true")) { 175 return false; 176 } 177 } 178 hds = req.getParameter("headers"); 179 if (hds != null) { 180 return false; 181 } 182 String c = req.getParameter("cache"); 183 if (c == null) 184 return false; 185 return c.equals("true"); 186 } 187 188 191 public Converter getConverter() { 192 return mConverter; 193 } 194 195 202 InputStream getItemStreamAsSWF(Item item, 203 String app, 204 HttpServletRequest req, 205 HttpServletResponse res, 206 DataSource dataSource) 207 throws IOException , DataSourceException, ConversionException { 208 209 long ifModifiedSince = -1; 210 long lastModified = -1; 211 212 CachedInfo info = item.getInfo(); 213 String enc = info.getEncoding(); 214 215 String hdr = req.getHeader(LZHttpUtils.IF_MODIFIED_SINCE); 216 if (hdr != null) { 217 mLogger.debug("req last modified time: " + hdr); 218 lastModified = LZHttpUtils.getDate(hdr); 219 } 220 221 boolean doClientCache = DataSource.isClientCacheable(req); 222 223 259 if (info.getLastModified() > lastModified || info.getLastModified() == -1) { 260 ifModifiedSince = info.getLastModified(); 261 mLogger.debug("using cached last modified time: " + ifModifiedSince); 262 } else { 263 ifModifiedSince = lastModified; 264 mLogger.debug("using req last modified time: " + ifModifiedSince); 265 } 266 267 Data data = null; 268 269 try { 270 271 try { 272 data = dataSource.getData(app, req, res, ifModifiedSince); 273 } catch (DataSourceException e) { 274 item.markDirty(); 277 throw e; 278 } catch (IOException e) { 279 item.markDirty(); 280 throw e; 281 } catch (RuntimeException e) { 282 item.markDirty(); 283 throw e; 284 } 285 286 if (data.notModified()) { 287 288 mLogger.debug("Remote response: NOT_MODIFIED"); 289 if (lastModified >= info.getLastModified() && doClientCache) { 290 res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 291 return null; 292 } 293 294 if (item.validForData(data)) { 295 296 if (enc != null) { 297 res.setHeader(LZHttpUtils.CONTENT_ENCODING, enc); 298 } 299 if (doClientCache) { 300 long l = info.getLastModified(); 301 if (l != -1) { 302 res.setDateHeader(LZHttpUtils.LAST_MODIFIED, l); 303 } 304 } else { 305 LZHttpUtils.noStore(res); 306 } 307 res.setContentLength( (int) info.getSize()); 308 return item.getStream(); 309 } 310 } 311 312 mLogger.debug("path name: " + item.getPathName()); 313 314 item.markDirty(); 316 317 info.setLastModified(data.lastModified()); 319 320 InputStream input = mConverter.convertToSWF(data, req, res); 322 327 try { 329 item.update(input); 330 item.updateInfo(); 331 item.markClean(); 332 } finally { 333 FileUtils.close(input); 334 } 335 336 342 InputStream str = item.getStream(); 343 344 if (enc != null) { 345 res.setHeader(LZHttpUtils.CONTENT_ENCODING, enc); 346 } 347 348 if (doClientCache) { 349 long l = info.getLastModified(); 350 if (l != -1) { 351 res.setDateHeader(LZHttpUtils.LAST_MODIFIED, l); 352 } 353 354 } else { 355 LZHttpUtils.noStore(res); 356 } 357 358 res.setContentLength( (int) info.getSize()); 359 360 return str; 361 362 } finally { 363 if (data != null) { 364 data.release(); 365 } 366 } 367 } 368 } 369 | Popular Tags |