function queue_encrypted_bytes(client, buf) # println("Adding $(length(buf)) for a total of $(length(buf) + length(client.write_buf))") append!(client.write_buf, buf) end function do_ssl_handshake(client) n = SSL_handshake(client) status = ssl_status(client, n) if status in (SSL_WANT_READ, SSL_WANT_WRITE) while true (n, buf) = bio_read(client) # println("bio_read: $(n)") if n > 0 queue_encrypted_bytes(client, buf) elseif !bio_should_retry(client.wbio) return -1 else break end end end # println("End of ssl handshake") return status end function send_unencrypted_bytes(client, buf) append!(client.encrypt_buf, buf) end function do_encrypt(client) ssl_init_finished(client) || return 0 while length(client.encrypt_buf) > 0 n = ssl_write(client, client.encrypt_buf) status = ccall((:SSL_get_error, libssl), SSL_ERRORS, (Ptr{Cvoid}, Cint), client.ssl, n) if n > 0 splice!(client.encrypt_buf, 1:n) while true (n, buf) = bio_read(client) if n > 0 queue_encrypted_bytes(client, buf) elseif !bio_should_retry(client.wbio) return -1 else break end end end if status in (SSL_ERROR, SSL_SYSCALL) @warn "SSL ERROR" return -1 end if n == 0 break end end return 0 end function on_read_cb(client, buffer) idx = 1 len = length(buffer) while len > 0 n = bio_write!(client, buffer[idx:end]) if n <= 0 return -1 end idx += n len -= n if ! ssl_init_finished(client) # println("SSL not finished yet") if (do_ssl_handshake(client) == -1) return -1 end if !ssl_init_finished(client) return 0 end end # println("NOW IT FINISHED\n") while true (n, buf) = read(client) if n > 0 client.io_on_read(buf[1:n]) else break end end status = ssl_status(client, n) if status in (SSL_WANT_READ, SSL_WANT_WRITE) while true (n, buf) = bio_read(client) if n > 0 queue_encrypted_bytes(client, buf) elseif !bio_should_retry(client.wbio) return -1 else break end end end if status in (SSL_ERROR, SSL_SYSCALL) return -1 end end return 0 end function do_sock_read(client::SSLClient) buf = readavailable(client.sock) if length(buf) > 0 return on_read_cb(client, buf) else return -1 end end function do_sock_write(client::SSLClient) n = write(client.sock, client.write_buf) # println("Written to the client: $n") if n > 0 splice!(client.write_buf, 1:n) return 0 else return -1 end end