Extracts a {@link Cache.Entry} from a {@link NetworkResponse}.

@param response The network response to parse headers from
@return a cache entry for the given response, or null if the response is not cacheable.
420851
public static Cache.Entry parseCacheHeaders(NetworkResponse response) {
        long now = System.currentTimeMillis();

        Headers headers = response.headers;

        long serverDate = 0;
        long lastModified = 0;
        long serverExpires = 0;
        long softExpire = 0;
        long finalExpire = 0;
        long maxAge = 0;
        long staleWhileRevalidate = 0;
        boolean hasCacheControl = false;
        boolean mustRevalidate = false;

        String serverEtag = null;
        String headerValue;
        List<String> headerValues;

        headerValue = headers.get("Date");
        if (headerValue != null) {
            serverDate = parseDateAsEpoch(headerValue);
        }

        //TODO check multiple cache and make stale if more than 1 value for given directive
        headerValues = headers.values("Cache-Control");
        if (headerValues != null && headerValues.size() > 0) {
            hasCacheControl = true;
            for (int i = 0; i < headerValues.size(); i++) {
                String[] tokens = headerValues.get(i).trim().split(",");
                for (int j = 0; j < tokens.length; j++) {
                    String token = tokens[j].trim();
                    if (token.equals("no-cache") || token.equals("no-store")) {
                        return null;
                    } else if (token.startsWith("max-age=")) {
                        try {
                            maxAge = Long.parseLong(token.substring(8));
                        } catch (Exception e) {
                        }
                    } else if (token.startsWith("stale-while-revalidate=")) {
                        try {
                            staleWhileRevalidate = Long.parseLong(token.substring(23));
                        } catch (Exception e) {
                        }
                    } else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) {

                        mustRevalidate = true;
                    }
                }
            }
        }

        headerValue = headers.get("Expires");
        if (headerValue != null) {
            serverExpires = parseDateAsEpoch(headerValue);
        }

        headerValue = headers.get("Last-Modified");
        if (headerValue != null) {
            lastModified = parseDateAsEpoch(headerValue);
        }

        serverEtag = headers.get("ETag");

        // Cache-Control takes precedence over an Expires header, even if both exist and Expires
        // is more restrictive.
        if (hasCacheControl) {
            softExpire = now + maxAge * 1000;
            finalExpire = mustRevalidate
                    ? softExpire
                    : softExpire + staleWhileRevalidate * 1000;
        } else if (serverDate > 0 && serverExpires >= serverDate) {
            // Default semantic for Expire header in HTTP specification is softExpire.
            softExpire = now + (serverExpires - serverDate);
            finalExpire = softExpire;
        }

        Cache.Entry entry = new Cache.Entry();
        entry.data = response.data;
        entry.etag = serverEtag;
        entry.softTtl = softExpire;
        entry.ttl = finalExpire;
        entry.serverDate = serverDate;
        entry.lastModified = lastModified;
        entry.responseHeaders = headers;

        return entry;
    }
34448
private void setDateAndCacheHeaders(final HttpResponse response) {
    final SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
    dateFormatter.setTimeZone(TimeZone.getTimeZone(HTTP_DATE_GMT_TIMEZONE));

    // Date header
    final Calendar time = new GregorianCalendar();
    response.headers().set(DATE, dateFormatter.format(time.getTime()));

    // Add cache headers
    time.add(Calendar.SECOND, HTTP_CACHE_SECONDS);
    response.headers().set(EXPIRES, dateFormatter.format(time.getTime()));
    response.headers().set(CACHE_CONTROL, "private, max-age=" + HTTP_CACHE_SECONDS);
    response.headers().set(LAST_MODIFIED, dateFormatter.format(new Date(startupTime)));
  }
1364918
@Api
	public static void configureNoCaching(HttpServletResponse response) {
		// HTTP 1.0 header:
		response.setHeader(HTTP_EXPIRES_HEADER, HTTP_EXPIRES_HEADER_NOCACHE_VALUE);
		response.setHeader(HTTP_CACHE_PRAGMA, HTTP_CACHE_PRAGMA_VALUE);

		// HTTP 1.1 header:
		response.setHeader(HTTP_CACHE_CONTROL_HEADER, HTTP_CACHE_CONTROL_HEADER_NOCACHE_VALUE);
	}
498958
@Override
    public final CacheKey getCacheKey(HttpServletRequest request, HttpServletResponse response) {
        final Resource stylesheetResource = this.getStylesheetResource(request);
        final Serializable stylesheetCacheKey;
        try {
            stylesheetCacheKey = this.xmlUtilities.getStylesheetCacheKey(stylesheetResource);
        } catch (TransformerConfigurationException e) {
            throw new RuntimeException(
                    "Failed to get Transformer for stylesheet: " + stylesheetResource, e);
        } catch (IOException e) {
            throw new RuntimeException("Failed to load stylesheet: " + stylesheetResource, e);
        }

        return CacheKey.build(stylesheetResource.getDescription(), stylesheetCacheKey);
    }
1011412
@Override
    public synchronized Entry get(String key) {
        CacheHeader entry = mEntries.get(key);
        // if the entry does not exist, return.
        if (entry == null) {
            return null;
        }

        File file = getFileForKey(key);
        CountingInputStream cis = null;
        try {
            cis = new CountingInputStream(new BufferedInputStream(new FileInputStream(file)));
            CacheHeader.readHeader(cis); // eat header
            byte[] data = streamToBytes(cis, (int) (file.length() - cis.bytesRead));
            return entry.toCacheEntry(data);
        } catch (IOException e) {
            //todo add queue markers
            JusLog.log(file.getAbsolutePath() + ": " + e.toString());
            remove(key);
            return null;
        } catch (NegativeArraySizeException e) {
            JusLog.log(file.getAbsolutePath() + ": " + e.toString());
            remove(key);
            return null;
        } finally {
            if (cis != null) {
                try {
                    cis.close();
                } catch (IOException ioe) {
                    return null;
                }
            }
        }
    }
933046
@RequestMapping(value = "/userLogout", method = RequestMethod.GET)
    @ResponseBody
    public JsonObject<?> logout(HttpServletResponse response) {
        JsonObject<?> ret = JsonObject.create();
        CookieUtils.resetCookieValue(response, UserWebConstant.CookieKey.USERNAME.getValue());
        CookieUtils.resetCookieValue(response, UserWebConstant.CookieKey.PWDMD5.getValue());
        return ret;
    }
44864
protected Map<String, Object> parseResponseObject(Response response) throws IOException {
		return parseResponse(response).parseObject();
	}
68969
@SuppressWarnings("unchecked")
	@Override
	public InputStream getInputStream(HttpServletRequest request,
			HttpServletResponse response) throws IOException {

		final String sourceMethod = "getInputStream"; //$NON-NLS-1$
		CacheEntry entry = null;
		String key = null;
		IAggregator aggr = (IAggregator)request.getAttribute(IAggregator.AGGREGATOR_REQATTRNAME);
		List<String> cacheInfoReport = null;
		ModuleList moduleList = null;
		boolean cacheKeyGenMutexAcquired = false;

		if (_isReportCacheInfo) {
			cacheInfoReport = (List<String>)request.getAttribute(LAYERCACHEINFO_PROPNAME);
			if (cacheInfoReport != null) {
				cacheInfoReport.clear();
			}
		}
		if (log.isLoggable(Level.FINEST) && cacheInfoReport == null) {
			cacheInfoReport = new LinkedList<String>();
		}
		try {
			IOptions options = aggr.getOptions();
			ICacheManager mgr = aggr.getCacheManager();
			boolean ignoreCached = RequestUtil.isIgnoreCached(request);
			boolean isSourceMapsEnabled = RequestUtil.isSourceMapsEnabled(request);
			InputStream result;
			long lastModified = getLastModified(request);
			CacheEntry newEntry = new CacheEntry(_id, _cacheKey, lastModified);
			CacheEntry existingEntry = null;

			if (ignoreCached) {
				request.setAttribute(NOCACHE_RESPONSE_REQATTRNAME, Boolean.TRUE);
			}
			if (options.isDevelopmentMode()) {
				synchronized(this) {
					// See if we need to discard previously built LayerBuilds
					if (lastModified > _lastModified) {
						if (cacheInfoReport != null) {
							cacheInfoReport.add("update_lastmod2"); //$NON-NLS-1$
						}
						_lastModified = lastModified;
						_cacheKeyGenerators = null;
					}
				}
			}

			if (_cacheKeyGenerators == null) {
				// The cache key generator for this layer hasn't been created yet.  Attempt
				// to grab the mutex.
				try {
					SignalUtil.aquire(_cacheKeyGenMutex, sourceClass, sourceMethod);
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
				if (_cacheKeyGenerators == null) {
					// We're the first thread for this layer.  Set flag and proceed to build the
					// layer.  We'll release the mutex and let other thread through once we have
					// a cache key generator.
					cacheKeyGenMutexAcquired = true;
				} else {
					// Another thread already created the cache key generator.  Just release the
					// mutex and continue.
					_cacheKeyGenMutex.release();
				}
			}
			Map<String, ICacheKeyGenerator> cacheKeyGenerators = _cacheKeyGenerators;

			// Creata a cache key.
			key = generateCacheKey(request, cacheKeyGenerators);

			if (!ignoreCached && key != null) {
				int loopGuard = 5;
				do {
					// Try to retrieve an existing layer build using the blocking putIfAbsent.  If the return
					// value is null, then the newEntry was successfully added to the map, otherwise the
					// existing entry is returned in the buildReader and newEntry was not added.
					existingEntry = _layerBuilds.putIfAbsent(key, newEntry, options.isDevelopmentMode());
					if (cacheInfoReport != null) {
						cacheInfoReport.add(existingEntry != null ? "hit_1" : "added"); //$NON-NLS-1$ //$NON-NLS-2$
					}
					if (existingEntry != null) {
						if ((result = trySetResponse(request, response, existingEntry)) != null) {
							if (log.isLoggable(Level.FINEST)) {
								log.finest(cacheInfoReport.toString() + "\n" +  //$NON-NLS-1$
										"key:" + key +  //$NON-NLS-1$
										"\n" + existingEntry.toString()); //$NON-NLS-1$
							}
							if (_isReportCacheInfo) {
								request.setAttribute(LAYERBUILDCACHEKEY_PROPNAME, key);
							}
							return result;
						} else if (existingEntry.isDeleted()) {
							if (_layerBuilds.replace(key, existingEntry, newEntry)) {
								// entry was replaced, use newEntry
								if (cacheInfoReport != null) {
									cacheInfoReport.add("replace_1"); //$NON-NLS-1$
								}
								existingEntry = null;
							} else {
								// Existing entry was removed from the cache by another thread
								// between the time we retrieved it and the time we tried to
								// replace it.  Try to add the new entry again.
								if (cacheInfoReport != null) {
									cacheInfoReport.add("retry_add"); //$NON-NLS-1$
								}
								if (--loopGuard == 0) {
									// Should never happen, but just in case
									throw new IllegalStateException();
								}
								continue;
							}
						}
					}
					break;
				} while (true);
			}

			// putIfAbsent() succeeded and the new entry was added to the cache
			entry = (existingEntry != null) ? existingEntry : newEntry;

			LayerBuilder layerBuilder = null;

			// List of Future<IModule.ModuleReader> objects that will be used to read the module
			// data from
			List<ICacheKeyGenerator> moduleKeyGens = null;

			// Synchronize on the LayerBuild object for the build.  This will prevent multiple
			// threads from building the same output.  If more than one thread requests the same
			// output (same cache key), then the first one to grab the sync object will win and
			// the rest will wait for the first thread to finish building and then just return
			// the output from the first thread when they wake.
			synchronized(entry) {

				// Check to see if data is available one more time in case a different thread finished
				// building the output while we were blocked on the sync object.
				if (!ignoreCached && key != null && (result = trySetResponse(request, response, entry)) != null) {
					if (cacheInfoReport != null) {
						cacheInfoReport.add("hit_2"); //$NON-NLS-1$
					}
					if (log.isLoggable(Level.FINEST)) {
						log.finest(cacheInfoReport.toString() + "\n" + //$NON-NLS-1$
								"key:" + key +  //$NON-NLS-1$
								"\n" + entry.toString()); //$NON-NLS-1$
					}
					if (_isReportCacheInfo) {
						request.setAttribute(LAYERBUILDCACHEKEY_PROPNAME, key);
					}
					return result;
				}

				boolean isGzip = RequestUtil.isGzipEncoding(request);
				byte[] bytes, smbytes = null;


				// See if we already have a cached response that uses a different gzip
				// encoding option.  If we do, then just zip (or unzip) the cached
				// response
				CacheEntry otherEntry = null;
				if (key != null) {
					StringBuffer sb = new StringBuffer();
					Matcher m = GZIPFLAG_KEY_PATTERN.matcher(key);
					m.find();
					m.appendReplacement(sb,
							new StringBuffer(s_layerCacheKeyGenerators.get(0).toString())
					.append(":") //$NON-NLS-1$
					.append("1".equals(m.group(1)) ? "0" : "1") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					.append(":").toString() //$NON-NLS-1$
							).appendTail(sb);
					otherEntry = _layerBuilds.get(sb.toString());
				}
				if (otherEntry != null) {
					MutableObject<byte[]> sourceMapRef = isSourceMapsEnabled ? new MutableObject<byte[]>() : null;
					if (isGzip) {
						if (cacheInfoReport != null) {
							cacheInfoReport.add("zip_unzipped"); //$NON-NLS-1$
						}
						// We need gzipped and the cached entry is unzipped
						// Create the compression stream for the output
						bytes = ZipUtil.zip(otherEntry.getInputStream(request, sourceMapRef));
						if (isSourceMapsEnabled && sourceMapRef.getValue() != null) {
							smbytes = ZipUtil.zip(new ByteArrayInputStream(sourceMapRef.getValue()));
						}
					} else {
						if (cacheInfoReport != null) {
							cacheInfoReport.add("unzip_zipped"); //$NON-NLS-1$
						}
						// We need unzipped and the cached entry is zipped.  Just unzip it
						bytes = ZipUtil.unzip(otherEntry.getInputStream(request, sourceMapRef));
						if (isSourceMapsEnabled && sourceMapRef.getValue() != null) {
							// unzip the source map too
							smbytes = ZipUtil.unzip(new ByteArrayInputStream(sourceMapRef.getValue()));
						}
					}
					// Set the buildReader to the LayerBuild and release the lock by exiting the sync block
					entry.setData(bytes, smbytes);
					if (!ignoreCached) {
						_layerBuilds.replace(key, entry, entry);	// updates entry weight in map
						if (cacheInfoReport != null) {
							cacheInfoReport.add("update_weights_1"); //$NON-NLS-1$
						}
						entry.persist(mgr);
					}
				} else {
					moduleKeyGens = new LinkedList<ICacheKeyGenerator>();

					moduleList = getModules(request);

					// Remove the module list from the request to safe-guard it now that we don't
					// need it there anymore
					request.removeAttribute(MODULE_FILES_PROPNAME);

					// Create a BuildListReader from the list of Futures.  This reader will obtain a
					// ModuleReader from each of the Futures in the list and read data from each one in
					// succession until all the data has been read, blocking on each Future until the
					// reader becomes available.
					layerBuilder = new LayerBuilder(request, moduleKeyGens, moduleList);
					String layer = layerBuilder.build();
					String sourceMap = layerBuilder.getSourceMap();

					if (isGzip) {
						if (cacheInfoReport != null) {
							cacheInfoReport.add("zip"); //$NON-NLS-1$
						}
						bytes = ZipUtil.zip(new ReaderInputStream(new StringReader(layer)));
						// now compress the source map if there is one
						if (sourceMap != null) {
							smbytes = ZipUtil.zip(new ReaderInputStream(new StringReader(sourceMap)));
						}
					} else {
						bytes = layer.getBytes();
						smbytes = (sourceMap != null) ? sourceMap.getBytes() : null;
					}
					// Set the buildReader to the LayerBuild and release the lock by exiting the sync block
					entry.setData(bytes, smbytes);
					// entry will be persisted below after we determine if cache key
					// generator needs to be updated
				}
			}

			// if any of the readers included an error response, then don't cache the layer.
			if (layerBuilder != null && layerBuilder.hasErrors()) {
				request.setAttribute(NOCACHE_RESPONSE_REQATTRNAME, Boolean.TRUE);
				if (cacheInfoReport != null) {
					cacheInfoReport.add(key == null ? "error_noaction" : "error_remove"); //$NON-NLS-1$ //$NON-NLS-2$
				}
				if (key != null) {
					_layerBuilds.remove(key, entry);
				}
			} else if (layerBuilder != null) {
				if (!ignoreCached) {
					// See if we need to create or update the cache key generators
					Map<String, ICacheKeyGenerator> newKeyGens = new HashMap<String, ICacheKeyGenerator>();
					Set<String> requiredModuleListDeps = moduleList.getDependentFeatures();
					addCacheKeyGenerators(newKeyGens, s_layerCacheKeyGenerators);
					addCacheKeyGenerators(newKeyGens, aggr.getTransport().getCacheKeyGenerators());
					addCacheKeyGenerators(newKeyGens, Arrays.asList(new ICacheKeyGenerator[]{new FeatureSetCacheKeyGenerator(requiredModuleListDeps, false)}));
					addCacheKeyGenerators(newKeyGens, moduleKeyGens);

					boolean cacheKeyGeneratorsUpdated = false;
					if (!newKeyGens.equals(cacheKeyGenerators)) {
						// If we don't yet have a cache key for this layer, then get one
						// from the cache key generators, and then update the cache key for this
						// cache entry.

						synchronized(this) {
							if (_cacheKeyGenerators != null) {
								addCacheKeyGenerators(newKeyGens, _cacheKeyGenerators.values());
							}
							_cacheKeyGenerators = Collections.unmodifiableMap(newKeyGens);
						}
						if (cacheKeyGenMutexAcquired) {
							cacheKeyGenMutexAcquired = false;
							_cacheKeyGenMutex.release();
						}
						if (cacheInfoReport != null) {
							cacheInfoReport.add("update_keygen"); //$NON-NLS-1$
						}
						cacheKeyGeneratorsUpdated = true;
					}
					final String originalKey = key;
					if (key == null || cacheKeyGeneratorsUpdated) {
						if (cacheInfoReport != null) {
							cacheInfoReport.add("update_key"); //$NON-NLS-1$
						}
						key = generateCacheKey(request, newKeyGens);
					}
					if (originalKey == null || !originalKey.equals(key)) {
						/*
						 * The cache key has changed from what was originally used to put the
						 * un-built entry into the cache.  Add the LayerBuild to the cache
						 * using the new key.
						 */
						if (log.isLoggable(Level.FINE)) {
							log.fine("Key changed!  Adding layer to cache with key: " + key); //$NON-NLS-1$
						}
						final CacheEntry originalEntry = entry;
						CacheEntry updateEntry = (originalKey == null) ? entry : new CacheEntry(entry);
						CacheEntry previousEntry = _layerBuilds.putIfAbsent(key, updateEntry, options.isDevelopmentMode());
						if (cacheInfoReport != null) {
							cacheInfoReport.add(previousEntry == null ? "update_add" : "update_hit"); //$NON-NLS-1$ //$NON-NLS-2$
						}
						// Write the file to disk only if the LayerBuild was successfully added to the cache
						if (previousEntry == null) {
							// Updated entry was added to the cache.
							entry = updateEntry;
							entry.persist(mgr);
						}
						// If the key changed, then remove the entry under the old key.  Use a
						// delay to give other threads a chance to start using the new cache
						// key generator.  No need to update entry weight in map
						if (originalKey != null) {
							aggr.getExecutors().getScheduledExecutor().schedule(new Runnable() {
								public void run() {
									_layerBuilds.remove(originalKey, originalEntry);
								}
							}, LAYERBUILD_REMOVE_DELAY_SECONDS, TimeUnit.SECONDS);
						}
					} else {
						if (cacheInfoReport != null) {
							cacheInfoReport.add("update_weights_2"); //$NON-NLS-1$
						}
						_layerBuilds.replace(key, entry, entry);	// updates entry weight in map
						entry.persist(mgr);
					}
				}
			}
			result = setResponse(request, response, entry);
			// return the input stream to the LayerBuild
			if (log.isLoggable(Level.FINEST)) {
				log.finest(cacheInfoReport.toString() + "\n" + //$NON-NLS-1$
						"key:" + key +  //$NON-NLS-1$
						"\n" + entry.toString()); //$NON-NLS-1$
			}
			if (_isReportCacheInfo) {
				request.setAttribute(LAYERBUILDCACHEKEY_PROPNAME, key);
			}
			return result;
		} catch (IOException e) {
			_layerBuilds.remove(key, entry);
			throw e;
		} catch (RuntimeException e) {
			_layerBuilds.remove(key, entry);
			throw e;
		} finally {
			if (cacheKeyGenMutexAcquired) {
				_cacheKeyGenMutex.release();
			}
			if (_layerBuilds.isLayerEvicted()) {
				_layerBuilds.removeLayerFromCache(this);
			}
			// Help out the GC by clearing the module list
			if (moduleList != null) {
				request.removeAttribute(MODULE_FILES_PROPNAME);
				moduleList.clear();
			}
		}
	}
561369
private String getNTLMHeader(final HttpProxyResponse response) {
        List<String> values = response.getHeaders().get("Proxy-Authenticate");

        for (String s : values) {
            if (s.startsWith("NTLM")) {
                return s;
            }
        }

        return null;
    }
827367
public com.ibm.websphere.cache.CacheEntry getCacheEntry(Object key) {
        return super.common_getCacheEntry(key);
	}
1093952
public String extractData(
                    final ClientHttpResponse response
                    )
    throws IOException
    {
        StringWriter  output = new StringWriter();
        IoUtil.copy( new InputStreamReader( response.getBody() ), output );

        return output.toString();
    }
745538
public static void preventCache( ServletResponse response )
    {
        if ( response instanceof HttpServletResponse )
        {
            HttpServletResponse httpResponse = ( HttpServletResponse ) response;
            httpResponse.setHeader( "Pragma", "No-cache" );
            httpResponse.setHeader( "Cache-Control", "no-cache,no-store,max-age=0" );
            httpResponse.setDateHeader( "Expires", 1 );
        }
    }
838905
public Map.Entry<K, V> getEntry(Object key) {
    EntryImpl<K, V> entry = _entries[keyHash(key) & _mask];
    while (entry != null) {
      if (key.equals(entry._key)) { return entry; }
      entry = entry._next;
    }
    return null;
  }
1356557
public com.ibm.websphere.cache.CacheEntry getEntry(com.ibm.websphere.cache.EntryInfo ei) {
        return getEntry(ei, true);
    }
1098307
public static <T> Response<T> success(T result, Cache.Entry cacheEntry) {
        return new Response<T>(result, cacheEntry);
    }
72514
public base_response loginchallengeresponse(String response) throws Exception
	{
		loginchallengeresponse logincr = new loginchallengeresponse(response);
		base_response result = logincr.perform_operation(this);
		if (result.errorcode == 0)
			this.sessionid = result.sessionid;
		return result;
	}
249457
protected void addNoCacheHeaders(HttpServletResponse response) {
		String cacheControlValue = response.getHeader(WebConstants.HEADER_CACHE_CONTROL);

		if (cacheControlValue != null && !cacheControlValue.isEmpty()) {
			cacheControlValue = cacheControlValue + ", " + WebConstants.CACHE_CONTROL_NO_STORE;
		} else {
			cacheControlValue = WebConstants.CACHE_CONTROL_NO_STORE;
		}

		response.setHeader(WebConstants.HEADER_CACHE_CONTROL, cacheControlValue);
		response.setHeader(WebConstants.HEADER_PRAGMA, WebConstants.PRAGMA_NO_CACHE);
	}