use of com.koushikdutta.async.callback.CompletedCallback in project AndroidAsync by koush.
the class AsyncHttpServer method directory.
public void directory(String regex, final File directory, final boolean list) {
assert directory.isDirectory();
addAction("GET", regex, new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, final AsyncHttpServerResponse response) {
String path = request.getMatcher().replaceAll("");
File file = new File(directory, path);
if (file.isDirectory() && list) {
ArrayList<File> dirs = new ArrayList<File>();
ArrayList<File> files = new ArrayList<File>();
for (File f : file.listFiles()) {
if (f.isDirectory())
dirs.add(f);
else
files.add(f);
}
Comparator<File> c = new Comparator<File>() {
@Override
public int compare(File lhs, File rhs) {
return lhs.getName().compareTo(rhs.getName());
}
};
Collections.sort(dirs, c);
Collections.sort(files, c);
files.addAll(0, dirs);
return;
}
if (!file.isFile()) {
response.code(404);
response.end();
return;
}
try {
FileInputStream is = new FileInputStream(file);
response.code(200);
Util.pump(is, response, new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
response.end();
}
});
} catch (FileNotFoundException ex) {
response.code(404);
response.end();
}
}
});
}
use of com.koushikdutta.async.callback.CompletedCallback in project AndroidAsync by koush.
the class AsyncHttpServer method directory.
public void directory(Context context, String regex, final String assetPath) {
final Context _context = context.getApplicationContext();
addAction(AsyncHttpGet.METHOD, regex, new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, final AsyncHttpServerResponse response) {
String path = request.getMatcher().replaceAll("");
android.util.Pair<Integer, InputStream> pair = getAssetStream(_context, assetPath + path);
if (pair == null || pair.second == null) {
response.code(404);
response.end();
return;
}
final InputStream is = pair.second;
response.getHeaders().set("Content-Length", String.valueOf(pair.first));
response.code(200);
response.getHeaders().add("Content-Type", getContentType(assetPath + path));
Util.pump(is, response, new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
response.end();
StreamUtility.closeQuietly(is);
}
});
}
});
addAction(AsyncHttpHead.METHOD, regex, new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, final AsyncHttpServerResponse response) {
String path = request.getMatcher().replaceAll("");
android.util.Pair<Integer, InputStream> pair = getAssetStream(_context, assetPath + path);
if (pair == null || pair.second == null) {
response.code(404);
response.end();
return;
}
final InputStream is = pair.second;
StreamUtility.closeQuietly(is);
response.getHeaders().set("Content-Length", String.valueOf(pair.first));
response.code(200);
response.getHeaders().add("Content-Type", getContentType(assetPath + path));
response.writeHead();
response.end();
}
});
}
use of com.koushikdutta.async.callback.CompletedCallback in project AndroidAsync by koush.
the class AsyncSocketMiddleware method getSocket.
@Override
public Cancellable getSocket(final GetSocketData data) {
final Uri uri = data.request.getUri();
final int port = getSchemePort(data.request.getUri());
if (port == -1) {
return null;
}
data.state.put("socket-owner", this);
final String lookup = computeLookup(uri, port, data.request.getProxyHost(), data.request.getProxyPort());
ConnectionInfo info = getOrCreateConnectionInfo(lookup);
synchronized (AsyncSocketMiddleware.this) {
if (info.openCount >= maxConnectionCount) {
// wait for a connection queue to free up
SimpleCancellable queueCancel = new SimpleCancellable();
info.queue.add(data);
return queueCancel;
}
info.openCount++;
while (!info.sockets.isEmpty()) {
IdleSocketHolder idleSocketHolder = info.sockets.pop();
final AsyncSocket socket = idleSocketHolder.socket;
if (idleSocketHolder.idleTime + idleTimeoutMs < System.currentTimeMillis()) {
socket.setClosedCallback(null);
socket.close();
continue;
}
if (!socket.isOpen())
continue;
data.request.logd("Reusing keep-alive socket");
data.connectCallback.onConnectCompleted(null, socket);
// just a noop/dummy, as this can't actually be cancelled.
SimpleCancellable ret = new SimpleCancellable();
ret.setComplete();
return ret;
}
}
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;
boolean proxied = false;
if (data.request.getProxyHost() == null && proxyHost != null)
data.request.enableProxy(proxyHost, proxyPort);
if (data.request.getProxyHost() != null) {
unresolvedHost = data.request.getProxyHost();
unresolvedPort = data.request.getProxyPort();
proxied = true;
} else {
unresolvedHost = uri.getHost();
unresolvedPort = port;
}
if (proxied) {
data.request.logv("Using proxy: " + unresolvedHost + ":" + unresolvedPort);
}
return mClient.getServer().connectSocket(unresolvedHost, unresolvedPort, wrapCallback(data, uri, port, proxied, data.connectCallback));
}
// 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);
wrapCallback(data, uri, port, false, 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");
if (setComplete(lastException)) {
wrapCallback(data, uri, port, false, data.connectCallback).onConnectCompleted(lastException, null);
}
}
});
for (final InetAddress address : result) {
final String inetSockAddress = String.format(Locale.ENGLISH, "%s:%s", address, port);
keepTrying.add(new ContinuationCallback() {
@Override
public void onContinue(Continuation continuation, final CompletedCallback next) throws Exception {
data.request.logv("attempting connection to " + inetSockAddress);
mClient.getServer().connectSocket(new InetSocketAddress(address, port), wrapCallback(data, uri, port, false, new ConnectCallback() {
@Override
public void onConnectCompleted(Exception ex, AsyncSocket socket) {
if (isDone()) {
lastException = new Exception("internal error during connect to " + inetSockAddress);
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(null, socket);
}
}
}));
}
});
}
keepTrying.start();
}
});
}
use of com.koushikdutta.async.callback.CompletedCallback in project AndroidAsync by koush.
the class AsyncSocketMiddleware method recycleSocket.
private void recycleSocket(final AsyncSocket socket, AsyncHttpRequest request) {
if (socket == null)
return;
Uri uri = request.getUri();
int port = getSchemePort(uri);
final String lookup = computeLookup(uri, port, request.getProxyHost(), request.getProxyPort());
final ArrayDeque<IdleSocketHolder> sockets;
final IdleSocketHolder idleSocketHolder = new IdleSocketHolder(socket);
synchronized (AsyncSocketMiddleware.this) {
ConnectionInfo info = getOrCreateConnectionInfo(lookup);
sockets = info.sockets;
sockets.push(idleSocketHolder);
}
socket.setClosedCallback(new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
synchronized (AsyncSocketMiddleware.this) {
sockets.remove(idleSocketHolder);
maybeCleanupConnectionInfo(lookup);
}
}
});
}
use of com.koushikdutta.async.callback.CompletedCallback in project AndroidAsync by koush.
the class AsyncHttpClient method executeSocket.
private void executeSocket(final AsyncHttpRequest request, final int redirectCount, final FutureAsyncHttpResponse cancel, final HttpConnectCallback callback, final AsyncHttpClientMiddleware.OnResponseCompleteDataOnRequestSentData data) {
// 4) wait for request to be sent fully
// and
// 6) wait for headers
final AsyncHttpResponseImpl ret = new AsyncHttpResponseImpl(request) {
@Override
protected void onRequestCompleted(Exception ex) {
if (ex != null) {
reportConnectedCompleted(cancel, ex, null, request, callback);
return;
}
request.logv("request completed");
if (cancel.isCancelled())
return;
// 5) after request is sent, set a header timeout
if (cancel.timeoutRunnable != null && mHeaders == null) {
mServer.removeAllCallbacks(cancel.scheduled);
cancel.scheduled = mServer.postDelayed(cancel.timeoutRunnable, getTimeoutRemaining(request));
}
for (AsyncHttpClientMiddleware middleware : mMiddleware) {
middleware.onRequestSent(data);
}
}
@Override
public void setDataEmitter(DataEmitter emitter) {
data.bodyEmitter = emitter;
for (AsyncHttpClientMiddleware middleware : mMiddleware) {
middleware.onBodyDecoder(data);
}
super.setDataEmitter(data.bodyEmitter);
Headers headers = mHeaders;
int responseCode = code();
if ((responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == 307) && request.getFollowRedirect()) {
String location = headers.get("Location");
Uri redirect;
try {
redirect = Uri.parse(location);
if (redirect.getScheme() == null) {
redirect = Uri.parse(new URL(new URL(request.getUri().toString()), location).toString());
}
} catch (Exception e) {
reportConnectedCompleted(cancel, e, this, request, callback);
return;
}
final String method = request.getMethod().equals(AsyncHttpHead.METHOD) ? AsyncHttpHead.METHOD : AsyncHttpGet.METHOD;
AsyncHttpRequest newReq = new AsyncHttpRequest(redirect, method);
newReq.executionTime = request.executionTime;
newReq.logLevel = request.logLevel;
newReq.LOGTAG = request.LOGTAG;
newReq.proxyHost = request.proxyHost;
newReq.proxyPort = request.proxyPort;
setupAndroidProxy(newReq);
copyHeader(request, newReq, "User-Agent");
copyHeader(request, newReq, "Range");
request.logi("Redirecting");
newReq.logi("Redirected");
execute(newReq, redirectCount + 1, cancel, callback);
setDataCallback(new NullDataCallback());
return;
}
request.logv("Final (post cache response) headers:\n" + toString());
// at this point the headers are done being modified
reportConnectedCompleted(cancel, null, this, request, callback);
}
protected void onHeadersReceived() {
super.onHeadersReceived();
if (cancel.isCancelled())
return;
// 7) on headers, cancel timeout
if (cancel.timeoutRunnable != null)
mServer.removeAllCallbacks(cancel.scheduled);
// allow the middleware to massage the headers before the body is decoded
request.logv("Received headers:\n" + toString());
for (AsyncHttpClientMiddleware middleware : mMiddleware) {
middleware.onHeadersReceived(data);
}
// drop through, and setDataEmitter will be called for the body decoder.
// headers will be further massaged in there.
}
@Override
protected void report(Exception ex) {
if (ex != null)
request.loge("exception during response", ex);
if (cancel.isCancelled())
return;
if (ex instanceof AsyncSSLException) {
request.loge("SSL Exception", ex);
AsyncSSLException ase = (AsyncSSLException) ex;
request.onHandshakeException(ase);
if (ase.getIgnore())
return;
}
final AsyncSocket socket = socket();
if (socket == null)
return;
super.report(ex);
if (!socket.isOpen() || ex != null) {
if (headers() == null && ex != null)
reportConnectedCompleted(cancel, ex, null, request, callback);
}
data.exception = ex;
for (AsyncHttpClientMiddleware middleware : mMiddleware) {
middleware.onResponseComplete(data);
}
}
@Override
public AsyncSocket detachSocket() {
request.logd("Detaching socket");
AsyncSocket socket = socket();
if (socket == null)
return null;
socket.setWriteableCallback(null);
socket.setClosedCallback(null);
socket.setEndCallback(null);
socket.setDataCallback(null);
setSocket(null);
return socket;
}
};
data.sendHeadersCallback = new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
if (ex != null)
ret.report(ex);
else
ret.onHeadersSent();
}
};
data.receiveHeadersCallback = new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
if (ex != null)
ret.report(ex);
else
ret.onHeadersReceived();
}
};
data.response = ret;
ret.setSocket(data.socket);
for (AsyncHttpClientMiddleware middleware : mMiddleware) {
if (middleware.exchangeHeaders(data))
break;
}
}
Aggregations