Search in sources :

Example 1 with SessionInputBuffer

use of cz.msebera.android.httpclient.io.SessionInputBuffer in project Zom-Android by zom.

the class OtrDataHandler method onIncomingRequest.

public synchronized void onIncomingRequest(Address requestThem, Address requestUs, byte[] value) {
    // Log.e( TAG, "onIncomingRequest:" + requestThem);
    SessionInputBuffer inBuf = new MemorySessionInputBuffer(value);
    HttpRequestParser parser = new HttpRequestParser(inBuf, lineParser, requestFactory, params);
    HttpRequest req;
    try {
        req = (HttpRequest) parser.parse();
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (HttpException e) {
        e.printStackTrace();
        return;
    }
    String requestMethod = req.getRequestLine().getMethod();
    String uid = req.getFirstHeader("Request-Id").getValue();
    String url = req.getRequestLine().getUri();
    if (requestMethod.equals("OFFER")) {
        debug("incoming OFFER " + url);
        for (Header header : req.getAllHeaders()) {
            debug("incoming header: " + header.getName() + "=" + header.getValue());
        }
        if (!url.startsWith(URI_PREFIX_OTR_IN_BAND)) {
            debug("Unknown url scheme " + url);
            sendResponse(requestUs, requestThem, 400, "Unknown scheme", uid, EMPTY_BODY);
            return;
        }
        if (!req.containsHeader("File-Length")) {
            sendResponse(requestUs, requestThem, 400, "File-Length must be supplied", uid, EMPTY_BODY);
            return;
        }
        int length = Integer.parseInt(req.getFirstHeader("File-Length").getValue());
        if (!req.containsHeader("File-Hash-SHA1")) {
            sendResponse(requestUs, requestThem, 400, "File-Hash-SHA1 must be supplied", uid, EMPTY_BODY);
            return;
        }
        sendResponse(requestUs, requestThem, 200, "OK", uid, EMPTY_BODY);
        String sum = req.getFirstHeader("File-Hash-SHA1").getValue();
        String type = null;
        if (req.containsHeader("Mime-Type")) {
            type = req.getFirstHeader("Mime-Type").getValue();
        }
        debug("Incoming sha1sum " + sum);
        Transfer transfer;
        try {
            transfer = new VfsTransfer(url, type, length, requestUs, requestThem, sum);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        transferCache.put(url, transfer);
        // Handle offer
        // TODO ask user to confirm we want this
        boolean accept = false;
        if (mDataListener != null) {
            try {
                mDataListener.onTransferRequested(url, requestThem.getAddress(), requestUs.getAddress(), transfer.url);
            // callback is now async, via "acceptTransfer" method
            // if (accept)
            // transfer.perform();
            } catch (RemoteException e) {
                LogCleaner.error(ImApp.LOG_TAG, "error approving OTRDATA transfer request", e);
            }
        }
    } else if (requestMethod.equals("GET") && url.startsWith(URI_PREFIX_OTR_IN_BAND)) {
        debug("incoming GET " + url);
        ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
        int reqEnd;
        try {
            Offer offer = offerCache.get(url);
            if (offer == null) {
                sendResponse(requestUs, requestThem, 400, "No such offer made", uid, EMPTY_BODY);
                return;
            }
            // in case we don't see a response to underlying request, but peer still proceeds
            offer.seen();
            if (!req.containsHeader("Range")) {
                sendResponse(requestUs, requestThem, 400, "Range must start with bytes=", uid, EMPTY_BODY);
                return;
            }
            String rangeHeader = req.getFirstHeader("Range").getValue();
            String[] spec = rangeHeader.split("=");
            if (spec.length != 2 || !spec[0].equals("bytes")) {
                sendResponse(requestUs, requestThem, 400, "Range must start with bytes=", uid, EMPTY_BODY);
                return;
            }
            String[] startEnd = spec[1].split("-");
            if (startEnd.length != 2) {
                sendResponse(requestUs, requestThem, 400, "Range must be START-END", uid, EMPTY_BODY);
                return;
            }
            int start = Integer.parseInt(startEnd[0]);
            int end = Integer.parseInt(startEnd[1]);
            if (end - start + 1 > MAX_CHUNK_LENGTH) {
                sendResponse(requestUs, requestThem, 400, "Range must be at most " + MAX_CHUNK_LENGTH, uid, EMPTY_BODY);
                return;
            }
            File fileGet = new File(offer.getUri());
            long fileLength = -1;
            if (fileGet.exists()) {
                fileLength = fileGet.length();
                FileInputStream is = new FileInputStream(fileGet);
                readIntoByteBuffer(byteBuffer, is, start, end);
                is.close();
            } else {
                java.io.File fileGetExtern = new java.io.File(offer.getUri());
                if (fileGetExtern.exists()) {
                    fileLength = fileGetExtern.length();
                    java.io.FileInputStream is = new java.io.FileInputStream(fileGetExtern);
                    readIntoByteBuffer(byteBuffer, is, start, end);
                    is.close();
                }
            }
            if (mDataListener != null && fileLength != -1) {
                float percent = ((float) end) / ((float) fileLength);
                mDataListener.onTransferProgress(true, offer.getId(), requestThem.getAddress(), offer.getUri(), percent);
                String mimeType = null;
                if (req.getFirstHeader("Mime-Type") != null)
                    mimeType = req.getFirstHeader("Mime-Type").getValue();
                mDataListener.onTransferComplete(true, offer.getId(), requestThem.getAddress(), offer.getUri(), mimeType, offer.getUri());
            }
        } catch (UnsupportedEncodingException e) {
            // throw new RuntimeException(e);
            sendResponse(requestUs, requestThem, 400, "Unsupported encoding", uid, EMPTY_BODY);
            return;
        } catch (IOException e) {
            // throw new RuntimeException(e);
            sendResponse(requestUs, requestThem, 400, "IOException", uid, EMPTY_BODY);
            return;
        } catch (NumberFormatException e) {
            sendResponse(requestUs, requestThem, 400, "Range is not numeric", uid, EMPTY_BODY);
            return;
        } catch (Exception e) {
            sendResponse(requestUs, requestThem, 500, "Unknown error", uid, EMPTY_BODY);
            return;
        }
        byte[] body = byteBuffer.toByteArray();
        // debug("Sent sha1 is " + sha1sum(body));
        sendResponse(requestUs, requestThem, 200, "OK", uid, body);
    } else {
        debug("Unknown method / url " + requestMethod + " " + url);
        sendResponse(requestUs, requestThem, 400, "OK", uid, EMPTY_BODY);
    }
}
Also used : HttpException(cz.msebera.android.httpclient.HttpException) HttpRequest(cz.msebera.android.httpclient.HttpRequest) BasicHttpRequest(cz.msebera.android.httpclient.message.BasicHttpRequest) AbstractSessionInputBuffer(cz.msebera.android.httpclient.impl.io.AbstractSessionInputBuffer) SessionInputBuffer(cz.msebera.android.httpclient.io.SessionInputBuffer) HttpRequestParser(cz.msebera.android.httpclient.impl.io.HttpRequestParser) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) FileInputStream(info.guardianproject.iocipher.FileInputStream) FileNotFoundException(java.io.FileNotFoundException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) RemoteException(android.os.RemoteException) HttpException(cz.msebera.android.httpclient.HttpException) IOException(java.io.IOException) MethodNotSupportedException(cz.msebera.android.httpclient.MethodNotSupportedException) Header(cz.msebera.android.httpclient.Header) RemoteException(android.os.RemoteException) RandomAccessFile(info.guardianproject.iocipher.RandomAccessFile) File(info.guardianproject.iocipher.File)

Example 2 with SessionInputBuffer

use of cz.msebera.android.httpclient.io.SessionInputBuffer in project Zom-Android by zom.

the class OtrDataHandler method onIncomingResponse.

public void onIncomingResponse(Address from, Address to, byte[] value) {
    // Log.e( TAG, "onIncomingResponse:" + value.length);
    SessionInputBuffer buffer = new MemorySessionInputBuffer(value);
    HttpResponseParser parser = new HttpResponseParser(buffer, lineParser, responseFactory, params);
    HttpResponse res;
    try {
        res = (HttpResponse) parser.parse();
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (HttpException e) {
        e.printStackTrace();
        return;
    }
    String uid = res.getFirstHeader("Request-Id").getValue();
    Request request = requestCache.get(uid);
    if (request == null) {
        debug("Unknown request ID " + uid);
        return;
    }
    if (request.isSeen()) {
        debug("Already seen request ID " + uid);
        return;
    }
    request.seen();
    int statusCode = res.getStatusLine().getStatusCode();
    if (statusCode != 200) {
        debug("got status " + statusCode + ": " + res.getStatusLine().getReasonPhrase());
        // TODO handle error
        return;
    }
    // TODO handle success
    try {
        ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
        readIntoByteBuffer(byteBuffer, buffer);
        // debug("Received sha1 @" + request.start + " is " + sha1sum(byteBuffer.toByteArray()));
        if (request.method.equals("GET")) {
            Transfer transfer = transferCache.get(request.url);
            if (transfer == null) {
                debug("Transfer expired for url " + request.url);
                return;
            }
            transfer.chunkReceived(request, byteBuffer.toByteArray());
            if (transfer.isDone()) {
                // Log.e( TAG, "onIncomingResponse: isDone");
                debug("Transfer complete for " + request.url);
                String filename = transfer.closeFile();
                Uri vfsUri = SecureMediaStore.vfsUri(filename);
                if (transfer.checkSum()) {
                    // Log.e( TAG, "onIncomingResponse: writing");
                    if (mDataListener != null)
                        mDataListener.onTransferComplete(false, null, from.getAddress(), transfer.url, transfer.type, vfsUri.toString());
                } else {
                    if (mDataListener != null)
                        mDataListener.onTransferFailed(false, null, to.getAddress(), transfer.url, "checksum");
                    debug("Wrong checksum for file");
                }
            } else {
                if (mDataListener != null)
                    mDataListener.onTransferProgress(true, null, to.getAddress(), transfer.url, ((float) transfer.chunksReceived) / transfer.chunks);
                transfer.perform();
                debug("Progress " + transfer.chunksReceived + " / " + transfer.chunks);
            }
        }
    } catch (IOException e) {
        debug("Could not read line from response");
    } catch (RemoteException e) {
        debug("Could not read remote exception");
    }
}
Also used : AbstractSessionInputBuffer(cz.msebera.android.httpclient.impl.io.AbstractSessionInputBuffer) SessionInputBuffer(cz.msebera.android.httpclient.io.SessionInputBuffer) HttpRequest(cz.msebera.android.httpclient.HttpRequest) BasicHttpRequest(cz.msebera.android.httpclient.message.BasicHttpRequest) HttpResponse(cz.msebera.android.httpclient.HttpResponse) BasicHttpResponse(cz.msebera.android.httpclient.message.BasicHttpResponse) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Uri(android.net.Uri) HttpResponseParser(cz.msebera.android.httpclient.impl.io.HttpResponseParser) HttpException(cz.msebera.android.httpclient.HttpException) RemoteException(android.os.RemoteException)

Aggregations

RemoteException (android.os.RemoteException)2 HttpException (cz.msebera.android.httpclient.HttpException)2 HttpRequest (cz.msebera.android.httpclient.HttpRequest)2 AbstractSessionInputBuffer (cz.msebera.android.httpclient.impl.io.AbstractSessionInputBuffer)2 SessionInputBuffer (cz.msebera.android.httpclient.io.SessionInputBuffer)2 BasicHttpRequest (cz.msebera.android.httpclient.message.BasicHttpRequest)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 Uri (android.net.Uri)1 Header (cz.msebera.android.httpclient.Header)1 HttpResponse (cz.msebera.android.httpclient.HttpResponse)1 MethodNotSupportedException (cz.msebera.android.httpclient.MethodNotSupportedException)1 HttpRequestParser (cz.msebera.android.httpclient.impl.io.HttpRequestParser)1 HttpResponseParser (cz.msebera.android.httpclient.impl.io.HttpResponseParser)1 BasicHttpResponse (cz.msebera.android.httpclient.message.BasicHttpResponse)1 File (info.guardianproject.iocipher.File)1 FileInputStream (info.guardianproject.iocipher.FileInputStream)1 RandomAccessFile (info.guardianproject.iocipher.RandomAccessFile)1 FileNotFoundException (java.io.FileNotFoundException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1