abstracthttpresponse.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,408 行 · 第 1/4 页

JAVA
2,408
字号
      ((SessionImpl) session).saveBeforeHeaders();    if (_sessionId != null && ! _hasSessionCookie) {      _hasSessionCookie = true;            SessionManager manager = webApp.getSessionManager();      String cookieName;      if (_request.isSecure())	cookieName = manager.getSSLCookieName();      else	cookieName = manager.getCookieName();            CookieImpl cookie = new CookieImpl(cookieName, _sessionId);      cookie.setVersion(manager.getCookieVersion());      String domain = manager.getCookieDomain();      if (domain != null)        cookie.setDomain(domain);      long maxAge = manager.getCookieMaxAge();      if (maxAge > 0)        cookie.setMaxAge((int) (maxAge / 1000));      cookie.setPath("/");            cookie.setPort(manager.getCookiePort());      if (manager.getCookieSecure()) {	cookie.setSecure(_request.isSecure());	/*	else if (manager.getCookiePort() == null)	  cookie.setPort(String.valueOf(_request.getServerPort()));	*/      }      addCookie(cookie);    }    _isChunked = writeHeadersInt(os, length, isHead);    return _isChunked;  }  /**   * Called to start caching.   */  protected boolean startCaching(boolean isByte)  {    if (_isHeaderWritten)      return false;    _isHeaderWritten = true;    if (_statusCode == SC_OK && ! _disableCaching) // && getBufferSize() > 0)      return startCaching(_headerKeys, _headerValues,			  _contentType, _charEncoding, isByte);    else      return false;  }  /**   * Tests to see if the response is cacheable.   *   * @param keys the header keys of the response   * @param values the header values of the response   * @param contentType the contentType of the response   * @param charEncoding the character encoding of the response   *   * @return true if caching has started   */  boolean startCaching(ArrayList<String> keys,                       ArrayList<String> values,                       String contentType, String charEncoding,		       boolean isByte)  {    if (_cacheInvocation == null)      return false;    /*      // jsp/17ah    else if (_responseStream != _originalResponseStream) {      return false;    }    */    else if (! isCauchoResponseStream()) {      return false;    }    else if (! (_originalRequest instanceof CauchoRequest)) {      return false;    }    else if (! _allowCache) {      return false;    }    else {      CauchoRequest request = (CauchoRequest) _originalRequest;            _newCacheEntry = _cacheInvocation.startCaching(request,						     this, keys, values,						     contentType,						     charEncoding,						     _contentLength);      if (_newCacheEntry == null) {	return false;      }      else if (isByte) {	_cacheStream = _newCacheEntry.openOutputStream();	if (_cacheStream != null)	  _originalResponseStream.setByteCacheStream(_cacheStream);      	return _cacheStream != null;      }      else {	_cacheWriter = _newCacheEntry.openWriter();	if (_cacheWriter != null)	  _originalResponseStream.setCharCacheStream(_cacheWriter);      	return _cacheWriter != null;      }    }  }    /**   * Handle a SC_NOT_MODIFIED response.  If we've got a cache, fill the   * results from the cache.   *   * @param isTop if true, this is the top-level request.   *   * @return true if we filled from the cache   */  private boolean handleNotModified(boolean isTop)    throws IOException  {    if (_statusCode != SC_NOT_MODIFIED) {      return false;    }    else if (_matchCacheEntry != null) {      if (_originalResponseStream.isCommitted())        return false;      // need to unclose because the not modified might be detected only      // when flushing the data      _originalResponseStream.clearClosed();      _isClosed = false;      /* XXX: complications with filters */      if (_cacheInvocation != null	  && _cacheInvocation.fillFromCache((CauchoRequest) _originalRequest,					    this, _matchCacheEntry, isTop)) {        _matchCacheEntry.updateExpiresDate();        _cacheInvocation = null;        _matchCacheEntry = null;        finish(); // Don't force a flush to avoid extra TCP packet              return true;      }    }    // server/13dh    else if (_cacheInvocation != null) {      CauchoRequest req = (CauchoRequest) _originalRequest;      WebApp app = req.getWebApp();            long maxAge = app.getMaxAge(req.getRequestURI());      if (maxAge > 0 && ! containsHeader("Expires")) {	setDateHeader("Expires", maxAge + Alarm.getCurrentTime());      }    }    return false;  }  abstract protected boolean writeHeadersInt(WriteStream os,					     int length,					     boolean isHead)    throws IOException;  /**   * Sets true if the cache is only for the browser, but not   * Resin's cache or proxies.   *   * <p>Since proxy caching also caches headers, cached pages with   * session ids can't be cached in the browser.   *   * XXX: but doesn't this just mean that Resin shouldn't   * send the session information back if the page is cached?   * Because a second request where everything is identical   * would see the same response except for the cookies.   */  public void setPrivateCache(boolean isPrivate)  {    // XXX: let the webApp override this?    _isPrivateCache = isPrivate;    // server/12dm    _allowCache = false;  }  /**   * Sets true if the cache is only for the browser and    * Resin's cache but not proxies.   */  public void setPrivateOrResinCache(boolean isPrivate)  {    // XXX: let the webApp override this?    _isPrivateCache = isPrivate;  }    /**   * Returns the value of the private cache.   */  public boolean getPrivateCache()  {    return _isPrivateCache;  }  /**   * Returns true if the response should contain a Cache-Control: private   */  protected boolean isPrivateCache()  {    return ! _hasCacheControl && _isPrivateCache;  }  /**   * Set if the page is non-cacheable.   */  public void setNoCache(boolean isNoCache)  {    _isNoCache = isNoCache;  }  /**   * Returns true if the page is non-cacheable   */  public boolean isNoCache()  {    return _isNoCache;  }  /**   * Set if the page is non-cacheable.   */  public void killCache()  {    _allowCache = false;    // server/1b15    // setNoCache(true);  }  /**   * Fills the response for a cookie   *   * @param cb result buffer to contain the generated string   * @param cookie the cookie   * @param date the current date   * @param version the cookies version   */  public boolean fillCookie(CharBuffer cb, Cookie cookie,                            long date, int version,			    boolean isCookie2)  {    // How to deal with quoted values?  Old browsers can't deal with    // the quotes.        cb.clear();    cb.append(cookie.getName());    if (isCookie2) {      cb.append("=\"");      cb.append(cookie.getValue());      cb.append("\"");    }    else {      cb.append("=");      cb.append(cookie.getValue());    }    String domain = cookie.getDomain();    if (domain != null && ! domain.equals("")) {      if (isCookie2) {        cb.append("; Domain=");              cb.append('"');        cb.append(domain);        cb.append('"');      }      else {        cb.append("; domain=");        cb.append(domain);      }    }    String path = cookie.getPath();    if (path != null && ! path.equals("")) {      if (isCookie2) {        cb.append("; Path=");              cb.append('"');        cb.append(path);        cb.append('"');      }      else {	// Caps from TCK test	if (version > 0)	  cb.append("; Path=");	else	  cb.append("; path=");        cb.append(path);      }    }        if (cookie.getSecure()) {      if (version > 0)        cb.append("; Secure");      else        cb.append("; secure");    }    int maxAge = cookie.getMaxAge();    if (version > 0) {      if (maxAge >= 0) {        cb.append("; Max-Age=");        cb.append(maxAge);      }            cb.append("; Version=");      cb.append(version);            if (cookie.getComment() != null) {        cb.append("; Comment=\"");        cb.append(cookie.getComment());        cb.append("\"");      }      if (cookie instanceof CookieImpl) {	CookieImpl extCookie = (CookieImpl) cookie;	String port = extCookie.getPort();	if (port != null && isCookie2) {	  cb.append("; Port=\"");	  cb.append(port);	  cb.append("\"");	}      }    }    if (isCookie2) {    }    else if (maxAge == 0) {      cb.append("; expires=Thu, 01-Dec-1994 16:00:00 GMT");    }    else if (maxAge >= 0) {      _calendar.setGMTTime(date + 1000L * (long) maxAge);      cb.append("; expires=");      cb.append(_calendar.format("%a, %d-%b-%Y %H:%M:%S GMT"));    }    WebApp app = _request.getWebApp();    if (app.getCookieHttpOnly()) {      cb.append("; HttpOnly");    }    return true;  }  protected ConnectionController getController()  {    if (_originalRequest instanceof AbstractHttpRequest) {      AbstractHttpRequest request = (AbstractHttpRequest) _originalRequest;      Connection conn = request.getConnection();      return conn.getController();    }    else      return null;  }  public TcpDuplexController upgradeProtocol(TcpDuplexHandler handler)  {    throw new IllegalStateException(L.l("'{0}' does not support upgrading",					this));  }    /**   * Complete the request.  Flushes the streams, completes caching   * and writes the appropriate logs.   */  public void finish() throws IOException  {    finish(false);  }  /**   * Complete the request.  Flushes the streams, completes caching   * and writes the appropriate logs.   *   * @param isClose true if the response should be flushed.   */  private void finish(boolean isClose) throws IOException  {    if (_isClosed)      return;    ConnectionController controller = null;    try {      if (_originalRequest instanceof AbstractHttpRequest) {	AbstractHttpRequest request = (AbstractHttpRequest) _originalRequest;		Connection conn = request.getConnection();	controller = conn.getController();	try {	  request.skip();	} catch (BadRequestException e) {	  log.warning(e.toString());	  log.log(Level.FINE, e.toString(), e);	} catch (Exception e) {	  log.log(Level.WARNING, e.toString(), e);	}      }      if (_statusCode == SC_NOT_MODIFIED) {	handleNotModified(_isTopCache);      }      if (controller != null && ! controller.isClosed())	isClose = false;      // include() files finish too, but shouldn't force a flush, hence      // flush is false      // Never send flush?      if (isClose)	_responseStream.close();      else if (_responseStream != _originalResponseStream)	_responseStream.finish();      else if (controller == null)	_responseStream.finish();      else	_responseStream.flush();      if (_responseStream != _originalResponseStream) {	if (isClose)	  _originalResponseStream.close();	else if (controller == null)	  _originalResponseStream.finish();      }      if (controller == null)	_isClosed = true;      if (_rawWrite == null) {      }      // server/0550      // else if (isClose)      // _rawWrite.close();      else	_rawWrite.flushBuffer();      if (_cacheInvocation == null) {      }      else if (_newCacheEntry != null) {	OutputStream cacheStream = _cacheStream;	_cacheStream = null;		Writer cacheWriter = _cacheWriter;	_cacheWriter = null;	if (cacheStream != null)	  cacheStream.close();	if (cacheWriter != null)	  cacheWriter.close();	        WebApp webApp = _request.getWebApp();	if (_statusCode == 200 && _allowCache            && webApp != null && webApp.isActive()) {	  AbstractCacheFilterChain cache = _cacheInvocation;	  _cacheInvocation = null;	  AbstractCacheEntry cacheEntry = _newCacheEntry;	  _newCacheEntry = null;	  	  cache.finishCaching(cacheEntry);	}      }    } catch (ClientDisconnectException e) {      _request.killKeepalive();      if (isIgnoreClientDisconnect())	log.fine(e.toString());      else	throw e;    } catch (IOException e) {      _request.killKeepalive();            throw e;    } finally {      if (controller == null)	_isClosed = true;      AbstractCacheFilterChain cache = _cacheInvocation;      _cacheInvocation = null;            AbstractCacheEntry cacheEntry = _newCacheEntry;      _newCacheEntry = null;            _cacheStream = null;      _cacheWriter = null;      if (cacheEntry != null)	cache.killCaching(cacheEntry);    }  }  public void killCaching()  {    AbstractCacheFilterChain cache = _cacheInvocation;    _cacheInvocation = null;        AbstractCacheEntry cacheEntry = _newCacheEntry;    _newCacheEntry = null;    if (cacheEntry != null)      cache.killCaching(cacheEntry);  }  TempBuffer getBuffer()  {    return _tempBuffer;  }  protected final QDate getCalendar()  {    return _calendar;  }  protected void free()  {    _request = null;    _originalRequest = null;    _cacheInvocation = null;    _newCacheEntry = null;    _matchCacheEntry = null;    _cacheStream = null;    _cacheWriter = null;  }  static {    _errors = new HashMap<String,String>();    _errors.put("100", "Continue");    _errors.put("101", "Switching Protocols");    _errors.put("200", "OK");    _errors.put("201", "Created");    _errors.put("202", "Accepted");    _errors.put("203", "Non-Authoritative Information");    _errors.put("204", "No Content");    _errors.put("205", "Reset Content");    _errors.put("206", "Partial Content");    _errors.put("300", "Multiple Choices");    _errors.put("301", "Moved Permanently");    _errors.put("302", "Found");    _errors.put("303", "See Other");    _errors.put("304", "Not Modified");    _errors.put("305", "Use Proxy");    _errors.put("307", "Temporary Redirect");    _errors.put("400", "Bad Request");    _errors.put("401", "Unauthorized");    _errors.put("402", "Payment Required");    _errors.put("403", "Forbidden");    _errors.put("404", "Not Found");    _errors.put("405", "Method Not Allowed");    _errors.put("406", "Not Acceptable");    _errors.put("407", "Proxy Authentication Required");    _errors.put("408", "Request Timeout");    _errors.put("409", "Conflict");    _errors.put("410", "Gone");    _errors.put("411", "Length Required");    _errors.put("412", "Precondition Failed");    _errors.put("413", "Request Entity Too Large");    _errors.put("414", "Request-URI Too Long");    _errors.put("415", "Unsupported Media Type");    _errors.put("416", "Requested Range Not Satisfiable");    _errors.put("417", "Expectation Failed");    _errors.put("500", "Internal Server Error");    _errors.put("501", "Not Implemented");    _errors.put("502", "Bad Gateway");    _errors.put("503", "Service Temporarily Unavailable");    _errors.put("504", "Gateway Timeout");    _errors.put("505", "Http Version Not Supported");    _headerCodes = new CaseInsensitiveIntMap();    _headerCodes.put("cache-control", HEADER_CACHE_CONTROL);    _headerCodes.put("connection", HEADER_CONNECTION);    _headerCodes.put("content-type", HEADER_CONTENT_TYPE);    _headerCodes.put("content-length", HEADER_CONTENT_LENGTH);    _headerCodes.put("date", HEADER_DATE);    _headerCodes.put("server", HEADER_SERVER);  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?