protected override bool CheckValid(ResponseDescription response, ref int validThrough, ref int completeLength)
{
if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"CheckValid({response.StatusBuffer})");
// If the response is less than 4 bytes long, it is too short to tell, so return true, valid so far.
if (response.StatusBuffer.Length < 4)
{
return true;
}
string responseString = response.StatusBuffer.ToString();
// Otherwise, if there is no status code for this response yet, get one.
if (response.Status == ResponseDescription.NoStatus)
{
// If the response does not start with three digits, then it is not a valid response from an FTP server.
if (!(Char.IsDigit(responseString[0]) && Char.IsDigit(responseString[1]) && Char.IsDigit(responseString[2]) && (responseString[3] == ' ' || responseString[3] == '-')))
{
return false;
}
else
{
response.StatusCodeString = responseString.Substring(0, 3);
response.Status = Convert.ToInt16(response.StatusCodeString, NumberFormatInfo.InvariantInfo);
}
// IF a hyphen follows the status code on the first line of the response, then we have a multiline response coming.
if (responseString[3] == '-')
{
response.Multiline = true;
}
}
// If a complete line of response has been received from the server, then see if the
// overall response is complete.
// If this was not a multiline response, then the response is complete at the end of the line.
// If this was a multiline response (indicated by three digits followed by a '-' in the first line),
// then we see if the last line received started with the same three digits followed by a space.
// If it did, then this is the sign of a complete multiline response.
// If the line contained three other digits followed by the response, then this is a violation of the
// FTP protocol for multiline responses.
// All other cases indicate that the response is not yet complete.
int index = 0;
while ((index = responseString.IndexOf("\r\n", validThrough)) != -1) // gets the end line.
{
int lineStart = validThrough;
validThrough = index + 2; // validThrough now marks the end of the line being examined.
if (!response.Multiline)
{
completeLength = validThrough;
return true;
}
if (responseString.Length > lineStart + 4)
{
// If the first three characters of the the response line currently being examined
// match the status code, then if they are followed by a space, then we
// have reached the end of the reply.
if (responseString.Substring(lineStart, 3) == response.StatusCodeString)
{
if (responseString[lineStart + 3] == ' ')
{
completeLength = validThrough;
return true;
}
}
}
}
return true;
}