using System; using System.Collections; using System.Globalization; using System.IO; using System.Text; namespace System.Net { // Token: 0x020001FF RID: 511 internal class ChunkStream { // Token: 0x06001153 RID: 4435 RVA: 0x000328A8 File Offset: 0x00030AA8 public ChunkStream(byte[] buffer, int offset, int size, WebHeaderCollection headers) : this(headers) { this.Write(buffer, offset, size); } // Token: 0x06001154 RID: 4436 RVA: 0x000328BC File Offset: 0x00030ABC public ChunkStream(WebHeaderCollection headers) { this.headers = headers; this.saved = new StringBuilder(); this.chunks = new ArrayList(); this.chunkSize = -1; } // Token: 0x06001155 RID: 4437 RVA: 0x000328F4 File Offset: 0x00030AF4 public void ResetBuffer() { this.chunkSize = -1; this.chunkRead = 0; this.chunks.Clear(); } // Token: 0x06001156 RID: 4438 RVA: 0x00032910 File Offset: 0x00030B10 public void WriteAndReadBack(byte[] buffer, int offset, int size, ref int read) { if (offset + read > 0) { this.Write(buffer, offset, offset + read); } read = this.Read(buffer, offset, size); } // Token: 0x06001157 RID: 4439 RVA: 0x00032944 File Offset: 0x00030B44 public int Read(byte[] buffer, int offset, int size) { return this.ReadFromChunks(buffer, offset, size); } // Token: 0x06001158 RID: 4440 RVA: 0x00032950 File Offset: 0x00030B50 private int ReadFromChunks(byte[] buffer, int offset, int size) { int count = this.chunks.Count; int num = 0; for (int i = 0; i < count; i++) { ChunkStream.Chunk chunk = (ChunkStream.Chunk)this.chunks[i]; if (chunk != null) { if (chunk.Offset == chunk.Bytes.Length) { this.chunks[i] = null; } else { num += chunk.Read(buffer, offset + num, size - num); if (num == size) { break; } } } } return num; } // Token: 0x06001159 RID: 4441 RVA: 0x000329DC File Offset: 0x00030BDC public void Write(byte[] buffer, int offset, int size) { this.InternalWrite(buffer, ref offset, size); } // Token: 0x0600115A RID: 4442 RVA: 0x000329E8 File Offset: 0x00030BE8 private void InternalWrite(byte[] buffer, ref int offset, int size) { if (this.state == ChunkStream.State.None) { this.state = this.GetChunkSize(buffer, ref offset, size); if (this.state == ChunkStream.State.None) { return; } this.saved.Length = 0; this.sawCR = false; this.gotit = false; } if (this.state == ChunkStream.State.Body && offset < size) { this.state = this.ReadBody(buffer, ref offset, size); if (this.state == ChunkStream.State.Body) { return; } } if (this.state == ChunkStream.State.BodyFinished && offset < size) { this.state = this.ReadCRLF(buffer, ref offset, size); if (this.state == ChunkStream.State.BodyFinished) { return; } this.sawCR = false; } if (this.state == ChunkStream.State.Trailer && offset < size) { this.state = this.ReadTrailer(buffer, ref offset, size); if (this.state == ChunkStream.State.Trailer) { return; } this.saved.Length = 0; this.sawCR = false; this.gotit = false; } if (offset < size) { this.InternalWrite(buffer, ref offset, size); } } // Token: 0x170005B5 RID: 1461 // (get) Token: 0x0600115B RID: 4443 RVA: 0x00032AF8 File Offset: 0x00030CF8 public bool WantMore { get { return this.chunkRead != this.chunkSize || this.chunkSize != 0 || this.state != ChunkStream.State.None; } } // Token: 0x170005B6 RID: 1462 // (get) Token: 0x0600115C RID: 4444 RVA: 0x00032B28 File Offset: 0x00030D28 public int ChunkLeft { get { return this.chunkSize - this.chunkRead; } } // Token: 0x0600115D RID: 4445 RVA: 0x00032B38 File Offset: 0x00030D38 private ChunkStream.State ReadBody(byte[] buffer, ref int offset, int size) { if (this.chunkSize == 0) { return ChunkStream.State.BodyFinished; } int num = size - offset; if (num + this.chunkRead > this.chunkSize) { num = this.chunkSize - this.chunkRead; } byte[] array = new byte[num]; Buffer.BlockCopy(buffer, offset, array, 0, num); this.chunks.Add(new ChunkStream.Chunk(array)); offset += num; this.chunkRead += num; return (this.chunkRead != this.chunkSize) ? ChunkStream.State.Body : ChunkStream.State.BodyFinished; } // Token: 0x0600115E RID: 4446 RVA: 0x00032BC8 File Offset: 0x00030DC8 private ChunkStream.State GetChunkSize(byte[] buffer, ref int offset, int size) { char c = '\0'; while (offset < size) { c = (char)buffer[offset++]; if (c == '\r') { if (this.sawCR) { ChunkStream.ThrowProtocolViolation("2 CR found"); } this.sawCR = true; } else { if (this.sawCR && c == '\n') { break; } if (c == ' ') { this.gotit = true; } if (!this.gotit) { this.saved.Append(c); } if (this.saved.Length > 20) { ChunkStream.ThrowProtocolViolation("chunk size too long."); } } } if (!this.sawCR || c != '\n') { if (offset < size) { ChunkStream.ThrowProtocolViolation("Missing \\n"); } try { if (this.saved.Length > 0) { this.chunkSize = int.Parse(ChunkStream.RemoveChunkExtension(this.saved.ToString()), NumberStyles.HexNumber); } } catch (Exception) { ChunkStream.ThrowProtocolViolation("Cannot parse chunk size."); } return ChunkStream.State.None; } this.chunkRead = 0; try { this.chunkSize = int.Parse(ChunkStream.RemoveChunkExtension(this.saved.ToString()), NumberStyles.HexNumber); } catch (Exception) { ChunkStream.ThrowProtocolViolation("Cannot parse chunk size."); } if (this.chunkSize == 0) { this.trailerState = 2; return ChunkStream.State.Trailer; } return ChunkStream.State.Body; } // Token: 0x0600115F RID: 4447 RVA: 0x00032D68 File Offset: 0x00030F68 private static string RemoveChunkExtension(string input) { int num = input.IndexOf(';'); if (num == -1) { return input; } return input.Substring(0, num); } // Token: 0x06001160 RID: 4448 RVA: 0x00032D90 File Offset: 0x00030F90 private ChunkStream.State ReadCRLF(byte[] buffer, ref int offset, int size) { if (!this.sawCR) { if ((ushort)buffer[offset++] != 13) { ChunkStream.ThrowProtocolViolation("Expecting \\r"); } this.sawCR = true; if (offset == size) { return ChunkStream.State.BodyFinished; } } if (this.sawCR && (ushort)buffer[offset++] != 10) { ChunkStream.ThrowProtocolViolation("Expecting \\n"); } return ChunkStream.State.None; } // Token: 0x06001161 RID: 4449 RVA: 0x00032E00 File Offset: 0x00031000 private ChunkStream.State ReadTrailer(byte[] buffer, ref int offset, int size) { if (this.trailerState == 2 && (ushort)buffer[offset] == 13 && this.saved.Length == 0) { offset++; if (offset < size && (ushort)buffer[offset] == 10) { offset++; return ChunkStream.State.None; } offset--; } int num = this.trailerState; string text = "\r\n\r"; while (offset < size && num < 4) { char c = (char)buffer[offset++]; if ((num == 0 || num == 2) && c == '\r') { num++; } else if ((num == 1 || num == 3) && c == '\n') { num++; } else if (num > 0) { this.saved.Append(text.Substring(0, (this.saved.Length != 0) ? num : (num - 2))); num = 0; if (this.saved.Length > 4196) { ChunkStream.ThrowProtocolViolation("Error reading trailer (too long)."); } } } if (num < 4) { this.trailerState = num; if (offset < size) { ChunkStream.ThrowProtocolViolation("Error reading trailer."); } return ChunkStream.State.Trailer; } StringReader stringReader = new StringReader(this.saved.ToString()); string text2; while ((text2 = stringReader.ReadLine()) != null && text2 != string.Empty) { this.headers.Add(text2); } return ChunkStream.State.None; } // Token: 0x06001162 RID: 4450 RVA: 0x00032F88 File Offset: 0x00031188 private static void ThrowProtocolViolation(string message) { WebException ex = new WebException(message, null, WebExceptionStatus.ServerProtocolViolation, null); throw ex; } // Token: 0x04000F5A RID: 3930 internal WebHeaderCollection headers; // Token: 0x04000F5B RID: 3931 private int chunkSize; // Token: 0x04000F5C RID: 3932 private int chunkRead; // Token: 0x04000F5D RID: 3933 private ChunkStream.State state; // Token: 0x04000F5E RID: 3934 private StringBuilder saved; // Token: 0x04000F5F RID: 3935 private bool sawCR; // Token: 0x04000F60 RID: 3936 private bool gotit; // Token: 0x04000F61 RID: 3937 private int trailerState; // Token: 0x04000F62 RID: 3938 private ArrayList chunks; // Token: 0x02000200 RID: 512 private enum State { // Token: 0x04000F64 RID: 3940 None, // Token: 0x04000F65 RID: 3941 Body, // Token: 0x04000F66 RID: 3942 BodyFinished, // Token: 0x04000F67 RID: 3943 Trailer } // Token: 0x02000201 RID: 513 private class Chunk { // Token: 0x06001163 RID: 4451 RVA: 0x00032FA4 File Offset: 0x000311A4 public Chunk(byte[] chunk) { this.Bytes = chunk; } // Token: 0x06001164 RID: 4452 RVA: 0x00032FB4 File Offset: 0x000311B4 public int Read(byte[] buffer, int offset, int size) { int num = ((size <= this.Bytes.Length - this.Offset) ? size : (this.Bytes.Length - this.Offset)); Buffer.BlockCopy(this.Bytes, this.Offset, buffer, offset, num); this.Offset += num; return num; } // Token: 0x04000F68 RID: 3944 public byte[] Bytes; // Token: 0x04000F69 RID: 3945 public int Offset; } } }