-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.rb
136 lines (110 loc) · 3.15 KB
/
server.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
require 'ds9'
require 'socket'
require 'openssl'
CERT = OpenSSL::X509::Certificate.new File.read ARGV[0]
KEY = OpenSSL::PKey::RSA.new File.read ARGV[1]
warn "Using nghttp: #{DS9.nghttp_version}" # I tried with 1.0.2
warn "OpenSSL: #{OpenSSL::OPENSSL_VERSION}"
module DS9
class Context
SETTINGS = [ [DS9::Settings::MAX_CONCURRENT_STREAMS, 100] ]
def initialize pubkey, privkey
@ctx = OpenSSL::SSL::SSLContext.new
@ctx.npn_protocols = [DS9::PROTO_VERSION_ID]
@pkey = OpenSSL::PKey::EC.new "prime256v1"
@ctx.tmp_ecdh = @pkey
@ctx.ssl_version = "SSLv23_server"
@ctx.cert = CERT
@ctx.key = KEY
server = TCPServer.new 8080
@server = OpenSSL::SSL::SSLServer.new server, @ctx
@server.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
end
class MySession < DS9::Server
def initialize sock
super()
@sock = sock
@read_streams = {}
@write_streams = {}
end
def on_begin_headers frame
p __method__ => frame
end
def on_data_source_read stream_id, length
x = @write_streams[stream_id].read(length)
p __method__ => [stream_id, length, x]
x
end
def on_frame_not_send frame, reason
p __method__ => frame
end
def on_stream_close id, error_code
@read_streams.delete id
@write_streams.delete id
p :CLOSING => id
end
def on_header name, value, frame, flags
p __method__ => [name, value]
end
def on_frame_recv frame
p __method__ => frame
return unless frame.headers?
@write_streams[frame.stream_id] = StringIO.new("hello world\n")
submit_response frame.stream_id, [
[":status", '200'],
["server", 'test server'],
["date", 'Sat, 27 Jun 2015 17:29:21 GMT']
]
true
end
def on_frame_send frame
p __method__ => [frame, frame.stream_id]
true
end
def send_event string
p __method__ => string
@sock.write string
end
def recv_event length
return '' unless want_read? || want_write?
x = @sock.read_nonblock length
p __method__ => [length, x, x.length]
x
rescue OpenSSL::SSL::SSLErrorWaitReadable
p __method__ => "WOULD BLOCK"
return DS9::ERR_WOULDBLOCK
rescue EOFError
p __method__ => "EOF"
return DS9::ERR_EOF
end
def run
while want_read? || want_write?
if want_read?
rd, _, _ = IO.select([@sock])
begin
return if rd.first.eof?
rescue OpenSSL::SSL::SSLError
return
end
receive
end
if want_write?
_, wr, _ = IO.select(nil, [@sock])
send
end
end
end
end
def run
loop do
sock = @server.accept
puts "OMG"
session = MySession.new sock
session.submit_settings SETTINGS
session.run
end
end
end
end
ctx = DS9::Context.new ARGV[0], ARGV[1]
ctx.run