// // ProxyCacheHandler // Copyright 2004 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany // Copyright 2011 by Florian Richter // First released 2011 at http://yacy.net // // $LastChangedDate$ // $LastChangedRevision$ // $LastChangedBy$ // // 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.http; import java.io.IOException; import java.util.Map.Entry; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.yacy.cora.document.id.DigestURL; import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.protocol.ResponseHeader; import net.yacy.crawler.data.Cache; import net.yacy.crawler.retrieval.Response; import net.yacy.http.servlets.YaCyDefaultServlet; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; /** * jetty http handler serves pages from cache if available and valid */ public class ProxyCacheHandler extends AbstractRemoteHandler implements Handler { private void handleRequestFromCache(@SuppressWarnings("unused") HttpServletRequest request, HttpServletResponse response, ResponseHeader cachedResponseHeader, byte[] content) throws IOException { // TODO: check if-modified for (Entry<String, String> entry : cachedResponseHeader.entrySet()) { response.addHeader(entry.getKey(), entry.getValue()); } response.setStatus(HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION); response.getOutputStream().write(content); // we handled this request, break out of handler chain } @Override public void handleRemote(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (request.getMethod().equals("GET")) { String queryString = request.getQueryString() != null ? "?" + request.getQueryString() : ""; DigestURL url = new DigestURL(request.getRequestURL().toString() + queryString); ResponseHeader cachedResponseHeader = Cache.getResponseHeader(url.hash()); if (cachedResponseHeader != null) { RequestHeader proxyHeaders = ProxyHandler.convertHeaderFromJetty(request); // TODO: this convertion is only necessary final net.yacy.crawler.retrieval.Request yacyRequest = new net.yacy.crawler.retrieval.Request( null, url, proxyHeaders.referer() == null ? null : new DigestURL(proxyHeaders.referer().toNormalform(true)).hash(), "", cachedResponseHeader.lastModified(), sb.crawler.defaultProxyProfile.handle(), 0, sb.crawler.defaultProxyProfile.timezoneOffset()); final Response cachedResponse = new Response( yacyRequest, proxyHeaders, cachedResponseHeader, sb.crawler.defaultProxyProfile, false, null); byte[] cacheContent = Cache.getContent(url.hash()); if (cacheContent != null && cachedResponse.isFreshForProxy()) { handleRequestFromCache(request, response, cachedResponseHeader, cacheContent); baseRequest.setHandled(true); } } } } }