rtsp_server 0.0.2-universal-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/ChangeLog.rdoc +74 -0
- data/Gemfile +3 -0
- data/LICENSE.rdoc +20 -0
- data/README.rdoc +152 -0
- data/Rakefile +23 -0
- data/bin/rtsp_client +133 -0
- data/features/client_changes_state.feature +58 -0
- data/features/client_requests.feature +27 -0
- data/features/control_streams_as_client.feature +26 -0
- data/features/step_definitions/client_changes_state_steps.rb +52 -0
- data/features/step_definitions/client_requests_steps.rb +68 -0
- data/features/step_definitions/control_streams_as_client_steps.rb +34 -0
- data/features/support/env.rb +50 -0
- data/features/support/hooks.rb +3 -0
- data/lib/ext/logger.rb +8 -0
- data/lib/rtsp/client.rb +520 -0
- data/lib/rtsp/common.rb +148 -0
- data/lib/rtsp/error.rb +6 -0
- data/lib/rtsp/global.rb +63 -0
- data/lib/rtsp/helpers.rb +28 -0
- data/lib/rtsp/message.rb +272 -0
- data/lib/rtsp/request.rb +39 -0
- data/lib/rtsp/response.rb +47 -0
- data/lib/rtsp/server.rb +311 -0
- data/lib/rtsp/socat_streaming.rb +320 -0
- data/lib/rtsp/stream_server.rb +37 -0
- data/lib/rtsp/transport_parser.rb +96 -0
- data/lib/rtsp/version.rb +4 -0
- data/lib/rtsp.rb +6 -0
- data/rtsp.gemspec +44 -0
- data/spec/rtsp/client_spec.rb +326 -0
- data/spec/rtsp/helpers_spec.rb +53 -0
- data/spec/rtsp/message_spec.rb +420 -0
- data/spec/rtsp/response_spec.rb +306 -0
- data/spec/rtsp/transport_parser_spec.rb +137 -0
- data/spec/rtsp_spec.rb +27 -0
- data/spec/spec_helper.rb +88 -0
- data/spec/support/fake_rtsp_server.rb +123 -0
- data/tasks/roodi.rake +9 -0
- data/tasks/roodi_config.yaml +14 -0
- data/tasks/stats.rake +12 -0
- metadata +280 -0
@@ -0,0 +1,420 @@
|
|
1
|
+
require 'sdp'
|
2
|
+
require_relative '../spec_helper'
|
3
|
+
require 'rtsp/message'
|
4
|
+
|
5
|
+
describe "RTSP::Message" do
|
6
|
+
let(:stream) { "rtsp://1.2.3.4/stream1" }
|
7
|
+
|
8
|
+
it "raises if the header type isn't a Symbol" do
|
9
|
+
message = RTSP::Message.options(stream)
|
10
|
+
|
11
|
+
lambda {
|
12
|
+
message.header "hi", "everyone"
|
13
|
+
}.should raise_error RTSP::Error
|
14
|
+
end
|
15
|
+
|
16
|
+
RTSP::Message.instance_variable_get(:@message_types).each do |method|
|
17
|
+
it "adds a User-Agent header to the #{method} method" do
|
18
|
+
message = RTSP::Message.send(method, stream)
|
19
|
+
message.to_s.should include "User-Agent: RubyRTSP/"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "builds an OPTIONS string" do
|
24
|
+
it "with default sequence number" do
|
25
|
+
message = RTSP::Message.options(stream)
|
26
|
+
message.to_s.should == "OPTIONS rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\nCSeq: 1\r\nUser-Agent: RubyRTSP/#{RTSP::VERSION} (Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL})\r\n\r\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "with new sequence number" do
|
30
|
+
message = RTSP::Message.options(stream)
|
31
|
+
message.header :cseq, 2345
|
32
|
+
message.to_s.should == "OPTIONS rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\nCSeq: 2345\r\nUser-Agent: RubyRTSP/#{RTSP::VERSION} (Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL})\r\n\r\n"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "builds a DESCRIBE string" do
|
37
|
+
it "with default sequence and accept values" do
|
38
|
+
message = RTSP::Message.describe(stream)
|
39
|
+
message.to_s.should match(/^DESCRIBE rtsp:/)
|
40
|
+
message.to_s.should include "DESCRIBE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
41
|
+
message.to_s.should include "CSeq: 1\r\n"
|
42
|
+
message.to_s.should include "Accept: application/sdp\r\n"
|
43
|
+
message.to_s.should match(/\r\n\r\n$/)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "with default sequence value" do
|
47
|
+
message = RTSP::Message.describe(stream).with_headers({
|
48
|
+
accept: 'application/sdp, application/rtsl' })
|
49
|
+
message.to_s.should match(/^DESCRIBE rtsp:/)
|
50
|
+
message.to_s.should include "DESCRIBE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
51
|
+
message.to_s.should include "CSeq: 1\r\n"
|
52
|
+
message.to_s.should include "Accept: application/sdp, application/rtsl\r\n"
|
53
|
+
message.to_s.should match(/\r\n\r\n$/)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "with new sequence and accept values" do
|
57
|
+
message = RTSP::Message.describe(stream).with_headers({
|
58
|
+
accept: 'application/sdp, application/rtsl',
|
59
|
+
cseq: 2345 })
|
60
|
+
|
61
|
+
message.to_s.should match(/^DESCRIBE rtsp:/)
|
62
|
+
message.to_s.should include "DESCRIBE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
63
|
+
message.to_s.should include "CSeq: 2345\r\n"
|
64
|
+
message.to_s.should include "Accept: application/sdp, application/rtsl\r\n"
|
65
|
+
message.to_s.should match(/\r\n\r\n$/)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "builds a ANNOUNCE string" do
|
70
|
+
it "with default sequence, content type, but no body" do
|
71
|
+
message = RTSP::Message.announce(stream).with_headers({ session: 123456789 })
|
72
|
+
|
73
|
+
message.to_s.should match(/^ANNOUNCE rtsp:/)
|
74
|
+
message.to_s.should include "ANNOUNCE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
75
|
+
message.to_s.should include "CSeq: 1\r\n"
|
76
|
+
message.to_s.should include "Session: 123456789\r\n"
|
77
|
+
message.to_s.should include "Content-Type: application/sdp\r\n"
|
78
|
+
message.to_s.should match(/\r\n\r\n$/)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "with passed-in session and content type but no body" do
|
82
|
+
message = RTSP::Message.announce(stream).with_headers({
|
83
|
+
session: 123456789,
|
84
|
+
content_type: 'application/sdp, application/rtsl' })
|
85
|
+
|
86
|
+
message.to_s.should match(/^ANNOUNCE rtsp:/)
|
87
|
+
message.to_s.should include "ANNOUNCE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
88
|
+
message.to_s.should include "CSeq: 1\r\n"
|
89
|
+
message.to_s.should include "Session: 123456789\r\n"
|
90
|
+
message.to_s.should include "Content-Type: application/sdp, application/rtsl\r\n"
|
91
|
+
message.to_s.should match(/\r\n\r\n$/)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "with passed-in sequence, session, content-type, but no body " do
|
95
|
+
message = RTSP::Message.announce(stream).with_headers({
|
96
|
+
session: 123456789,
|
97
|
+
content_type: 'application/sdp, application/rtsl',
|
98
|
+
cseq: 2345 })
|
99
|
+
|
100
|
+
message.to_s.should match(/^ANNOUNCE rtsp:/)
|
101
|
+
message.to_s.should include "ANNOUNCE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
102
|
+
message.to_s.should include "CSeq: 2345\r\n"
|
103
|
+
message.to_s.should include "Session: 123456789\r\n"
|
104
|
+
message.to_s.should include "Content-Type: application/sdp, application/rtsl\r\n"
|
105
|
+
message.to_s.should match(/\r\n\r\n$/)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "with passed-in sequence, session, content-type, and SDP body" do
|
109
|
+
sdp = SDP::Description.new
|
110
|
+
sdp.protocol_version = 1
|
111
|
+
sdp.username = 'bobo'
|
112
|
+
|
113
|
+
message = RTSP::Message.announce(stream).with_headers({
|
114
|
+
session: 123456789,
|
115
|
+
content_type: 'application/sdp',
|
116
|
+
cseq: 2345 })
|
117
|
+
message.body = sdp.to_s
|
118
|
+
|
119
|
+
message.to_s.should match(/^ANNOUNCE rtsp/)
|
120
|
+
message.to_s.should include "ANNOUNCE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
121
|
+
message.to_s.should include "CSeq: 2345\r\n"
|
122
|
+
message.to_s.should include "Session: 123456789\r\n"
|
123
|
+
message.to_s.should include "Content-Type: application/sdp\r\n"
|
124
|
+
message.to_s.should include "Content-Length: 29\r\n"
|
125
|
+
message.to_s.should match(/\r\n\r\nv=1\r\no=bobo \r\ns=\r\nt= \r\n\r\n$/)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "builds a SETUP string" do
|
130
|
+
it "with default sequence, client_port, and routing values" do
|
131
|
+
message = RTSP::Message.setup(stream)
|
132
|
+
|
133
|
+
message.to_s.should match(/^SETUP rtsp/)
|
134
|
+
message.to_s.should include "SETUP rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
135
|
+
message.to_s.should include "CSeq: 1\r\n"
|
136
|
+
message.to_s.should match(/\r\n\r\n$/)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "with default sequence, transport, and client_port values" do
|
140
|
+
message = RTSP::Message.setup(stream).with_headers({
|
141
|
+
transport: ["RTP/AVP", "multicast", { :client_port => "9000-9001" }] })
|
142
|
+
|
143
|
+
message.to_s.should match(/^SETUP rtsp/)
|
144
|
+
message.to_s.should include "SETUP rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
145
|
+
message.to_s.should include "CSeq: 1\r\n"
|
146
|
+
message.to_s.should include "Transport: RTP/AVP;multicast;client_port=9000-9001\r\n"
|
147
|
+
message.to_s.should match(/\r\n\r\n$/)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "with default transport, client_port, and routing values" do
|
151
|
+
message = RTSP::Message.setup(stream).with_headers({
|
152
|
+
transport: ["RTP/AVP", "multicast", { :client_port => "9000-9001" }],
|
153
|
+
cseq: 2345 })
|
154
|
+
|
155
|
+
message.to_s.should match(/^SETUP rtsp/)
|
156
|
+
message.to_s.should include "SETUP rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
157
|
+
message.to_s.should include "CSeq: 2345\r\n"
|
158
|
+
message.to_s.should include "Transport: RTP/AVP;multicast;client_port=9000-9001\r\n"
|
159
|
+
message.to_s.should match(/\r\n\r\n$/)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "builds a PLAY string" do
|
164
|
+
it "with default sequence and range values" do
|
165
|
+
message = RTSP::Message.play(stream).with_headers({
|
166
|
+
session: 123456789 })
|
167
|
+
|
168
|
+
message.to_s.should match(/^PLAY rtsp/)
|
169
|
+
message.to_s.should include "PLAY rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
170
|
+
message.to_s.should include "CSeq: 1\r\n"
|
171
|
+
message.to_s.should include "Session: 123456789\r\n"
|
172
|
+
message.to_s.should include "Range: npt=0.000-\r\n"
|
173
|
+
message.to_s.should match(/\r\n\r\n/)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "with default sequence value" do
|
177
|
+
message = RTSP::Message.play(stream).with_headers({
|
178
|
+
session: 123456789,
|
179
|
+
range: { :npt => "0.000-1.234" } })
|
180
|
+
|
181
|
+
message.to_s.should match(/^PLAY rtsp/)
|
182
|
+
message.to_s.should include "PLAY rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
183
|
+
message.to_s.should include "CSeq: 1\r\n"
|
184
|
+
message.to_s.should include "Session: 123456789\r\n"
|
185
|
+
message.to_s.should include "Range: npt=0.000-1.234\r\n"
|
186
|
+
message.to_s.should match(/\r\n\r\n/)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context "builds a PAUSE string" do
|
191
|
+
it "with required Request values" do
|
192
|
+
message = RTSP::Message.pause(stream)
|
193
|
+
|
194
|
+
message.to_s.should match(/^PAUSE rtsp/)
|
195
|
+
message.to_s.should include "PAUSE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
196
|
+
message.to_s.should include "CSeq: 1\r\n"
|
197
|
+
message.to_s.should match(/\r\n\r\n/)
|
198
|
+
end
|
199
|
+
|
200
|
+
it "with session and range headers" do
|
201
|
+
message = RTSP::Message.pause(stream).with_headers({
|
202
|
+
session: 123456789,
|
203
|
+
range: { :npt => "0.000" } })
|
204
|
+
|
205
|
+
message.to_s.should match(/^PAUSE rtsp/)
|
206
|
+
message.to_s.should include "PAUSE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
207
|
+
message.to_s.should include "CSeq: 1\r\n"
|
208
|
+
message.to_s.should include "Session: 123456789\r\n"
|
209
|
+
message.to_s.should include "Range: npt=0.000\r\n"
|
210
|
+
message.to_s.should match(/\r\n\r\n/)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context "builds a TEARDOWN string" do
|
215
|
+
it "with required Request values" do
|
216
|
+
message = RTSP::Message.teardown(stream)
|
217
|
+
|
218
|
+
message.to_s.should match(/^TEARDOWN rtsp/)
|
219
|
+
message.to_s.should include "TEARDOWN rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
220
|
+
message.to_s.should include "CSeq: 1\r\n"
|
221
|
+
message.to_s.should match(/\r\n\r\n/)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "with session and range headers" do
|
225
|
+
message = RTSP::Message.teardown(stream).with_headers({
|
226
|
+
session: 123456789 })
|
227
|
+
|
228
|
+
message.to_s.should match(/^TEARDOWN rtsp/)
|
229
|
+
message.to_s.should include "TEARDOWN rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
230
|
+
message.to_s.should include "CSeq: 1\r\n"
|
231
|
+
message.to_s.should include "Session: 123456789\r\n"
|
232
|
+
message.to_s.should match(/\r\n\r\n/)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context "builds a GET_PARAMETER string" do
|
237
|
+
it "with required Request values" do
|
238
|
+
message = RTSP::Message.get_parameter(stream)
|
239
|
+
|
240
|
+
message.to_s.should match(/^GET_PARAMETER rtsp/)
|
241
|
+
message.to_s.should include "GET_PARAMETER rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
242
|
+
message.to_s.should include "CSeq: 1\r\n"
|
243
|
+
message.to_s.should match(/\r\n\r\n/)
|
244
|
+
end
|
245
|
+
|
246
|
+
it "with cseq, content type, session headers, and text body" do
|
247
|
+
the_body = "packets_received\r\njitter\r\n"
|
248
|
+
|
249
|
+
message = RTSP::Message.get_parameter(stream).with_headers({
|
250
|
+
cseq: 431,
|
251
|
+
content_type: 'text/parameters',
|
252
|
+
session: 123456789 })
|
253
|
+
|
254
|
+
message.body = the_body
|
255
|
+
|
256
|
+
message.to_s.should match(/^GET_PARAMETER rtsp/)
|
257
|
+
message.to_s.should include "GET_PARAMETER rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
258
|
+
message.to_s.should include "CSeq: 431\r\n"
|
259
|
+
message.to_s.should include "Session: 123456789\r\n"
|
260
|
+
message.to_s.should include "Content-Type: text/parameters\r\n"
|
261
|
+
message.to_s.should include "Content-Length: #{the_body.length}\r\n"
|
262
|
+
message.to_s.should include the_body
|
263
|
+
message.to_s.should match(/\r\n\r\n/)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context "builds a SET_PARAMETER string" do
|
268
|
+
it "with required Request values" do
|
269
|
+
message = RTSP::Message.set_parameter(stream)
|
270
|
+
|
271
|
+
message.to_s.should match(/^SET_PARAMETER rtsp/)
|
272
|
+
message.to_s.should include "SET_PARAMETER rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
273
|
+
message.to_s.should include "CSeq: 1\r\n"
|
274
|
+
message.to_s.should match(/\r\n\r\n/)
|
275
|
+
end
|
276
|
+
|
277
|
+
it "with cseq, content type, session headers, and text body" do
|
278
|
+
the_body = "barparam: barstuff\r\n"
|
279
|
+
|
280
|
+
message = RTSP::Message.set_parameter(stream).with_headers({
|
281
|
+
cseq: 431,
|
282
|
+
content_type: 'text/parameters',
|
283
|
+
session: 123456789 })
|
284
|
+
message.body = the_body
|
285
|
+
|
286
|
+
message.to_s.should match(/^SET_PARAMETER rtsp/)
|
287
|
+
message.to_s.should include "SET_PARAMETER rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
288
|
+
message.to_s.should include "CSeq: 431\r\n"
|
289
|
+
message.to_s.should include "Session: 123456789\r\n"
|
290
|
+
message.to_s.should include "Content-Type: text/parameters\r\n"
|
291
|
+
message.to_s.should include "Content-Length: #{the_body.length}\r\n"
|
292
|
+
message.to_s.should include the_body
|
293
|
+
message.to_s.should match(/\r\n\r\n/)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
context "builds a REDIRECT string" do
|
298
|
+
it "with required Request values" do
|
299
|
+
message = RTSP::Message.redirect(stream)
|
300
|
+
|
301
|
+
message.to_s.should match(/^REDIRECT rtsp/)
|
302
|
+
message.to_s.should include "REDIRECT rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
303
|
+
message.to_s.should include "CSeq: 1\r\n"
|
304
|
+
message.to_s.should match(/\r\n\r\n/)
|
305
|
+
end
|
306
|
+
|
307
|
+
it "with cseq, location, and range headers" do
|
308
|
+
message = RTSP::Message.redirect(stream).with_headers({
|
309
|
+
cseq: 732,
|
310
|
+
location: "rtsp://bigserver.com:8001",
|
311
|
+
range: { :clock => "19960213T143205Z-" } })
|
312
|
+
|
313
|
+
message.to_s.should match(/^REDIRECT rtsp/)
|
314
|
+
message.to_s.should include "REDIRECT rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
315
|
+
message.to_s.should include "CSeq: 732\r\n"
|
316
|
+
message.to_s.should include "Location: rtsp://bigserver.com:8001\r\n"
|
317
|
+
message.to_s.should include "Range: clock=19960213T143205Z-\r\n"
|
318
|
+
message.to_s.should match(/\r\n\r\n/)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
context "builds a RECORD string" do
|
323
|
+
it "with required Request values" do
|
324
|
+
message = RTSP::Message.record(stream)
|
325
|
+
|
326
|
+
message.to_s.should match(/^RECORD rtsp/)
|
327
|
+
message.to_s.should include "RECORD rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
328
|
+
message.to_s.should include "CSeq: 1\r\n"
|
329
|
+
message.to_s.should match(/\r\n\r\n/)
|
330
|
+
end
|
331
|
+
|
332
|
+
it "with cseq, session, and conference headers" do
|
333
|
+
message = RTSP::Message.record(stream).with_headers({
|
334
|
+
cseq: 954,
|
335
|
+
session: 12345678,
|
336
|
+
conference: "128.16.64.19/32492374" })
|
337
|
+
|
338
|
+
message.to_s.should match(/^RECORD rtsp/)
|
339
|
+
message.to_s.should include "RECORD rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
|
340
|
+
message.to_s.should include "CSeq: 954\r\n"
|
341
|
+
message.to_s.should include "Session: 12345678\r\n"
|
342
|
+
message.to_s.should include "Conference: 128.16.64.19/32492374\r\n"
|
343
|
+
message.to_s.should match(/\r\n\r\n/)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
context "#to_s turns a Hash into an String of header strings" do
|
348
|
+
it "single header, non-hyphenated name, hash value" do
|
349
|
+
message = RTSP::Message.play(stream).with_headers({
|
350
|
+
range: { npt: "0.000-" }
|
351
|
+
})
|
352
|
+
|
353
|
+
string = message.to_s
|
354
|
+
string.is_a?(String).should be_true
|
355
|
+
string.should include "Range: npt=0.000-"
|
356
|
+
end
|
357
|
+
|
358
|
+
it "single header, hyphenated, non-hash value" do
|
359
|
+
message = RTSP::Message.play(stream).with_headers({
|
360
|
+
:if_modified_since => "Sat, 29 Oct 1994 19:43:31 GMT"
|
361
|
+
})
|
362
|
+
|
363
|
+
string = message.to_s
|
364
|
+
string.is_a?(String).should be_true
|
365
|
+
string.should include "If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT"
|
366
|
+
end
|
367
|
+
|
368
|
+
it "two headers, mixed hyphenated, array & hash values" do
|
369
|
+
message = RTSP::Message.redirect(stream).with_headers({
|
370
|
+
:cache_control => ["no-cache", { :max_age => 12345 }],
|
371
|
+
:content_type => ['application/sdp', 'application/x-rtsp-mh']
|
372
|
+
})
|
373
|
+
|
374
|
+
string = message.to_s
|
375
|
+
string.is_a?(String).should be_true
|
376
|
+
string.should include "Cache-Control: no-cache;max_age=12345"
|
377
|
+
string.should include "Content-Type: application/sdp, application/x-rtsp-mh"
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
describe "#with_headers" do
|
382
|
+
it "returns an RTSP::Message" do
|
383
|
+
message = RTSP::Message.options(stream)
|
384
|
+
result = message.with_headers({ test: "test" })
|
385
|
+
result.class.should == RTSP::Message
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
describe "#with_body" do
|
390
|
+
it "adds the passed-in text to the body of the message" do
|
391
|
+
new_body = "1234567890"
|
392
|
+
message = RTSP::Message.record("rtsp://localhost/track").with_body(new_body)
|
393
|
+
message.to_s.should match(/\r\n\r\n#{new_body}$/)
|
394
|
+
end
|
395
|
+
|
396
|
+
it "adds the Content-Length header to reflect the body" do
|
397
|
+
new_body = "1234567890"
|
398
|
+
message = RTSP::Message.record("rtsp://localhost/track").with_body(new_body)
|
399
|
+
message.to_s.should match(/Content-Length: #{new_body.size}\r\n/)
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
describe "#respond_to?" do
|
404
|
+
it "returns true to each method in the list of supported method types" do
|
405
|
+
RTSP::Message.instance_variable_get(:@message_types).each do |m|
|
406
|
+
RTSP::Message.respond_to?(m).should be_true
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
it "returns false to a method that's not in the list of supported methods" do
|
411
|
+
RTSP::Message.respond_to?(:meow).should be_false
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
describe "#method_missing" do
|
416
|
+
it "returns " do
|
417
|
+
lambda { RTSP::Message.meow }.should raise_error NoMethodError
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|