Skip to content

Commit c44b41a

Browse files
committed
Separate blocking from non blocking IO
1 parent af80934 commit c44b41a

File tree

7 files changed

+249
-186
lines changed

7 files changed

+249
-186
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ build/
3232

3333
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
3434
.rvmrc
35+
build_config.rb.lock

README.md

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ end
1717
By default libtls looks in /etc/ssl/cert.pem for ca certs, you can find how to change that in the examples below.
1818

1919

20-
Example
21-
=======
20+
Client example with blocking IO
21+
================================
2222
```ruby
2323
client = Tls::Client.new
2424
client.connect('github.com:443').write("GET / HTTP/1.1\r\nHost: github.com\r\nConnection: close\r\n\r\n")
@@ -47,7 +47,57 @@ If you later want to change a config setting
4747
client.config.ca_file = '/etc/ssl/cert.pem'
4848
```
4949

50-
You can also create a configuration object to share with several connections.
50+
Client example with non blocking IO
51+
====================================
52+
requires mruby-poll gem
53+
```ruby
54+
tcp_socket = TCPSocket.new "github.com", 443
55+
client = Tls::Client.new
56+
client.connect_socket tcp_socket.fileno, "github.com"
57+
tcp_socket._setnonblock(true)
58+
poll = Poll.new
59+
tcp_socket_pi = poll.add(tcp_socket, Poll::Out)
60+
61+
buf = "GET / HTTP/1.1\r\nHost: github.com\r\nConnection: close\r\n\r\n"
62+
while buf
63+
unless poll.wait
64+
raise "Can't write to socket"
65+
end
66+
tmp = client.write_nonblock(buf)
67+
case tmp
68+
when :tls_want_pollin
69+
tcp_socket_pi.events = Poll::In
70+
when :tls_want_pollout
71+
tcp_socket_pi.events = Poll::Out
72+
when Fixnum
73+
buf = buf[tmp+1...-1]
74+
end
75+
end
76+
77+
tcp_socket_pi.events = Poll::In
78+
poll.wait
79+
until (buf = client.read_nonblock()).is_a? String
80+
case buf
81+
when :tls_want_pollin
82+
tcp_socket_pi.events = Poll::In
83+
when :tls_want_pollout
84+
tcp_socket_pi.events = Poll::Out
85+
end
86+
unless poll.wait
87+
raise "Can't read from socket"
88+
end
89+
end
90+
91+
puts buf
92+
93+
tcp_socket._setnonblock(false)
94+
client.close
95+
tcp_socket.close
96+
```
97+
98+
Configuration Examples
99+
======================
100+
You can create a configuration object to share with several connections.
51101
```ruby
52102
config = Tls::Config.new # see https://github.com/Asmod4n/mruby-tls/blob/master/mrblib/config.rb for options.
53103

@@ -60,6 +110,7 @@ client.config = config
60110
```
61111

62112
Server example
113+
==============
63114
```sh
64115
openssl ecparam -name secp256r1 -genkey -out private-key.pem
65116
openssl req -new -x509 -key private-key.pem -out server.pem
@@ -75,18 +126,11 @@ tls_client.close
75126

76127
Client Connections don't have a configurable config at the moment
77128

78-
The following Errors can be thrown:
79-
```ruby
80-
SystemCallError # Errno::*
81-
Tls::WantPollin # The underlying read file descriptor needs to be readable in order to continue.
82-
Tls::WantPollout # The underlying write file descriptor needs to be writeable in order to continue.
83-
```
84-
85129
This maps the C Api 1:1, to get a overview http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/tls_accept_fds.3?query=tls%5finit&sec=3 is a good starting point.
86130

87131
License
88132
=======
89-
Copyright 2015,2016 Hendrik Beskow
133+
Copyright 2015,2016,2024 Hendrik Beskow
90134

91135
Licensed under the Apache License, Version 2.0 (the "License");
92136
you may not use this project except in compliance with the License.

include/mruby/tls.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ MRB_BEGIN_DECL
77

88
#define E_TLS_ERROR (mrb_class_get_under(mrb, mrb_module_get(mrb, "Tls"), "Error"))
99
#define E_TLS_CONFIG_ERROR (mrb_class_get_under(mrb, mrb_class_get_under(mrb, mrb_module_get(mrb, "Tls"), "Config"), "Error"))
10-
#define E_TLS_WANT_POLLIN (mrb_class_get_under(mrb, mrb_module_get(mrb, "Tls"), "WantPollin"))
11-
#define E_TLS_WANT_POLLOUT (mrb_class_get_under(mrb, mrb_module_get(mrb, "Tls"), "WantPollout"))
1210

1311
MRB_END_DECL
1412

mrblib/config.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def self.new(options = {})
3535
instance.noverify(v)
3636
end
3737
else
38-
raise ArgumentError, "unknown option #{k}"
38+
raise ArgumentError, "unknown option #{k.dump}"
3939
end
4040
end
4141
instance

mrblib/context.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def self.new(config = nil)
1414
when NilClass
1515
super()
1616
else
17-
raise ArgumentError, "Cannot handle #{config.class}"
17+
raise ArgumentError, "Cannot handle #{config.class.dump}"
1818
end
1919
end
2020
end

mrblib/error.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
module Tls
22
class Error < RuntimeError; end
3-
class WantPollin < Error; end
4-
class WantPollout < Error; end
53
class Config
64
class Error < Tls::Error; end
75
end

0 commit comments

Comments
 (0)