
Public Member Functions | |
| HTTPClientConnection (RTSPOverHTTPServer &ourServer, int clientSocket) | |
| virtual | ~HTTPClientConnection () |
Private Member Functions | |
| void | incomingRequestHandler1 () |
| UsageEnvironment & | envir () |
| void | resetRequestBuffer () |
| Boolean | parseHTTPRequestString (char *resultCmdName, unsigned resultCmdNameMaxSize, char *sessionCookie, unsigned sessionCookieMaxSize, char *acceptStr, unsigned acceptStrMaxSize, char *contentTypeStr, unsigned contentTypeStrMaxSize) |
| void | handleCmd_bad () |
Static Private Member Functions | |
| static void | incomingRequestHandler (void *, int) |
Private Attributes | |
| RTSPOverHTTPServer & | fOurServer |
| int | fClientSocket |
| unsigned char | fRequestBuffer [HTTP_BUFFER_SIZE] |
| unsigned | fRequestBytesAlreadySeen |
| unsigned | fRequestBufferBytesLeft |
| unsigned char * | fLastCRLF |
| unsigned char | fResponseBuffer [HTTP_BUFFER_SIZE] |
| Boolean | fSessionIsActive |
Definition at line 50 of file RTSPOverHTTPServer.hh.
| RTSPOverHTTPServer::HTTPClientConnection::HTTPClientConnection | ( | RTSPOverHTTPServer & | ourServer, | |
| int | clientSocket | |||
| ) |
Definition at line 142 of file RTSPOverHTTPServer.cpp.
References envir(), fClientSocket, incomingRequestHandler(), resetRequestBuffer(), UsageEnvironment::taskScheduler(), and TaskScheduler::turnOnBackgroundReadHandling().
00143 : fOurServer(ourServer), fClientSocket(clientSocket), fSessionIsActive(True) { 00144 // Arrange to handle incoming requests: 00145 resetRequestBuffer(); 00146 envir().taskScheduler().turnOnBackgroundReadHandling(fClientSocket, 00147 (TaskScheduler::BackgroundHandlerProc*)&incomingRequestHandler, this); 00148 }
| RTSPOverHTTPServer::HTTPClientConnection::~HTTPClientConnection | ( | ) | [virtual] |
Definition at line 151 of file RTSPOverHTTPServer.cpp.
References closeSocket, Medium::envir(), UsageEnvironment::taskScheduler(), and TaskScheduler::turnOffBackgroundReadHandling().
00151 { 00152 // Turn off background read handling: 00153 envir().taskScheduler().turnOffBackgroundReadHandling(fClientSocket); 00154 00155 ::closeSocket(fClientSocket); 00156 }
| void RTSPOverHTTPServer::HTTPClientConnection::incomingRequestHandler | ( | void * | , | |
| int | ||||
| ) | [static, private] |
Definition at line 159 of file RTSPOverHTTPServer.cpp.
References incomingRequestHandler1().
Referenced by HTTPClientConnection().
00159 { 00160 HTTPClientConnection* connection = (HTTPClientConnection*)instance; 00161 connection->incomingRequestHandler1(); 00162 }
| void RTSPOverHTTPServer::HTTPClientConnection::incomingRequestHandler1 | ( | ) | [private] |
Definition at line 164 of file RTSPOverHTTPServer.cpp.
References envir(), False, fClientSocket, fLastCRLF, fRequestBuffer, fRequestBufferBytesLeft, fRequestBytesAlreadySeen, fResponseBuffer, fSessionIsActive, handleCmd_bad(), HTTP_PARAM_STRING_MAX, parseHTTPRequestString(), readSocket(), and resetRequestBuffer().
Referenced by incomingRequestHandler().
00164 { 00165 struct sockaddr_in dummy; // 'from' address, meaningless in this case 00166 Boolean endOfMsg = False; 00167 unsigned char* ptr = &fRequestBuffer[fRequestBytesAlreadySeen]; 00168 00169 int bytesRead = readSocket(envir(), fClientSocket, 00170 ptr, fRequestBufferBytesLeft, dummy); 00171 if (bytesRead <= 0 || (unsigned)bytesRead >= fRequestBufferBytesLeft) { 00172 // Either the client socket has died, or the request was too big for us. 00173 // Terminate this connection: 00174 #ifdef DEBUG 00175 fprintf(stderr, "HTTPClientConnection[%p]::incomingRequestHandler1() read %d bytes (of %d); terminating connection!\n", this, bytesRead, fRequestBufferBytesLeft); 00176 #endif 00177 delete this; 00178 return; 00179 } 00180 #ifdef DEBUG 00181 ptr[bytesRead] = '\0'; 00182 fprintf(stderr, "HTTPClientConnection[%p]::incomingRequestHandler1() read %d bytes:%s\n", 00183 this, bytesRead, ptr); 00184 #endif 00185 00186 // Look for the end of the message: <CR><LF><CR><LF> 00187 unsigned char *tmpPtr = ptr; 00188 if (fRequestBytesAlreadySeen > 0) --tmpPtr; 00189 // in case the last read ended with a <CR> 00190 while (tmpPtr < &ptr[bytesRead-1]) { 00191 if (*tmpPtr == '\r' && *(tmpPtr+1) == '\n') { 00192 if (tmpPtr - fLastCRLF == 2) { // This is it: 00193 endOfMsg = 1; 00194 break; 00195 } 00196 fLastCRLF = tmpPtr; 00197 } 00198 ++tmpPtr; 00199 } 00200 00201 fRequestBufferBytesLeft -= bytesRead; 00202 fRequestBytesAlreadySeen += bytesRead; 00203 00204 if (!endOfMsg) return; // subsequent reads will be needed to complete the request 00205 00206 // Parse the request string to get the (few) parameters that we care about, 00207 // then handle the command: 00208 fRequestBuffer[fRequestBytesAlreadySeen] = '\0'; 00209 char cmdName[HTTP_PARAM_STRING_MAX]; 00210 char sessionCookie[HTTP_PARAM_STRING_MAX]; 00211 char acceptStr[HTTP_PARAM_STRING_MAX]; 00212 char contentTypeStr[HTTP_PARAM_STRING_MAX]; 00213 if (!parseHTTPRequestString(cmdName, sizeof cmdName, 00214 sessionCookie, sizeof sessionCookie, 00215 acceptStr, sizeof acceptStr, 00216 contentTypeStr, sizeof contentTypeStr)) { 00217 #ifdef DEBUG 00218 fprintf(stderr, "parseHTTPRTSPRequestString() failed!\n"); 00219 #endif 00220 handleCmd_bad(); 00221 } else { 00222 #ifdef DEBUG 00223 fprintf(stderr, "parseHTTPRTSPRequestString() returned cmdName \"%s\", sessionCookie \"%s\", acceptStr \"%s\", contentTypeStr \"%s\"\n", cmdName, sessionCookie, acceptStr, contentTypeStr); 00224 #endif 00225 #if 0 00226 if (strcmp(cmdName, "OPTIONS") == 0) { 00227 handleCmd_OPTIONS(cseq); 00228 } else if (strcmp(cmdName, "DESCRIBE") == 0) { 00229 handleCmd_DESCRIBE(cseq, urlSuffix, (char const*)fRequestBuffer); 00230 } else if (strcmp(cmdName, "SETUP") == 0) { 00231 handleCmd_SETUP(cseq, urlPreSuffix, urlSuffix, (char const*)fRequestBuffer); 00232 } else if (strcmp(cmdName, "TEARDOWN") == 0 00233 || strcmp(cmdName, "PLAY") == 0 00234 || strcmp(cmdName, "PAUSE") == 0 00235 || strcmp(cmdName, "GET_PARAMETER") == 0) { 00236 handleCmd_withinSession(cmdName, urlPreSuffix, urlSuffix, cseq, 00237 (char const*)fRequestBuffer); 00238 } else { 00239 handleCmd_notSupported(cseq); 00240 } 00241 #endif 00242 } 00243 00244 #ifdef DEBUG 00245 fprintf(stderr, "sending response: %s", fResponseBuffer); 00246 #endif 00247 send(fClientSocket, (char const*)fResponseBuffer, strlen((char*)fResponseBuffer), 0); 00248 00249 resetRequestBuffer(); // to prepare for any subsequent request 00250 if (!fSessionIsActive) delete this; 00251 }
| UsageEnvironment& RTSPOverHTTPServer::HTTPClientConnection::envir | ( | ) | [inline, private] |
Definition at line 57 of file RTSPOverHTTPServer.hh.
References Medium::envir(), and fOurServer.
Referenced by HTTPClientConnection(), and incomingRequestHandler1().
00057 { return fOurServer.envir(); }
| void RTSPOverHTTPServer::HTTPClientConnection::resetRequestBuffer | ( | ) | [private] |
Definition at line 253 of file RTSPOverHTTPServer.cpp.
References fLastCRLF, fRequestBuffer, fRequestBufferBytesLeft, and fRequestBytesAlreadySeen.
Referenced by HTTPClientConnection(), and incomingRequestHandler1().
00253 { 00254 fRequestBytesAlreadySeen = 0; 00255 fRequestBufferBytesLeft = sizeof fRequestBuffer; 00256 fLastCRLF = &fRequestBuffer[-3]; // hack 00257 }
| Boolean RTSPOverHTTPServer::HTTPClientConnection::parseHTTPRequestString | ( | char * | resultCmdName, | |
| unsigned | resultCmdNameMaxSize, | |||
| char * | sessionCookie, | |||
| unsigned | sessionCookieMaxSize, | |||
| char * | acceptStr, | |||
| unsigned | acceptStrMaxSize, | |||
| char * | contentTypeStr, | |||
| unsigned | contentTypeStrMaxSize | |||
| ) | [private] |
Definition at line 260 of file RTSPOverHTTPServer.cpp.
Referenced by incomingRequestHandler1().
00267 { 00268 return False; //#####@@@@@ 00269 #if 0 00270 // This parser is currently rather dumb; it should be made smarter ##### 00271 00272 // Read everything up to the first space as the command name: 00273 Boolean parseSucceeded = False; 00274 unsigned i; 00275 for (i = 0; i < resultCmdNameMaxSize-1 && i < reqStrSize; ++i) { 00276 char c = reqStr[i]; 00277 if (c == ' ' || c == '\t') { 00278 parseSucceeded = True; 00279 break; 00280 } 00281 00282 resultCmdName[i] = c; 00283 } 00284 resultCmdName[i] = '\0'; 00285 if (!parseSucceeded) return False; 00286 00287 // Skip over the prefix of any "rtsp://" or "rtsp:/" URL that follows: 00288 unsigned j = i+1; 00289 while (j < reqStrSize && (reqStr[j] == ' ' || reqStr[j] == '\t')) ++j; // skip over any additional white space 00290 for (j = i+1; j < reqStrSize-8; ++j) { 00291 if ((reqStr[j] == 'r' || reqStr[j] == 'R') 00292 && (reqStr[j+1] == 't' || reqStr[j+1] == 'T') 00293 && (reqStr[j+2] == 's' || reqStr[j+2] == 'S') 00294 && (reqStr[j+3] == 'p' || reqStr[j+3] == 'P') 00295 && reqStr[j+4] == ':' && reqStr[j+5] == '/') { 00296 j += 6; 00297 if (reqStr[j] == '/') { 00298 // This is a "rtsp://" URL; skip over the host:port part that follows: 00299 ++j; 00300 while (j < reqStrSize && reqStr[j] != '/' && reqStr[j] != ' ') ++j; 00301 } else { 00302 // This is a "rtsp:/" URL; back up to the "/": 00303 --j; 00304 } 00305 i = j; 00306 break; 00307 } 00308 } 00309 00310 // Look for the URL suffix (before the following "RTSP/"): 00311 parseSucceeded = False; 00312 for (unsigned k = i+1; k < reqStrSize-5; ++k) { 00313 if (reqStr[k] == 'R' && reqStr[k+1] == 'T' && 00314 reqStr[k+2] == 'S' && reqStr[k+3] == 'P' && reqStr[k+4] == '/') { 00315 while (--k >= i && reqStr[k] == ' ') {} // go back over all spaces before "RTSP/" 00316 unsigned k1 = k; 00317 while (k1 > i && reqStr[k1] != '/' && reqStr[k1] != ' ') --k1; 00318 // the URL suffix comes from [k1+1,k] 00319 00320 // Copy "resultURLSuffix": 00321 if (k - k1 + 1 > resultURLSuffixMaxSize) return False; // there's no room 00322 unsigned n = 0, k2 = k1+1; 00323 while (k2 <= k) resultURLSuffix[n++] = reqStr[k2++]; 00324 resultURLSuffix[n] = '\0'; 00325 00326 // Also look for the URL 'pre-suffix' before this: 00327 unsigned k3 = --k1; 00328 while (k3 > i && reqStr[k3] != '/' && reqStr[k3] != ' ') --k3; 00329 // the URL pre-suffix comes from [k3+1,k1] 00330 00331 // Copy "resultURLPreSuffix": 00332 if (k1 - k3 + 1 > resultURLPreSuffixMaxSize) return False; // there's no room 00333 n = 0; k2 = k3+1; 00334 while (k2 <= k1) resultURLPreSuffix[n++] = reqStr[k2++]; 00335 resultURLPreSuffix[n] = '\0'; 00336 00337 i = k + 7; // to go past " RTSP/" 00338 parseSucceeded = True; 00339 break; 00340 } 00341 } 00342 if (!parseSucceeded) return False; 00343 00344 // Look for "CSeq:", skip whitespace, 00345 // then read everything up to the next \r or \n as 'CSeq': 00346 parseSucceeded = False; 00347 for (j = i; j < reqStrSize-5; ++j) { 00348 if (reqStr[j] == 'C' && reqStr[j+1] == 'S' && reqStr[j+2] == 'e' && 00349 reqStr[j+3] == 'q' && reqStr[j+4] == ':') { 00350 j += 5; 00351 unsigned n; 00352 while (j < reqStrSize && (reqStr[j] == ' ' || reqStr[j] == '\t')) ++j; 00353 for (n = 0; n < resultCSeqMaxSize-1 && j < reqStrSize; ++n,++j) { 00354 char c = reqStr[j]; 00355 if (c == '\r' || c == '\n') { 00356 parseSucceeded = True; 00357 break; 00358 } 00359 00360 resultCSeq[n] = c; 00361 } 00362 resultCSeq[n] = '\0'; 00363 break; 00364 } 00365 } 00366 if (!parseSucceeded) return False; 00367 00368 return True; 00369 #endif 00370 }
| void RTSPOverHTTPServer::HTTPClientConnection::handleCmd_bad | ( | ) | [private] |
Definition at line 374 of file RTSPOverHTTPServer.cpp.
References fResponseBuffer.
Referenced by incomingRequestHandler1().
00374 { 00375 snprintf((char*)fResponseBuffer, sizeof fResponseBuffer, 00376 "HTTP/1.1 400 Bad Request\r\nAllow: %s\r\n\r\n", 00377 allowedCommandNames); 00378 }
int RTSPOverHTTPServer::HTTPClientConnection::fClientSocket [private] |
Definition at line 103 of file RTSPOverHTTPServer.hh.
Referenced by HTTPClientConnection(), and incomingRequestHandler1().
unsigned char RTSPOverHTTPServer::HTTPClientConnection::fRequestBuffer[HTTP_BUFFER_SIZE] [private] |
Definition at line 108 of file RTSPOverHTTPServer.hh.
Referenced by incomingRequestHandler1(), and resetRequestBuffer().
unsigned RTSPOverHTTPServer::HTTPClientConnection::fRequestBytesAlreadySeen [private] |
Definition at line 109 of file RTSPOverHTTPServer.hh.
Referenced by incomingRequestHandler1(), and resetRequestBuffer().
unsigned RTSPOverHTTPServer::HTTPClientConnection::fRequestBufferBytesLeft [private] |
Definition at line 109 of file RTSPOverHTTPServer.hh.
Referenced by incomingRequestHandler1(), and resetRequestBuffer().
unsigned char* RTSPOverHTTPServer::HTTPClientConnection::fLastCRLF [private] |
Definition at line 110 of file RTSPOverHTTPServer.hh.
Referenced by incomingRequestHandler1(), and resetRequestBuffer().
unsigned char RTSPOverHTTPServer::HTTPClientConnection::fResponseBuffer[HTTP_BUFFER_SIZE] [private] |
Definition at line 111 of file RTSPOverHTTPServer.hh.
Referenced by handleCmd_bad(), and incomingRequestHandler1().
1.5.2