private void writeToFromFile(OutputStream os, RequestParams.FileWrapper wrapper) throws IOException { // Send the meta data. writeMetaData(os, wrapper.file.getName(), wrapper.contentType); int bytesRead; long bytesWritten = 0, totalSize = wrapper.file.length(); // Open the file for reading. FileInputStream in = new FileInputStream(wrapper.file); // Upload the file's contents in Base64. Base64OutputStream bos = new Base64OutputStream(os, Base64.NO_CLOSE | Base64.NO_WRAP); // Read from file until no more data's left to read. while ((bytesRead = in.read(buffer)) != -1) { bos.write(buffer, 0, bytesRead); bytesWritten += bytesRead; progressHandler.sendProgressMessage(bytesWritten, totalSize); } // Close the Base64 output stream. AsyncHttpClient.silentCloseOutputStream(bos); // End the meta data. endMetaData(os); // Safely close the input stream. AsyncHttpClient.silentCloseInputStream(in); }
@Test(groups = {"standalone", "default_provider"}) public void testListenableFuture() throws Exception { final AtomicInteger statusCode = new AtomicInteger(500); try (AsyncHttpClient ahc = asyncHttpClient()) { final CountDownLatch latch = new CountDownLatch(1); final ListenableFuture<Response> future = ahc.prepareGet(getTargetUrl()).execute(); future.addListener( new Runnable() { public void run() { try { statusCode.set(future.get().getStatusCode()); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }, Executors.newFixedThreadPool(1)); latch.await(10, TimeUnit.SECONDS); assertEquals(statusCode.get(), 200); } }
@Test(groups = "standalone") public void asyncStreamThrowableRefusedTest() throws Exception { final CountDownLatch l = new CountDownLatch(1); try (AsyncHttpClient c = asyncHttpClient()) { c.prepareGet(getTargetUrl()) .execute( new AsyncHandlerAdapter() { @Override public State onHeadersReceived(HttpResponseHeaders content) throws Exception { throw new RuntimeException("FOO"); } @Override public void onThrowable(Throwable t) { try { if (t.getMessage() != null) { assertEquals(t.getMessage(), "FOO"); } } finally { l.countDown(); } } }); if (!l.await(10, TimeUnit.SECONDS)) { fail("Timed out"); } } }
@Test(groups = "online") public void asyncOptionsTest() throws Exception { final AtomicReference<HttpHeaders> responseHeaders = new AtomicReference<>(); try (AsyncHttpClient c = asyncHttpClient()) { final String[] expected = {"GET", "HEAD", "OPTIONS", "POST", "TRACE"}; Future<String> f = c.prepareOptions("http://www.apache.org/") .execute( new AsyncHandlerAdapter() { @Override public State onHeadersReceived(HttpResponseHeaders content) throws Exception { responseHeaders.set(content.getHeaders()); return State.ABORT; } @Override public String onCompleted() throws Exception { return "OK"; } }); f.get(20, TimeUnit.SECONDS); HttpHeaders h = responseHeaders.get(); assertNotNull(h); String[] values = h.get(HttpHeaders.Names.ALLOW).split(",|, "); assertNotNull(values); assertEquals(values.length, expected.length); Arrays.sort(values); assertEquals(values, expected); } }
private F.Promise<WSResponse> execute(Request request) { final scala.concurrent.Promise<WSResponse> scalaPromise = scala.concurrent.Promise$.MODULE$.<WSResponse>apply(); try { AsyncHttpClient asyncHttpClient = (AsyncHttpClient) client.getUnderlying(); asyncHttpClient.executeRequest( request, new AsyncCompletionHandler<Response>() { @Override public Response onCompleted(Response response) { final Response ahcResponse = response; scalaPromise.success(new AhcWSResponse(ahcResponse)); return response; } @Override public void onThrowable(Throwable t) { scalaPromise.failure(t); } }); } catch (RuntimeException exception) { scalaPromise.failure(exception); } return F.Promise.wrap(scalaPromise.future()); }
@Test(groups = "online") public void asyncStatusHEADContentLenghtTest() throws Exception { try (AsyncHttpClient p = asyncHttpClient(config().setFollowRedirect(true))) { final CountDownLatch l = new CountDownLatch(1); p.executeRequest( head("http://www.google.com/"), new AsyncCompletionHandlerAdapter() { @Override public Response onCompleted(Response response) throws Exception { try { assertEquals(response.getStatusCode(), 200); return response; } finally { l.countDown(); } } }) .get(); if (!l.await(5, TimeUnit.SECONDS)) { fail("Timeout out"); } } }
private void writeToFromStream(OutputStream os, RequestParams.StreamWrapper entry) throws IOException { // Send the meta data. writeMetaData(os, entry.name, entry.contentType); int bytesRead; // Upload the file's contents in Base64. Base64OutputStream bos = new Base64OutputStream(os, Base64.NO_CLOSE | Base64.NO_WRAP); // Read from input stream until no more data's left to read. while ((bytesRead = entry.inputStream.read(buffer)) != -1) { bos.write(buffer, 0, bytesRead); } // Close the Base64 output stream. AsyncHttpClient.silentCloseOutputStream(bos); // End the meta data. endMetaData(os); // Close input stream. if (entry.autoClose) { // Safely close the input stream. AsyncHttpClient.silentCloseInputStream(entry.inputStream); } }
@Test(groups = "online") public void testGoogleComWithTimeout() throws Exception { try (AsyncHttpClient c = asyncHttpClient(config().setRequestTimeout(10000))) { Response response = c.prepareGet("http://google.com/").execute().get(10, TimeUnit.SECONDS); assertNotNull(response); assertTrue(response.getStatusCode() == 301 || response.getStatusCode() == 302); } }
@Test(groups = "online") public void testMailGoogleCom() throws Exception { try (AsyncHttpClient c = asyncHttpClient(config().setRequestTimeout(10000))) { Response response = c.prepareGet("http://mail.google.com/").execute().get(10, TimeUnit.SECONDS); assertNotNull(response); assertEquals(response.getStatusCode(), 200); } }
@Test(groups = "online", enabled = false) // FIXME public void testMicrosoftCom() throws Exception { try (AsyncHttpClient c = asyncHttpClient(config().setRequestTimeout(10000))) { Response response = c.prepareGet("http://microsoft.com/").execute().get(10, TimeUnit.SECONDS); assertNotNull(response); assertEquals(response.getStatusCode(), 301); } }
// FIXME Get a 302 in France... @Test(groups = "online", enabled = false) public void testUrlRequestParametersEncoding() throws Exception { try (AsyncHttpClient client = asyncHttpClient()) { String requestUrl2 = URL + URLEncoder.encode(REQUEST_PARAM, UTF_8.name()); logger.info(String.format("Executing request [%s] ...", requestUrl2)); Response response = client.prepareGet(requestUrl2).execute().get(); assertEquals(response.getStatusCode(), 302); } }
@Test(groups = "online") public void stripQueryStringTest() throws Exception { try (AsyncHttpClient c = asyncHttpClient(config().setFollowRedirect(true))) { Response response = c.prepareGet("http://www.freakonomics.com/?p=55846").execute().get(); assertNotNull(response); assertEquals(response.getStatusCode(), 200); } }
@Test(groups = "online") public void asyncFullBodyProperlyRead() throws Exception { try (AsyncHttpClient client = asyncHttpClient()) { Response r = client.prepareGet("http://www.cyberpresse.ca/").execute().get(); InputStream stream = r.getResponseBodyAsStream(); int contentLength = Integer.valueOf(r.getHeader("Content-Length")); assertEquals(contentLength, IOUtils.toByteArray(stream).length); } }
// @Test(groups = "online") public void notRedirected302Test() throws Exception { isSet.getAndSet(false); try (AsyncHttpClient c = asyncHttpClient(config().setFollowRedirect(true))) { Response response = c.prepareGet(getTargetUrl()) .setFollowRedirect(false) .setHeader("X-redirect", "http://www.microsoft.com/") .execute() .get(); assertNotNull(response); assertEquals(response.getStatusCode(), 302); } }
@Test(groups = "standalone") public void testQueryParameters() throws Exception { try (AsyncHttpClient client = asyncHttpClient()) { Future<Response> f = client .prepareGet("http://127.0.0.1:" + port1 + "/foo") .addHeader("Accepts", "*/*") .execute(); Response resp = f.get(3, TimeUnit.SECONDS); assertNotNull(resp); assertEquals(resp.getStatusCode(), 400); assertEquals(resp.getResponseBody(), BAD_REQUEST_STR); } }
public static ResponseCacheMiddleware addCache(AsyncHttpClient client, File cacheDir, long size) throws IOException { for (AsyncHttpClientMiddleware middleware : client.getMiddleware()) { if (middleware instanceof ResponseCacheMiddleware) throw new IOException("Response cache already added to http client"); } ResponseCacheMiddleware ret = new ResponseCacheMiddleware(); ret.size = size; ret.client = client; ret.cacheDir = cacheDir; ret.open(); client.insertMiddleware(ret); return ret; }
// @Test(groups = "standalone") public void relativeLocationUrl() throws Exception { isSet.getAndSet(false); try (AsyncHttpClient c = asyncHttpClient()) { Response response = c.preparePost(getTargetUrl()) .setFollowRedirect(true) .setHeader("X-redirect", "/foo/test") .execute() .get(); assertNotNull(response); assertEquals(response.getStatusCode(), 200); assertEquals(response.getUri().toString(), getTargetUrl()); } }
/** * Deconstructs response into given content handler * * @param entity returned HttpEntity * @return deconstructed response * @throws java.io.IOException * @see org.apache.http.HttpEntity */ @Override protected byte[] getResponseData(HttpEntity entity) throws IOException { if (entity != null) { InputStream instream = entity.getContent(); InputStreamReader inputStreamReader = null; if (instream != null) { try { SAXParserFactory sfactory = SAXParserFactory.newInstance(); SAXParser sparser = sfactory.newSAXParser(); XMLReader rssReader = sparser.getXMLReader(); rssReader.setContentHandler(handler); inputStreamReader = new InputStreamReader(instream, DEFAULT_CHARSET); rssReader.parse(new InputSource(inputStreamReader)); } catch (SAXException e) { Log.e(LOG_TAG, "getResponseData exception", e); } catch (ParserConfigurationException e) { Log.e(LOG_TAG, "getResponseData exception", e); } finally { AsyncHttpClient.silentCloseInputStream(instream); if (inputStreamReader != null) { try { inputStreamReader.close(); } catch (IOException e) { /*ignore*/ } } } } } return null; }
@Test(groups = "standalone") public void asyncStreamFutureTest() throws Exception { final AtomicReference<HttpHeaders> responseHeaders = new AtomicReference<>(); final AtomicReference<Throwable> throwable = new AtomicReference<>(); try (AsyncHttpClient c = asyncHttpClient()) { Future<String> f = c.preparePost(getTargetUrl()) .addFormParam("param_1", "value_1") .execute( new AsyncHandlerAdapter() { private StringBuilder builder = new StringBuilder(); @Override public State onHeadersReceived(HttpResponseHeaders content) throws Exception { responseHeaders.set(content.getHeaders()); return State.CONTINUE; } @Override public State onBodyPartReceived(HttpResponseBodyPart content) throws Exception { builder.append(new String(content.getBodyPartBytes())); return State.CONTINUE; } @Override public String onCompleted() throws Exception { return builder.toString().trim(); } @Override public void onThrowable(Throwable t) { throwable.set(t); } }); String responseBody = f.get(5, TimeUnit.SECONDS); HttpHeaders h = responseHeaders.get(); assertNotNull(h, "Should receive non null headers"); assertEquals( h.get(HttpHeaders.Names.CONTENT_TYPE).toLowerCase(Locale.ENGLISH), TEXT_HTML_CONTENT_TYPE_WITH_UTF_8_CHARSET.toLowerCase(Locale.ENGLISH), "Unexpected content-type"); assertNotNull(responseBody, "No response body"); assertEquals(responseBody.trim(), RESPONSE, "Unexpected response body"); assertNull(throwable.get(), "Unexpected exception"); } }
@Test(groups = "standalone") public void asyncStreamInterruptTest() throws Exception { final CountDownLatch l = new CountDownLatch(1); final AtomicReference<HttpHeaders> responseHeaders = new AtomicReference<>(); final AtomicBoolean bodyReceived = new AtomicBoolean(false); final AtomicReference<Throwable> throwable = new AtomicReference<>(); try (AsyncHttpClient c = asyncHttpClient()) { c.preparePost(getTargetUrl()) // .setHeader("Content-Type", "application/x-www-form-urlencoded") // .addFormParam("param_1", "value_1") // .execute( new AsyncHandlerAdapter() { @Override public State onHeadersReceived(HttpResponseHeaders content) throws Exception { responseHeaders.set(content.getHeaders()); return State.ABORT; } @Override public State onBodyPartReceived(final HttpResponseBodyPart content) throws Exception { bodyReceived.set(true); return State.ABORT; } @Override public void onThrowable(Throwable t) { throwable.set(t); l.countDown(); } }); l.await(5, TimeUnit.SECONDS); assertTrue(!bodyReceived.get(), "Interrupted not working"); HttpHeaders h = responseHeaders.get(); assertNotNull(h, "Should receive non null headers"); assertEquals( h.get(HttpHeaders.Names.CONTENT_TYPE).toLowerCase(Locale.ENGLISH), TEXT_HTML_CONTENT_TYPE_WITH_UTF_8_CHARSET.toLowerCase(Locale.ENGLISH), "Unexpected content-type"); assertNull(throwable.get(), "Should get an exception"); } }
@Test(groups = "online") public void asyncStream302RedirectWithBody() throws Exception { final AtomicReference<Integer> statusCode = new AtomicReference<>(0); final AtomicReference<HttpHeaders> responseHeaders = new AtomicReference<>(); try (AsyncHttpClient c = asyncHttpClient(config().setFollowRedirect(true))) { Future<String> f = c.prepareGet("http://google.com/") .execute( new AsyncHandlerAdapter() { public State onStatusReceived(HttpResponseStatus status) throws Exception { statusCode.set(status.getStatusCode()); return State.CONTINUE; } @Override public State onHeadersReceived(HttpResponseHeaders content) throws Exception { responseHeaders.set(content.getHeaders()); return State.CONTINUE; } @Override public String onCompleted() throws Exception { return null; } }); f.get(20, TimeUnit.SECONDS); assertTrue(statusCode.get() != 302); HttpHeaders h = responseHeaders.get(); assertNotNull(h); assertEquals(h.get("server"), "gws"); // This assertion below is not an invariant, since implicitly contains locale-dependant // settings // and fails when run in country having own localized Google site and it's locale relies on // something // other than ISO-8859-1. // In Hungary for example, http://google.com/ redirects to http://www.google.hu/, a localized // Google site, that uses ISO-8892-2 encoding (default for HU). Similar is true for other // non-ISO-8859-1 using countries that have "localized" google, like google.hr, google.rs, // google.cz, google.sk etc. // // assertEquals(h.get(HttpHeaders.Names.CONTENT_TYPE), "text/html; charset=ISO-8859-1"); } }
@Test(groups = "standalone") public void closeConnectionTest() throws Exception { try (AsyncHttpClient c = asyncHttpClient()) { Response r = c.prepareGet(getTargetUrl()) .execute( new AsyncHandler<Response>() { private Response.ResponseBuilder builder = new Response.ResponseBuilder(); public State onHeadersReceived(HttpResponseHeaders content) throws Exception { builder.accumulate(content); return State.CONTINUE; } public void onThrowable(Throwable t) {} public State onBodyPartReceived(HttpResponseBodyPart content) throws Exception { builder.accumulate(content); if (content.isLast()) { content.markUnderlyingConnectionAsToBeClosed(); } return State.CONTINUE; } public State onStatusReceived(HttpResponseStatus responseStatus) throws Exception { builder.accumulate(responseStatus); return State.CONTINUE; } public Response onCompleted() throws Exception { return builder.build(); } }) .get(); assertNotNull(r); assertEquals(r.getStatusCode(), 200); } }
// @Test(groups = "standalone") public void redirected302InvalidTest() throws Exception { isSet.getAndSet(false); Exception e = null; try (AsyncHttpClient c = asyncHttpClient()) { c.preparePost(getTargetUrl()) .setFollowRedirect(true) .setHeader("X-redirect", String.format("http://localhost:%d/", port2)) .execute() .get(); } catch (ExecutionException ex) { e = ex; } assertNotNull(e); Throwable cause = e.getCause(); assertTrue(cause instanceof ConnectException); assertTrue(cause.getMessage().contains(":" + port2)); }
@Test(groups = "standalone") public void asyncStreamGETTest() throws Exception { final CountDownLatch l = new CountDownLatch(1); final AtomicReference<HttpHeaders> responseHeaders = new AtomicReference<>(); final AtomicReference<Throwable> throwable = new AtomicReference<>(); try (AsyncHttpClient c = asyncHttpClient()) { c.prepareGet(getTargetUrl()) .execute( new AsyncHandlerAdapter() { @Override public State onHeadersReceived(HttpResponseHeaders content) throws Exception { try { responseHeaders.set(content.getHeaders()); return State.ABORT; } finally { l.countDown(); } } @Override public void onThrowable(Throwable t) { try { throwable.set(t); } finally { l.countDown(); } } }); if (!l.await(5, TimeUnit.SECONDS)) { fail("Timeout out"); } HttpHeaders h = responseHeaders.get(); assertNotNull(h, "No response headers"); assertEquals( h.get(HttpHeaders.Names.CONTENT_TYPE), TEXT_HTML_CONTENT_TYPE_WITH_UTF_8_CHARSET, "Unexpected content-type"); assertNull(throwable.get(), "Unexpected exception"); } }
@Test(groups = "online", enabled = false) public void testAHC62Com() throws Exception { try (AsyncHttpClient c = asyncHttpClient(config().setFollowRedirect(true))) { Response response = c.prepareGet("http://api.crunchbase.com/v/1/financial-organization/kinsey-hills-group.js") .execute( new AsyncHandler<Response>() { private Response.ResponseBuilder builder = new Response.ResponseBuilder(); public void onThrowable(Throwable t) { t.printStackTrace(); } public State onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception { System.out.println(bodyPart.getBodyPartBytes().length); builder.accumulate(bodyPart); return State.CONTINUE; } public State onStatusReceived(HttpResponseStatus responseStatus) throws Exception { builder.accumulate(responseStatus); return State.CONTINUE; } public State onHeadersReceived(HttpResponseHeaders headers) throws Exception { builder.accumulate(headers); return State.CONTINUE; } public Response onCompleted() throws Exception { return builder.build(); } }) .get(10, TimeUnit.SECONDS); assertNotNull(response); assertTrue(response.getResponseBody().length() >= 3870); } }
// @Test(groups = "online") public void redirected302Test() throws Exception { isSet.getAndSet(false); try (AsyncHttpClient c = asyncHttpClient()) { Response response = c.prepareGet(getTargetUrl()) .setFollowRedirect(true) .setHeader("X-redirect", "http://www.microsoft.com/") .execute() .get(); assertNotNull(response); assertEquals(response.getStatusCode(), 200); String anyMicrosoftPage = "http://www.microsoft.com[^:]*:80"; String baseUrl = getBaseUrl(response.getUri()); assertTrue( baseUrl.matches(anyMicrosoftPage), "response does not show redirection to " + anyMicrosoftPage); } }
@Test(groups = "online", enabled = false) public void invalidStreamTest2() throws Exception { AsyncHttpClientConfig config = config() // .setRequestTimeout(10000) // .setFollowRedirect(true) // .setKeepAlive(false) // .setMaxRedirects(6) // .build(); try (AsyncHttpClient c = asyncHttpClient(config)) { Response response = c.prepareGet("http://bit.ly/aUjTtG").execute().get(); if (response != null) { System.out.println(response); } } catch (Throwable t) { t.printStackTrace(); assertNotNull(t.getCause()); assertEquals(t.getCause().getMessage(), "invalid version format: ICY"); } }
@Test(groups = "standalone") public void asyncStreamPOSTTest() throws Exception { final AtomicReference<HttpHeaders> responseHeaders = new AtomicReference<>(); try (AsyncHttpClient c = asyncHttpClient()) { Future<String> f = c.preparePost(getTargetUrl()) // .setHeader("Content-Type", "application/x-www-form-urlencoded") // .addFormParam("param_1", "value_1") // .execute( new AsyncHandlerAdapter() { private StringBuilder builder = new StringBuilder(); @Override public State onHeadersReceived(HttpResponseHeaders content) throws Exception { responseHeaders.set(content.getHeaders()); return State.CONTINUE; } @Override public State onBodyPartReceived(HttpResponseBodyPart content) throws Exception { builder.append(new String(content.getBodyPartBytes())); return State.CONTINUE; } @Override public String onCompleted() throws Exception { return builder.toString().trim(); } }); String responseBody = f.get(10, TimeUnit.SECONDS); HttpHeaders h = responseHeaders.get(); assertNotNull(h); assertEquals( h.get(HttpHeaders.Names.CONTENT_TYPE), TEXT_HTML_CONTENT_TYPE_WITH_UTF_8_CHARSET); assertEquals(responseBody, RESPONSE); } }
@Test(groups = "online") public void evilCoookieTest() throws Exception { try (AsyncHttpClient c = asyncHttpClient()) { RequestBuilder builder = get("http://localhost") // .setFollowRedirect(true) // .setUrl("http://www.google.com/") // .addHeader("Content-Type", "text/plain") // .addCookie( new Cookie( "evilcookie", "test", false, ".google.com", "/", Long.MIN_VALUE, false, false)); Response response = c.executeRequest(builder.build()).get(); assertNotNull(response); assertEquals(response.getStatusCode(), 200); } }
@Override public Cancellable getSocket(final AsyncHttpClientMiddleware.GetSocketData data) { final URI uri = data.request.getUri(); final int port = getSchemePort(data.request.getUri()); if (port == -1) { return null; } ConnectionInfo info = getConnectionInfo(uri.getScheme(), uri.getHost(), port); if (info.openCount >= maxConnectionCount) { // wait for a connection queue to free up SimpleCancellable queueCancel = new SimpleCancellable(); info.queue.add(data); return queueCancel; } info.openCount++; final String lookup = computeLookup(uri, port, data.request); data.state.putBoolean(getClass().getCanonicalName() + ".owned", true); synchronized (this) { final HashSet<AsyncSocket> sockets = mSockets.get(lookup); if (sockets != null) { for (final AsyncSocket socket : sockets) { if (socket.isOpen()) { sockets.remove(socket); socket.setClosedCallback(null); mClient .getServer() .post( new Runnable() { @Override public void run() { data.request.logd("Reusing keep-alive socket"); data.connectCallback.onConnectCompleted(null, socket); } }); // replace above code with immediate callback? // data.request.logd("Reusing keep-alive socket"); // data.connectCallback.onConnectCompleted(null, socket); // just a noop/dummy, as this can't actually be cancelled. return new SimpleCancellable(); } } } } if (!connectAllAddresses || proxyHost != null || data.request.getProxyHost() != null) { // just default to connecting to a single address data.request.logd("Connecting socket"); String unresolvedHost; int unresolvedPort; if (data.request.getProxyHost() != null) { unresolvedHost = data.request.getProxyHost(); unresolvedPort = data.request.getProxyPort(); // set the host and port explicitly for proxied connections data.request .getHeaders() .getHeaders() .setStatusLine(data.request.getProxyRequestLine().toString()); } else if (proxyHost != null) { unresolvedHost = proxyHost; unresolvedPort = proxyPort; // set the host and port explicitly for proxied connections data.request .getHeaders() .getHeaders() .setStatusLine(data.request.getProxyRequestLine().toString()); } else { unresolvedHost = uri.getHost(); unresolvedPort = port; } return mClient .getServer() .connectSocket( unresolvedHost, unresolvedPort, wrapCallback(data.connectCallback, uri, port)); } // try to connect to everything... data.request.logv("Resolving domain and connecting to all available addresses"); return mClient .getServer() .getAllByName(uri.getHost()) .then( new TransformFuture<AsyncSocket, InetAddress[]>() { Exception lastException; @Override protected void error(Exception e) { super.error(e); data.connectCallback.onConnectCompleted(e, null); } @Override protected void transform(final InetAddress[] result) throws Exception { Continuation keepTrying = new Continuation( new CompletedCallback() { @Override public void onCompleted(Exception ex) { // if it completed, that means that the connection failed if (lastException == null) lastException = new ConnectionFailedException( "Unable to connect to remote address"); setComplete(lastException); } }); for (final InetAddress address : result) { keepTrying.add( new ContinuationCallback() { @Override public void onContinue( Continuation continuation, final CompletedCallback next) throws Exception { mClient .getServer() .connectSocket( new InetSocketAddress(address, port), wrapCallback( new ConnectCallback() { @Override public void onConnectCompleted( Exception ex, AsyncSocket socket) { if (isDone()) { lastException = new Exception("internal error during connect"); next.onCompleted(null); return; } // try the next address if (ex != null) { lastException = ex; next.onCompleted(null); return; } // if the socket is no longer needed, just hang onto it... if (isDone() || isCancelled()) { data.request.logd( "Recycling extra socket leftover from cancelled operation"); idleSocket(socket); recycleSocket(socket, data.request); return; } if (setComplete(null, socket)) { data.connectCallback.onConnectCompleted(ex, socket); } } }, uri, port)); } }); } keepTrying.start(); } }); }