RTSPServer::RTSPClientConnection Class Reference

#include <RTSPServer.hh>

Inheritance diagram for RTSPServer::RTSPClientConnection:

Inheritance graph
[legend]
Collaboration diagram for RTSPServer::RTSPClientConnection:

Collaboration graph
[legend]

Public Member Functions

 RTSPClientConnection (RTSPServer &ourServer, int clientSocket, struct sockaddr_in clientAddr)
virtual ~RTSPClientConnection ()

Protected Member Functions

virtual void handleCmd_OPTIONS ()
virtual void handleCmd_GET_PARAMETER (char const *fullRequestStr)
virtual void handleCmd_SET_PARAMETER (char const *fullRequestStr)
virtual void handleCmd_DESCRIBE (char const *urlPreSuffix, char const *urlSuffix, char const *fullRequestStr)
virtual void handleCmd_REGISTER (char const *url, char const *urlSuffix, Boolean registerRemote)
virtual void handleCmd_bad ()
virtual void handleCmd_notSupported ()
virtual void handleCmd_notFound ()
virtual void handleCmd_sessionNotFound ()
virtual void handleCmd_unsupportedTransport ()
virtual Boolean parseHTTPRequestString (char *resultCmdName, unsigned resultCmdNameMaxSize, char *urlSuffix, unsigned urlSuffixMaxSize, char *sessionCookie, unsigned sessionCookieMaxSize, char *acceptStr, unsigned acceptStrMaxSize)
virtual void handleHTTPCmd_notSupported ()
virtual void handleHTTPCmd_notFound ()
virtual void handleHTTPCmd_TunnelingGET (char const *sessionCookie)
virtual Boolean handleHTTPCmd_TunnelingPOST (char const *sessionCookie, unsigned char const *extraData, unsigned extraDataSize)
virtual void handleHTTPCmd_StreamingGET (char const *urlSuffix, char const *fullRequestStr)
UsageEnvironmentenvir ()
void resetRequestBuffer ()
void closeSockets ()
void incomingRequestHandler1 ()
void handleAlternativeRequestByte1 (u_int8_t requestByte)
void handleRequestBytes (int newBytesRead)
Boolean authenticationOK (char const *cmdName, char const *urlSuffix, char const *fullRequestStr)
void changeClientInputSocket (int newSocketNum, unsigned char const *extraData, unsigned extraDataSize)
virtual void continueHandlingREGISTER1 (ParamsForREGISTER *params)
void setRTSPResponse (char const *responseStr)
void setRTSPResponse (char const *responseStr, u_int32_t sessionId)
void setRTSPResponse (char const *responseStr, char const *contentStr)
void setRTSPResponse (char const *responseStr, u_int32_t sessionId, char const *contentStr)

Static Protected Member Functions

static void incomingRequestHandler (void *, int)
static void handleAlternativeRequestByte (void *, u_int8_t requestByte)
static void continueHandlingREGISTER (ParamsForREGISTER *params)

Protected Attributes

RTSPServerfOurServer
Boolean fIsActive
int fClientInputSocket
int fClientOutputSocket
sockaddr_in fClientAddr
unsigned char fRequestBuffer [RTSP_BUFFER_SIZE]
unsigned fRequestBytesAlreadySeen
unsigned fRequestBufferBytesLeft
unsigned char * fLastCRLF
unsigned char fResponseBuffer [RTSP_BUFFER_SIZE]
unsigned fRecursionCount
char const * fCurrentCSeq
Authenticator fCurrentAuthenticator
char * fOurSessionCookie
unsigned fBase64RemainderCount

Friends

class RTSPClientSession

Data Structures

class  ParamsForREGISTER

Detailed Description

Definition at line 169 of file RTSPServer.hh.


Constructor & Destructor Documentation

RTSPServer::RTSPClientConnection::RTSPClientConnection ( RTSPServer ourServer,
int  clientSocket,
struct sockaddr_in  clientAddr 
)

Definition at line 418 of file RTSPServer.cpp.

References HashTable::Add(), envir(), RTSPServer::fClientConnections, fClientInputSocket, fOurServer, incomingRequestHandler(), resetRequestBuffer(), TaskScheduler::setBackgroundHandling(), SOCKET_EXCEPTION, SOCKET_READABLE, and UsageEnvironment::taskScheduler().

00419   : fOurServer(ourServer), fIsActive(True),
00420     fClientInputSocket(clientSocket), fClientOutputSocket(clientSocket), fClientAddr(clientAddr),
00421     fRecursionCount(0), fOurSessionCookie(NULL) {
00422   // Add ourself to our 'client connections' table:
00423   fOurServer.fClientConnections->Add((char const*)this, this);
00424 
00425   // Arrange to handle incoming requests:
00426   resetRequestBuffer();
00427   envir().taskScheduler().setBackgroundHandling(fClientInputSocket, SOCKET_READABLE|SOCKET_EXCEPTION,
00428                                                 (TaskScheduler::BackgroundHandlerProc*)&incomingRequestHandler, this);
00429 }

RTSPServer::RTSPClientConnection::~RTSPClientConnection (  )  [virtual]

Definition at line 431 of file RTSPServer.cpp.

References closeSockets(), RTSPServer::fClientConnections, RTSPServer::fClientConnectionsForHTTPTunneling, fOurServer, fOurSessionCookie, NULL, and HashTable::Remove().

00431                                                       {
00432   // Remove ourself from the server's 'client connections' hash table before we go:
00433   fOurServer.fClientConnections->Remove((char const*)this);
00434 
00435   if (fOurSessionCookie != NULL) {
00436     // We were being used for RTSP-over-HTTP tunneling. Also remove ourselves from the 'session cookie' hash table before we go:
00437     fOurServer.fClientConnectionsForHTTPTunneling->Remove(fOurSessionCookie);
00438     delete[] fOurSessionCookie;
00439   }
00440 
00441   closeSockets();
00442 }


Member Function Documentation

void RTSPServer::RTSPClientConnection::handleCmd_OPTIONS (  )  [protected, virtual]

Definition at line 457 of file RTSPServer.cpp.

References RTSPServer::allowedCommandNames(), dateHeader(), fCurrentCSeq, fOurServer, and fResponseBuffer.

Referenced by handleRequestBytes().

00457                                                        {
00458   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
00459            "RTSP/1.0 200 OK\r\nCSeq: %s\r\n%sPublic: %s\r\n\r\n",
00460            fCurrentCSeq, dateHeader(), fOurServer.allowedCommandNames());
00461 }

void RTSPServer::RTSPClientConnection::handleCmd_GET_PARAMETER ( char const *  fullRequestStr  )  [protected, virtual]

Definition at line 464 of file RTSPServer.cpp.

References LIVEMEDIA_LIBRARY_VERSION_STRING.

Referenced by handleRequestBytes().

00464                                                         {
00465   // By default, we implement "GET_PARAMETER" (on the entire server) just as a 'no op', and send back a dummy response.
00466   // (If you want to handle this type of "GET_PARAMETER" differently, you can do so by defining a subclass of "RTSPServer"
00467   // and "RTSPServer::RTSPClientConnection", and then reimplement this virtual function in your subclass.)
00468   setRTSPResponse("200 OK", LIVEMEDIA_LIBRARY_VERSION_STRING);
00469 }

void RTSPServer::RTSPClientConnection::handleCmd_SET_PARAMETER ( char const *  fullRequestStr  )  [protected, virtual]

Definition at line 472 of file RTSPServer.cpp.

Referenced by handleRequestBytes().

00472                                                         {
00473   // By default, we implement "SET_PARAMETER" (on the entire server) just as a 'no op', and send back an empty response.
00474   // (If you want to handle this type of "SET_PARAMETER" differently, you can do so by defining a subclass of "RTSPServer"
00475   // and "RTSPServer::RTSPClientConnection", and then reimplement this virtual function in your subclass.)
00476   setRTSPResponse("200 OK");
00477 }

void RTSPServer::RTSPClientConnection::handleCmd_DESCRIBE ( char const *  urlPreSuffix,
char const *  urlSuffix,
char const *  fullRequestStr 
) [protected, virtual]

Definition at line 480 of file RTSPServer.cpp.

References dateHeader(), NULL, RTSP_PARAM_STRING_MAX, RTSPServer::rtspURL(), and session.

Referenced by handleRequestBytes().

00480                                                                                                 {
00481   char* sdpDescription = NULL;
00482   char* rtspURL = NULL;
00483   do {
00484     char urlTotalSuffix[RTSP_PARAM_STRING_MAX];
00485     if (strlen(urlPreSuffix) + strlen(urlSuffix) + 2 > sizeof urlTotalSuffix) {
00486       handleCmd_bad();
00487       break;
00488     }
00489     urlTotalSuffix[0] = '\0';
00490     if (urlPreSuffix[0] != '\0') {
00491       strcat(urlTotalSuffix, urlPreSuffix);
00492       strcat(urlTotalSuffix, "/");
00493     }
00494     strcat(urlTotalSuffix, urlSuffix);
00495       
00496     if (!authenticationOK("DESCRIBE", urlTotalSuffix, fullRequestStr)) break;
00497     
00498     // We should really check that the request contains an "Accept:" #####
00499     // for "application/sdp", because that's what we're sending back #####
00500     
00501     // Begin by looking up the "ServerMediaSession" object for the specified "urlTotalSuffix":
00502     ServerMediaSession* session = fOurServer.lookupServerMediaSession(urlTotalSuffix);
00503     if (session == NULL) {
00504       handleCmd_notFound();
00505       break;
00506     }
00507     
00508     // Then, assemble a SDP description for this session:
00509     sdpDescription = session->generateSDPDescription();
00510     if (sdpDescription == NULL) {
00511       // This usually means that a file name that was specified for a
00512       // "ServerMediaSubsession" does not exist.
00513       setRTSPResponse("404 File Not Found, Or In Incorrect Format");
00514       break;
00515     }
00516     unsigned sdpDescriptionSize = strlen(sdpDescription);
00517     
00518     // Also, generate our RTSP URL, for the "Content-Base:" header
00519     // (which is necessary to ensure that the correct URL gets used in subsequent "SETUP" requests).
00520     rtspURL = fOurServer.rtspURL(session, fClientInputSocket);
00521     
00522     snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
00523              "RTSP/1.0 200 OK\r\nCSeq: %s\r\n"
00524              "%s"
00525              "Content-Base: %s/\r\n"
00526              "Content-Type: application/sdp\r\n"
00527              "Content-Length: %d\r\n\r\n"
00528              "%s",
00529              fCurrentCSeq,
00530              dateHeader(),
00531              rtspURL,
00532              sdpDescriptionSize,
00533              sdpDescription);
00534   } while (0);
00535 
00536   delete[] sdpDescription;
00537   delete[] rtspURL;
00538 }

void RTSPServer::RTSPClientConnection::handleCmd_REGISTER ( char const *  url,
char const *  urlSuffix,
Boolean  registerRemote 
) [protected, virtual]

Definition at line 562 of file RTSPServer.cpp.

References continueHandlingREGISTER(), envir(), fOurServer, handleCmd_notSupported(), TaskScheduler::scheduleDelayedTask(), setRTSPResponse(), UsageEnvironment::taskScheduler(), and RTSPServer::weImplementREGISTER().

Referenced by handleRequestBytes().

00562                                                                                                                       {
00563   if (fOurServer.weImplementREGISTER()) {
00564     // We implement the "REGISTER" command by first replying to it, then actually handling it
00565     // (in a separate event-loop task, that will get called after the reply has been done):
00566     setRTSPResponse("200 OK");
00567 
00568     ParamsForREGISTER* registerParams = new ParamsForREGISTER(this, url, urlSuffix, registerRemote);
00569     envir().taskScheduler().scheduleDelayedTask(0, (TaskFunc*)continueHandlingREGISTER, registerParams);
00570   } else {
00571     handleCmd_notSupported();
00572   }
00573 }

void RTSPServer::RTSPClientConnection::handleCmd_bad (  )  [protected, virtual]

Definition at line 575 of file RTSPServer.cpp.

References RTSPServer::allowedCommandNames(), dateHeader(), fOurServer, and fResponseBuffer.

Referenced by RTSPServer::RTSPClientSession::handleCmd_SETUP(), and handleRequestBytes().

00575                                                    {
00576   // Don't do anything with "fCurrentCSeq", because it might be nonsense
00577   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
00578            "RTSP/1.0 400 Bad Request\r\n%sAllow: %s\r\n\r\n",
00579            dateHeader(), fOurServer.allowedCommandNames());
00580 }

void RTSPServer::RTSPClientConnection::handleCmd_notSupported (  )  [protected, virtual]

Definition at line 582 of file RTSPServer.cpp.

References RTSPServer::allowedCommandNames(), dateHeader(), fCurrentCSeq, fOurServer, and fResponseBuffer.

Referenced by handleCmd_REGISTER(), RTSPServer::RTSPClientSession::handleCmd_withinSession(), and handleRequestBytes().

00582                                                             {
00583   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
00584            "RTSP/1.0 405 Method Not Allowed\r\nCSeq: %s\r\n%sAllow: %s\r\n\r\n",
00585            fCurrentCSeq, dateHeader(), fOurServer.allowedCommandNames());
00586 }

void RTSPServer::RTSPClientConnection::handleCmd_notFound (  )  [protected, virtual]

Definition at line 588 of file RTSPServer.cpp.

References setRTSPResponse().

Referenced by RTSPServer::RTSPClientSession::handleCmd_SETUP(), and RTSPServer::RTSPClientSession::handleCmd_withinSession().

00588                                                         {
00589   setRTSPResponse("404 Stream Not Found");
00590 }

void RTSPServer::RTSPClientConnection::handleCmd_sessionNotFound (  )  [protected, virtual]

Definition at line 592 of file RTSPServer.cpp.

References setRTSPResponse().

Referenced by handleRequestBytes().

00592                                                                {
00593   setRTSPResponse("454 Session Not Found");
00594 }

void RTSPServer::RTSPClientConnection::handleCmd_unsupportedTransport (  )  [protected, virtual]

Definition at line 596 of file RTSPServer.cpp.

References setRTSPResponse().

Referenced by RTSPServer::RTSPClientSession::handleCmd_SETUP().

00596                                                                     {
00597   setRTSPResponse("461 Unsupported Transport");
00598 }

Boolean RTSPServer::RTSPClientConnection::parseHTTPRequestString ( char *  resultCmdName,
unsigned  resultCmdNameMaxSize,
char *  urlSuffix,
unsigned  urlSuffixMaxSize,
char *  sessionCookie,
unsigned  sessionCookieMaxSize,
char *  acceptStr,
unsigned  acceptStrMaxSize 
) [protected, virtual]

Definition at line 600 of file RTSPServer.cpp.

References False, fRequestBuffer, fRequestBytesAlreadySeen, lookForHeader(), and True.

Referenced by handleRequestBytes().

00603                                                                                                              {
00604   // Check for the limited HTTP requests that we expect for specifying RTSP-over-HTTP tunneling.
00605   // This parser is currently rather dumb; it should be made smarter #####
00606   char const* reqStr = (char const*)fRequestBuffer;
00607   unsigned const reqStrSize = fRequestBytesAlreadySeen;
00608 
00609   // Read everything up to the first space as the command name:
00610   Boolean parseSucceeded = False;
00611   unsigned i;
00612   for (i = 0; i < resultCmdNameMaxSize-1 && i < reqStrSize; ++i) {
00613     char c = reqStr[i];
00614     if (c == ' ' || c == '\t') {
00615       parseSucceeded = True;
00616       break;
00617     }
00618 
00619     resultCmdName[i] = c;
00620   }
00621   resultCmdName[i] = '\0';
00622   if (!parseSucceeded) return False;
00623 
00624   // Look for the string "HTTP/", before the first \r or \n:
00625   parseSucceeded = False;
00626   for (; i < reqStrSize-5 && reqStr[i] != '\r' && reqStr[i] != '\n'; ++i) {
00627     if (reqStr[i] == 'H' && reqStr[i+1] == 'T' && reqStr[i+2]== 'T' && reqStr[i+3]== 'P' && reqStr[i+4]== '/') {
00628       i += 5; // to advance past the "HTTP/"
00629       parseSucceeded = True;
00630       break;
00631     }
00632   }
00633   if (!parseSucceeded) return False;
00634 
00635   // Get the 'URL suffix' that occurred before this:
00636   unsigned k = i-6;
00637   while (k > 0 && reqStr[k] == ' ') --k; // back up over white space
00638   unsigned j = k;
00639   while (j > 0 && reqStr[j] != ' ' && reqStr[j] != '/') --j;
00640   // The URL suffix is in position (j,k]:
00641   if (k - j + 1 > urlSuffixMaxSize) return False; // there's no room> 
00642   unsigned n = 0;
00643   while (++j <= k) urlSuffix[n++] = reqStr[j];
00644   urlSuffix[n] = '\0';
00645 
00646   // Look for various headers that we're interested in:
00647   lookForHeader("x-sessioncookie", &reqStr[i], reqStrSize-i, sessionCookie, sessionCookieMaxSize);
00648   lookForHeader("Accept", &reqStr[i], reqStrSize-i, acceptStr, acceptStrMaxSize);
00649 
00650   return True;
00651 }

void RTSPServer::RTSPClientConnection::handleHTTPCmd_notSupported (  )  [protected, virtual]

Definition at line 653 of file RTSPServer.cpp.

References dateHeader(), and fResponseBuffer.

Referenced by handleHTTPCmd_StreamingGET(), and handleRequestBytes().

00653                                                                 {
00654   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
00655            "HTTP/1.0 405 Method Not Allowed\r\n%s\r\n\r\n",
00656            dateHeader());
00657 }

void RTSPServer::RTSPClientConnection::handleHTTPCmd_notFound (  )  [protected, virtual]

Definition at line 659 of file RTSPServer.cpp.

References dateHeader(), and fResponseBuffer.

00659                                                             {
00660   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
00661            "HTTP/1.0 404 Not Found\r\n%s\r\n\r\n",
00662            dateHeader());
00663 }

void RTSPServer::RTSPClientConnection::handleHTTPCmd_TunnelingGET ( char const *  sessionCookie  )  [protected, virtual]

Definition at line 665 of file RTSPServer.cpp.

References HashTable::Add(), HashTable::create(), RTSPServer::fClientConnectionsForHTTPTunneling, fClientOutputSocket, fOurServer, fOurSessionCookie, fResponseBuffer, NULL, strDup(), and STRING_HASH_KEYS.

Referenced by handleRequestBytes().

00665                                                                                          {
00666   // Record ourself as having this 'session cookie', so that a subsequent HTTP "POST" command (with the same 'session cookie')
00667   // can find us:
00668   if (fOurServer.fClientConnectionsForHTTPTunneling == NULL) {
00669     fOurServer.fClientConnectionsForHTTPTunneling = HashTable::create(STRING_HASH_KEYS);
00670   }
00671   delete[] fOurSessionCookie; fOurSessionCookie = strDup(sessionCookie);
00672   fOurServer.fClientConnectionsForHTTPTunneling->Add(sessionCookie, (void*)this);
00673 #ifdef DEBUG
00674   fprintf(stderr, "Handled HTTP \"GET\" request (client output socket: %d)\n", fClientOutputSocket);
00675 #endif
00676 
00677   // Construct our response:
00678   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
00679            "HTTP/1.0 200 OK\r\n"
00680            "Date: Thu, 19 Aug 1982 18:30:00 GMT\r\n"
00681            "Cache-Control: no-cache\r\n"
00682            "Pragma: no-cache\r\n"
00683            "Content-Type: application/x-rtsp-tunnelled\r\n"
00684            "\r\n");
00685 }

Boolean RTSPServer::RTSPClientConnection::handleHTTPCmd_TunnelingPOST ( char const *  sessionCookie,
unsigned char const *  extraData,
unsigned  extraDataSize 
) [protected, virtual]

Definition at line 688 of file RTSPServer.cpp.

References changeClientInputSocket(), HashTable::create(), False, NULL, STRING_HASH_KEYS, and True.

Referenced by handleRequestBytes().

00688                                                                                                                {
00689   // Use the "sessionCookie" string to look up the separate "RTSPClientConnection" object that should have been used to handle
00690   // an earlier HTTP "GET" request:
00691   if (fOurServer.fClientConnectionsForHTTPTunneling == NULL) {
00692     fOurServer.fClientConnectionsForHTTPTunneling = HashTable::create(STRING_HASH_KEYS);
00693   }
00694   RTSPServer::RTSPClientConnection* prevClientConnection
00695     = (RTSPServer::RTSPClientConnection*)(fOurServer.fClientConnectionsForHTTPTunneling->Lookup(sessionCookie));
00696   if (prevClientConnection == NULL) {
00697     // There was no previous HTTP "GET" request; treat this "POST" request as bad:
00698     handleHTTPCmd_notSupported();
00699     fIsActive = False; // triggers deletion of ourself
00700     return False;
00701   }
00702 #ifdef DEBUG
00703   fprintf(stderr, "Handled HTTP \"POST\" request (client input socket: %d)\n", fClientInputSocket);
00704 #endif
00705 
00706   // Change the previous "RTSPClientSession" object's input socket to ours.  It will be used for subsequent requests:
00707   prevClientConnection->changeClientInputSocket(fClientInputSocket, extraData, extraDataSize);
00708   fClientInputSocket = fClientOutputSocket = -1; // so the socket doesn't get closed when we get deleted
00709   return True;
00710 }

void RTSPServer::RTSPClientConnection::handleHTTPCmd_StreamingGET ( char const *  urlSuffix,
char const *  fullRequestStr 
) [protected, virtual]

Reimplemented in RTSPServerSupportingHTTPStreaming::RTSPClientConnectionSupportingHTTPStreaming.

Definition at line 712 of file RTSPServer.cpp.

References handleHTTPCmd_notSupported().

Referenced by handleRequestBytes().

00712                                                                                                                          {
00713   // By default, we don't support requests to access streams via HTTP:
00714   handleHTTPCmd_notSupported();
00715 }

UsageEnvironment& RTSPServer::RTSPClientConnection::envir (  )  [inline, protected]

Definition at line 213 of file RTSPServer.hh.

References Medium::envir(), and fOurServer.

Referenced by closeSockets(), handleAlternativeRequestByte1(), handleCmd_REGISTER(), incomingRequestHandler1(), and RTSPClientConnection().

00213 { return fOurServer.envir(); }

void RTSPServer::RTSPClientConnection::resetRequestBuffer (  )  [protected]

Definition at line 717 of file RTSPServer.cpp.

References fBase64RemainderCount, fLastCRLF, fRequestBuffer, fRequestBufferBytesLeft, and fRequestBytesAlreadySeen.

Referenced by handleRequestBytes(), and RTSPClientConnection().

00717                                                         {
00718   fRequestBytesAlreadySeen = 0;
00719   fRequestBufferBytesLeft = sizeof fRequestBuffer;
00720   fLastCRLF = &fRequestBuffer[-3]; // hack: Ensures that we don't think we have end-of-msg if the data starts with <CR><LF>
00721   fBase64RemainderCount = 0;
00722 }

void RTSPServer::RTSPClientConnection::closeSockets (  )  [protected]

Definition at line 724 of file RTSPServer.cpp.

References closeSocket, TaskScheduler::disableBackgroundHandling(), envir(), fClientInputSocket, fClientOutputSocket, and UsageEnvironment::taskScheduler().

Referenced by handleRequestBytes(), and ~RTSPClientConnection().

00724                                                   {
00725   // Turn off background handling on our input socket (and output socket, if different); then close it (or them):
00726   if (fClientOutputSocket != fClientInputSocket) {
00727     envir().taskScheduler().disableBackgroundHandling(fClientOutputSocket);
00728     ::closeSocket(fClientOutputSocket);
00729   }
00730 
00731   envir().taskScheduler().disableBackgroundHandling(fClientInputSocket);
00732   ::closeSocket(fClientInputSocket);
00733 
00734   fClientInputSocket = fClientOutputSocket = -1;
00735 }

void RTSPServer::RTSPClientConnection::incomingRequestHandler ( void *  ,
int   
) [static, protected]

Definition at line 737 of file RTSPServer.cpp.

References session.

Referenced by handleAlternativeRequestByte1(), and RTSPClientConnection().

00737                                                                                         {
00738   RTSPClientConnection* session = (RTSPClientConnection*)instance;
00739   session->incomingRequestHandler1();
00740 }

void RTSPServer::RTSPClientConnection::incomingRequestHandler1 (  )  [protected]

Definition at line 742 of file RTSPServer.cpp.

References envir(), fClientInputSocket, fRequestBuffer, fRequestBufferBytesLeft, fRequestBytesAlreadySeen, handleRequestBytes(), and readSocket().

00742                                                              {
00743   struct sockaddr_in dummy; // 'from' address, meaningless in this case
00744 
00745   int bytesRead = readSocket(envir(), fClientInputSocket, &fRequestBuffer[fRequestBytesAlreadySeen], fRequestBufferBytesLeft, dummy);
00746   handleRequestBytes(bytesRead);
00747 }

void RTSPServer::RTSPClientConnection::handleAlternativeRequestByte ( void *  ,
u_int8_t  requestByte 
) [static, protected]

Definition at line 749 of file RTSPServer.cpp.

References session.

Referenced by RTSPServer::RTSPClientSession::handleCmd_PLAY().

00749                                                                                                       {
00750   RTSPClientConnection* session = (RTSPClientConnection*)instance;
00751   session->handleAlternativeRequestByte1(requestByte);
00752 }

void RTSPServer::RTSPClientConnection::handleAlternativeRequestByte1 ( u_int8_t  requestByte  )  [protected]

Definition at line 754 of file RTSPServer.cpp.

References envir(), fClientInputSocket, fRequestBuffer, fRequestBufferBytesLeft, fRequestBytesAlreadySeen, handleRequestBytes(), incomingRequestHandler(), RTSP_BUFFER_SIZE, TaskScheduler::setBackgroundHandling(), SOCKET_EXCEPTION, SOCKET_READABLE, and UsageEnvironment::taskScheduler().

00754                                                                                        {
00755   if (requestByte == 0xFF) {
00756     // Hack: The new handler of the input TCP socket encountered an error reading it.  Indicate this:
00757     handleRequestBytes(-1);
00758   } else if (requestByte == 0xFE) {
00759     // Another hack: The new handler of the input TCP socket no longer needs it, so take back control of it:
00760     envir().taskScheduler().setBackgroundHandling(fClientInputSocket, SOCKET_READABLE|SOCKET_EXCEPTION,
00761                                                   (TaskScheduler::BackgroundHandlerProc*)&incomingRequestHandler, this);
00762   } else {
00763     // Normal case: Add this character to our buffer; then try to handle the data that we have buffered so far:
00764     if (fRequestBufferBytesLeft == 0 || fRequestBytesAlreadySeen >= RTSP_BUFFER_SIZE) return;
00765     fRequestBuffer[fRequestBytesAlreadySeen] = requestByte;
00766     handleRequestBytes(1);
00767   }
00768 }

void RTSPServer::RTSPClientConnection::handleRequestBytes ( int  newBytesRead  )  [protected]

Definition at line 770 of file RTSPServer.cpp.

References HashTable::Add(), base64Decode(), closeSockets(), RTSPServer::createNewClientSession(), False, fBase64RemainderCount, fClientInputSocket, fClientOutputSocket, RTSPServer::fClientSessions, fCurrentCSeq, fIsActive, fLastCRLF, fOurServer, fRecursionCount, fRequestBuffer, fRequestBufferBytesLeft, fRequestBytesAlreadySeen, fResponseBuffer, RTSPServer::RTSPClientSession::fStreamAfterSETUP, handleCmd_bad(), handleCmd_DESCRIBE(), handleCmd_GET_PARAMETER(), handleCmd_notSupported(), handleCmd_OPTIONS(), handleCmd_REGISTER(), handleCmd_sessionNotFound(), handleCmd_SET_PARAMETER(), RTSPServer::RTSPClientSession::handleCmd_SETUP(), RTSPServer::RTSPClientSession::handleCmd_withinSession(), handleHTTPCmd_notSupported(), handleHTTPCmd_StreamingGET(), handleHTTPCmd_TunnelingGET(), handleHTTPCmd_TunnelingPOST(), HashTable::Lookup(), RTSPServer::RTSPClientSession::noteLiveness(), NULL, numBytesRemaining, our_random32(), parseHTTPRequestString(), parseRTSPRequestString(), resetRequestBuffer(), RTSP_PARAM_STRING_MAX, strDupSize(), and True.

Referenced by handleAlternativeRequestByte1(), and incomingRequestHandler1().

00770                                                                         {
00771   int numBytesRemaining = 0;
00772   ++fRecursionCount;
00773 
00774   do {
00775     RTSPServer::RTSPClientSession* clientSession = NULL;
00776 
00777     if (newBytesRead < 0 || (unsigned)newBytesRead >= fRequestBufferBytesLeft) {
00778       // Either the client socket has died, or the request was too big for us.
00779       // Terminate this connection:
00780 #ifdef DEBUG
00781       fprintf(stderr, "RTSPClientConnection[%p]::handleRequestBytes() read %d new bytes (of %d); terminating connection!\n", this, newBytesRead, fRequestBufferBytesLeft);
00782 #endif
00783       fIsActive = False;
00784       break;
00785     }
00786     
00787     Boolean endOfMsg = False;
00788     unsigned char* ptr = &fRequestBuffer[fRequestBytesAlreadySeen];
00789 #ifdef DEBUG
00790     ptr[newBytesRead] = '\0';
00791     fprintf(stderr, "RTSPClientConnection[%p]::handleRequestBytes() %s %d new bytes:%s\n",
00792             this, numBytesRemaining > 0 ? "processing" : "read", newBytesRead, ptr);
00793 #endif
00794     
00795     if (fClientOutputSocket != fClientInputSocket) {
00796       // We're doing RTSP-over-HTTP tunneling, and input commands are assumed to have been Base64-encoded.
00797       // We therefore Base64-decode as much of this new data as we can (i.e., up to a multiple of 4 bytes):
00798       unsigned numBytesToDecode = fBase64RemainderCount + newBytesRead;
00799       unsigned newBase64RemainderCount = numBytesToDecode%4;
00800       numBytesToDecode -= newBase64RemainderCount;
00801       if (numBytesToDecode > 0) {
00802         ptr[newBytesRead] = '\0';
00803         unsigned decodedSize;
00804         unsigned char* decodedBytes = base64Decode((char const*)(ptr-fBase64RemainderCount), decodedSize);
00805 #ifdef DEBUG
00806         fprintf(stderr, "Base64-decoded %d input bytes into %d new bytes:", numBytesToDecode, decodedSize);
00807         for (unsigned k = 0; k < decodedSize; ++k) fprintf(stderr, "%c", decodedBytes[k]);
00808         fprintf(stderr, "\n");
00809 #endif
00810         
00811         // Copy the new decoded bytes in place of the old ones (we can do this because there are fewer decoded bytes than original):
00812         unsigned char* to = ptr-fBase64RemainderCount;
00813         for (unsigned i = 0; i < decodedSize; ++i) *to++ = decodedBytes[i];
00814         
00815         // Then copy any remaining (undecoded) bytes to the end:
00816         for (unsigned j = 0; j < newBase64RemainderCount; ++j) *to++ = (ptr-fBase64RemainderCount+numBytesToDecode)[j];
00817         
00818         newBytesRead = decodedSize + newBase64RemainderCount; // adjust to allow for the size of the new decoded data (+ remainder)
00819         delete[] decodedBytes;
00820       }
00821       fBase64RemainderCount = newBase64RemainderCount;
00822       if (fBase64RemainderCount > 0) break; // because we know that we have more input bytes still to receive
00823     }
00824     
00825     // Look for the end of the message: <CR><LF><CR><LF>
00826     unsigned char *tmpPtr = fLastCRLF + 2;
00827     if (tmpPtr < fRequestBuffer) tmpPtr = fRequestBuffer;
00828     while (tmpPtr < &ptr[newBytesRead-1]) {
00829       if (*tmpPtr == '\r' && *(tmpPtr+1) == '\n') {
00830         if (tmpPtr - fLastCRLF == 2) { // This is it:
00831           endOfMsg = True;
00832           break;
00833         }
00834         fLastCRLF = tmpPtr;
00835       }
00836       ++tmpPtr;
00837     }
00838     
00839     fRequestBufferBytesLeft -= newBytesRead;
00840     fRequestBytesAlreadySeen += newBytesRead;
00841     
00842     if (!endOfMsg) break; // subsequent reads will be needed to complete the request
00843     
00844     // Parse the request string into command name and 'CSeq', then handle the command:
00845     fRequestBuffer[fRequestBytesAlreadySeen] = '\0';
00846     char cmdName[RTSP_PARAM_STRING_MAX];
00847     char urlPreSuffix[RTSP_PARAM_STRING_MAX];
00848     char urlSuffix[RTSP_PARAM_STRING_MAX];
00849     char cseq[RTSP_PARAM_STRING_MAX];
00850     char sessionIdStr[RTSP_PARAM_STRING_MAX];
00851     unsigned contentLength = 0;
00852     fLastCRLF[2] = '\0'; // temporarily, for parsing
00853     Boolean parseSucceeded = parseRTSPRequestString((char*)fRequestBuffer, fLastCRLF+2 - fRequestBuffer,
00854                                                     cmdName, sizeof cmdName,
00855                                                     urlPreSuffix, sizeof urlPreSuffix,
00856                                                     urlSuffix, sizeof urlSuffix,
00857                                                     cseq, sizeof cseq,
00858                                                     sessionIdStr, sizeof sessionIdStr,
00859                                                     contentLength);
00860     fLastCRLF[2] = '\r'; // restore its value
00861     if (parseSucceeded) {
00862 #ifdef DEBUG
00863       fprintf(stderr, "parseRTSPRequestString() succeeded, returning cmdName \"%s\", urlPreSuffix \"%s\", urlSuffix \"%s\", CSeq \"%s\", Content-Length %u, with %d bytes following the message.\n", cmdName, urlPreSuffix, urlSuffix, cseq, contentLength, ptr + newBytesRead - (tmpPtr + 2));
00864 #endif
00865       // If there was a "Content-Length:" header, then make sure we've received all of the data that it specified:
00866       if (ptr + newBytesRead < tmpPtr + 2 + contentLength) break; // we still need more data; subsequent reads will give it to us 
00867       
00868       // We now have a complete RTSP request.
00869       // Handle the specified command (beginning by checking those that don't require session ids):
00870       fCurrentCSeq = cseq;
00871       if (strcmp(cmdName, "OPTIONS") == 0) {
00872         // If the request included a "Session:" id, and it refers to a client session that's current ongoing, then use this
00873         // command to indicate 'liveness' on that client session:
00874         if (sessionIdStr[0] != '\0') {
00875           clientSession = (RTSPServer::RTSPClientSession*)(fOurServer.fClientSessions->Lookup(sessionIdStr));
00876           if (clientSession != NULL) clientSession->noteLiveness();
00877         }
00878         handleCmd_OPTIONS();
00879       } else if (urlPreSuffix[0] == '\0' && urlSuffix[0] == '*' && urlSuffix[1] == '\0') {
00880         // The special "*" URL means: an operation on the entire server.  This works only for GET_PARAMETER and SET_PARAMETER:
00881         if (strcmp(cmdName, "GET_PARAMETER") == 0) {
00882           handleCmd_GET_PARAMETER((char const*)fRequestBuffer);
00883         } else if (strcmp(cmdName, "SET_PARAMETER") == 0) {
00884           handleCmd_SET_PARAMETER((char const*)fRequestBuffer);
00885         } else {
00886           handleCmd_notSupported();
00887         }
00888       } else if (strcmp(cmdName, "DESCRIBE") == 0) {
00889         handleCmd_DESCRIBE(urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
00890       } else if (strcmp(cmdName, "SETUP") == 0) {
00891         if (sessionIdStr[0] == '\0') {
00892           // No session id was present in the request.  So create a new "RTSPClientSession" object for this request.
00893           // Choose a random (unused) 32-bit integer for the session id (it will be encoded as a 8-digit hex number).
00894           // (We avoid choosing session id 0, because that has a special use (by "OnDemandServerMediaSubsession").)
00895           u_int32_t sessionId;
00896           do {
00897             sessionId = (u_int32_t)our_random32();
00898             sprintf(sessionIdStr, "%08X", sessionId);
00899           } while (sessionId == 0 || fOurServer.fClientSessions->Lookup(sessionIdStr) != NULL);
00900           clientSession = fOurServer.createNewClientSession(sessionId);
00901           fOurServer.fClientSessions->Add(sessionIdStr, clientSession);
00902         } else {
00903           // The request included a session id.  Make sure it's one that we have already set up:
00904           clientSession = (RTSPServer::RTSPClientSession*)(fOurServer.fClientSessions->Lookup(sessionIdStr));
00905 
00906           if (clientSession == NULL) {
00907             handleCmd_sessionNotFound();
00908           }
00909         }
00910         if (clientSession != NULL) clientSession->handleCmd_SETUP(this, urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
00911       } else if (strcmp(cmdName, "TEARDOWN") == 0
00912                  || strcmp(cmdName, "PLAY") == 0
00913                  || strcmp(cmdName, "PAUSE") == 0
00914                  || strcmp(cmdName, "GET_PARAMETER") == 0
00915                  || strcmp(cmdName, "SET_PARAMETER") == 0) {
00916         RTSPServer::RTSPClientSession* clientSession
00917           = sessionIdStr[0] == '\0' ? NULL : (RTSPServer::RTSPClientSession*)(fOurServer.fClientSessions->Lookup(sessionIdStr));
00918         if (clientSession == NULL) {
00919           handleCmd_sessionNotFound();
00920         } else {
00921           clientSession->handleCmd_withinSession(this, cmdName, urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
00922         }
00923       } else if (strcmp(cmdName, "REGISTER") == 0 || strcmp(cmdName, "REGISTER_REMOTE") == 0) {
00924         // Because - unlike other commands - an implementation of these commands needs the entire URL, we re-parse the
00925         // command to get it:
00926         char* url = strDupSize((char*)fRequestBuffer);
00927         if (sscanf((char*)fRequestBuffer, "%*s %s", url) == 1) {
00928           handleCmd_REGISTER(url, urlSuffix, strcmp(cmdName, "REGISTER_REMOTE") == 0);
00929         } else {
00930           handleCmd_bad();
00931         }
00932         delete[] url;
00933       } else {
00934         // The command is one that we don't handle:
00935         handleCmd_notSupported();
00936       }
00937     } else {
00938 #ifdef DEBUG
00939       fprintf(stderr, "parseRTSPRequestString() failed; checking now for HTTP commands (for RTSP-over-HTTP tunneling)...\n");
00940 #endif
00941       // The request was not (valid) RTSP, but check for a special case: HTTP commands (for setting up RTSP-over-HTTP tunneling):
00942       char sessionCookie[RTSP_PARAM_STRING_MAX];
00943       char acceptStr[RTSP_PARAM_STRING_MAX];
00944       *fLastCRLF = '\0'; // temporarily, for parsing
00945       parseSucceeded = parseHTTPRequestString(cmdName, sizeof cmdName,
00946                                               urlSuffix, sizeof urlPreSuffix,
00947                                               sessionCookie, sizeof sessionCookie,
00948                                               acceptStr, sizeof acceptStr);
00949       *fLastCRLF = '\r';
00950       if (parseSucceeded) {
00951 #ifdef DEBUG
00952         fprintf(stderr, "parseHTTPRequestString() succeeded, returning cmdName \"%s\", urlSuffix \"%s\", sessionCookie \"%s\", acceptStr \"%s\"\n", cmdName, urlSuffix, sessionCookie, acceptStr);
00953 #endif
00954         // Check that the HTTP command is valid for RTSP-over-HTTP tunneling: There must be a 'session cookie'.
00955         Boolean isValidHTTPCmd = True;
00956         if (sessionCookie[0] == '\0') {
00957           // There was no "x-sessioncookie:" header.  If there was an "Accept: application/x-rtsp-tunnelled" header,
00958           // then this is a bad tunneling request.  Otherwise, assume that it's an attempt to access the stream via HTTP.
00959           if (strcmp(acceptStr, "application/x-rtsp-tunnelled") == 0) {
00960             isValidHTTPCmd = False;
00961           } else {
00962             handleHTTPCmd_StreamingGET(urlSuffix, (char const*)fRequestBuffer);
00963           }
00964         } else if (strcmp(cmdName, "GET") == 0) {
00965           handleHTTPCmd_TunnelingGET(sessionCookie);
00966         } else if (strcmp(cmdName, "POST") == 0) {
00967           // We might have received additional data following the HTTP "POST" command - i.e., the first Base64-encoded RTSP command.
00968           // Check for this, and handle it if it exists:
00969           unsigned char const* extraData = fLastCRLF+4;
00970           unsigned extraDataSize = &fRequestBuffer[fRequestBytesAlreadySeen] - extraData;
00971           if (handleHTTPCmd_TunnelingPOST(sessionCookie, extraData, extraDataSize)) {
00972             // We don't respond to the "POST" command, and we go away:
00973             fIsActive = False;
00974             break;
00975           }
00976         } else {
00977           isValidHTTPCmd = False;
00978         }
00979         if (!isValidHTTPCmd) {
00980           handleHTTPCmd_notSupported();
00981         }
00982       } else {
00983 #ifdef DEBUG
00984         fprintf(stderr, "parseHTTPRequestString() failed!\n");
00985 #endif
00986         handleCmd_bad();
00987       }
00988     }
00989     
00990 #ifdef DEBUG
00991     fprintf(stderr, "sending response: %s", fResponseBuffer);
00992 #endif
00993     send(fClientOutputSocket, (char const*)fResponseBuffer, strlen((char*)fResponseBuffer), 0);
00994     
00995     if (clientSession != NULL && clientSession->fStreamAfterSETUP && strcmp(cmdName, "SETUP") == 0) {
00996       // The client has asked for streaming to commence now, rather than after a
00997       // subsequent "PLAY" command.  So, simulate the effect of a "PLAY" command:
00998       clientSession->handleCmd_withinSession(this, "PLAY", urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
00999     }
01000     
01001     // Check whether there are extra bytes remaining in the buffer, after the end of the request (a rare case).
01002     // If so, move them to the front of our buffer, and keep processing it, because it might be a following, pipelined request.
01003     unsigned requestSize = (fLastCRLF+4-fRequestBuffer) + contentLength;
01004     numBytesRemaining = fRequestBytesAlreadySeen - requestSize;
01005     resetRequestBuffer(); // to prepare for any subsequent request
01006 
01007     if (numBytesRemaining > 0) {
01008       memmove(fRequestBuffer, &fRequestBuffer[requestSize], numBytesRemaining);
01009       newBytesRead = numBytesRemaining;
01010     }
01011   } while (numBytesRemaining > 0);
01012 
01013   --fRecursionCount;
01014   if (!fIsActive) {
01015     if (fRecursionCount > 0) closeSockets(); else delete this;
01016     // Note: The "fRecursionCount" test is for a pathological situation where we reenter the event loop and get called recursively
01017     // while handling a command (e.g., while handling a "DESCRIBE", to get a SDP description).
01018     // In such a case we don't want to actually delete ourself until we leave the outermost call.
01019   }
01020 }

Boolean RTSPServer::RTSPClientConnection::authenticationOK ( char const *  cmdName,
char const *  urlSuffix,
char const *  fullRequestStr 
) [protected]

Definition at line 1070 of file RTSPServer.cpp.

References dateHeader(), False, NULL, parseAuthorizationHeader(), password, True, and username.

01070                                                                                          {
01071 
01072   if (!fOurServer.specialClientAccessCheck(fClientInputSocket, fClientAddr, urlSuffix)) {
01073     setRTSPResponse("401 Unauthorized");
01074     return False;
01075   }
01076 
01077   // If we weren't set up with an authentication database, we're OK:
01078   if (fOurServer.fAuthDB == NULL) return True;
01079 
01080   char const* username = NULL; char const* realm = NULL; char const* nonce = NULL;
01081   char const* uri = NULL; char const* response = NULL;
01082   Boolean success = False;
01083 
01084   do {
01085     // To authenticate, we first need to have a nonce set up
01086     // from a previous attempt:
01087     if (fCurrentAuthenticator.nonce() == NULL) break;
01088 
01089     // Next, the request needs to contain an "Authorization:" header,
01090     // containing a username, (our) realm, (our) nonce, uri,
01091     // and response string:
01092     if (!parseAuthorizationHeader(fullRequestStr,
01093                                   username, realm, nonce, uri, response)
01094         || username == NULL
01095         || realm == NULL || strcmp(realm, fCurrentAuthenticator.realm()) != 0
01096         || nonce == NULL || strcmp(nonce, fCurrentAuthenticator.nonce()) != 0
01097         || uri == NULL || response == NULL) {
01098       break;
01099     }
01100 
01101     // Next, the username has to be known to us:
01102     char const* password = fOurServer.fAuthDB->lookupPassword(username);
01103 #ifdef DEBUG
01104     fprintf(stderr, "lookupPassword(%s) returned password %s\n", username, password);
01105 #endif
01106     if (password == NULL) break;
01107     fCurrentAuthenticator.
01108       setUsernameAndPassword(username, password,
01109                              fOurServer.fAuthDB->passwordsAreMD5());
01110 
01111     // Finally, compute a digest response from the information that we have,
01112     // and compare it to the one that we were given:
01113     char const* ourResponse
01114       = fCurrentAuthenticator.computeDigestResponse(cmdName, uri);
01115     success = (strcmp(ourResponse, response) == 0);
01116     fCurrentAuthenticator.reclaimDigestResponse(ourResponse);
01117   } while (0);
01118 
01119   delete[] (char*)realm; delete[] (char*)nonce;
01120   delete[] (char*)uri; delete[] (char*)response;
01121 
01122   if (success) {
01123     // The user has been authenticated.
01124     // Now allow subclasses a chance to validate the user against the IP address and/or URL suffix.
01125     if (!fOurServer.specialClientUserAccessCheck(fClientInputSocket, fClientAddr, urlSuffix, username)) {
01126       // Note: We don't return a "WWW-Authenticate" header here, because the user is valid,
01127       // even though the server has decided that they should not have access.
01128       setRTSPResponse("401 Unauthorized");
01129       delete[] (char*)username;
01130       return False;
01131     }
01132   }
01133   delete[] (char*)username;
01134   if (success) return True;
01135 
01136   // If we get here, we failed to authenticate the user.
01137   // Send back a "401 Unauthorized" response, with a new random nonce:
01138   fCurrentAuthenticator.setRealmAndRandomNonce(fOurServer.fAuthDB->realm());
01139   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
01140            "RTSP/1.0 401 Unauthorized\r\n"
01141            "CSeq: %s\r\n"
01142            "%s"
01143            "WWW-Authenticate: Digest realm=\"%s\", nonce=\"%s\"\r\n\r\n",
01144            fCurrentCSeq,
01145            dateHeader(),
01146            fCurrentAuthenticator.realm(), fCurrentAuthenticator.nonce());
01147   return False;
01148 }

void RTSPServer::RTSPClientConnection::changeClientInputSocket ( int  newSocketNum,
unsigned char const *  extraData,
unsigned  extraDataSize 
) [protected]

Definition at line 1213 of file RTSPServer.cpp.

References TaskScheduler::disableBackgroundHandling(), Medium::envir(), TaskScheduler::setBackgroundHandling(), SOCKET_EXCEPTION, SOCKET_READABLE, and UsageEnvironment::taskScheduler().

Referenced by handleHTTPCmd_TunnelingPOST().

01213                                                                                                   {
01214   envir().taskScheduler().disableBackgroundHandling(fClientInputSocket);
01215   fClientInputSocket = newSocketNum;
01216   envir().taskScheduler().setBackgroundHandling(fClientInputSocket, SOCKET_READABLE|SOCKET_EXCEPTION,
01217                                                 (TaskScheduler::BackgroundHandlerProc*)&incomingRequestHandler, this);
01218 
01219   // Also write any extra data to our buffer, and handle it:
01220   if (extraDataSize > 0 && extraDataSize <= fRequestBufferBytesLeft/*sanity check; should always be true*/) {
01221     unsigned char* ptr = &fRequestBuffer[fRequestBytesAlreadySeen];
01222     for (unsigned i = 0; i < extraDataSize; ++i) {
01223       ptr[i] = extraData[i];
01224     }
01225     handleRequestBytes(extraDataSize);
01226   }
01227 }

void RTSPServer::RTSPClientConnection::continueHandlingREGISTER ( ParamsForREGISTER params  )  [static, protected]

Definition at line 1229 of file RTSPServer.cpp.

References continueHandlingREGISTER1(), and RTSPServer::RTSPClientConnection::ParamsForREGISTER::fOurConnection.

Referenced by handleCmd_REGISTER().

01229                                                                                        {
01230   params->fOurConnection->continueHandlingREGISTER1(params);
01231 }

void RTSPServer::RTSPClientConnection::continueHandlingREGISTER1 ( ParamsForREGISTER params  )  [protected, virtual]

Definition at line 1233 of file RTSPServer.cpp.

References fClientInputSocket, fClientOutputSocket, fOurServer, RTSPServer::RTSPClientConnection::ParamsForREGISTER::fRegisterRemote, RTSPServer::RTSPClientConnection::ParamsForREGISTER::fURL, RTSPServer::RTSPClientConnection::ParamsForREGISTER::fURLSuffix, and RTSPServer::implementCmd_REGISTER().

Referenced by continueHandlingREGISTER().

01233                                                                                         {
01234   int socketNumToBackEndServer = params->fRegisterRemote ? -1 : fClientOutputSocket;
01235   RTSPServer* ourServer = &fOurServer; // copy the pointer now, in case we "delete this" below
01236 
01237   if (socketNumToBackEndServer >= 0) {
01238     // Because our socket will no longer be used by the server to handle incoming requests, we can now delete this
01239     // "RTSPClientConnection" object.  We do this now, in case the "implementCmd_REGISTER()" call below would also end up
01240     // deleting this.
01241     fClientInputSocket = fClientOutputSocket = -1; // so the socket doesn't get closed when we get deleted
01242     delete this;
01243   }
01244 
01245   ourServer->implementCmd_REGISTER(params->fURL, params->fURLSuffix, socketNumToBackEndServer);
01246   delete params;
01247 }

void RTSPServer::RTSPClientConnection::setRTSPResponse ( char const *  responseStr  )  [protected]

Definition at line 1151 of file RTSPServer.cpp.

References dateHeader().

Referenced by RTSPServer::RTSPClientSession::handleCmd_GET_PARAMETER(), handleCmd_notFound(), RTSPServer::RTSPClientSession::handleCmd_PAUSE(), handleCmd_REGISTER(), handleCmd_sessionNotFound(), RTSPServer::RTSPClientSession::handleCmd_SET_PARAMETER(), RTSPServer::RTSPClientSession::handleCmd_TEARDOWN(), handleCmd_unsupportedTransport(), and RTSPServer::RTSPClientSession::setRTSPResponse().

01151                                          {
01152   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
01153            "RTSP/1.0 %s\r\n"
01154            "CSeq: %s\r\n"
01155            "%s\r\n",
01156            responseStr,
01157            fCurrentCSeq,
01158            dateHeader());
01159 }

void RTSPServer::RTSPClientConnection::setRTSPResponse ( char const *  responseStr,
u_int32_t  sessionId 
) [protected]

Definition at line 1162 of file RTSPServer.cpp.

References dateHeader().

01162                                                               {
01163   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
01164            "RTSP/1.0 %s\r\n"
01165            "CSeq: %s\r\n"
01166            "%s"
01167            "Session: %08X\r\n\r\n",
01168            responseStr,
01169            fCurrentCSeq,
01170            dateHeader(),
01171            sessionId);
01172 }

void RTSPServer::RTSPClientConnection::setRTSPResponse ( char const *  responseStr,
char const *  contentStr 
) [protected]

Definition at line 1175 of file RTSPServer.cpp.

References dateHeader(), and NULL.

01175                                                                  {
01176   if (contentStr == NULL) contentStr = "";
01177   unsigned const contentLen = strlen(contentStr);
01178 
01179   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
01180            "RTSP/1.0 %s\r\n"
01181            "CSeq: %s\r\n"
01182            "%s"
01183            "Content-Length: %d\r\n\r\n"
01184            "%s",
01185            responseStr,
01186            fCurrentCSeq,
01187            dateHeader(),
01188            contentLen,
01189            contentStr);
01190 }

void RTSPServer::RTSPClientConnection::setRTSPResponse ( char const *  responseStr,
u_int32_t  sessionId,
char const *  contentStr 
) [protected]

Definition at line 1193 of file RTSPServer.cpp.

References dateHeader(), and NULL.

01193                                                                                       {
01194   if (contentStr == NULL) contentStr = "";
01195   unsigned const contentLen = strlen(contentStr);
01196 
01197   snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
01198            "RTSP/1.0 %s\r\n"
01199            "CSeq: %s\r\n"
01200            "%s"
01201            "Session: %08X\r\n"
01202            "Content-Length: %d\r\n\r\n"
01203            "%s",
01204            responseStr,
01205            fCurrentCSeq,
01206            dateHeader(),
01207            sessionId,
01208            contentLen,
01209            contentStr);
01210 }


Friends And Related Function Documentation

friend class RTSPClientSession [friend]

Definition at line 186 of file RTSPServer.hh.


Field Documentation

RTSPServer& RTSPServer::RTSPClientConnection::fOurServer [protected]

Definition at line 233 of file RTSPServer.hh.

Referenced by continueHandlingREGISTER1(), envir(), handleCmd_bad(), handleCmd_notSupported(), handleCmd_OPTIONS(), handleCmd_REGISTER(), handleHTTPCmd_TunnelingGET(), handleRequestBytes(), RTSPClientConnection(), and ~RTSPClientConnection().

Boolean RTSPServer::RTSPClientConnection::fIsActive [protected]

Definition at line 234 of file RTSPServer.hh.

Referenced by RTSPServerSupportingHTTPStreaming::RTSPClientConnectionSupportingHTTPStreaming::afterStreaming(), and handleRequestBytes().

int RTSPServer::RTSPClientConnection::fClientInputSocket [protected]

Definition at line 235 of file RTSPServer.hh.

Referenced by closeSockets(), continueHandlingREGISTER1(), handleAlternativeRequestByte1(), RTSPServer::RTSPClientSession::handleCmd_PLAY(), RTSPServer::RTSPClientSession::handleCmd_SETUP(), handleRequestBytes(), incomingRequestHandler1(), and RTSPClientConnection().

int RTSPServer::RTSPClientConnection::fClientOutputSocket [protected]

Definition at line 235 of file RTSPServer.hh.

Referenced by closeSockets(), continueHandlingREGISTER1(), RTSPServer::RTSPClientSession::handleCmd_SETUP(), handleHTTPCmd_TunnelingGET(), and handleRequestBytes().

struct sockaddr_in RTSPServer::RTSPClientConnection::fClientAddr [read, protected]

Definition at line 236 of file RTSPServer.hh.

Referenced by RTSPServer::RTSPClientSession::handleCmd_SETUP().

unsigned char RTSPServer::RTSPClientConnection::fRequestBuffer[RTSP_BUFFER_SIZE] [protected]

Definition at line 237 of file RTSPServer.hh.

Referenced by handleAlternativeRequestByte1(), handleRequestBytes(), incomingRequestHandler1(), parseHTTPRequestString(), and resetRequestBuffer().

unsigned RTSPServer::RTSPClientConnection::fRequestBytesAlreadySeen [protected]

Definition at line 238 of file RTSPServer.hh.

Referenced by handleAlternativeRequestByte1(), handleRequestBytes(), incomingRequestHandler1(), parseHTTPRequestString(), and resetRequestBuffer().

unsigned RTSPServer::RTSPClientConnection::fRequestBufferBytesLeft [protected]

Definition at line 238 of file RTSPServer.hh.

Referenced by handleAlternativeRequestByte1(), handleRequestBytes(), incomingRequestHandler1(), and resetRequestBuffer().

unsigned char* RTSPServer::RTSPClientConnection::fLastCRLF [protected]

Definition at line 239 of file RTSPServer.hh.

Referenced by handleRequestBytes(), and resetRequestBuffer().

unsigned char RTSPServer::RTSPClientConnection::fResponseBuffer[RTSP_BUFFER_SIZE] [protected]

Definition at line 240 of file RTSPServer.hh.

Referenced by handleCmd_bad(), handleCmd_notSupported(), handleCmd_OPTIONS(), RTSPServer::RTSPClientSession::handleCmd_PLAY(), RTSPServer::RTSPClientSession::handleCmd_SETUP(), handleHTTPCmd_notFound(), handleHTTPCmd_notSupported(), handleHTTPCmd_TunnelingGET(), and handleRequestBytes().

unsigned RTSPServer::RTSPClientConnection::fRecursionCount [protected]

Definition at line 241 of file RTSPServer.hh.

Referenced by RTSPServerSupportingHTTPStreaming::RTSPClientConnectionSupportingHTTPStreaming::afterStreaming(), and handleRequestBytes().

char const* RTSPServer::RTSPClientConnection::fCurrentCSeq [protected]

Definition at line 242 of file RTSPServer.hh.

Referenced by handleCmd_notSupported(), handleCmd_OPTIONS(), RTSPServer::RTSPClientSession::handleCmd_PLAY(), RTSPServer::RTSPClientSession::handleCmd_SETUP(), and handleRequestBytes().

Authenticator RTSPServer::RTSPClientConnection::fCurrentAuthenticator [protected]

Definition at line 243 of file RTSPServer.hh.

char* RTSPServer::RTSPClientConnection::fOurSessionCookie [protected]

Definition at line 244 of file RTSPServer.hh.

Referenced by handleHTTPCmd_TunnelingGET(), and ~RTSPClientConnection().

unsigned RTSPServer::RTSPClientConnection::fBase64RemainderCount [protected]

Definition at line 245 of file RTSPServer.hh.

Referenced by handleRequestBytes(), and resetRequestBuffer().


The documentation for this class was generated from the following files:
Generated on Tue Jun 18 13:21:29 2013 for live by  doxygen 1.5.2