private void OnSendCompleted(AsyncResult res) { var stream = this.NetworkStream; /*var buff = new byte[4096]; var bytes = 0; do { bytes += stream.Read(buff, bytes, buff.Length - bytes); } while (bytes < buff.Length); File.WriteAllBytes("c:\\response.dat", buff);*/ var httpStateLine = ReadLine(stream); var stateMatch = Regex.Match(httpStateLine, @"^HTTP/\d\.\d (?<code>\d+) .+$"); var stateCode = (HttpStatusCode)int.Parse(stateMatch.Groups["code"].Value); var respMsg = new HttpMessage.Response(stream, stateCode); string hdr; while (!string.IsNullOrEmpty(hdr = ReadLine(stream))) { var delimiterPos = hdr.IndexOf(": "); respMsg.Headers.Add(hdr.Substring(0, delimiterPos), hdr.Substring(delimiterPos + 1)); } switch (stateCode) { case HttpStatusCode.Continue: // continue reading response this.OnSendCompleted(res); // read next http response break; case HttpStatusCode.Found: // temporary redirect res.Client.Close(); stream.Dispose(); var newUrl = respMsg.Headers["Location"]; if (res.RequestMessage.Stream != null) { // need to send data again, move stream to the beginning res.RequestMessage.Stream.Position = res.RequestStreamStart; } this.BeginSend(newUrl, res.RequestMessage, res.CallBack, res.AsyncState); break; case HttpStatusCode.OK: case HttpStatusCode.PartialContent: var cook = respMsg.Headers["Set-Cookie"]; if (this.CookieContainer != null && !string.IsNullOrEmpty(cook)) { this.CookieContainer.SetCookies(res.Uri, cook); } res.OnComplete(respMsg); break; default: res.ThrowException(new ApplicationException("Server returned: HTTP " + stateCode)); break; } }