|
105 | 105 | end
|
106 | 106 | end
|
107 | 107 |
|
| 108 | +FailedToNegotiate = Sus::Shared("a failed websocket request") do |
| 109 | + it 'raises an error' do |
| 110 | + expect do |
| 111 | + Async::WebSocket::Client.connect(client_endpoint) {} |
| 112 | + end.to raise_exception(Async::WebSocket::ProtocolError, message: be =~ /Failed to negotiate connection/) |
| 113 | + end |
| 114 | +end |
| 115 | + |
108 | 116 | describe Async::WebSocket::Client do
|
109 | 117 | include Sus::Fixtures::Async::HTTP::ServerContext
|
110 | 118 |
|
111 | 119 | with 'http/1' do
|
112 | 120 | let(:protocol) {Async::HTTP::Protocol::HTTP1}
|
113 | 121 | it_behaves_like ClientExamples
|
114 | 122 |
|
| 123 | + def valid_headers(request) |
| 124 | + { |
| 125 | + 'connection' => 'upgrade', |
| 126 | + 'upgrade' => 'websocket', |
| 127 | + 'sec-websocket-accept' => Protocol::WebSocket::Headers::Nounce.accept_digest(request.headers['sec-websocket-key'].first) |
| 128 | + } |
| 129 | + end |
| 130 | + |
| 131 | + with 'invalid connection header' do |
| 132 | + let(:app) do |
| 133 | + Protocol::HTTP::Middleware.for do |request| |
| 134 | + Protocol::HTTP::Response[101, valid_headers(request).except('connection'), []] |
| 135 | + end |
| 136 | + end |
| 137 | + |
| 138 | + it_behaves_like FailedToNegotiate |
| 139 | + end |
| 140 | + |
| 141 | + with 'invalid upgrade header' do |
| 142 | + let(:app) do |
| 143 | + Protocol::HTTP::Middleware.for do |request| |
| 144 | + Protocol::HTTP::Response[101, valid_headers(request).except('upgrade'), []] |
| 145 | + end |
| 146 | + end |
| 147 | + |
| 148 | + it_behaves_like FailedToNegotiate |
| 149 | + end |
| 150 | + |
115 | 151 | with 'invalid sec-websocket-accept header' do
|
116 | 152 | let(:app) do
|
117 | 153 | Protocol::HTTP::Middleware.for do |request|
|
118 |
| - Protocol::HTTP::Response[101, {'sec-websocket-accept'=>'wrong-digest'}, []] |
| 154 | + Protocol::HTTP::Response[101, valid_headers(request).merge('sec-websocket-accept'=>'wrong-digest'), []] |
119 | 155 | end
|
120 | 156 | end
|
121 | 157 |
|
|
125 | 161 | end.to raise_exception(Async::WebSocket::ProtocolError, message: be =~ /Invalid accept digest/)
|
126 | 162 | end
|
127 | 163 | end
|
128 |
| - |
| 164 | + |
129 | 165 | with 'missing sec-websocket-accept header' do
|
130 | 166 | let(:app) do
|
131 | 167 | Protocol::HTTP::Middleware.for do |request|
|
132 |
| - Protocol::HTTP::Response[101, {}, []] |
| 168 | + Protocol::HTTP::Response[101, valid_headers(request).except('sec-websocket-accept'), []] |
133 | 169 | end
|
134 | 170 | end
|
135 | 171 |
|
136 |
| - it 'raises an error' do |
137 |
| - expect do |
138 |
| - Async::WebSocket::Client.connect(client_endpoint) {} |
139 |
| - end.to raise_exception(Async::WebSocket::ProtocolError, message: be =~ /Failed to negotiate connection/) |
| 172 | + it_behaves_like FailedToNegotiate |
| 173 | + end |
| 174 | + |
| 175 | + with 'invalid status' do |
| 176 | + let(:app) do |
| 177 | + Protocol::HTTP::Middleware.for do |request| |
| 178 | + Protocol::HTTP::Response[403, valid_headers(request), []] |
| 179 | + end |
140 | 180 | end
|
| 181 | + |
| 182 | + it_behaves_like FailedToNegotiate |
141 | 183 | end
|
142 | 184 | end
|
143 | 185 |
|
144 | 186 | with 'http/2' do
|
145 | 187 | let(:protocol) {Async::HTTP::Protocol::HTTP2}
|
146 | 188 | it_behaves_like ClientExamples
|
| 189 | + |
| 190 | + with 'invalid status' do |
| 191 | + let(:app) do |
| 192 | + Protocol::HTTP::Middleware.for do |request| |
| 193 | + Protocol::HTTP::Response[403, {}, []] |
| 194 | + end |
| 195 | + end |
| 196 | + |
| 197 | + it_behaves_like FailedToNegotiate |
| 198 | + end |
147 | 199 | end
|
148 | 200 | end
|
0 commit comments