You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2010/02/02 00:05:44 UTC
svn commit: r905439 - in /incubator/shindig/trunk: ./
java/common/src/main/java/org/apache/shindig/common/cache/ java/gadgets/
java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ java/samples/
java/social-api/ java/social-api/src/main/java/org/...
Author: lindner
Date: Mon Feb 1 23:05:43 2010
New Revision: 905439
URL: http://svn.apache.org/viewvc?rev=905439&view=rev
Log:
httpclient 4.0 upgrade
Modified:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/cache/LruCacheProvider.java
incubator/shindig/trunk/java/gadgets/pom.xml
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java
incubator/shindig/trunk/java/samples/pom.xml
incubator/shindig/trunk/java/social-api/pom.xml
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/service/SampleContainerHandler.java
incubator/shindig/trunk/pom.xml
Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/cache/LruCacheProvider.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/cache/LruCacheProvider.java?rev=905439&r1=905438&r2=905439&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/cache/LruCacheProvider.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/cache/LruCacheProvider.java Mon Feb 1 23:05:43 2010
@@ -84,12 +84,12 @@
public <K, V> Cache<K, V> createCache(String name) {
int capacity = getCapacity(name);
if (name == null) {
- LOG.info("Creating anonymous cache");
+ LOG.fine("Creating anonymous cache");
return new LruCache<K, V>(capacity);
} else {
Cache<K, V> cache = (Cache<K, V>) caches.get(name);
if (cache == null) {
- LOG.info("Creating cache named " + name);
+ LOG.fine("Creating cache named " + name);
cache = new LruCache<K, V>(capacity);
caches.put(name, cache);
}
Modified: incubator/shindig/trunk/java/gadgets/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/pom.xml?rev=905439&r1=905438&r2=905439&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/pom.xml (original)
+++ incubator/shindig/trunk/java/gadgets/pom.xml Mon Feb 1 23:05:43 2010
@@ -143,7 +143,7 @@
</dependency>
<dependency>
<groupId>net.oauth.core</groupId>
- <artifactId>oauth-httpclient3</artifactId>
+ <artifactId>oauth-httpclient4</artifactId>
</dependency>
<dependency>
<groupId>com.google.collections</groupId>
@@ -208,8 +208,9 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.0.1</version>
</dependency>
<!-- test -->
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java?rev=905439&r1=905438&r2=905439&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java Mon Feb 1 23:05:43 2010
@@ -17,259 +17,386 @@
*/
package org.apache.shindig.gadgets.http;
-import com.google.inject.internal.Preconditions;
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.HttpStatus;
-import org.apache.commons.httpclient.methods.DeleteMethod;
-import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.HeadMethod;
-import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.PutMethod;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.io.output.ByteArrayOutputStream;
-import org.apache.shindig.common.uri.Uri;
-
-import com.google.common.collect.Maps;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.google.inject.internal.Preconditions;
import com.google.inject.name.Named;
-import java.io.ByteArrayInputStream;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.HttpVersion;
+import org.apache.http.NoHttpResponseException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.params.HttpClientParams;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.ConnectionPoolTimeoutException;
+import org.apache.http.conn.HttpHostConnectException;
+import org.apache.http.conn.params.ConnManagerParams;
+import org.apache.http.conn.params.ConnPerRouteBean;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.HttpEntityWrapper;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
+import org.apache.http.impl.conn.ProxySelectorRoutePlanner;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+
import java.io.IOException;
import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
import java.net.ProxySelector;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
/**
- * A very primitive HTTP fetcher implementation. Not recommended for production deployments until
+ * A simple HTTP fetcher implementation based on Apache httpclient. Not recommended for production deployments until
* the following issues are addressed:
- *
+ * <p/>
* 1. This class potentially allows access to resources behind an organization's firewall.
- * 2. This class does not handle most advanced HTTP functionality correctly (SSL, etc.)
- * 3. This class does not enforce any limits on what is fetched from remote hosts.
+ * 2. This class does not enforce any limits on what is fetched from remote hosts.
*/
@Singleton
public class BasicHttpFetcher implements HttpFetcher {
private static final int DEFAULT_CONNECT_TIMEOUT_MS = 5000;
+ private static final int DEFAULT_READ_TIMEOUT_MS = 5000;
private static final int DEFAULT_MAX_OBJECT_SIZE = 0; // no limit
- private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+ private static final long DEFAULT_SLOW_RESPONSE_WARNING = 10000;
+
+ protected final HttpClient FETCHER;
// mutable fields must be volatile
- private volatile int maxObjSize;
- private volatile int connectionTimeoutMs;
+ private volatile int maxObjSize;
+ private volatile long slowResponseWarning;
- /**
- * Creates a new fetcher for fetching HTTP objects. Not really suitable
- * for production use. Use of an HTTP proxy for security is also necessary
- * for production deployment.
- *
- * @param maxObjSize Maximum size, in bytes, of the object we will fetch, 0 if no limit..
- * @param connectionTimeoutMs timeout, in milliseconds, for requests.
- */
- public BasicHttpFetcher(int maxObjSize, int connectionTimeoutMs) {
- setMaxObjectSizeBytes(maxObjSize);
- setConnectionTimeoutMs(connectionTimeoutMs);
- }
+ private static final Logger LOG = Logger.getLogger(BasicHttpFetcher.class.getName());
+
+ private final Set<Class<?>> TIMEOUT_EXCEPTIONS = ImmutableSet.<Class<?>>of(ConnectionPoolTimeoutException.class,
+ SocketTimeoutException.class, SocketException.class, HttpHostConnectException.class, NoHttpResponseException.class,
+ InterruptedException.class, UnknownHostException.class);
/**
* Creates a new fetcher using the default maximum object size and timeout --
* no limit and 5 seconds.
*/
public BasicHttpFetcher() {
- this(DEFAULT_MAX_OBJECT_SIZE, DEFAULT_CONNECT_TIMEOUT_MS);
+ this(DEFAULT_MAX_OBJECT_SIZE, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_READ_TIMEOUT_MS);
}
- /**
- * Change the global maximum fetch size (in bytes) for all fetches.
- *
- * @param maxObjectSizeBytes value for maximum number of bytes, or 0 for no limit
- */
- @Inject(optional = true)
- public void setMaxObjectSizeBytes(@Named("shindig.http.client.max-object-size-bytes") int maxObjectSizeBytes) {
- this.maxObjSize = maxObjectSizeBytes;
+ @Deprecated
+ public BasicHttpFetcher(int maxObjSize, int connectionTimeoutMs) {
+ this(maxObjSize, connectionTimeoutMs, DEFAULT_READ_TIMEOUT_MS);
}
/**
- * Change the global connection timeout for all fetchs.
+ * Creates a new fetcher for fetching HTTP objects. Not really suitable
+ * for production use. Use of an HTTP proxy for security is also necessary
+ * for production deployment.
*
- * @param connectionTimeoutMs new connection timeout in milliseconds
+ * @param maxObjSize Maximum size, in bytes, of the object we will fetch, 0 if no limit..
+ * @param connectionTimeoutMs timeout, in milliseconds, for connecting to hosts.
+ * @param readTimeoutMs timeout, in millseconds, for unresponsive connections
*/
- @Inject(optional = true)
- public void setConnectionTimeoutMs(@Named("shindig.http.client.connection-timeout-ms") int connectionTimeoutMs) {
- Preconditions.checkArgument(connectionTimeoutMs > 0, "connection-timeout-ms must be greater than 0");
- this.connectionTimeoutMs = connectionTimeoutMs;
- }
+ public BasicHttpFetcher(int maxObjSize, int connectionTimeoutMs, int readTimeoutMs) {
+ // Create and initialize HTTP parameters
+ setMaxObjectSizeBytes(maxObjSize);
+ setSlowResponseWarning(DEFAULT_SLOW_RESPONSE_WARNING);
- /**
- * @param httpMethod
- * @param responseCode
- * @return A HttpResponse object made by consuming the response of the
- * given HttpMethod.
- * @throws java.io.IOException
- */
- private HttpResponse makeResponse(HttpMethod httpMethod, int responseCode) throws IOException {
- Map<String, String> headers = Maps.newHashMap();
+ HttpParams params = new BasicHttpParams();
+
+ ConnManagerParams.setTimeout(params, connectionTimeoutMs);
+
+ // These are probably overkill for most sites.
+ ConnManagerParams.setMaxTotalConnections(params, 1152);
+ ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(256));
- if (httpMethod.getResponseHeaders() != null) {
- for (Header h : httpMethod.getResponseHeaders()) {
- headers.put(h.getName(), h.getValue());
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setUserAgent(params, "Apache Shindig");
+ HttpProtocolParams.setContentCharset(params, "UTF-8");
+
+ HttpConnectionParams.setConnectionTimeout(params, connectionTimeoutMs);
+ HttpConnectionParams.setSoTimeout(params, readTimeoutMs);
+ HttpConnectionParams.setStaleCheckingEnabled(params, true);
+
+ HttpClientParams.setRedirecting(params, true);
+ HttpClientParams.setAuthenticating(params, false);
+
+ // Create and initialize scheme registry
+ SchemeRegistry schemeRegistry = new SchemeRegistry();
+ schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
+
+ ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
+
+ DefaultHttpClient client = new DefaultHttpClient(cm, params);
+
+ // try resending the request once
+ client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(1, true));
+
+ // Add hooks for gzip/deflate
+ client.addRequestInterceptor(new HttpRequestInterceptor() {
+ public void process(
+ final org.apache.http.HttpRequest request,
+ final HttpContext context) throws HttpException, IOException {
+ if (!request.containsHeader("Accept-Encoding")) {
+ request.addHeader("Accept-Encoding", "gzip, deflate");
+ }
}
- }
+ });
+ client.addResponseInterceptor(new HttpResponseInterceptor() {
+ public void process(
+ final org.apache.http.HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+ HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ Header ceheader = entity.getContentEncoding();
+ if (ceheader != null) {
+ for (HeaderElement codec : ceheader.getElements()) {
+ String codecname = codec.getName();
+ if ("gzip".equalsIgnoreCase(codecname)) {
+ response.setEntity(
+ new GzipDecompressingEntity(response.getEntity()));
+ return;
+ } else if ("deflate".equals(codecname)) {
+ response.setEntity(new DeflateDecompressingEntity(response.getEntity()));
+ return;
+ }
+ }
+ }
+ }
+ }
+ });
+ client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler() );
- // The first header is always null here to provide the response body.
- headers.remove(null);
+ // Use Java's built-in proxy logic
+ ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(
+ client.getConnectionManager().getSchemeRegistry(),
+ ProxySelector.getDefault());
+ client.setRoutePlanner(routePlanner);
- // Find the response stream - the error stream may be valid in cases
- // where the input stream is not.
- InputStream responseBodyStream = null;
- try {
- responseBodyStream = httpMethod.getResponseBodyAsStream();
- } catch (IOException e) {
- // normal for 401, 403 and 404 responses, for example...
- }
+ FETCHER = client;
+ }
- if (responseBodyStream == null) {
- // Fall back to zero length response.
- responseBodyStream = new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY);
+ static class GzipDecompressingEntity extends HttpEntityWrapper {
+ public GzipDecompressingEntity(final HttpEntity entity) {
+ super(entity);
}
- String encoding = headers.get("Content-Encoding");
+ public InputStream getContent() throws IOException, IllegalStateException {
+ // the wrapped entity's getContent() decides about repeatability
+ InputStream wrappedin = wrappedEntity.getContent();
- // Create the appropriate stream wrapper based on the encoding type.
- InputStream is = responseBodyStream;
- if (encoding == null) {
- is = responseBodyStream;
- } else if (encoding.equalsIgnoreCase("gzip")) {
- is = new GZIPInputStream(responseBodyStream);
- } else if (encoding.equalsIgnoreCase("deflate")) {
- Inflater inflater = new Inflater(true);
- is = new InflaterInputStream(responseBodyStream, inflater);
+ return new GZIPInputStream(wrappedin);
}
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
- int totalBytesRead = 0;
- int currentBytesRead;
-
- while ((currentBytesRead = is.read(buffer)) != -1) {
- output.write(buffer, 0, currentBytesRead);
- totalBytesRead += currentBytesRead;
-
- if(maxObjSize > 0 && totalBytesRead > maxObjSize) {
- IOUtils.closeQuietly(is);
- IOUtils.closeQuietly(output);
- // Exceeded max # of bytes
- return HttpResponse.badrequest("Exceeded maximum number of bytes - " + this.maxObjSize);
- }
+ public long getContentLength() {
+ // length of ungzipped content is not known
+ return -1;
}
-
- return new HttpResponseBuilder()
- .setHttpStatusCode(responseCode)
- .setResponse(output.toByteArray())
- .addHeaders(headers)
- .create();
}
- /** {@inheritDoc} */
- public HttpResponse fetch(HttpRequest request) {
- HttpClient httpClient = new HttpClient();
- HttpMethod httpMethod;
- String methodType = request.getMethod();
- String requestUri = request.getUri().toString();
-
- // Select a proxy based on the URI. May be Proxy.NO_PROXY
- Proxy proxy = ProxySelector.getDefault().select(request.getUri().toJavaUri()).get(0);
-
- if (proxy != Proxy.NO_PROXY) {
- InetSocketAddress address = (InetSocketAddress) proxy.address();
- httpClient.getHostConfiguration().setProxy(address.getHostName(), address.getPort());
+ static class DeflateDecompressingEntity extends HttpEntityWrapper {
+ public DeflateDecompressingEntity(final HttpEntity entity) {
+ super(entity);
}
+ public InputStream getContent()
+ throws IOException, IllegalStateException {
- // true for non-HEAD requests
- boolean requestCompressedContent = true;
+ // the wrapped entity's getContent() decides about repeatability
+ InputStream wrappedin = wrappedEntity.getContent();
- if ("POST".equals(methodType) || "PUT".equals(methodType)) {
- EntityEnclosingMethod enclosingMethod = ("POST".equals(methodType))
- ? new PostMethod(requestUri)
- : new PutMethod(requestUri);
-
- if (request.getPostBodyLength() > 0) {
- enclosingMethod.setRequestEntity(new InputStreamRequestEntity(request.getPostBody()));
- enclosingMethod.setRequestHeader("Content-Length",
- String.valueOf(request.getPostBodyLength()));
- }
- httpMethod = enclosingMethod;
- } else if ("DELETE".equals(methodType)) {
- httpMethod = new DeleteMethod(requestUri);
- } else if ("HEAD".equals(methodType)) {
- httpMethod = new HeadMethod(requestUri);
- } else {
- httpMethod = new GetMethod(requestUri);
+ return new InflaterInputStream(wrappedin, new Inflater(true));
}
- httpMethod.setFollowRedirects(false);
- httpMethod.getParams().setSoTimeout(connectionTimeoutMs);
+ public long getContentLength() {
+ // length of ungzipped content is not known
+ return -1;
+ }
+ }
- if (requestCompressedContent)
- httpMethod.setRequestHeader("Accept-Encoding", "gzip, deflate");
+ public HttpResponse fetch(org.apache.shindig.gadgets.http.HttpRequest request) {
+ HttpUriRequest httpMethod = null;
+ Preconditions.checkNotNull(request);
+ final String methodType = request.getMethod();
+ final String requestUri = request.getUri().toString();
- for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
- httpMethod.setRequestHeader(entry.getKey(), StringUtils.join(entry.getValue(), ','));
- }
+ final org.apache.http.HttpResponse response;
+ final long started = System.currentTimeMillis();
try {
+ if ("POST".equals(methodType) || "PUT".equals(methodType)) {
+ HttpEntityEnclosingRequestBase enclosingMethod = ("POST".equals(methodType))
+ ? new HttpPost(requestUri)
+ : new HttpPut(requestUri);
+
+ if (request.getPostBodyLength() > 0) {
+ enclosingMethod.setEntity(new InputStreamEntity(request.getPostBody(), request.getPostBodyLength()));
+ }
+ httpMethod = enclosingMethod;
+ } else if ("GET".equals(methodType)) {
+ httpMethod = new HttpGet(requestUri);
+ } else if ("HEAD".equals(methodType)) {
+ httpMethod = new HttpHead(requestUri);
+ } else if ("DELETE".equals(methodType)) {
+ httpMethod = new HttpDelete(requestUri);
+ }
+ for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
+ httpMethod.addHeader(entry.getKey(), StringUtils.join(entry.getValue(), ','));
+ }
- int statusCode = httpClient.executeMethod(httpMethod);
+ if (!request.getFollowRedirects())
+ httpMethod.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
+
+ response = FETCHER.execute(httpMethod);
- // Handle redirects manually
- if (request.getFollowRedirects() &&
- ((statusCode == HttpStatus.SC_MOVED_TEMPORARILY) ||
- (statusCode == HttpStatus.SC_MOVED_PERMANENTLY) ||
- (statusCode == HttpStatus.SC_SEE_OTHER) ||
- (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT))) {
-
- Header header = httpMethod.getResponseHeader("location");
- if (header != null) {
- String redirectUri = header.getValue();
+ if (response == null)
+ throw new IOException("Unknown problem with request");
- if ((redirectUri == null) || (redirectUri.equals(""))) {
- redirectUri = "/";
- }
- // Url can be relative to original:
- redirectUri = request.getUri().resolve(Uri.parse(redirectUri)).toString();
-
- httpMethod.releaseConnection();
- httpMethod = new GetMethod(redirectUri);
+ if (response.getEntity() == null) {
+ throw new IOException("Cannot retrieve " + request.getUri() + " reason " + response.getStatusLine().getReasonPhrase());
+ }
- statusCode = httpClient.executeMethod(httpMethod);
- }
+ long now = System.currentTimeMillis();
+ if (now - started > slowResponseWarning) {
+ slowResponseWarning(request, started, now);
}
- return makeResponse(httpMethod, statusCode);
+ return makeResponse(response);
- } catch (IOException e) {
- if (e instanceof java.net.SocketTimeoutException ||
- e instanceof java.net.SocketException) {
+ } catch (Exception e) {
+ long now = System.currentTimeMillis();
+
+ // Find timeout exceptions, respond accordingly
+ if (TIMEOUT_EXCEPTIONS.contains(e.getClass())) {
+ LOG.warning("Timeout for " + request.getUri() + " Exception: " + e.getClass().getName() + " - " + e.getMessage() + " - " + (now - started) + "ms");
return HttpResponse.timeout();
}
- return HttpResponse.error();
+ LOG.log(Level.WARNING, "Got Exception fetching " + request.getUri() + " - " + (now - started) + "ms", e);
+ return HttpResponse.error();
} finally {
- httpMethod.releaseConnection();
+ // cleanup any outstanding resources..
+ if (httpMethod != null) try {
+ httpMethod.abort();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Called when a request takes too long. Consider subclassing this if you want to do something other than logging
+ * a warning .
+ *
+ * @param request the request that generated the slowrequest
+ * @param started the time the request started, in milliseconds.
+ * @param finished the time the request finished, in milliseconds.
+ */
+ protected void slowResponseWarning(HttpRequest request, long started, long finished) {
+ LOG.warning("Slow response from " + request.getUri() + ' ' + (finished - started) + "ms");
+ }
+
+ /**
+ * Change the global maximum fetch size (in bytes) for all fetches.
+ *
+ * @param maxObjectSizeBytes value for maximum number of bytes, or 0 for no limit
+ */
+ @Inject(optional = true)
+ public void setMaxObjectSizeBytes(@Named("shindig.http.client.max-object-size-bytes") int maxObjectSizeBytes) {
+ this.maxObjSize = maxObjectSizeBytes;
+ }
+
+ /**
+ * Change the global threshold for warning about slow responses
+ *
+ * @param slowResponseWarning time in milliseconds after we issue a warning
+ */
+
+ @Inject(optional = true)
+ public void setSlowResponseWarning(@Named("shindig.http.client.slow-response-warning") long slowResponseWarning) {
+ this.slowResponseWarning = slowResponseWarning;
+ }
+
+ /**
+ * Change the global connection timeout for all new fetchs.
+ *
+ * @param connectionTimeoutMs new connection timeout in milliseconds
+ */
+ @Inject(optional = true)
+ public void setConnectionTimeoutMs(@Named("shindig.http.client.connection-timeout-ms") int connectionTimeoutMs) {
+ Preconditions.checkArgument(connectionTimeoutMs > 0, "connection-timeout-ms must be greater than 0");
+ FETCHER.getParams().setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT, connectionTimeoutMs);
+ }
+
+ /**
+ * Change the global read timeout for all new fetchs.
+ *
+ * @param connectionTimeoutMs new connection timeout in milliseconds
+ */
+ @Inject(optional = true)
+ public void setReadTimeoutMs(@Named("shindig.http.client.read-timeout-ms") int connectionTimeoutMs) {
+ Preconditions.checkArgument(connectionTimeoutMs > 0, "connection-timeout-ms must be greater than 0");
+ FETCHER.getParams().setIntParameter(HttpConnectionParams.SO_TIMEOUT, connectionTimeoutMs);
+ }
+
+
+ /**
+ * @param response The response to parse
+ * @return A HttpResponse object made by consuming the response of the
+ * given HttpMethod.
+ * @throws IOException when problems occur processing the body content
+ */
+ private HttpResponse makeResponse(org.apache.http.HttpResponse response) throws IOException {
+ HttpResponseBuilder builder = new HttpResponseBuilder();
+
+ if (response.getAllHeaders() != null) {
+ for (Header h : response.getAllHeaders()) {
+ if (h.getName() != null)
+ builder.addHeader(h.getName(), h.getValue());
+ }
}
+
+ HttpEntity entity = Preconditions.checkNotNull(response.getEntity());
+
+ if (maxObjSize > 0 && entity.getContentLength() > maxObjSize) {
+ return HttpResponse.badrequest("Exceeded maximum number of bytes - " + maxObjSize);
+ }
+
+ return builder
+ .setHttpStatusCode(response.getStatusLine().getStatusCode())
+ .setResponse(EntityUtils.toByteArray(entity))
+ .create();
}
}
Modified: incubator/shindig/trunk/java/samples/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/samples/pom.xml?rev=905439&r1=905438&r2=905439&view=diff
==============================================================================
--- incubator/shindig/trunk/java/samples/pom.xml (original)
+++ incubator/shindig/trunk/java/samples/pom.xml Mon Feb 1 23:05:43 2010
@@ -142,7 +142,7 @@
</dependency>
<dependency>
<groupId>net.oauth.core</groupId>
- <artifactId>oauth-httpclient3</artifactId>
+ <artifactId>oauth-httpclient4</artifactId>
</dependency>
<!-- Hibernate -->
Modified: incubator/shindig/trunk/java/social-api/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/pom.xml?rev=905439&r1=905438&r2=905439&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/pom.xml (original)
+++ incubator/shindig/trunk/java/social-api/pom.xml Mon Feb 1 23:05:43 2010
@@ -59,6 +59,12 @@
<groupId>org.apache.shindig</groupId>
<artifactId>shindig-common</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.shindig</groupId>
+ <artifactId>shindig-gadgets</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.apache.shindig</groupId>
<artifactId>shindig-common</artifactId>
@@ -99,7 +105,7 @@
</dependency>
<dependency>
<groupId>net.oauth.core</groupId>
- <artifactId>oauth-httpclient3</artifactId>
+ <artifactId>oauth-httpclient4</artifactId>
</dependency>
<!-- may only be needed for JDK < 1.6 -->
@@ -124,8 +130,8 @@
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>xml-apis</groupId>
Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/service/SampleContainerHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/service/SampleContainerHandler.java?rev=905439&r1=905438&r2=905439&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/service/SampleContainerHandler.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/service/SampleContainerHandler.java Mon Feb 1 23:05:43 2010
@@ -18,10 +18,8 @@
package org.apache.shindig.social.sample.service;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.shindig.common.util.ImmediateFuture;
+import org.apache.shindig.common.uri.Uri;
import org.apache.shindig.protocol.Operation;
import org.apache.shindig.protocol.ProtocolException;
import org.apache.shindig.protocol.RequestItem;
@@ -29,6 +27,11 @@
import org.apache.shindig.social.sample.spi.JsonDbOpensocialService;
import org.json.JSONException;
import org.json.JSONObject;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.http.HttpFetcher;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
+
import java.io.IOException;
import java.util.concurrent.Future;
@@ -42,10 +45,11 @@
public class SampleContainerHandler {
private final JsonDbOpensocialService service;
-
+ private final HttpFetcher fetcher;
@Inject
- public SampleContainerHandler(JsonDbOpensocialService dbService) {
+ public SampleContainerHandler(JsonDbOpensocialService dbService, HttpFetcher fetcher) {
this.service = dbService;
+ this.fetcher = fetcher;
}
/**
@@ -93,19 +97,14 @@
String errorMessage = "The json state file " + stateFileLocation
+ " could not be fetched and parsed.";
- HttpMethod jsonState = new GetMethod(stateFileLocation);
- HttpClient client = new HttpClient();
try {
- client.executeMethod(jsonState);
-
- if (jsonState.getStatusCode() != 200) {
+ HttpResponse response = fetcher.fetch(new HttpRequest(Uri.parse(stateFileLocation)));
+ if (response.getHttpStatusCode() != 200) {
throw new RuntimeException(errorMessage);
}
- return jsonState.getResponseBodyAsString();
- } catch (IOException e) {
+ return response.getResponseAsString();
+ } catch (GadgetException e) {
throw new RuntimeException(errorMessage, e);
- } finally {
- jsonState.releaseConnection();
}
}
}
Modified: incubator/shindig/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/pom.xml?rev=905439&r1=905438&r2=905439&view=diff
==============================================================================
--- incubator/shindig/trunk/pom.xml (original)
+++ incubator/shindig/trunk/pom.xml Mon Feb 1 23:05:43 2010
@@ -1385,7 +1385,7 @@
</dependency>
<dependency>
<groupId>net.oauth.core</groupId>
- <artifactId>oauth-httpclient3</artifactId>
+ <artifactId>oauth-httpclient4</artifactId>
<version>20090531</version>
<scope>compile</scope>
</dependency>
@@ -1524,9 +1524,9 @@
<version>1.3.04</version>
</dependency>
<dependency>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- <version>3.1</version>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.jsecurity</groupId>