404 lines
9.7 KiB
C#
404 lines
9.7 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|