private void ParseHeaders(HttpClient client)
        {
            Headers = CreateCollection(client.Headers);

            string header;

            // Parse Accept.

            if (client.Headers.TryGetValue("Accept", out header))
            {
                string[] parts = header.Split(',');

                HttpUtil.TrimAll(parts);

                AcceptTypes = parts;
            }
            else
            {
                AcceptTypes = EmptyStringArray;
            }

            // Parse Content-Type.

            if (client.Headers.TryGetValue("Content-Type", out header))
            {
                string[] parts = header.Split(new[] { ';' }, 2);

                ContentType = parts[0].Trim();

                if (parts.Length == 2)
                {
                    string[] encoding = parts[1].Trim().Split(new[] { '=' }, 2);

                    if (encoding.Length == 2 && String.Equals(encoding[0], "charset", StringComparison.OrdinalIgnoreCase))
                    {
                        ContentEncoding = Encoding.GetEncoding(encoding[1]);
                    }
                }
            }

            // Parse Content-Length.

            if (client.Headers.TryGetValue("Content-Length", out header))
            {
                int contentLength;

                if (int.TryParse(header, out contentLength))
                {
                    ContentLength = contentLength;
                }
            }

            // Parse Referer.

            if (client.Headers.TryGetValue("Referer", out header))
            {
                UrlReferer = new Uri(header);
            }

            // Parse User-Agent.

            if (client.Headers.TryGetValue("User-Agent", out header))
            {
                UserAgent = header;
            }

            // Parse Accept-Language.

            if (client.Headers.TryGetValue("Accept-Language", out header))
            {
                string[] parts = header.Split(',');

                HttpUtil.TrimAll(parts);

                UserLanguages = parts;
            }
            else
            {
                UserLanguages = EmptyStringArray;
            }

            // Parse Cookie.

            Cookies = new HttpCookieCollection();

            if (client.Headers.TryGetValue("Cookie", out header))
            {
                string[] parts = header.Split(';');

                foreach (string part in parts)
                {
                    string[] partParts = part.Split(new[] { '=' }, 2);

                    string name  = partParts[0].Trim();
                    string value = partParts.Length == 1 ? null : partParts[1];

                    Cookies.AddCookie(new HttpCookie(name, value), true);
                }
            }
        }
        private void ParsePath(HttpClient client)
        {
            RawUrl = client.Request;

            string[] parts = client.Request.Split(new[] { '?' }, 2);

            Path = parts[0];

            QueryString = new NameValueCollection();
            if (parts.Length == 2)
            {
                HttpUtil.UrlDecodeTo(parts[1], QueryString);
            }

            string host;
            string port;
            string hostHeader;

            if (client.Headers.TryGetValue("Host", out hostHeader))
            {
                parts = hostHeader.Split(new[] { ':' }, 2);

                host = parts[0];

                if (parts.Length == 2)
                {
                    port = parts[1];
                }
                else
                {
                    port = null;
                }
            }
            else
            {
                var endPoint = client.Server.EndPoint;

                host = endPoint.Address.ToString();

                if (endPoint.Port == 80)
                {
                    port = null;
                }
                else
                {
                    port = endPoint.Port.ToString(CultureInfo.InvariantCulture);
                }
            }

            var sb = new StringBuilder();

            sb.Append("http://");
            sb.Append(host);

            if (port != null)
            {
                sb.Append(':');
                sb.Append(port);
            }

            sb.Append(client.Request);

            Url = new Uri(sb.ToString());
        }
        public static string HtmlDecode(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            var sb = new StringBuilder();

            for (int i = 0; i < value.Length; i++)
            {
                if (value[i] == '&' && value.Length > i + 2)
                {
                    // Scan for the ;.

                    int maxSearch   = Math.Min(value.Length, i + _longestHtmlEntity + 2);
                    int endPosition = -1;

                    for (int j = i + 1; j < maxSearch; j++)
                    {
                        if (value[j] == ';')
                        {
                            endPosition = j;
                            break;
                        }
                    }

                    // If we did not find an end separator, just skip over this
                    // entity and treat is at text.

                    if (endPosition == -1)
                    {
                        sb.Append(value[i]);
                        continue;
                    }

                    // Are we in a numeric separator?

                    if (value[i + 1] == '#')
                    {
                        int offset = 2;

                        bool isHexNumeric = false;

                        if (value[i + 2] == 'x' || value[i + 2] == 'X')
                        {
                            isHexNumeric = true;
                            offset++;
                        }

                        // All parts of the numeric separator must be digits.

                        bool isNumeric = true;

                        for (int j = i + offset; j < endPosition; j++)
                        {
                            if (!(
                                    Char.IsDigit(value[j]) ||
                                    (isHexNumeric && HttpUtil.IsHex(value[j]))
                                    ))
                            {
                                isNumeric = false;
                                break;
                            }
                        }

                        // If not all numeric, just skip over this
                        // entity and treat is at text.

                        if (!isNumeric)
                        {
                            sb.Append(value[i]);
                            continue;
                        }

                        // Convert the numeric entity to unicode.

                        string numericEntity = value.Substring(i + offset, endPosition - (i + offset));

                        sb.Append((char)int.Parse(numericEntity, isHexNumeric ? NumberStyles.HexNumber : NumberStyles.Integer));

                        i = endPosition;
                    }
                    else
                    {
                        string entity = value.Substring(i + 1, endPosition - (i + 1));

                        int codePoint;

                        if (_htmlEntitiesByEntity.TryGetValue(entity, out codePoint))
                        {
                            sb.Append((char)codePoint);

                            i = endPosition;
                        }
                        else
                        {
                            // If we don't know the entity, just skip over this
                            // entity and treat is at text.

                            sb.Append(value[i]);
                        }
                    }
                }
                else
                {
                    sb.Append(value[i]);
                }
            }

            return(sb.ToString());
        }