Я не знаю, почему, но половина сайтов, которые проходят через ssl, получает буферный поток во время моего чтения.Android SSLEngine BUFFER_UNDERFLOW после разворачивания при чтении
Когда у меня есть моя программа, прикованная к разным сайтам ssl последовательно, она не работает на половине ссылок, но если я вызываю один за другим в отдельности, они работают. Например, я использовал инструменты разработчика Chrome для вызова https://www.facebook.com на моем планшете Nexus 7. Когда я вижу, запросы, ссылки называемые являются:
- https://www.facebook.com/
- https://fbstatic-a.akamaihd.net/rsrc.php/v2/y7/r/Zj_YpNlIRKt.css
- https://fbstatic-a.akamaihd.net/rsrc.php/v2/yI/r/5EMLHs-7t29.css и т.д.
- ... (около 26 ссылок).
Если бы я приковать их вместе (для имитации вызова https://www.facebook.com из браузера), я получаю половину ссылки получать буфер обнуляется, пока в конце концов, я не должен закрывать соединения (Reading 0 байт). Однако, если я закажу их один за другим индивидуально, они всегда в порядке. Вот мой код для чтения:
public int readSSLFrom(SelectionKey key, SecureIO session) throws IOException{
int result = 0;
String TAG = "readSSLFrom";
Log.i(TAG,"Hanshake status: "+session.sslEngine.getHandshakeStatus().toString());
synchronized (buffer){
ByteBuffer sslIn = ByteBuffer.allocate(session.getApplicationSizeBuffer());
ByteBuffer tmp = ByteBuffer.allocate(session.getApplicationSizeBuffer());
ReadableByteChannel channel = (ReadableByteChannel) key.channel();
if (buffer.remaining() < session.getPacketBufferSize()){
increaseSize(session.getPacketBufferSize());
}
int read = 0;
while (((read = channel.read(sslIn)) > 0) &&
buffer.remaining() >= session.getApplicationSizeBuffer()){
if (read < 0){
session.sslEngine.closeInbound();
return -1;
}
inner: while (sslIn.position() > 0){
sslIn.flip();
tmp.clear();
SSLEngineResult res = session.sslEngine.unwrap(sslIn, tmp);
result = result + res.bytesProduced();
sslIn.compact();
tmp.flip();
if (tmp.hasRemaining()){
buffer.put(tmp);
}
switch (res.getStatus()){
case BUFFER_OVERFLOW:
Log.i(TAG,"Buffer overflow");
throw new Error();
case BUFFER_UNDERFLOW:
Log.i(TAG,"Buffer underflow");
if (session.getPacketBufferSize() > tmp.capacity()){
Log.i(TAG,"increasing capacity");
ByteBuffer b = ByteBuffer.allocate(session.getPacketBufferSize());
sslIn.flip();
b.put(sslIn);
sslIn = b;
}
break inner;
case CLOSED:
Log.i(TAG,"Closed");
if (sslIn.position() == 0){
break inner;
} else{
return -1;
}
case OK:
Log.i(TAG,"OK");
session.checkHandshake(key);
break;
default:
break;
}
}
}
if (read < 0){
//session.sslEngine.closeInbound();
return -1;
}
}
dataEnd = buffer.position();
return result;
}
Спасибо.
Я не понял вашу проблему четко, но я написал что-то, что упрощает использование sslengine java - почему бы вам не взглянуть на него - [SSLFacade] (https://github.com/kashifrazzaqui/ sslfacade) – kashif
Спасибо, kashif, на самом деле я уже скачал ваш проект, но у меня не было времени посмотреть на него. Основная проблема, с которой я сталкиваюсь, и я не могу легко решить, так это то, что иногда во время разворота я получаю сообщение об исключении. Я, наконец, нашел причину, потому что у ByteBuffers заканчивается пространство с некоторыми запросами. Те запросы, у которых эта проблема заканчиваются, составляют 300 КБ страниц (например, страница .js), а мой ByteBuffer - это только пакетSizeBuffer(), который намного меньше, поэтому я могу только частично распаковать страницу, но я обязательно посмотрю в вашем проекте. –