aboutsummaryrefslogtreecommitdiff
path: root/SocketHttpListener.Portable/Net/ChunkedInputStream.cs
blob: 6dfd8d8a1d1fed1c59bc830bff9a900cbb67799a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System;
using System.IO;
using System.Runtime.InteropServices;
using SocketHttpListener.Primitives;

namespace SocketHttpListener.Net
{
    class ChunkedInputStream : RequestStream
    {
        bool disposed;
        ChunkStream decoder;
        HttpListenerContext context;
        bool no_more_data;

        //class ReadBufferState
        //{
        //    public byte[] Buffer;
        //    public int Offset;
        //    public int Count;
        //    public int InitialCount;
        //    public HttpStreamAsyncResult Ares;
        //    public ReadBufferState(byte[] buffer, int offset, int count,
        //                HttpStreamAsyncResult ares)
        //    {
        //        Buffer = buffer;
        //        Offset = offset;
        //        Count = count;
        //        InitialCount = count;
        //        Ares = ares;
        //    }
        //}

        public ChunkedInputStream(HttpListenerContext context, Stream stream,
                        byte[] buffer, int offset, int length)
            : base(stream, buffer, offset, length)
        {
            this.context = context;
            WebHeaderCollection coll = (WebHeaderCollection)context.Request.Headers;
            decoder = new ChunkStream(coll);
        }

        //public ChunkStream Decoder
        //{
        //    get { return decoder; }
        //    set { decoder = value; }
        //}

        //public override int Read([In, Out] byte[] buffer, int offset, int count)
        //{
        //    IAsyncResult ares = BeginRead(buffer, offset, count, null, null);
        //    return EndRead(ares);
        //}

        //public override IAsyncResult BeginRead(byte[] buffer, int offset, int count,
        //                    AsyncCallback cback, object state)
        //{
        //    if (disposed)
        //        throw new ObjectDisposedException(GetType().ToString());

        //    if (buffer == null)
        //        throw new ArgumentNullException("buffer");

        //    int len = buffer.Length;
        //    if (offset < 0 || offset > len)
        //        throw new ArgumentOutOfRangeException("offset exceeds the size of buffer");

        //    if (count < 0 || offset > len - count)
        //        throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");

        //    HttpStreamAsyncResult ares = new HttpStreamAsyncResult();
        //    ares.Callback = cback;
        //    ares.State = state;
        //    if (no_more_data)
        //    {
        //        ares.Complete();
        //        return ares;
        //    }
        //    int nread = decoder.Read(buffer, offset, count);
        //    offset += nread;
        //    count -= nread;
        //    if (count == 0)
        //    {
        //        // got all we wanted, no need to bother the decoder yet
        //        ares.Count = nread;
        //        ares.Complete();
        //        return ares;
        //    }
        //    if (!decoder.WantMore)
        //    {
        //        no_more_data = nread == 0;
        //        ares.Count = nread;
        //        ares.Complete();
        //        return ares;
        //    }
        //    ares.Buffer = new byte[8192];
        //    ares.Offset = 0;
        //    ares.Count = 8192;
        //    ReadBufferState rb = new ReadBufferState(buffer, offset, count, ares);
        //    rb.InitialCount += nread;
        //    base.BeginRead(ares.Buffer, ares.Offset, ares.Count, OnRead, rb);
        //    return ares;
        //}

        //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);
        //    }
        //}

        //public override int EndRead(IAsyncResult ares)
        //{
        //    if (disposed)
        //        throw new ObjectDisposedException(GetType().ToString());

        //    HttpStreamAsyncResult my_ares = ares as HttpStreamAsyncResult;
        //    if (ares == null)
        //        throw new ArgumentException("Invalid IAsyncResult", "ares");

        //    if (!ares.IsCompleted)
        //        ares.AsyncWaitHandle.WaitOne();

        //    if (my_ares.Error != null)
        //        throw new HttpListenerException(400, "I/O operation aborted: " + my_ares.Error.Message);

        //    return my_ares.Count;
        //}

        //protected override void Dispose(bool disposing)
        //{
        //    if (!disposed)
        //    {
        //        disposed = true;
        //        base.Dispose(disposing);
        //    }
        //}
    }
}