private bool ParseNormalHeaders()
{
_inboundHeaders.SetValue();
_inboundContent = "";
if (InputBuffer.AvaliableByteCounts < 4) return true;
//2. Detect the headers boundaries
var headersSize = 0;
var markerFound = false;
var pos = InputBuffer.Position;
while (InputBuffer.AvaliableByteCounts >= 4)
{
if (InputBuffer.Position - pos >= RTSP_MAX_HEADERS_SIZE)
{
FATAL("Headers section too long");
return false;
}
if (InputBuffer.ReadByte() != 0x0d || InputBuffer.ReadByte() != 0x0a|| InputBuffer.ReadByte() != 0x0d || InputBuffer.ReadByte() != 0x0a) continue;
markerFound = true;
headersSize = (int) (InputBuffer.Position-pos - 4);
break;
}
//3. Are the boundaries correct?
//Do we have enough data to parse the headers?
if (headersSize == 0)
{
return !markerFound;
}
InputBuffer.Position = pos;
var rawHeaders = Encoding.ASCII.GetString(InputBuffer.Reader.ReadBytes(headersSize));
System.Diagnostics.Debug.WriteLine(rawHeaders);
var lines = rawHeaders.Split(new []{ "\r\n" },StringSplitOptions.None);
if(lines.Length==0)
{
FATAL("Incorrect RTSP request");
return false;
}
//4. Get the fisrt line and parse it. This is either a status code
//for a previous request made by us, or the request that we just received
if (!ParseFirstLine(lines[0]))
{
FATAL("Unable to parse the first line");
return false;
}
_inboundHeaders[RTSP_HEADERS] = Variant.Get();
foreach (var line in lines.Skip(1))
{
string splitter = ": ";
if (line.StartsWith(splitter) || line.EndsWith(splitter))
{
splitter = ":";
if (line.StartsWith(splitter) || line.EndsWith(splitter))
{
WARN("Invalid header line: {0}", (line));
continue;
}
}
_inboundHeaders[RTSP_HEADERS][line.Substring(0, line.IndexOf(splitter, StringComparison.Ordinal))] =
line.Substring(line.IndexOf(splitter, StringComparison.Ordinal) + splitter.Length);
}
//6. default a transfer type to Content-Length: 0 if necessary
if (_inboundHeaders[RTSP_HEADERS, RTSP_HEADERS_CONTENT_LENGTH] == null)
{
_inboundHeaders[RTSP_HEADERS,RTSP_HEADERS_CONTENT_LENGTH] = "0";
}
//7. read the transfer type and set this request or response flags
string contentLengthString = _inboundHeaders[RTSP_HEADERS, RTSP_HEADERS_CONTENT_LENGTH];
contentLengthString= contentLengthString.Replace(" ", "");
try
{
_contentLength = Convert.ToUInt32(contentLengthString);
}
catch
{
FATAL("Invalid RTSP headers:\n{0}", (_inboundHeaders.ToString()));
return false;
}
//7. Advance the state and ignore the headers part from the buffer
_state = RtspState.Playload;
_rtpData = false;
InputBuffer.Ignore(4);
return true;
}