Long receive time for chunked ssl response
------------------------------------------
Key: HTTPCORE-196
URL: https://issues.apache.org/jira/browse/HTTPCORE-196
Project: HttpComponents HttpCore
Issue Type: Bug
Affects Versions: 4.0
Environment: MacOSX (Leopard) / Tomcat / Eclipse
Reporter: Scott Willey
Fix For: Future
Processing a chunked SSL response of 221 characters, I found I was waiting over
three seconds for the entire response to be read. Upon investigation, this
appears to be happening because the decrypt method in SSLIOSession does not
decrypt everything in the encrypted buffer at one go. Because of this, portions
of my response didn't get processed via the processing of the events, but
rather via the BaseIOReactor's validate method which means I experienced
multiple select interval timeouts prior to the message being fully processed.
In reviewing the java nio documentation for the unwrap method of the sslEngine,
the comments in the javadoc state: "This method will attempt to consume one
complete SSL/TLS network packet". It appears that one time through the decrypt
method decrypted small packets with almost no data in them, leaving encrypted
data waiting. As an experiment, I changed the code in isAppInputReady in
SSLIOSession to call decrypt in a loop until everything in the en
crypted buffer was processed and bingo the response processed in under 5ms.
Unfortunately, I do not have a "sharable" test case as the server side for this
case is inside a corporate filrewall. In theory this should be reproducable
with any server over an SSL connection getting a chunked response.
I have a current "patch" for this issue as follows in
SSLIOSession.isAppInputReady, but I will feel much more comfortable with and
"official" patch
public synchronized boolean isAppInputReady() throws IOException {
int bytesRead = receiveEncryptedData();
if (bytesRead == -1) {
//changed per https://issues.apache.org/jira/browse/HTTPCORE-193
// this.status = CLOSED;
this.endOfStream = true;
//end change
}
doHandshake();
//MODIFICATION
//Doing a single decrypt call does not always completely decrypt
available
//data (data read above in receiveEncryptedData). The documentation for
//sslEngine states that the unwrap method (used in decrypt method)
//
// "This method will attempt to consume one complete SSL/TLS network
packet"
//
//Presumedly, when there are multiple network packets, we only decode
one
//at a time, so multiple calls to decrypt may be necessary to decrypt
all
//we have. If we do not, we will not process all data available and we
//will fail to process incoming responses in a timely way. This may
cause
//data to be processed only during calls to validation at the reactor
level,
//which is done once every selectInterval (default value: 1 sec)
//original
//decryptData();
//change:
int priorPos = 0;
while(this.inEncrypted.position() > 0 && this.inEncrypted.position() !=
priorPos){
priorPos = this.inEncrypted.position();
decryptData();
}
//MODIFICATION END
// Some decrypted data is available or at the end of stream
return this.inPlain.position() > 0 || this.status != ACTIVE;
}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]