(&self, data: ArgBytesLike, vm: &VirtualMachine)
| 3688 | |
| 3689 | #[pymethod] |
| 3690 | fn write(&self, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> { |
| 3691 | let data_bytes = data.borrow_buf(); |
| 3692 | let data_len = data_bytes.len(); |
| 3693 | |
| 3694 | if data_len == 0 { |
| 3695 | return Ok(0); |
| 3696 | } |
| 3697 | |
| 3698 | // Ensure handshake is done (SSL_write auto-completes handshake) |
| 3699 | if !*self.handshake_done.lock() { |
| 3700 | self.do_handshake(vm)?; |
| 3701 | } |
| 3702 | |
| 3703 | // Check shutdown state |
| 3704 | // Only block after shutdown is COMPLETED, not during shutdown process |
| 3705 | if *self.shutdown_state.lock() == ShutdownState::Completed { |
| 3706 | return Err(vm |
| 3707 | .new_os_subtype_error( |
| 3708 | PySSLError::class(&vm.ctx).to_owned(), |
| 3709 | None, |
| 3710 | "cannot write after shutdown", |
| 3711 | ) |
| 3712 | .upcast()); |
| 3713 | } |
| 3714 | |
| 3715 | // Call ssl_write (matches CPython's SSL_write_ex loop) |
| 3716 | let result = { |
| 3717 | let mut conn_guard = self.connection.lock(); |
| 3718 | let conn = conn_guard |
| 3719 | .as_mut() |
| 3720 | .ok_or_else(|| vm.new_value_error("Connection not established"))?; |
| 3721 | |
| 3722 | crate::ssl::compat::ssl_write(conn, data_bytes.as_ref(), self, vm) |
| 3723 | }; |
| 3724 | |
| 3725 | match result { |
| 3726 | Ok(n) => { |
| 3727 | self.check_deferred_cert_error(vm)?; |
| 3728 | Ok(n) |
| 3729 | } |
| 3730 | Err(crate::ssl::compat::SslError::WantRead) => { |
| 3731 | Err(create_ssl_want_read_error(vm).upcast()) |
| 3732 | } |
| 3733 | Err(crate::ssl::compat::SslError::WantWrite) => { |
| 3734 | Err(create_ssl_want_write_error(vm).upcast()) |
| 3735 | } |
| 3736 | Err(crate::ssl::compat::SslError::Timeout(msg)) => { |
| 3737 | Err(timeout_error_msg(vm, msg).upcast()) |
| 3738 | } |
| 3739 | Err(e) => Err(e.into_py_err(vm)), |
| 3740 | } |
| 3741 | } |
| 3742 | |
| 3743 | #[pymethod] |
| 3744 | fn getpeercert( |
no test coverage detected