/** * ResponseHeader * Copyright 2008 by Michael Peter Christen, mc@yacy.net, Frankfurt a. M., Germany * First released 22.08.2008 at http://yacy.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in the file lgpl21.txt * If not, see <http://www.gnu.org/licenses/>. */ package net.yacy.cora.protocol; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import javax.servlet.http.Cookie; import org.apache.http.Header; public class ResponseHeader extends HeaderFramework { // response header properties private static final long serialVersionUID = 0L; // cached values for quicker repeated access private Date date_cache_Date = null; private Date date_cache_Expires = null; private Date date_cache_LastModified = null; public ResponseHeader(final int statusCode) { super(); this.put(HeaderFramework.STATUS_CODE, Integer.toString(statusCode)); } public ResponseHeader(final int statusCode, final Header[] headers) { super(); this.put(HeaderFramework.STATUS_CODE, Integer.toString(statusCode)); for (final Header h : headers) { add(h.getName(), h.getValue()); } } public ResponseHeader(final Map<String, String> othermap) { super(othermap); } public int getStatusCode() { String statuscode = this.get(HeaderFramework.STATUS_CODE); if (statuscode == null) return 200; try { return Integer.parseInt(statuscode); } catch (final NumberFormatException e) { return 200; } } /** * Get the http field Date or now (if header date missing) * @return date message was created or now */ public Date date() { if (this.date_cache_Date != null) return this.date_cache_Date; final Date d = headerDate(HeaderFramework.DATE); final Date now = new Date(); this.date_cache_Date = (d == null) ? now : d.after(now) ? now : d; return this.date_cache_Date; } /** * get http field Expires if available * @return date or null */ public Date expires() { if (this.date_cache_Expires != null) return this.date_cache_Expires; this.date_cache_Expires = headerDate(HeaderFramework.EXPIRES); return this.date_cache_Expires; } /** * get http field Last-Modified or now (if header field is missing) * @return valid date (always != null) */ public Date lastModified() { if (this.date_cache_LastModified != null) return this.date_cache_LastModified; Date d = headerDate(HeaderFramework.LAST_MODIFIED); final Date now = new Date(); this.date_cache_LastModified = (d == null) ? date() : d.after(now) ? now : d; return this.date_cache_LastModified; } /** * age in milliseconds (difference between now and last_modified) * @return age in milliseconds */ public long age() { final Date lm = lastModified(); final Date now = new Date(); return now.getTime() - lm.getTime(); } public boolean gzip() { return ((containsKey(HeaderFramework.CONTENT_ENCODING)) && ((get(HeaderFramework.CONTENT_ENCODING)).toUpperCase().startsWith("GZIP"))); } public String getXRobotsTag() { String x_robots_tag = this.get(HeaderFramework.X_ROBOTS_TAG, ""); if (x_robots_tag.isEmpty()) { x_robots_tag = this.get(HeaderFramework.X_ROBOTS, ""); } return x_robots_tag.toLowerCase(); } /* * Patch BEGIN: (moved from HeaderFramework here (2016-11-20) * Name: Header Property Patch * Date: Fri. 13.01.2006 * Description: Makes possible to send header properties such as cookies back to the client. * Part 1 of 5 * Questions: sergej.z@list.ru */ /** * Holds header properties */ //Since properties such as cookies can be multiple, we cannot use HashMap here. We have to use Vector. private List<Cookie> cookieStore; // init on first access /** * Sets Cookie on the client machine. * * @param name Cookie name * @param value Cookie value * @param maxage time to live in seconds, none negative number, according to https://tools.ietf.org/html/rfc2109, 0=discard in https://tools.ietf.org/html/rfc2965 * @param path Path the cookie belongs to. Default - "/". Can be <b>null</b>. * @param domain Domain this cookie belongs to. Default - domain name. Can be <b>null</b>. * @param secure If true cookie will be send only over safe connection such as https * @see further documentation: <a href="http://docs.sun.com/source/816-6408-10/cookies.htm">docs.sun.com</a> */ public void setCookie(final String name, final String value, final Integer maxage, final String path, final String domain, final boolean secure) { /* * TODO:Here every value can be validated for correctness if needed * For example semicolon should be not in any of the values * However an exception in this case would be an overhead IMHO. */ if (!name.isEmpty()) { if (this.cookieStore == null) this.cookieStore = new ArrayList<Cookie>(); Cookie c = new Cookie (name, value); if (maxage != null && maxage >= 0) c.setMaxAge(maxage); if (path != null) c.setPath(path); if (domain != null) c.setDomain(domain); if (secure) c.setSecure(secure); this.cookieStore.add(c); } } /** * Sets Cookie on the client machine. * * @param name Cookie name * @param value Cookie value * * Note: this cookie will be sent over each connection independent if it is safe connection or not. This cookie never expires * @see further documentation: <a href="http://docs.sun.com/source/816-6408-10/cookies.htm">docs.sun.com</a> */ public void setCookie(final String name, final String value ) { setCookie( name, value, null, null, null, false); } public List<Cookie> getCookiesEntries() { return this.cookieStore; } /* * Patch END: * Name: Header Property Patch */ }