#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 () |
| char const* dateHeader | ( | ) |
Definition at line 188 of file RTSPCommon.cpp.
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.
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 }
1.5.2