@@ -1009,21 +1009,45 @@ public IRubyObject pending() {
1009
1009
return getRuntime ().getNil ();
1010
1010
}
1011
1011
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
+
1012
1023
@ JRubyMethod (name = "session_reused?" )
1013
1024
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
1016
1034
}
1017
1035
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 () {
1019
1039
return engine == null ? null : engine .getSession ();
1020
1040
}
1021
1041
1022
1042
private transient SSLSession session ;
1023
1043
1024
1044
@ JRubyMethod (name = "session" )
1025
1045
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 ) {
1027
1051
if ( session == null ) {
1028
1052
return session = new SSLSession (context .runtime ).initializeImpl (context , this );
1029
1053
}
@@ -1032,8 +1056,21 @@ public IRubyObject session(final ThreadContext context) {
1032
1056
1033
1057
@ JRubyMethod (name = "session=" )
1034
1058
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 ;
1037
1074
}
1038
1075
1039
1076
@ JRubyMethod
0 commit comments