| 499 | } |
| 500 | |
| 501 | void TSSLSocket::write(const uint8_t* buf, uint32_t len) { |
| 502 | initializeHandshake(); |
| 503 | if (!checkHandshake()) |
| 504 | return; |
| 505 | // loop in case SSL_MODE_ENABLE_PARTIAL_WRITE is set in SSL_CTX. |
| 506 | uint32_t written = 0; |
| 507 | while (written < len) { |
| 508 | ERR_clear_error(); |
| 509 | int32_t bytes = SSL_write(ssl_, &buf[written], len - written); |
| 510 | if (bytes <= 0) { |
| 511 | int errno_copy = THRIFT_GET_SOCKET_ERROR; |
| 512 | int error = SSL_get_error(ssl_, bytes); |
| 513 | switch (error) { |
| 514 | case SSL_ERROR_SYSCALL: |
| 515 | if ((errno_copy != THRIFT_EINTR) |
| 516 | && (errno_copy != THRIFT_EAGAIN)) { |
| 517 | break; |
| 518 | } |
| 519 | // fallthrough |
| 520 | case SSL_ERROR_WANT_READ: |
| 521 | case SSL_ERROR_WANT_WRITE: |
| 522 | if (isLibeventSafe()) { |
| 523 | return; |
| 524 | } |
| 525 | else { |
| 526 | // in the case of SSL_ERROR_SYSCALL we want to wait for an write event again |
| 527 | waitForEvent(error == SSL_ERROR_WANT_READ); |
| 528 | continue; |
| 529 | } |
| 530 | default:;// do nothing |
| 531 | } |
| 532 | string errors; |
| 533 | buildErrors(errors, errno_copy, error); |
| 534 | throw TSSLException("SSL_write: " + errors); |
| 535 | } |
| 536 | written += bytes; |
| 537 | } |
| 538 | } |
| 539 | |
| 540 | /* |
| 541 | * Returns number of bytes written in SSL Socket. |
nothing calls this directly
no test coverage detected