liveMedia/RTSPCommon.cpp File Reference

#include "RTSPCommon.hh"
#include "Locale.hh"
#include <string.h>
#include <stdio.h>
#include <time.h>

Include dependency graph for RTSPCommon.cpp:

Go to the source code of this file.

Functions

Boolean parseRTSPRequestString (char const *reqStr, unsigned reqStrSize, char *resultCmdName, unsigned resultCmdNameMaxSize, char *resultURLPreSuffix, unsigned resultURLPreSuffixMaxSize, char *resultURLSuffix, unsigned resultURLSuffixMaxSize, char *resultCSeq, unsigned resultCSeqMaxSize, unsigned &contentLength)
Boolean parseRangeParam (char const *paramStr, double &rangeStart, double &rangeEnd)
Boolean parseRangeHeader (char const *buf, double &rangeStart, double &rangeEnd)
char const * dateHeader ()


Function Documentation

char const* dateHeader (  ) 

Definition at line 188 of file RTSPCommon.cpp.

References DWORD, and NULL.

Referenced by RTSPServer::RTSPClientSession::authenticationOK(), RTSPServer::RTSPClientSession::handleCmd_bad(), RTSPServer::RTSPClientSession::handleCmd_DESCRIBE(), RTSPServer::RTSPClientSession::handleCmd_GET_PARAMETER(), RTSPServer::RTSPClientSession::handleCmd_notFound(), RTSPServer::RTSPClientSession::handleCmd_notSupported(), RTSPServer::RTSPClientSession::handleCmd_OPTIONS(), RTSPServer::RTSPClientSession::handleCmd_PAUSE(), RTSPServer::RTSPClientSession::handleCmd_PLAY(), RTSPServer::RTSPClientSession::handleCmd_SET_PARAMETER(), RTSPServer::RTSPClientSession::handleCmd_SETUP(), RTSPServer::RTSPClientSession::handleCmd_TEARDOWN(), RTSPServer::RTSPClientSession::handleCmd_unsupportedTransport(), RTSPServer::RTSPClientSession::handleHTTPCmd_notFound(), RTSPServer::RTSPClientSession::handleHTTPCmd_notSupported(), and RTSPServerSupportingHTTPStreaming::RTSPClientSessionSupportingHTTPStreaming::handleHTTPCmd_StreamingGET().

00188                          {
00189   static char buf[200];
00190 #if !defined(_WIN32_WCE)
00191   time_t tt = time(NULL);
00192   strftime(buf, sizeof buf, "Date: %a, %b %d %Y %H:%M:%S GMT\r\n", gmtime(&tt));
00193 #else
00194   // WinCE apparently doesn't have "time()", "strftime()", or "gmtime()",
00195   // so generate the "Date:" header a different, WinCE-specific way.
00196   // (Thanks to Pierre l'Hussiez for this code)
00197   // RSF: But where is the "Date: " string?  This code doesn't look quite right...
00198   SYSTEMTIME SystemTime;
00199   GetSystemTime(&SystemTime);
00200   WCHAR dateFormat[] = L"ddd, MMM dd yyyy";
00201   WCHAR timeFormat[] = L"HH:mm:ss GMT\r\n";
00202   WCHAR inBuf[200];
00203   DWORD locale = LOCALE_NEUTRAL;
00204 
00205   int ret = GetDateFormat(locale, 0, &SystemTime,
00206                           (LPTSTR)dateFormat, (LPTSTR)inBuf, sizeof inBuf);
00207   inBuf[ret - 1] = ' ';
00208   ret = GetTimeFormat(locale, 0, &SystemTime,
00209                       (LPTSTR)timeFormat,
00210                       (LPTSTR)inBuf + ret, (sizeof inBuf) - ret);
00211   wcstombs(buf, inBuf, wcslen(inBuf));
00212 #endif
00213   return buf;
00214 }

Boolean parseRangeHeader ( char const *  buf,
double &  rangeStart,
double &  rangeEnd 
)

Definition at line 174 of file RTSPCommon.cpp.

References _strncasecmp, False, and parseRangeParam().

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

00174                                                                                 {
00175   // First, find "Range:"
00176   while (1) {
00177     if (*buf == '\0') return False; // not found
00178     if (_strncasecmp(buf, "Range: ", 7) == 0) break;
00179     ++buf;
00180   }
00181 
00182   // Then, run through each of the fields, looking for ones we handle:
00183   char const* fields = buf + 7;
00184   while (*fields == ' ') ++fields;
00185   return parseRangeParam(fields, rangeStart, rangeEnd);
00186 }

Boolean parseRangeParam ( char const *  paramStr,
double &  rangeStart,
double &  rangeEnd 
)

Definition at line 150 of file RTSPCommon.cpp.

References False, Numeric, and True.

Referenced by RTSPClient::handlePLAYResponse(), and parseRangeHeader().

00150                                                                                     {
00151   double start, end;
00152   int numCharsMatched = 0;
00153   Locale l("C", Numeric);
00154   if (sscanf(paramStr, "npt = %lf - %lf", &start, &end) == 2) {
00155     rangeStart = start;
00156     rangeEnd = end;
00157   } else if (sscanf(paramStr, "npt = %lf -", &start) == 1) {
00158     rangeStart = start;
00159     rangeEnd = 0.0;
00160   } else if (strcmp(paramStr, "npt=now-") == 0) {
00161     rangeStart = 0.0;
00162     rangeEnd = 0.0;
00163   } else if (sscanf(paramStr, "clock = %*s%n", &numCharsMatched) == 0 && numCharsMatched > 0) {
00164     // We accept "clock=" parameters, but currently do no interpret them.
00165   } else if (sscanf(paramStr, "smtpe = %*s%n", &numCharsMatched) == 0 && numCharsMatched > 0) {
00166     // We accept "smtpe=" parameters, but currently do no interpret them.
00167   } else {
00168     return False; // The header is malformed
00169   }
00170 
00171   return True;
00172 }

Boolean parseRTSPRequestString ( char const *  reqStr,
unsigned  reqStrSize,
char *  resultCmdName,
unsigned  resultCmdNameMaxSize,
char *  resultURLPreSuffix,
unsigned  resultURLPreSuffixMaxSize,
char *  resultURLSuffix,
unsigned  resultURLSuffixMaxSize,
char *  resultCSeq,
unsigned  resultCSeqMaxSize,
unsigned &  contentLength 
)

Definition at line 27 of file RTSPCommon.cpp.

References False, and True.

Referenced by RTSPClient::handleIncomingRequest(), and RTSPServer::RTSPClientSession::handleRequestBytes().

00037                                                         {
00038   // This parser is currently rather dumb; it should be made smarter #####
00039   contentLength = 0; // default value
00040 
00041   // Read everything up to the first space as the command name:
00042   Boolean parseSucceeded = False;
00043   unsigned i;
00044   for (i = 0; i < resultCmdNameMaxSize-1 && i < reqStrSize; ++i) {
00045     char c = reqStr[i];
00046     if (c == ' ' || c == '\t') {
00047       parseSucceeded = True;
00048       break;
00049     }
00050 
00051     resultCmdName[i] = c;
00052   }
00053   resultCmdName[i] = '\0';
00054   if (!parseSucceeded) return False;
00055 
00056   // Skip over the prefix of any "rtsp://" or "rtsp:/" URL that follows:
00057   unsigned j = i+1;
00058   while (j < reqStrSize && (reqStr[j] == ' ' || reqStr[j] == '\t')) ++j; // skip over any additional white space
00059   for (; (int)j < (int)(reqStrSize-8); ++j) {
00060     if ((reqStr[j] == 'r' || reqStr[j] == 'R')
00061         && (reqStr[j+1] == 't' || reqStr[j+1] == 'T')
00062         && (reqStr[j+2] == 's' || reqStr[j+2] == 'S')
00063         && (reqStr[j+3] == 'p' || reqStr[j+3] == 'P')
00064         && reqStr[j+4] == ':' && reqStr[j+5] == '/') {
00065       j += 6;
00066       if (reqStr[j] == '/') {
00067         // This is a "rtsp://" URL; skip over the host:port part that follows:
00068         ++j;
00069         while (j < reqStrSize && reqStr[j] != '/' && reqStr[j] != ' ') ++j;
00070       } else {
00071         // This is a "rtsp:/" URL; back up to the "/":
00072         --j;
00073       }
00074       i = j;
00075       break;
00076     }
00077   }
00078 
00079   // Look for the URL suffix (before the following "RTSP/"):
00080   parseSucceeded = False;
00081   for (unsigned k = i+1; (int)k < (int)(reqStrSize-5); ++k) {
00082     if (reqStr[k] == 'R' && reqStr[k+1] == 'T' &&
00083         reqStr[k+2] == 'S' && reqStr[k+3] == 'P' && reqStr[k+4] == '/') {
00084       while (--k >= i && reqStr[k] == ' ') {} // go back over all spaces before "RTSP/"
00085       unsigned k1 = k;
00086       while (k1 > i && reqStr[k1] != '/') --k1;
00087 
00088       // The URL suffix comes from [k1+1,k]
00089       // Copy "resultURLSuffix":
00090       if (k - k1 + 1 > resultURLSuffixMaxSize) return False; // there's no room
00091       unsigned n = 0, k2 = k1+1;
00092       while (k2 <= k) resultURLSuffix[n++] = reqStr[k2++];
00093       resultURLSuffix[n] = '\0';
00094 
00095       // The URL 'pre-suffix' comes from [i+1,k1-1]
00096       // Copy "resultURLPreSuffix":
00097       if (k1 - i > resultURLPreSuffixMaxSize) return False; // there's no room
00098       n = 0; k2 = i + 1;
00099       while (k2 <= k1 - 1) resultURLPreSuffix[n++] = reqStr[k2++];
00100       resultURLPreSuffix[n] = '\0';
00101 
00102       i = k + 7; // to go past " RTSP/"
00103       parseSucceeded = True;
00104       break;
00105     }
00106   }
00107   if (!parseSucceeded) return False;
00108 
00109   // Look for "CSeq:", skip whitespace,
00110   // then read everything up to the next \r or \n as 'CSeq':
00111   parseSucceeded = False;
00112   for (j = i; (int)j < (int)(reqStrSize-5); ++j) {
00113     if (reqStr[j] == 'C' && reqStr[j+1] == 'S' && reqStr[j+2] == 'e' &&
00114         reqStr[j+3] == 'q' && reqStr[j+4] == ':') {
00115       j += 5;
00116       while (j < reqStrSize && (reqStr[j] ==  ' ' || reqStr[j] == '\t')) ++j;
00117       unsigned n;
00118       for (n = 0; n < resultCSeqMaxSize-1 && j < reqStrSize; ++n,++j) {
00119         char c = reqStr[j];
00120         if (c == '\r' || c == '\n') {
00121           parseSucceeded = True;
00122           break;
00123         }
00124 
00125         resultCSeq[n] = c;
00126       }
00127       resultCSeq[n] = '\0';
00128       break;
00129     }
00130   }
00131   if (!parseSucceeded) return False;
00132 
00133   // Also: Look for "Content-Length:" (optional)
00134   for (j = i; (int)j < (int)(reqStrSize-15); ++j) {
00135     if (reqStr[j] == 'C' && reqStr[j+1] == 'o' && reqStr[j+2] == 'n' && reqStr[j+3] == 't' && reqStr[j+4] == 'e' &&
00136         reqStr[j+5] == 'n' && reqStr[j+6] == 't' && reqStr[j+7] == '-' && (reqStr[j+8] == 'L' || reqStr[j+8] == 'l') &&
00137         reqStr[j+9] == 'e' && reqStr[j+10] == 'n' && reqStr[j+11] == 'g' && reqStr[j+12] == 't' && reqStr[j+13] == 'h' &&
00138         reqStr[j+14] == ':') {
00139       j += 15;
00140       while (j < reqStrSize && (reqStr[j] ==  ' ' || reqStr[j] == '\t')) ++j;
00141       unsigned num;
00142       if (sscanf(&reqStr[j], "%u", &num) == 1) {
00143         contentLength = num;
00144       }
00145     }
00146   }
00147   return True;
00148 }


Generated on Thu May 17 07:14:21 2012 for live by  doxygen 1.5.2