You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by Paul Lindner <li...@apache.org> on 2010/02/02 00:12:29 UTC

Fwd: 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/ja

My apologies, this change got pushed along with my other changeset that
cleans up some unit tests to use junit 4 annotations...

Pending review I'll leave it in, but will happily revert if anyone has a -1
on it.


---------- Forwarded message ----------
From: <li...@apache.org>
Date: Mon, Feb 1, 2010 at 3:05 PM
Subject: 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/...
To: shindig-commits@incubator.apache.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>