Search in sources :

Example 1 with HttpRequestParser

use of cz.msebera.android.httpclient.impl.io.HttpRequestParser 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)

Aggregations

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