Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
instance method
OpenSSL::SSL::SSLSocket#ssl_write
ssl.ssl_write(str) → integer, :wait_readable, or :wait_writable
ext/openssl/ossl_ssl.c
View on GitHub ↗
static VALUE
ossl_ssl_write(VALUE self, VALUE str)
{
SSL *ssl;
VALUE cb_state;
GetSSL(self, ssl);
if (!ssl_started(ssl))
rb_raise(eSSLError, "SSL session is not started yet");
StringValue(str);
/* SSL_write(3ssl) manpage states num == 0 is undefined */
int num = RSTRING_LENINT(str);
if (num == 0)
return INT2FIX(0);
#ifdef __APPLE__
retry:;
#endif
int frozen = RB_OBJ_FROZEN(str);
if (!frozen) {
rb_str_locktmp(str);
}
int nwritten = SSL_write(ssl, RSTRING_PTR(str), num);
if (!frozen) {
rb_str_unlocktmp(str);
}
int saved_errno = errno_mapped();
cb_state = rb_attr_get(self, ID_callback_state);
if (!NIL_P(cb_state)) {
rb_ivar_set(self, ID_callback_state, Qnil);
ossl_clear_error();
rb_jump_tag(NUM2INT(cb_state));
}
switch (SSL_get_error(ssl, nwritten)) {
case SSL_ERROR_NONE:
return INT2NUM(nwritten);
case SSL_ERROR_WANT_WRITE:
return sym_wait_writable;
case SSL_ERROR_WANT_READ:
return sym_wait_readable;
case SSL_ERROR_SYSCALL:
if (saved_errno) {
ossl_clear_error();
#ifdef __APPLE__
/*
* It appears that send syscall can return EPROTOTYPE if the
* socket is being torn down. Retry to get a proper errno to
* make the error handling in line with the socket library.
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
*/
if (saved_errno == EPROTOTYPE)
goto retry;
#endif
rb_exc_raise(rb_syserr_new(saved_errno, "SSL_write"));
}
/* fallthrough */
default:
ossl_raise(eSSLError, "SSL_write");
}
}
No documentation available