private void ReadCallback(IAsyncResult result) { if (state == HttpStates.CLOSED) { return; } State = HttpStates.READING; var read = 0; try { read = stream.EndRead(result); if (read < 0) { throw new HttpException("Client did not send anything"); } DebugFormat("{0} - Read {1} bytes", this, read); readStream.Write(buffer, 0, read); lastActivity = DateTime.Now; } catch (Exception) { if (!IsATimeout) { WarnFormat("{0} - Failed to read data", this); Close(); } return; } try { if (!hasHeaders) { readStream.Seek(0, SeekOrigin.Begin); var reader = new StreamReader(readStream); for (var line = reader.ReadLine(); line != null; line = reader.ReadLine()) { line = line.Trim(); if (string.IsNullOrEmpty(line)) { hasHeaders = true; readStream = new MemoryStream(); if (headers.ContainsKey("content-length") && uint.TryParse(headers["content-length"], out bodyBytes)) { if (bodyBytes > (1 << 20)) { throw new IOException("Body too long"); } var bytes = Encoding.ASCII.GetBytes(reader.ReadToEnd()); readStream.Write(bytes, 0, bytes.Length); DebugFormat("Must read body bytes {0}", bodyBytes); } else { readStream = new MemoryStream(); } break; } if (method == null) { var parts = line.Split(new char[] { ' ' }, 3); method = parts[0].Trim().ToUpper(); path = parts[1].Trim(); DebugFormat("{0} - {1} request for {2}", this, method, path); } else { var parts = line.Split(new char[] { ':' }, 2); headers[parts[0]] = Uri.UnescapeDataString(parts[1]).Trim(); } } } if (bodyBytes != 0 && bodyBytes > readStream.Length) { DebugFormat("{0} - Bytes to go {1}", this, bodyBytes - readStream.Length); Read(); return; } using (readStream) { body = Encoding.UTF8.GetString(readStream.ToArray()); Debug(body); Debug(headers); } SetupResponse(); } catch (Exception ex) { Warn(String.Format("{0} - Failed to process request", this), ex); response = Error500.HandleRequest(this); SendResponse(); } }