Search in sources :

Example 1 with CompletedCallback

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();
            }
        }
    });
}
Also used : CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) ArrayList(java.util.ArrayList) FileNotFoundException(java.io.FileNotFoundException) FileInputStream(java.io.FileInputStream) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) Comparator(java.util.Comparator) File(java.io.File)

Example 2 with CompletedCallback

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();
        }
    });
}
Also used : Context(android.content.Context) SSLContext(javax.net.ssl.SSLContext) CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException)

Example 3 with CompletedCallback

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();
        }
    });
}
Also used : Continuation(com.koushikdutta.async.future.Continuation) CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) InetSocketAddress(java.net.InetSocketAddress) Uri(android.net.Uri) AsyncSocket(com.koushikdutta.async.AsyncSocket) ContinuationCallback(com.koushikdutta.async.callback.ContinuationCallback) SimpleCancellable(com.koushikdutta.async.future.SimpleCancellable) ConnectCallback(com.koushikdutta.async.callback.ConnectCallback) InetAddress(java.net.InetAddress)

Example 4 with CompletedCallback

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);
            }
        }
    });
}
Also used : CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) Uri(android.net.Uri)

Example 5 with CompletedCallback

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;
    }
}
Also used : CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) Uri(android.net.Uri) TimeoutException(java.util.concurrent.TimeoutException) AsyncSSLException(com.koushikdutta.async.AsyncSSLException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) SuppressLint(android.annotation.SuppressLint) URL(java.net.URL) AsyncSocket(com.koushikdutta.async.AsyncSocket) DataEmitter(com.koushikdutta.async.DataEmitter) AsyncSSLException(com.koushikdutta.async.AsyncSSLException)

Aggregations

CompletedCallback (com.koushikdutta.async.callback.CompletedCallback)46 IOException (java.io.IOException)12 TimeoutException (java.util.concurrent.TimeoutException)11 ByteBufferList (com.koushikdutta.async.ByteBufferList)10 DataEmitter (com.koushikdutta.async.DataEmitter)10 DataCallback (com.koushikdutta.async.callback.DataCallback)10 Semaphore (java.util.concurrent.Semaphore)9 ContinuationCallback (com.koushikdutta.async.callback.ContinuationCallback)8 Continuation (com.koushikdutta.async.future.Continuation)8 CancellationException (java.util.concurrent.CancellationException)8 ExecutionException (java.util.concurrent.ExecutionException)8 AsyncHttpServer (com.koushikdutta.async.http.server.AsyncHttpServer)7 AsyncHttpServerRequest (com.koushikdutta.async.http.server.AsyncHttpServerRequest)7 FileNotFoundException (java.io.FileNotFoundException)7 AsyncHttpServerResponse (com.koushikdutta.async.http.server.AsyncHttpServerResponse)6 HttpServerRequestCallback (com.koushikdutta.async.http.server.HttpServerRequestCallback)6 AsyncSocket (com.koushikdutta.async.AsyncSocket)5 UnsupportedEncodingException (java.io.UnsupportedEncodingException)5 Uri (android.net.Uri)4 WritableCallback (com.koushikdutta.async.callback.WritableCallback)4