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);
}
}
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");
}
}
Aggregations