| 1 | /********** |
| 2 | This library is free software; you can redistribute it and/or modify it under |
| 3 | the terms of the GNU Lesser General Public License as published by the |
| 4 | Free Software Foundation; either version 3 of the License, or (at your |
| 5 | option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) |
| 6 | |
| 7 | This library is distributed in the hope that it will be useful, but WITHOUT |
| 8 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 9 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for |
| 10 | more details. |
| 11 | |
| 12 | You should have received a copy of the GNU Lesser General Public License |
| 13 | along with this library; if not, write to the Free Software Foundation, Inc., |
| 14 | 51 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 | |
| 27 | RTSPRegisterOrDeregisterSender |
| 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 | |
| 45 | RTSPRegisterOrDeregisterSender::~RTSPRegisterOrDeregisterSender() { |
| 46 | } |
| 47 | |
| 48 | RTSPRegisterOrDeregisterSender::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 | |
| 58 | RTSPRegisterOrDeregisterSender::RequestRecord_REGISTER_or_DEREGISTER |
| 59 | ::~RequestRecord_REGISTER_or_DEREGISTER() { |
| 60 | delete[] fRTSPURLToRegisterOrDeregister; |
| 61 | delete[] fProxyURLSuffix; |
| 62 | } |
| 63 | |
| 64 | |
| 65 | ////////// RTSPRegisterSender implementation ///////// |
| 66 | |
| 67 | RTSPRegisterSender* 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 | |
| 79 | void 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 | |
| 86 | RTSPRegisterSender |
| 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 | |
| 98 | RTSPRegisterSender::~RTSPRegisterSender() { |
| 99 | } |
| 100 | |
| 101 | Boolean RTSPRegisterSender::setRequestFields(RequestRecord* request, |
| 102 | char*& cmdURL, Boolean& cmdURLWasAllocated, |
| 103 | char const*& protocolStr, |
| 104 | char*& , Boolean& ) { |
| 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* = "Transport: %spreferred_delivery_protocol=%s%s\r\n" ; |
| 126 | unsigned = strlen(transportHeaderFmt) + 100/*conservative*/ + strlen(proxyURLSuffixParameterStr); |
| 127 | char* = 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 | |
| 143 | RTSPRegisterSender::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 | |
| 150 | RTSPRegisterSender::RequestRecord_REGISTER::~RequestRecord_REGISTER() { |
| 151 | } |
| 152 | |
| 153 | |
| 154 | ////////// RTSPDeregisterSender implementation ///////// |
| 155 | |
| 156 | RTSPDeregisterSender* 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 | |
| 166 | RTSPDeregisterSender |
| 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 | |
| 178 | RTSPDeregisterSender::~RTSPDeregisterSender() { |
| 179 | } |
| 180 | |
| 181 | Boolean RTSPDeregisterSender::setRequestFields(RequestRecord* request, |
| 182 | char*& cmdURL, Boolean& cmdURLWasAllocated, |
| 183 | char const*& protocolStr, |
| 184 | char*& , Boolean& ) { |
| 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* = "Transport: %s\r\n" ; |
| 206 | unsigned = strlen(transportHeaderFmt) + strlen(proxyURLSuffixParameterStr); |
| 207 | char* = 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 | |
| 221 | RTSPDeregisterSender::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 | |
| 227 | RTSPDeregisterSender::RequestRecord_DEREGISTER::~RequestRecord_DEREGISTER() { |
| 228 | } |
| 229 | |