Пример #1
0
Boolean parseRangeHeader(char const* buf, double& rangeStart, double& rangeEnd) {
  // First, find "Range:"
  while (1) {
    if (*buf == '\0') return False; // not found
    if (_strncasecmp(buf, "Range: ", 7) == 0) break;
    ++buf;
  }
  
  // Then, run through each of the fields, looking for ones we handle:
  char const* fields = buf + 7;
  while (*fields == ' ') ++fields;
  double start, end;
  Locale l("C", LC_NUMERIC);
  if (sscanf(fields, "npt = %lf - %lf", &start, &end) == 2) {
    rangeStart = start;
    rangeEnd = end;
  } else if (sscanf(fields, "npt = %lf -", &start) == 1) {
    rangeStart = start;
    rangeEnd = 0.0;
  } else {
    return False; // The header is malformed
  }

  return True;
}
Пример #2
0
Boolean parsePlayNowHeader(char const* buf) {
	// Find "x-playNow:" header, if present
	while (1) {
		if (*buf == '\0') return False; // not found
		if (_strncasecmp(buf, "x-playNow:", 10) == 0) break;
		++buf;
	}
	
	return True;
}
Boolean parseRangeHeader(char const* buf, double& rangeStart, double& rangeEnd, char*& absStartTime, char*& absEndTime) {
  // First, find "Range:"
  while (1) {
    if (*buf == '\0') return False; // not found
    if (_strncasecmp(buf, "Range: ", 7) == 0) break;
    ++buf;
  }

  // Then, run through each of the fields, looking for ones we handle:
  char const* fields = buf + 7;
  while (*fields == ' ') ++fields;
  return parseRangeParam(fields, rangeStart, rangeEnd, absStartTime, absEndTime);
}
Пример #4
0
// A special version of "parseTransportHeader()", used just for parsing the "Transport:" header in an incoming "REGISTER" command:
void parseTransportHeaderForREGISTER(char const* buf,
				     Boolean &reuseConnection,
				     Boolean& deliverViaTCP,
				     char*& proxyURLSuffix) {
  // Initialize the result parameters to default values:
  reuseConnection = False;
  deliverViaTCP = False;
  proxyURLSuffix = NULL;
  
  // First, find "Transport:"
  while (1) {
    if (*buf == '\0') return; // not found
    if (*buf == '\r' && *(buf+1) == '\n' && *(buf+2) == '\r') return; // end of the headers => not found
    if (_strncasecmp(buf, "Transport:", 10) == 0) break;
    ++buf;
  }
  
  // Then, run through each of the fields, looking for ones we handle:
  char const* fields = buf + 10;
  while (*fields == ' ') ++fields;
  char* field = strDupSize(fields);
  while (sscanf(fields, "%[^;\r\n]", field) == 1) {
    if (strcmp(field, "reuse_connection") == 0) {
      reuseConnection = True;
    } else if (_strncasecmp(field, "preferred_delivery_protocol=udp", 31) == 0) {
      deliverViaTCP = False;
    } else if (_strncasecmp(field, "preferred_delivery_protocol=interleaved", 39) == 0) {
      deliverViaTCP = True;
    } else if (_strncasecmp(field, "proxy_url_suffix=", 17) == 0) {
      delete[] proxyURLSuffix;
      proxyURLSuffix = strDup(field+17);
    }
    
    fields += strlen(field);
    while (*fields == ';' || *fields == ' ' || *fields == '\t') ++fields; // skip over separating ';' chars or whitespace
    if (*fields == '\0' || *fields == '\r' || *fields == '\n') break;
  }
  delete[] field;
}
Пример #5
0
Boolean parseRangeHeader(char const* buf,
			 double& rangeStart, double& rangeEnd,
			 char*& absStartTime, char*& absEndTime,
			 Boolean& startTimeIsNow) {
  // First, find "Range:"
  while (1) {
    if (*buf == '\0') return False; // not found
    if (_strncasecmp(buf, "Range: ", 7) == 0) break;
    ++buf;
  }

  char const* fields = buf + 7;
  while (*fields == ' ') ++fields;
  return parseRangeParam(fields, rangeStart, rangeEnd, absStartTime, absEndTime, startTimeIsNow);
}
Пример #6
0
static Boolean parseAuthorizationHeader(char const* buf,
					char const*& username,
					char const*& realm,
					char const*& nonce, char const*& uri,
					char const*& response) {
	// Initialize the result parameters to default values:
  username = realm = nonce = uri = response = NULL;

	// First, find "Authorization:"
  while (1) {
	  if (*buf == '\0') return False; // not found
	  if (_strncasecmp(buf, "Authorization: Digest ", 22) == 0) break;
		++buf;
	}

	// Then, run through each of the fields, looking for ones we handle:
  char const* fields = buf + 22;
  while (*fields == ' ') ++fields;
  char* parameter = strDupSize(fields);
  char* value = strDupSize(fields);
  while (1) {
	  value[0] = '\0';
	  if (sscanf(fields, "%[^=]=\"%[^\"]\"", parameter, value) != 2 &&
	sscanf(fields, "%[^=]=\"\"", parameter) != 1) {
		  break;
		}
	  if (strcmp(parameter, "username") == 0) {
		  username = strDup(value);
		} else if (strcmp(parameter, "realm") == 0) {
		  realm = strDup(value);
		} else if (strcmp(parameter, "nonce") == 0) {
		  nonce = strDup(value);
		} else if (strcmp(parameter, "uri") == 0) {
		  uri = strDup(value);
		} else if (strcmp(parameter, "response") == 0) {
		  response = strDup(value);
		}

	  fields += strlen(parameter) + 2 /*="*/ + strlen(value) + 1 /*"*/;
	  while (*fields == ',' || *fields == ' ') ++fields;
				// skip over any separating ',' and ' ' chars
	  if (*fields == '\0' || *fields == '\r' || *fields == '\n') break;
	}
  delete[] parameter; delete[] value;
  return True;
}
Пример #7
0
Boolean SIPClient::parseSIPURLUsernamePassword(char const* url,
					       char*& username,
					       char*& password) {
  username = password = NULL; // by default
  do {
    // Parse the URL as "sip:<username>[:<password>]@<whatever>"
    char const* prefix = "sip:";
    unsigned const prefixLength = 4;
    if (_strncasecmp(url, prefix, prefixLength) != 0) break;

    // Look for the ':' and '@':
    unsigned usernameIndex = prefixLength;
    unsigned colonIndex = 0, atIndex = 0;
    for (unsigned i = usernameIndex; url[i] != '\0' && url[i] != '/'; ++i) {
      if (url[i] == ':' && colonIndex == 0) {
	colonIndex = i;
      } else if (url[i] == '@') {
        atIndex = i;
        break; // we're done
      }
    }
    if (atIndex == 0) break; // no '@' found

    char* urlCopy = strDup(url);
    urlCopy[atIndex] = '\0';
    if (colonIndex > 0) {
      urlCopy[colonIndex] = '\0';
      password = strDup(&urlCopy[colonIndex+1]);
    } else {
      password = strDup("");
    }
    username = strDup(&urlCopy[usernameIndex]);
    delete[] urlCopy;

    return True;
  } while (0);

  return False;
}
Пример #8
0
Boolean parseScaleHeader(char const* buf, float& scale) {
  // Initialize the result parameter to a default value:
  scale = 1.0;

  // First, find "Scale:"
  while (1) {
    if (*buf == '\0') return False; // not found
    if (_strncasecmp(buf, "Scale:", 6) == 0) break;
    ++buf;
  }

  char const* fields = buf + 6;
  while (*fields == ' ') ++fields;
  float sc;
  if (sscanf(fields, "%f", &sc) == 1) {
    scale = sc;
  } else {
    return False; // The header is malformed
  }

  return True;
}
Пример #9
0
Boolean parseSpecifiedStringParam(char const* buf, char *find_str, char *specified_str, Boolean specified_str_len)
{
	// First, find "Content-type:"
	while (1) {
		if (*buf == '\0') return False; // not found
		if (_strncasecmp(buf, specified_str, specified_str_len) == 0) break;
		++buf;
	}
	// Then, run through each of the fields, looking for ones we handle:
	char const* fields = buf + specified_str_len;
	while (*fields == ' ') ++fields;

	Boolean i = 0;
	while (1) {	   	
		if (fields[i] == '\r' && fields[i+1] == '\n'){
			find_str[i] = '\0';
			return i;
		}
		find_str[i] = fields[i];
		++i;
	}
	return True;
}
Boolean parseRTSPRequestString(char const* reqStr,
			       unsigned reqStrSize,
			       char* resultCmdName,
			       unsigned resultCmdNameMaxSize,
			       char* resultURLPreSuffix,
			       unsigned resultURLPreSuffixMaxSize,
			       char* resultURLSuffix,
			       unsigned resultURLSuffixMaxSize,
			       char* resultCSeq,
			       unsigned resultCSeqMaxSize,
                               char* resultSessionIdStr,
                               unsigned resultSessionIdStrMaxSize,
			       unsigned& contentLength,
	               unsigned& resultPinId,
	               unsigned& resultDisplayId) {
  // This parser is currently rather dumb; it should be made smarter #####

  // Read everything up to the first space as the command name:
  Boolean parseSucceeded = False;
  unsigned i;
  for (i = 0; i < resultCmdNameMaxSize-1 && i < reqStrSize; ++i) {
    char c = reqStr[i];
    if (c == ' ' || c == '\t') {
      parseSucceeded = True;
      break;
    }

    resultCmdName[i] = c;
  }
  resultCmdName[i] = '\0';
  if (!parseSucceeded) return False;

  // Skip over the prefix of any "rtsp://" or "rtsp:/" URL that follows:
  unsigned j = i+1;
  while (j < reqStrSize && (reqStr[j] == ' ' || reqStr[j] == '\t')) ++j; // skip over any additional white space
  for (; (int)j < (int)(reqStrSize-8); ++j) {
    if ((reqStr[j] == 'r' || reqStr[j] == 'R')
	&& (reqStr[j+1] == 't' || reqStr[j+1] == 'T')
	&& (reqStr[j+2] == 's' || reqStr[j+2] == 'S')
	&& (reqStr[j+3] == 'p' || reqStr[j+3] == 'P')
	&& reqStr[j+4] == ':' && reqStr[j+5] == '/') {
      j += 6;
      if (reqStr[j] == '/') {
	// This is a "rtsp://" URL; skip over the host:port part that follows:
	++j;
	while (j < reqStrSize && reqStr[j] != '/' && reqStr[j] != ' ') ++j;
      } else {
	// This is a "rtsp:/" URL; back up to the "/":
	--j;
      }
      i = j;
      break;
    }
  }

  // Look for the URL suffix (before the following "RTSP/"):
  parseSucceeded = False;
  for (unsigned k = i+1; (int)k < (int)(reqStrSize-5); ++k) {
    if (reqStr[k] == 'R' && reqStr[k+1] == 'T' &&
	reqStr[k+2] == 'S' && reqStr[k+3] == 'P' && reqStr[k+4] == '/') {
      while (--k >= i && reqStr[k] == ' ') {} // go back over all spaces before "RTSP/"
      unsigned k1 = k;
      while (k1 > i && reqStr[k1] != '/') --k1;

      // ASSERT: At this point
      //   i: first space or slash after "host" or "host:port"
      //   k: last non-space before "RTSP/"
      //   k1: last slash in the range [i,k]

      // The URL suffix comes from [k1+1,k]
      // Copy "resultURLSuffix":
      unsigned n = 0, k2 = k1+1;
      if (i <= k) { // There's a slash after "host" or "host:port"
        if (k - k1 + 1 > resultURLSuffixMaxSize) return False; // there's no room
        while (k2 <= k) resultURLSuffix[n++] = reqStr[k2++];
      }
      resultURLSuffix[n] = '\0';

      // The URL 'pre-suffix' comes from [i+1,k1-1]
      // Copy "resultURLPreSuffix":
      n = 0; k2 = i + 1;
      if (i <= k) { // There's a slash after "host" or "host:port"
        if (k1 - i > resultURLPreSuffixMaxSize) return False; // there's no room
        while (k2 <= k1 - 1) resultURLPreSuffix[n++] = reqStr[k2++];
      }
      resultURLPreSuffix[n] = '\0';
      decodeURL(resultURLPreSuffix);

      i = k + 7; // to go past " RTSP/"
      parseSucceeded = True;
      break;
    }
  }
  if (!parseSucceeded) return False;

  // Look for "CSeq:" (mandatory, case insensitive), skip whitespace,
  // then read everything up to the next \r or \n as 'CSeq':
  parseSucceeded = False;
  for (j = i; (int)j < (int)(reqStrSize-5); ++j) {
    if (_strncasecmp("CSeq:", &reqStr[j], 5) == 0) {
      j += 5;
      while (j < reqStrSize && (reqStr[j] ==  ' ' || reqStr[j] == '\t')) ++j;
      unsigned n;
      for (n = 0; n < resultCSeqMaxSize-1 && j < reqStrSize; ++n,++j) {
	char c = reqStr[j];
	if (c == '\r' || c == '\n') {
	  parseSucceeded = True;
	  break;
	}

	resultCSeq[n] = c;
      }
      resultCSeq[n] = '\0';
      break;
    }
  }
  if (!parseSucceeded) return False;

  // Look for "Session:" (optional, case insensitive), skip whitespace,
  // then read everything up to the next \r or \n as 'Session':
  resultSessionIdStr[0] = '\0'; // default value (empty string)
  for (j = i; (int)j < (int)(reqStrSize-8); ++j) {
    if (_strncasecmp("Session:", &reqStr[j], 8) == 0) {
      j += 8;
      while (j < reqStrSize && (reqStr[j] ==  ' ' || reqStr[j] == '\t')) ++j;
      unsigned n;
      for (n = 0; n < resultSessionIdStrMaxSize-1 && j < reqStrSize; ++n,++j) {
	char c = reqStr[j];
	if (c == '\r' || c == '\n') {
	  break;
	}

	resultSessionIdStr[n] = c;
      }
      resultSessionIdStr[n] = '\0';
      break;
    }
  }


  // Also: Look for "Content-Length:" (optional, case insensitive)
  contentLength = 0; // default value
  for (j = i; (int)j < (int)(reqStrSize-15); ++j) {
    if (_strncasecmp("Content-Length:", &(reqStr[j]), 15) == 0) {
      j += 15;
      while (j < reqStrSize && (reqStr[j] ==  ' ' || reqStr[j] == '\t')) ++j;
      unsigned num;
      if (sscanf(&reqStr[j], "%u", &num) == 1) {
	contentLength = num;
      }
    }
  }

  // ESD: Look for "DisplayId:" (optional, case insensitive)
  resultDisplayId = 1; // default value
  for (j = i; (int)j < (int)(reqStrSize-10); ++j) {
    if (_strncasecmp("DisplayId:", &(reqStr[j]), 10) == 0) {
      j += 10;
      while (j < reqStrSize && (reqStr[j] ==  ' ' || reqStr[j] == '\t')) ++j;
      unsigned num;
      if (sscanf(&reqStr[j], "%u", &num) == 1) {
        resultDisplayId = num;
      }
    }
  }

  // ESD: Look for "Pin:" (optional, case insensitive)
  resultPinId = 0; // default value
  for (j = i; (int)j < (int)(reqStrSize-4); ++j) {
    if (_strncasecmp("Pin:", &(reqStr[j]), 4) == 0) {
      j += 4;
      while (j < reqStrSize && (reqStr[j] ==  ' ' || reqStr[j] == '\t')) ++j;
      unsigned num;
      if (sscanf(&reqStr[j], "%u", &num) == 1) {
        resultPinId = num;
      }
    }
  }

  return true;
}
Пример #11
0
void parseTransportHeader(char const* buf,
		StreamingMode& streamingMode,
		char*& streamingModeString,
		char*& destinationAddressStr,
		unsigned char& destinationTTL,
		unsigned short& clientRTPPortNum, // if UDP
		unsigned short& clientRTCPPortNum, // if UDP
		unsigned char& rtpChannelId, // if TCP
		unsigned char& rtcpChannelId // if TCP
		) {
	// Initialize the result parameters to default values:
	streamingMode = RTP_UDP;
	streamingModeString = NULL;
	destinationAddressStr = NULL;
	destinationTTL = 255;
	clientRTPPortNum = 0;
	clientRTCPPortNum = 1;
	rtpChannelId = rtcpChannelId = 0xFF;
	
	unsigned short p1, p2;
	unsigned ttl, rtpCid, rtcpCid;
	
	// First, find "Transport:"
	while (1) {
		if (*buf == '\0') return; // not found
		if (_strncasecmp(buf, "Transport: ", 11) == 0) break;
		++buf;
	}

	// Then, run through each of the fields, looking for ones we handle:
	char const* fields = buf + 11;
	char* field = strDupSize(fields);
	while (sscanf(fields, "%[^;]", field) == 1) {
		if (strcmp(field, "RTP/AVP/TCP") == 0) {
			streamingMode = RTP_TCP;
		} else if (strcmp(field, "RAW/RAW/UDP") == 0 ||
			strcmp(field, "MP2T/H2221/UDP") == 0) {
			streamingMode = RAW_UDP;
			streamingModeString = strDup(field);
		} else if (_strncasecmp(field, "destination=", 12) == 0) {
			delete[] destinationAddressStr;
			destinationAddressStr = strDup(field+12);
		} else if (sscanf(field, "ttl%u", &ttl) == 1) {
			destinationTTL = (unsigned char)ttl;
		} else if (sscanf(field, "client_port=%hu-%hu", &p1, &p2) == 2) {
			clientRTPPortNum = p1;
			clientRTCPPortNum = p2;
		} else if (sscanf(field, "client_port=%hu", &p1) == 1) {
			clientRTPPortNum = p1;
			clientRTCPPortNum = streamingMode == RAW_UDP ? 0 : p1 + 1;
		} else if (sscanf(field, "interleaved=%u-%u", &rtpCid, &rtcpCid) == 2) {
			rtpChannelId = (unsigned char)rtpCid;
			rtcpChannelId = (unsigned char)rtcpCid;
		}
		
		fields += strlen(field);
		while (*fields == ';') ++fields; // skip over separating ';' chars
		if (*fields == '\0' || *fields == '\r' || *fields == '\n') break;
	}
	delete[] field;
}
Пример #12
0
Boolean SIPClient::parseSIPURL(UsageEnvironment& env, char const* url,
			       NetAddress& address,
			       portNumBits& portNum) {
  do {
    // Parse the URL as "sip:<username>@<address>:<port>/<etc>"
    // (with ":<port>" and "/<etc>" optional)
    // Also, skip over any "<username>[:<password>]@" preceding <address>
    char const* prefix = "sip:";
    unsigned const prefixLength = 4;
    if (_strncasecmp(url, prefix, prefixLength) != 0) {
      env.setResultMsg("URL is not of the form \"", prefix, "\"");
      break;
    }

    unsigned const parseBufferSize = 100;
    char parseBuffer[parseBufferSize];
    unsigned addressStartIndex = prefixLength;
    while (url[addressStartIndex] != '\0'
	   && url[addressStartIndex++] != '@') {}
    char const* from = &url[addressStartIndex];

    // Skip over any "<username>[:<password>]@"
    char const* from1 = from;
    while (*from1 != '\0' && *from1 != '/') {
      if (*from1 == '@') {
	from = ++from1;
	break;
      }
      ++from1;
    }

    char* to = &parseBuffer[0];
    unsigned i;
    for (i = 0; i < parseBufferSize; ++i) {
      if (*from == '\0' || *from == ':' || *from == '/') {
	// We've completed parsing the address
	*to = '\0';
	break;
      }
      *to++ = *from++;
    }
    if (i == parseBufferSize) {
      env.setResultMsg("URL is too long");
      break;
    }

    NetAddressList addresses(parseBuffer);
    if (addresses.numAddresses() == 0) {
      env.setResultMsg("Failed to find network address for \"",
			   parseBuffer, "\"");
      break;
    }
    address = *(addresses.firstAddress());

    portNum = 5060; // default value
    char nextChar = *from;
    if (nextChar == ':') {
      int portNumInt;
      if (sscanf(++from, "%d", &portNumInt) != 1) {
	env.setResultMsg("No port number follows ':'");
	break;
      }
      if (portNumInt < 1 || portNumInt > 65535) {
	env.setResultMsg("Bad port number");
	break;
      }
      portNum = (portNumBits)portNumInt;
    }

    return True;
  } while (0);

  return False;
}