@@ -242,6 +242,7 @@ private IRubyObject connectImpl(final ThreadContext context, final boolean block
242242 handshakeStatus = engine .getHandshakeStatus ();
243243 initialHandshake = true ;
244244 }
245+ callRenegotiationCallback (context );
245246 final IRubyObject ex = doHandshake (blocking , exception );
246247 if ( ex != null ) return ex ; // :wait_readable | :wait_writable
247248 }
@@ -325,6 +326,7 @@ private IRubyObject acceptImpl(final ThreadContext context, final boolean blocki
325326 handshakeStatus = engine .getHandshakeStatus ();
326327 initialHandshake = true ;
327328 }
329+ callRenegotiationCallback (context );
328330 final IRubyObject ex = doHandshake (blocking , exception );
329331 if ( ex != null ) return ex ; // :wait_readable | :wait_writable
330332 }
@@ -592,6 +594,18 @@ private int writeToChannel(ByteBuffer buffer, boolean blocking) throws IOExcepti
592594 private void finishInitialHandshake () {
593595 initialHandshake = false ;
594596 }
597+
598+ private void callRenegotiationCallback (final ThreadContext context ) throws RaiseException {
599+ IRubyObject renegotiationCallback = sslContext .getInstanceVariable ("@renegotiation_cb" );
600+ if (renegotiationCallback == null || renegotiationCallback .isNil ()) {
601+ return ;
602+ }
603+ else {
604+ // the return of the Proc is not important
605+ // Can throw ruby exception to "disallow" renegotiations
606+ renegotiationCallback .callMethod (context , "call" , this );
607+ }
608+ }
595609
596610 public int write (ByteBuffer src , boolean blocking ) throws SSLException , IOException {
597611 if ( initialHandshake ) {
0 commit comments