/* * This file is part of Flicklib. * * Copyright (C) Zsombor Gegesy * * 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. */ package com.flicklib.service; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.HttpConnectionParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; import com.google.inject.name.Named; public class HttpClientSourceLoader implements SourceLoader { private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientSourceLoader.class); private final DefaultHttpClient client; @Inject public HttpClientSourceLoader(@Named(value = Constants.HTTP_TIMEOUT) final Integer timeout) { ThreadSafeClientConnManager tm = new ThreadSafeClientConnManager(); tm.setDefaultMaxPerRoute(20); tm.setMaxTotal(200); client = new DefaultHttpClient(tm); if (timeout != null) { // wait max x sec HttpConnectionParams.setSoTimeout(client.getParams(), timeout); } } @Override public Source loadSource(String url) throws IOException { HttpResponse response = null; try { LOGGER.info("Loading " + url); HttpGet httpMethod = new HttpGet(url); //httpMethod.addRequestHeader("Content-Type","text/html; charset=UTF-8"); HttpContext ctx = new BasicHttpContext(); response = client.execute(httpMethod, ctx); return buildSource(url, response, httpMethod, ctx); } finally { if (response != null) { EntityUtils.consume(response.getEntity()); } } } @Override public Source loadSource(String url, boolean useCache) throws IOException { return loadSource(url); } @Override public Source post(String url, Map<String, String> parameters, Map<String, String> headers) throws IOException { HttpResponse response = null; try { LOGGER.info("Loading " + url); HttpPost httpMethod = new HttpPost(url); if (parameters != null && !parameters.isEmpty()) { List<NameValuePair> formparams = new ArrayList<NameValuePair>(); for (Entry<String, String> entry : parameters.entrySet()) { formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8"); httpMethod.setEntity(form); } if (headers != null && !headers.isEmpty()) { for (Entry<String, String> entry : headers.entrySet()) { httpMethod.addHeader(entry.getKey(), entry.getValue()); } } HttpContext ctx = new BasicHttpContext(); response = client.execute(httpMethod, ctx); return buildSource(url, response, httpMethod, ctx); } finally { EntityUtils.consume(response.getEntity()); } } @Override public RestBuilder url(final String url) { return new HttpClientRestBuilder(url); } private Source buildSource(String url, HttpResponse response, HttpRequestBase httpMethod, HttpContext ctx) throws IOException { LOGGER.info("Finished loading at " + httpMethod.getURI().toString()); final HttpEntity entity = response.getEntity(); String responseCharset = EntityUtils.getContentCharSet(entity); String contentType = EntityUtils.getContentMimeType(entity); LOGGER.info("Response charset = " + responseCharset); String content = EntityUtils.toString(entity); HttpUriRequest req = (HttpUriRequest) ctx.getAttribute(ExecutionContext.HTTP_REQUEST); HttpHost target = (HttpHost) ctx.getAttribute(ExecutionContext.HTTP_TARGET_HOST); URI resultUri; try { resultUri = (target != null && req != null) ? new URI(target.toURI() + req.getURI().toString()) : httpMethod.getURI(); } catch (URISyntaxException e) { e.printStackTrace(); resultUri = httpMethod.getURI(); } // String contentType = URLConnection.guessContentTypeFromName(url) return new Source(resultUri.toString(), content, contentType, url); } private final class HttpClientRestBuilder implements RestBuilder { private final List<Header> headers = new ArrayList<Header>(); private final String url; public HttpClientRestBuilder(final String url) { this.url = url; } @Override public RestBuilder setHeader(String name, String value) { headers.add(new Header(name, value)); return this; } @Override public RestResult get() throws IOException { HttpGet httpMethod = new HttpGet(url); for(Header header:headers){ httpMethod.addHeader(header.name,header.value); } HttpContext ctx = new BasicHttpContext(); HttpResponse response = client.execute(httpMethod, ctx); return new HttpClientRestResult(response); } } private static final class Header{ private final String name; private final String value; private Header(String name, String value) { super(); this.name = name; this.value = value; } } private final class HttpClientRestResult implements RestResult { private final HttpResponse response; public HttpClientRestResult(final HttpResponse response) { this.response = response; } @Override public String getString() throws IOException { final HttpEntity entity = response.getEntity(); String content = EntityUtils.toString(entity); return content; } } }