Skip to content

Commit f12aab2

Browse files
committed
try to do smt SSLContext.session= is set and also try answering session_reused?
... this might resolve issues such as net/http using session= to force session re-use
1 parent 916ef9b commit f12aab2

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

src/main/java/org/jruby/ext/openssl/SSLContext.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,10 +662,12 @@ private static SSLEngine dummySSLEngine(final String protocol) throws GeneralSec
662662
}
663663

664664
// should keep SSLContext as a member for introducin SSLSession. later...
665-
SSLEngine createSSLEngine(String peerHost, int peerPort) throws NoSuchAlgorithmException, KeyManagementException {
665+
final SSLEngine createSSLEngine(String peerHost, int peerPort)
666+
throws NoSuchAlgorithmException, KeyManagementException {
666667
final SSLEngine engine;
667668
// an empty peerHost implies no SNI (RFC 3546) support requested
668-
if (peerHost == null || peerHost.length() == 0) {
669+
if ( peerHost == null || peerHost.length() == 0 ) {
670+
// no hints for an internal session reuse strategy
669671
engine = internalContext.getSSLContext().createSSLEngine();
670672
}
671673
// SNI is attempted for valid peerHost hostname on Java >= 7

src/main/java/org/jruby/ext/openssl/SSLSession.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import static org.jruby.ext.openssl.OpenSSL._OpenSSLError;
4545
import static org.jruby.ext.openssl.OpenSSL.warn;
4646
import static org.jruby.ext.openssl.SSL._SSL;
47+
import static org.jruby.ext.openssl.OpenSSL.warn;
4748

4849
/**
4950
* OpenSSL::SSL::Session
@@ -88,7 +89,7 @@ public IRubyObject initialize(final ThreadContext context, final IRubyObject arg
8889
}
8990

9091
SSLSession initializeImpl(final ThreadContext context, final SSLSocket socket) {
91-
sslSession = socket.getSession();
92+
sslSession = socket.sslSession();
9293
return this;
9394
}
9495

src/main/java/org/jruby/ext/openssl/SSLSocket.java

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,21 +1009,45 @@ public IRubyObject pending() {
10091009
return getRuntime().getNil();
10101010
}
10111011

1012+
private boolean reusableSSLEngine() {
1013+
if ( engine != null ) {
1014+
final String peerHost = engine.getPeerHost();
1015+
if ( peerHost != null && peerHost.length() > 0 ) {
1016+
// NOT getSSLContext().createSSLEngine() - no hints for session reuse
1017+
return true;
1018+
}
1019+
}
1020+
return false;
1021+
}
1022+
10121023
@JRubyMethod(name = "session_reused?")
10131024
public IRubyObject session_reused_p() {
1014-
warn(getRuntime().getCurrentContext(), "WARNING: SSLSocket#session_reused? is not supported");
1015-
return getRuntime().getNil(); // throw new UnsupportedOperationException();
1025+
if ( reusableSSLEngine() ) {
1026+
if ( ! engine.getEnableSessionCreation() ) {
1027+
// if session creation is disabled we can be sure its to be re-used
1028+
return getRuntime().getTrue();
1029+
}
1030+
//return getRuntime().getFalse(); // NOTE: likely incorrect (we can not decide)
1031+
}
1032+
//warn(getRuntime().getCurrentContext(), "WARNING: SSLSocket#session_reused? is not supported");
1033+
return getRuntime().getNil(); // can not decide - probably not
10161034
}
10171035

1018-
final javax.net.ssl.SSLSession getSession() {
1036+
// JSSE: SSL Sessions can be reused only if connecting to the same host at the same port
1037+
1038+
final javax.net.ssl.SSLSession sslSession() {
10191039
return engine == null ? null : engine.getSession();
10201040
}
10211041

10221042
private transient SSLSession session;
10231043

10241044
@JRubyMethod(name = "session")
10251045
public IRubyObject session(final ThreadContext context) {
1026-
if ( getSession() == null ) return context.nil;
1046+
if ( sslSession() == null ) return context.nil;
1047+
return getSession(context);
1048+
}
1049+
1050+
private SSLSession getSession(final ThreadContext context) {
10271051
if ( session == null ) {
10281052
return session = new SSLSession(context.runtime).initializeImpl(context, this);
10291053
}
@@ -1032,8 +1056,21 @@ public IRubyObject session(final ThreadContext context) {
10321056

10331057
@JRubyMethod(name = "session=")
10341058
public IRubyObject set_session(IRubyObject session) {
1035-
warn(getRuntime().getCurrentContext(), "WARNING: SSLSocket#session= is not supported");
1036-
return getRuntime().getNil(); // throw new UnsupportedOperationException();
1059+
final ThreadContext context = getRuntime().getCurrentContext();
1060+
// NOTE: we can not fully support this without the SSL provider internals
1061+
// but we can assume setting a session= is meant as a forced session re-use
1062+
if ( reusableSSLEngine() ) {
1063+
engine.setEnableSessionCreation(false);
1064+
if ( session instanceof SSLSession ) {
1065+
final SSLSession theSession = (SSLSession) session;
1066+
if ( ! theSession.equals( getSession(context) ) ) {
1067+
getSession(context).set_timeout(context, theSession.timeout(context));
1068+
}
1069+
}
1070+
return getSession(context);
1071+
}
1072+
warn(context, "WARNING: SSLSocket#session= has not effect");
1073+
return context.nil;
10371074
}
10381075

10391076
@JRubyMethod

0 commit comments

Comments
 (0)