static IEnumerable<object> ReadHeadersInternal(this ISocket socket) { LinkedList<ArraySegment<byte>> result = new LinkedList<ArraySegment<byte>>(); int bufferPosition = 0, totalBytesRead = 0; byte[] buffer = null; while (true) { if (buffer == null || bufferPosition > BufferSize / 2) { buffer = new byte[BufferSize]; bufferPosition = 0; } int bytesRead = 0; Trace.Write("About to read header chunk."); yield return socket.Read(buffer, bufferPosition, buffer.Length - bufferPosition).Do(n => bytesRead = n); Trace.Write("Read {0} bytes.", bytesRead); result.AddLast(new ArraySegment<byte>(buffer, bufferPosition, bytesRead)); if (bytesRead == 0) break; bufferPosition += bytesRead; totalBytesRead += bytesRead; var bodyDataPosition = result.IndexOfAfterCRLFCRLF(); if (bodyDataPosition != -1) { //Console.WriteLine("Read " + totalBytesRead + ", body starts at " + bodyDataPosition); var last = result.Last.Value; result.RemoveLast(); var overlapLength = totalBytesRead - bodyDataPosition; result.AddLast(new ArraySegment<byte>(last.Array, last.Offset, last.Count - overlapLength)); result.AddLast(new ArraySegment<byte>(last.Array, last.Offset + last.Count - overlapLength, overlapLength)); break; } // TODO test this if (totalBytesRead > MaxHeaderLength) throw new Exception("Request headers data exceeds max header length."); } Trace.Write("Yielding result."); yield return result; Trace.Write("Yielded result."); }