Beispiel #1
0
        /*public bool IsChunkedCompleted
         * {
         *      get
         *      {
         *              if(!IsChunked)
         *                      return false;
         *
         *              if(_is_chunked_completed)
         *                      return true;
         *
         *              return WorkOnChunk(Body_Bytes.ToArray());
         *      }
         * }*/

        void WorkOnChunk(byte[] bb)
        {
            try
            {
                int iter_counter      = 0;
                int max_iter_counter  = 2500;
                int max_size_in_bytes = 1638400;
                if (bb.Length > max_size_in_bytes)
                {
                    throw new Exception("Body too large to dechunk.");
                }

                if (_is_chunked_completed)
                {
                    return;
                }

                if (_is_chunked_failed)
                {
                    return;
                }

                byte[] nlb  = Enc.GetBytes("\r\n");
                string body = Enc.GetString(bb.ToArray());
                if (!body.Contains("\r\n0\r\n"))
                {
                    return;
                }

                var line = new String(body.Take(body.IndexOf("\r\n")).ToArray());
                var s    = line.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[0];
                int size = Convert.ToInt32(s.Trim(), 16);

                int    skip = Enc.GetBytes(line).Length + nlb.Length;
                byte[] tmp  = new byte[bb.Length - skip];
                for (int j = skip; j < bb.Length; j++)
                {
                    tmp[j - skip] = bb[j];
                }
                bb = tmp;

                List <byte> completed = new List <byte>();
                while (true)
                {
                    if (size == 0)
                    {
                        if (bb.Length > 0)
                        {
                            string after_headers = Enc.GetString(bb);
                            if (!after_headers.EndsWith("\r\n"))
                            {
                                return;
                            }

                            if (after_headers != "\r\n")
                            {
                                Headers_String = Headers_String + "\r\n" + after_headers;
                            }
                        }
                        _is_chunked_completed = true;
                        Body_Bytes            = completed;
                        return;
                    }
                    for (int j = 0; j < size; j++)
                    {
                        completed.Add(bb[j]);
                    }

                    int length = bb.Length;
                    tmp = new byte[length - size - nlb.Length];
                    for (int j = size + nlb.Length; j < length; j++)
                    {
                        tmp[j - size - nlb.Length] = bb[j];
                    }
                    bb = tmp;
                    int         i;
                    List <char> hex_digits = new List <char>()
                    {
                        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f'
                    };
                    for (i = 0; i < bb.Length - 1; i++)
                    {
                        iter_counter++;
                        if (i > 30 || iter_counter > max_iter_counter)
                        {
                            throw new Exception("Coudn't dechunk in time");
                        }

                        if (bb[i] == nlb[1])
                        {
                            //try
                            //{
                            tmp = new byte[i];
                            for (int j = 0; j < i; j++)
                            {
                                tmp[j] = bb[j];
                            }
                            string number = Enc.GetString(tmp).Trim();
                            number = new String(number.ToArray <char>().Where(f => hex_digits.Contains(f)).ToArray <char>());
                            size   = Convert.ToInt32(number, 16);
                            //}
                            //catch(Exception )
                            //{
                            //	Console.WriteLine(Enc.GetString (completed.ToArray()));
                            //}
                            tmp = new byte[bb.Length - i - 1];
                            for (int j = i + 1; j < bb.Length; j++)
                            {
                                tmp[j - i - 1] = bb[j];
                            }
                            bb = tmp;
                            i  = 0;
                            break;
                        }
                    }
                    if (i != 0)
                    {
                        return;
                    }
                }
            }
            catch (Exception)
            {
                _is_chunked_failed = true;
                var    b   = Enc.GetBytes("***Catcher: couldn't combine chunks***\r\n\r\n");
                int    l   = b.Length;
                byte[] res = new byte[b.Length + bb.Length];
                for (int j = 0; j < b.Length; j++)
                {
                    res[j] = b[j];
                }
                for (int j = 0; j < bb.Length; j++)
                {
                    res[l + j] = bb[j];
                }
                Body_Bytes = new List <byte>(res);
                return;
            }
        }