void OnRead(IAsyncResult base_ares) { ReadBufferState rb = (ReadBufferState)base_ares.AsyncState; HttpStreamAsyncResult ares = rb.Ares; try { int nread = base.EndRead(base_ares); decoder.Write(ares.Buffer, ares.Offset, nread); nread = decoder.Read(rb.Buffer, rb.Offset, rb.Count); rb.Offset += nread; rb.Count -= nread; if (rb.Count == 0 || !decoder.WantMore || nread == 0) { no_more_data = !decoder.WantMore && nread == 0; ares.Count = rb.InitialCount - rb.Count; ares.Complete(); return; } ares.Offset = 0; ares.Count = Math.Min(8192, decoder.ChunkLeft + 6); base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb); } catch (Exception e) { context.Connection.SendError(e.Message, 400); ares.Complete(e); } }
async Task <int> EnsureReadAsync(byte[] buffer, int offset, int size, CancellationToken cancellationToken) { byte[] morebytes = null; int nbytes = 0; while (nbytes == 0 && ChunkStream.WantMore && !cancellationToken.IsCancellationRequested) { int localsize = ChunkStream.ChunkLeft; if (localsize <= 0) // not read chunk size yet { localsize = 1024; } else if (localsize > 16384) { localsize = 16384; } if (morebytes == null || morebytes.Length < localsize) { morebytes = new byte[localsize]; } int nread = await InnerStream.ReadAsync(morebytes, 0, localsize, cancellationToken).ConfigureAwait(false); if (nread <= 0) { return(0); // Error } ChunkStream.Write(morebytes, 0, nread); nbytes += ChunkStream.Read(buffer, offset + nbytes, size - nbytes); } return(nbytes); }
void ReadDone(IAsyncResult result) { WebConnectionData data = Data; Stream ns = nstream; if (ns == null) { Close(true); return; } int nread = -1; try { nread = ns.EndRead(result); } catch (ObjectDisposedException) { return; } catch (Exception e) { if (e.InnerException is ObjectDisposedException) { return; } HandleError(WebExceptionStatus.ReceiveFailure, e, "ReadDone1"); return; } if (nread == 0) { HandleError(WebExceptionStatus.ReceiveFailure, null, "ReadDone2"); return; } if (nread < 0) { HandleError(WebExceptionStatus.ServerProtocolViolation, null, "ReadDone3"); return; } int pos = -1; nread += position; if (data.ReadState == ReadState.None) { Exception exc = null; try { pos = GetResponse(data, sPoint, buffer, nread); } catch (Exception e) { exc = e; } if (exc != null || pos == -1) { HandleError(WebExceptionStatus.ServerProtocolViolation, exc, "ReadDone4"); return; } } if (data.ReadState == ReadState.Aborted) { HandleError(WebExceptionStatus.RequestCanceled, null, "ReadDone"); return; } if (data.ReadState != ReadState.Content) { int est = nread * 2; int max = (est < buffer.Length) ? buffer.Length : est; byte [] newBuffer = new byte [max]; Buffer.BlockCopy(buffer, 0, newBuffer, 0, nread); buffer = newBuffer; position = nread; data.ReadState = ReadState.None; InitRead(); return; } position = 0; WebConnectionStream stream = new WebConnectionStream(this, data); bool expect_content = ExpectContent(data.StatusCode, data.request.Method); string tencoding = null; if (expect_content) { tencoding = data.Headers ["Transfer-Encoding"]; } chunkedRead = (tencoding != null && tencoding.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) != -1); if (!chunkedRead) { stream.ReadBuffer = buffer; stream.ReadBufferOffset = pos; stream.ReadBufferSize = nread; try { stream.CheckResponseInBuffer(); } catch (Exception e) { HandleError(WebExceptionStatus.ReceiveFailure, e, "ReadDone7"); } } else if (chunkStream == null) { try { chunkStream = new MonoChunkStream(buffer, pos, nread, data.Headers); } catch (Exception e) { HandleError(WebExceptionStatus.ServerProtocolViolation, e, "ReadDone5"); return; } } else { chunkStream.ResetBuffer(); try { chunkStream.Write(buffer, pos, nread); } catch (Exception e) { HandleError(WebExceptionStatus.ServerProtocolViolation, e, "ReadDone6"); return; } } data.stream = stream; if (!expect_content) { stream.ForceCompletion(); } data.request.SetResponseData(data); }