package com.flicklib.service.cache; /* * This file is part of Flicklib. * * Copyright (C) Francis De Brabandere * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.httpclient.HttpClient; import org.codehaus.httpcache4j.HTTPMethod; import org.codehaus.httpcache4j.HTTPRequest; import org.codehaus.httpcache4j.HTTPResponse; import org.codehaus.httpcache4j.MIMEType; import org.codehaus.httpcache4j.Parameter; import org.codehaus.httpcache4j.cache.HTTPCache; import org.codehaus.httpcache4j.cache.MemoryCacheStorage; import org.codehaus.httpcache4j.client.HTTPClientResponseResolver; import org.codehaus.httpcache4j.payload.ByteArrayPayload; import org.codehaus.httpcache4j.payload.Payload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.flicklib.service.Source; import com.flicklib.service.SourceLoader; import com.flicklib.tools.IOTools; public class HttpCache4J implements SourceLoader { private static final Logger LOGGER = LoggerFactory.getLogger(HttpCache4J.class); private final HTTPCache cache; public HttpCache4J() { this.cache = new HTTPCache(new MemoryCacheStorage(), new HTTPClientResponseResolver(new HttpClient())); } /** {@inheritDoc} */ @Override public Source loadSource(final String url, boolean useCache) { HTTPRequest request = new HTTPRequest(URI.create(url)); HTTPResponse response = cache.execute(request, !useCache); String content = payloadToString(response); String respUrl = response.getHeaders().getFirstHeaderValue("Content-Location"); //System.err.println(response.getHeaders().toString()); final String theUrl = respUrl != null ? respUrl : url; Source source = new Source(theUrl, content, response.getPayload().getMimeType().toString(), url); return source; } /** {@inheritDoc} */ @Override public Source post(String url, Map<String, String> parameters, Map<String, String> headers) { HTTPRequest request = new HTTPRequest(URI.create(url), HTTPMethod.POST); for(Entry<String, String> header:headers.entrySet()) { request.addHeader(header.getKey(), header.getValue()); } // TODO Enable when new version of httpcache4j is released // // List<FormParameter> params = new ArrayList<FormParameter>(); // for(Entry<String,String> param:parameters.entrySet()){ // params.add(new FormParameter(param.getKey(), param.getValue())); // } // FormDataPayload payload = new FormDataPayload(params); // request = request.payload(payload); ///////////////// TODO replace this part with the code above ///////////////////// StringBuilder builder = new StringBuilder(); // TODO fix when this is fixed: http://jira.codehaus.org/browse/HTCJ-51 // or see in httpclient if we can reuse code for(Entry<String,String> param:parameters.entrySet()){ if(builder.length() > 0){ builder.append("&"); } String encoding = "UTF-8"; try { builder.append(URLEncoder.encode(param.getKey(), encoding)).append("=").append(URLEncoder.encode(param.getValue(), encoding)); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } ByteArrayInputStream bis = new ByteArrayInputStream(builder.toString().getBytes()); MIMEType mimeType = new MIMEType("application/x-www-form-urlencoded"); Payload payload = null; try { payload = new ByteArrayPayload(bis, mimeType); } catch (IOException e) { LOGGER.error(e.getMessage(), e); } request = request.payload(payload); ////////////////////////////////////////////////////////////////////////// HTTPResponse response = cache.execute(request, false); String content = payloadToString(response); final String respUrl = response.getHeaders().getFirstHeaderValue("Content-Location"); final String theUrl = (respUrl != null) ? respUrl : url; Source source = new Source(theUrl, content, response.getPayload().getMimeType().toString(), url); return source; } @Override public Source loadSource(String url) throws IOException { return loadSource(url, true); } private String payloadToString(HTTPResponse response){ String content = null; InputStream is = null; try{ is = response.getPayload().getInputStream(); //httpMethod.addRequestHeader("Content-Type","text/html; charset=UTF-8"); String contentType = response.getHeaders().getFirstHeaderValue("Content-Type"); MIMEType mimeType = new MIMEType(contentType); // default as described in: http://hc.apache.org/httpclient-3.x/charencodings.html String encoding = "ISO-8859-1"; if(contentType.contains("charset")){ for(Parameter parameter:mimeType.getParameters()){ if("charset".equals(parameter.getName())){ encoding = parameter.getValue(); } } } content = IOTools.inputSreamToString(is, encoding); } catch (IOException e) { LOGGER.error(e.getMessage(),e); }finally{ IOTools.close(is); } return content; } @Override public RestBuilder url(String url) { throw new UnsupportedOperationException("not implemented"); } }