-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo-client.rb
152 lines (125 loc) · 3.41 KB
/
demo-client.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# encoding: BINARY
# vim: ts=2 sts=2 sw=2 expandtab
require 'optparse'
opts = {
:host => 'localhost',
:port => 8888,
:https => true,
}
OptionParser.new do |o|
o.banner = "Usage: ruby #{$0} [options]"
o.on('-h', '--host HOST', 'The server name to connect to [default=localhost]') {|h| opts[:host] = h }
o.on('-p', '--port PORT', OptionParser::DecimalInteger, 'The TCP port to connect to [default=8888]') {|p| opts[:port] = Integer(p) }
o.on('-s', '--[no-]https', 'Whether or not to use HTTPS [default=true]') {|s| opts[:https] = s }
o.on('-?', '--help', 'Show this help message, and quit') { puts o; exit }
end.parse!
require 'socket'
s = TCPSocket.new opts[:host], opts[:port]
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
$authority = opts[:host]
if opts[:https]
$scheme = 'https'
$authority += ":#{opts[:port]}" if opts[:port] != 443
require 'openssl'
ctx = OpenSSL::SSL::SSLContext.new :TLSv1_2_client
ctx.verify_callback = lambda {|pverify_ok, store_context| true } # security!
if ctx.respond_to? :alpn_protocols=
ctx.alpn_protocols = %w[h2]
else
STDERR.puts "OpenSSL version doesn't support ALPN"
end
s = OpenSSL::SSL::SSLSocket.new s, ctx
if s.respond_to? :hostname=
s.hostname = opts[:host]
else
STDERR.puts "OpenSSL version doesn't support SNI"
end
s.sync_close = true
s.connect
else
$scheme = 'http'
$authority += ":#{opts[:port]}" if opts[:port] != 80
end
require 'logger'
logger = Logger.new STDERR
logger.progname = 'demo-client'
logger.datetime_format = '%Y-%m-%d %H:%M:%S'
logger.sev_threshold = Logger::DEBUG
require_relative 'lib/ruby-h2/http-client-agent'
require_relative 'lib/ruby-h2/http-request'
$shutdown = false
agent = RUBYH2::HTTPClientAgent.new(logger)
agent.on_response do |sid,r|
#puts "RECEIVED RESPONSE: #{r.inspect}"
puts '--'
r.headers.each_pair do |k,v|
puts "#{k}: [#{v}]"
end
puts ''
puts r.body
puts '--'
end
wrapper = Thread.new do
begin
agent.wrap s
rescue Exception => e
if !$shutdown
logger.error "#{e.class.name}: #{e}"
STDERR.puts "#{e.class.name}: #{e}", *e.backtrace.map{|bt|"\t#{bt}"}
end
end
end
agent.ping 'UUUUUUUU'
headers = {
':scheme' => $scheme,
':authority' => $authority,
'user-agent' => 'TestClient/1.0',
}
agent.request RUBYH2::HTTPRequest.new('GET', '/', headers)
agent.ping '33333333'
sleep 1
headers = {
':scheme' => $scheme,
':authority' => $authority,
'user-agent' => 'TestClient/1.0',
}
agent.request RUBYH2::HTTPRequest.new('GET', '/nonesuch', headers)
sleep 0.5
payload = 'foobar'
headers = {
':scheme' => $scheme,
':authority' => $authority,
'user-agent' => 'TestClient/1.0',
'content-type' => 'text/plain',
'content-length' => payload.bytesize.to_s,
}
agent.request RUBYH2::HTTPRequest.new('POST', '/', headers, payload)
sleep 0.5
headers = {
':scheme' => $scheme,
':authority' => $authority,
'user-agent' => 'TestClient/1.0',
}
agent.request RUBYH2::HTTPRequest.new('GET', '/padded', headers)
sleep 1
agent.accept_gzip!
sleep 0.25
headers = {
':scheme' => $scheme,
':authority' => $authority,
'user-agent' => 'TestClient/1.0',
}
agent.request RUBYH2::HTTPRequest.new('GET', '/', headers)
sleep 0.5
headers = {
':scheme' => $scheme,
':authority' => $authority,
'user-agent' => 'TestClient/1.0',
}
agent.request RUBYH2::HTTPRequest.new('GET', '/padded', headers)
sleep 5
$shutdown = true
agent.shut_down
sleep 2
s.close
wrapper.join