1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// Special objects which, when created, sends a custom RTSP "REGISTER" (or "DEREGISTER") command
19// to a specified client.
20// Implementation
21
22#include "RTSPRegisterSender.hh"
23#include <GroupsockHelper.hh> // for MAKE_SOCKADDR_IN
24
25////////// RTSPRegisterOrDeregisterSender implementation /////////
26
27RTSPRegisterOrDeregisterSender
28::RTSPRegisterOrDeregisterSender(UsageEnvironment& env,
29 char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum,
30 Authenticator* authenticator,
31 int verbosityLevel, char const* applicationName)
32 : RTSPClient(env, NULL, verbosityLevel, applicationName, 0, -1),
33 fRemoteClientPortNum(remoteClientPortNum) {
34 // Set up a connection to the remote client. To do this, we create a fake "rtsp://" URL for it:
35 char const* fakeRTSPURLFmt = "rtsp://%s:%u/";
36 unsigned fakeRTSPURLSize = strlen(fakeRTSPURLFmt) + strlen(remoteClientNameOrAddress) + 5/* max port num len */;
37 char* fakeRTSPURL = new char[fakeRTSPURLSize];
38 sprintf(fakeRTSPURL, fakeRTSPURLFmt, remoteClientNameOrAddress, remoteClientPortNum);
39 setBaseURL(fakeRTSPURL);
40 delete[] fakeRTSPURL;
41
42 if (authenticator != NULL) fCurrentAuthenticator = *authenticator;
43}
44
45RTSPRegisterOrDeregisterSender::~RTSPRegisterOrDeregisterSender() {
46}
47
48RTSPRegisterOrDeregisterSender::RequestRecord_REGISTER_or_DEREGISTER
49::RequestRecord_REGISTER_or_DEREGISTER(unsigned cseq, char const* cmdName,
50 RTSPClient::responseHandler* rtspResponseHandler,
51 char const* rtspURLToRegisterOrDeregister,
52 char const* proxyURLSuffix)
53 : RTSPClient::RequestRecord(cseq, cmdName, rtspResponseHandler),
54 fRTSPURLToRegisterOrDeregister(strDup(rtspURLToRegisterOrDeregister)),
55 fProxyURLSuffix(strDup(proxyURLSuffix)) {
56}
57
58RTSPRegisterOrDeregisterSender::RequestRecord_REGISTER_or_DEREGISTER
59::~RequestRecord_REGISTER_or_DEREGISTER() {
60 delete[] fRTSPURLToRegisterOrDeregister;
61 delete[] fProxyURLSuffix;
62}
63
64
65////////// RTSPRegisterSender implementation /////////
66
67RTSPRegisterSender* RTSPRegisterSender
68::createNew(UsageEnvironment& env,
69 char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum, char const* rtspURLToRegister,
70 RTSPClient::responseHandler* rtspResponseHandler, Authenticator* authenticator,
71 Boolean requestStreamingViaTCP, char const* proxyURLSuffix, Boolean reuseConnection,
72 int verbosityLevel, char const* applicationName) {
73 return new RTSPRegisterSender(env, remoteClientNameOrAddress, remoteClientPortNum, rtspURLToRegister,
74 rtspResponseHandler, authenticator,
75 requestStreamingViaTCP, proxyURLSuffix, reuseConnection,
76 verbosityLevel, applicationName);
77}
78
79void RTSPRegisterSender::grabConnection(int& sock, struct sockaddr_in& remoteAddress) {
80 sock = grabSocket();
81
82 MAKE_SOCKADDR_IN(remoteAddr, fServerAddress, htons(fRemoteClientPortNum));
83 remoteAddress = remoteAddr;
84}
85
86RTSPRegisterSender
87::RTSPRegisterSender(UsageEnvironment& env,
88 char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum, char const* rtspURLToRegister,
89 RTSPClient::responseHandler* rtspResponseHandler, Authenticator* authenticator,
90 Boolean requestStreamingViaTCP, char const* proxyURLSuffix, Boolean reuseConnection,
91 int verbosityLevel, char const* applicationName)
92 : RTSPRegisterOrDeregisterSender(env, remoteClientNameOrAddress, remoteClientPortNum, authenticator, verbosityLevel, applicationName) {
93 // Send the "REGISTER" request:
94 (void)sendRequest(new RequestRecord_REGISTER(++fCSeq, rtspResponseHandler,
95 rtspURLToRegister, reuseConnection, requestStreamingViaTCP, proxyURLSuffix));
96}
97
98RTSPRegisterSender::~RTSPRegisterSender() {
99}
100
101Boolean RTSPRegisterSender::setRequestFields(RequestRecord* request,
102 char*& cmdURL, Boolean& cmdURLWasAllocated,
103 char const*& protocolStr,
104 char*& extraHeaders, Boolean& extraHeadersWereAllocated) {
105 if (strcmp(request->commandName(), "REGISTER") == 0) {
106 RequestRecord_REGISTER* request_REGISTER = (RequestRecord_REGISTER*)request;
107
108 setBaseURL(request_REGISTER->rtspURLToRegister());
109 cmdURL = (char*)url();
110 cmdURLWasAllocated = False;
111
112 // Generate the "Transport:" header that will contain our REGISTER-specific parameters. This will be "extraHeaders".
113 // First, generate the "proxy_url_suffix" parameter string, if any:
114 char* proxyURLSuffixParameterStr;
115 if (request_REGISTER->proxyURLSuffix() == NULL) {
116 proxyURLSuffixParameterStr = strDup("");
117 } else {
118 char const* proxyURLSuffixParameterFmt = "; proxy_url_suffix=%s";
119 unsigned proxyURLSuffixParameterSize = strlen(proxyURLSuffixParameterFmt)
120 + strlen(request_REGISTER->proxyURLSuffix());
121 proxyURLSuffixParameterStr = new char[proxyURLSuffixParameterSize];
122 sprintf(proxyURLSuffixParameterStr, proxyURLSuffixParameterFmt, request_REGISTER->proxyURLSuffix());
123 }
124
125 char const* transportHeaderFmt = "Transport: %spreferred_delivery_protocol=%s%s\r\n";
126 unsigned transportHeaderSize = strlen(transportHeaderFmt) + 100/*conservative*/ + strlen(proxyURLSuffixParameterStr);
127 char* transportHeaderStr = new char[transportHeaderSize];
128 sprintf(transportHeaderStr, transportHeaderFmt,
129 request_REGISTER->reuseConnection() ? "reuse_connection; " : "",
130 request_REGISTER->requestStreamingViaTCP() ? "interleaved" : "udp",
131 proxyURLSuffixParameterStr);
132 delete[] proxyURLSuffixParameterStr;
133
134 extraHeaders = transportHeaderStr;
135 extraHeadersWereAllocated = True;
136
137 return True;
138 } else {
139 return RTSPClient::setRequestFields(request, cmdURL, cmdURLWasAllocated, protocolStr, extraHeaders, extraHeadersWereAllocated);
140 }
141}
142
143RTSPRegisterSender::RequestRecord_REGISTER
144::RequestRecord_REGISTER(unsigned cseq, RTSPClient::responseHandler* rtspResponseHandler, char const* rtspURLToRegister,
145 Boolean reuseConnection, Boolean requestStreamingViaTCP, char const* proxyURLSuffix)
146 : RTSPRegisterOrDeregisterSender::RequestRecord_REGISTER_or_DEREGISTER(cseq, "REGISTER", rtspResponseHandler, rtspURLToRegister, proxyURLSuffix),
147 fReuseConnection(reuseConnection), fRequestStreamingViaTCP(requestStreamingViaTCP) {
148}
149
150RTSPRegisterSender::RequestRecord_REGISTER::~RequestRecord_REGISTER() {
151}
152
153
154////////// RTSPDeregisterSender implementation /////////
155
156RTSPDeregisterSender* RTSPDeregisterSender
157::createNew(UsageEnvironment& env,
158 char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum, char const* rtspURLToDeregister,
159 RTSPClient::responseHandler* rtspResponseHandler, Authenticator* authenticator,
160 char const* proxyURLSuffix, int verbosityLevel, char const* applicationName) {
161 return new RTSPDeregisterSender(env, remoteClientNameOrAddress, remoteClientPortNum, rtspURLToDeregister,
162 rtspResponseHandler, authenticator,
163 proxyURLSuffix, verbosityLevel, applicationName);
164}
165
166RTSPDeregisterSender
167::RTSPDeregisterSender(UsageEnvironment& env,
168 char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum, char const* rtspURLToDeregister,
169 RTSPClient::responseHandler* rtspResponseHandler, Authenticator* authenticator,
170 char const* proxyURLSuffix,
171 int verbosityLevel, char const* applicationName)
172 : RTSPRegisterOrDeregisterSender(env, remoteClientNameOrAddress, remoteClientPortNum, authenticator, verbosityLevel, applicationName) {
173 // Send the "DEREGISTER" request:
174 (void)sendRequest(new RequestRecord_DEREGISTER(++fCSeq, rtspResponseHandler,
175 rtspURLToDeregister, proxyURLSuffix));
176}
177
178RTSPDeregisterSender::~RTSPDeregisterSender() {
179}
180
181Boolean RTSPDeregisterSender::setRequestFields(RequestRecord* request,
182 char*& cmdURL, Boolean& cmdURLWasAllocated,
183 char const*& protocolStr,
184 char*& extraHeaders, Boolean& extraHeadersWereAllocated) {
185 if (strcmp(request->commandName(), "DEREGISTER") == 0) {
186 RequestRecord_DEREGISTER* request_DEREGISTER = (RequestRecord_DEREGISTER*)request;
187
188 setBaseURL(request_DEREGISTER->rtspURLToDeregister());
189 cmdURL = (char*)url();
190 cmdURLWasAllocated = False;
191
192 // Generate the "Transport:" header that will contain our DEREGISTER-specific parameters. This will be "extraHeaders".
193 // First, generate the "proxy_url_suffix" parameter string, if any:
194 char* proxyURLSuffixParameterStr;
195 if (request_DEREGISTER->proxyURLSuffix() == NULL) {
196 proxyURLSuffixParameterStr = strDup("");
197 } else {
198 char const* proxyURLSuffixParameterFmt = "proxy_url_suffix=%s";
199 unsigned proxyURLSuffixParameterSize = strlen(proxyURLSuffixParameterFmt)
200 + strlen(request_DEREGISTER->proxyURLSuffix());
201 proxyURLSuffixParameterStr = new char[proxyURLSuffixParameterSize];
202 sprintf(proxyURLSuffixParameterStr, proxyURLSuffixParameterFmt, request_DEREGISTER->proxyURLSuffix());
203 }
204
205 char const* transportHeaderFmt = "Transport: %s\r\n";
206 unsigned transportHeaderSize = strlen(transportHeaderFmt) + strlen(proxyURLSuffixParameterStr);
207 char* transportHeaderStr = new char[transportHeaderSize];
208 sprintf(transportHeaderStr, transportHeaderFmt,
209 proxyURLSuffixParameterStr);
210 delete[] proxyURLSuffixParameterStr;
211
212 extraHeaders = transportHeaderStr;
213 extraHeadersWereAllocated = True;
214
215 return True;
216 } else {
217 return RTSPClient::setRequestFields(request, cmdURL, cmdURLWasAllocated, protocolStr, extraHeaders, extraHeadersWereAllocated);
218 }
219}
220
221RTSPDeregisterSender::RequestRecord_DEREGISTER
222::RequestRecord_DEREGISTER(unsigned cseq, RTSPClient::responseHandler* rtspResponseHandler, char const* rtspURLToDeregister,
223 char const* proxyURLSuffix)
224 : RTSPRegisterOrDeregisterSender::RequestRecord_REGISTER_or_DEREGISTER(cseq, "DEREGISTER", rtspResponseHandler, rtspURLToDeregister, proxyURLSuffix) {
225}
226
227RTSPDeregisterSender::RequestRecord_DEREGISTER::~RequestRecord_DEREGISTER() {
228}
229