#include <RTSPServer.hh>
Inheritance diagram for RTSPServer::RTSPClientConnection:


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) |
| UsageEnvironment & | envir () |
| 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 | |
| RTSPServer & | fOurServer |
| 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 |
Definition at line 169 of file RTSPServer.hh.
| 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 }
| 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().
| 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 }
friend class RTSPClientSession [friend] |
Definition at line 186 of file RTSPServer.hh.
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().
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().
1.5.2