How to limit the number of characters read by StreamReader.ReadLine() in .NET?

Roman Shumikhin picture Roman Shumikhin · Dec 30, 2008 · Viewed 16.1k times · Source

I am writing a web server application in C# and using StreamReader class to read from an underlying NetworkStream:

 NetworkStream ns = new NetworkStream(clientSocket);
 StreamReader sr = new StreamReader(ns);
 String request = sr.ReadLine();

This code is prone to DoS attacks because if the attacker never disconnects we will never finish reading the line. Is there any way to limit the number of characters read by StreamReader.ReadLine() in .NET?

Answer

Marc Gravell picture Marc Gravell · Dec 30, 2008

You would have to use the Read(char[], int, int) overload (which does limit the length) and do your own end-of-line detection; shouldn't be too tricky.

For a slightly lazy version (that uses the single-characted reading version):

static IEnumerable<string> ReadLines(string path, int maxLineLength)
{
    StringBuilder currentLine = new StringBuilder(maxLineLength);
    using (var reader = File.OpenText(path))
    {
        int i;
        while((i = reader.Read()) > 0) {
            char c = (char) i;
            if(c == '\r' || c == '\n') {
                yield return currentLine.ToString();
                currentLine.Length = 0;
                continue;
            }
            currentLine.Append((char)c);
            if (currentLine.Length > maxLineLength)
            {
                throw new InvalidOperationException("Max length exceeded");
            }
        }
        if (currentLine.Length > 0)
        {
            yield return currentLine.ToString();
        }                
    }
}