public override bool Handle(byte[] firstPacket, int length, Socket socket, object state)
 {
     if (socket.ProtocolType != ProtocolType.Tcp)
     {
         return(false);
     }
     try
     {
         string   request = Encoding.UTF8.GetString(firstPacket, 0, length);
         string[] lines = request.Split('\r', '\n');
         bool     hostMatch = false, pathMatch = false, useSocks = false;
         bool     secretMatch = PacSecret.IsNullOrEmpty();
         foreach (string line in lines)
         {
             string[] kv = line.Split(new char[] { ':' }, 2);
             if (kv.Length == 2)
             {
                 if (kv[0] == "Host")
                 {
                     if (kv[1].Trim() == ((IPEndPoint)socket.LocalEndPoint).ToString())
                     {
                         hostMatch = true;
                     }
                 }
                 //else if (kv[0] == "User-Agent")
                 //{
                 //    // we need to drop connections when changing servers
                 //    if (kv[1].IndexOf("Chrome") >= 0)
                 //    {
                 //        useSocks = true;
                 //    }
                 //}
             }
             else if (kv.Length == 1)
             {
                 if (line.IndexOf("pac", StringComparison.Ordinal) >= 0)
                 {
                     pathMatch = true;
                 }
                 if (!secretMatch)
                 {
                     if (line.IndexOf(PacSecret, StringComparison.Ordinal) >= 0)
                     {
                         secretMatch = true;
                     }
                 }
             }
         }
         if (hostMatch && pathMatch)
         {
             if (!secretMatch)
             {
                 socket.Close(); // Close immediately
             }
             else
             {
                 SendResponse(socket, useSocks);
             }
             return(true);
         }
         return(false);
     }
     catch (ArgumentException)
     {
         return(false);
     }
 }
        public override bool Handle(byte[] firstPacket, int length, Socket socket, object state)
        {
            if (socket.ProtocolType != ProtocolType.Tcp)
            {
                return(false);
            }

            try
            {
                /*
                 *  RFC 7230
                 *
                 *  GET /hello.txt HTTP/1.1
                 *  User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
                 *  Host: www.example.com
                 *  Accept-Language: en, mi
                 */

                string   request = Encoding.UTF8.GetString(firstPacket, 0, length);
                string[] lines = request.Split('\r', '\n');
                bool     hostMatch = false, pathMatch = false, useSocks = false;
                bool     secretMatch = PacSecret.IsNullOrEmpty();

                if (lines.Length < 2)   // need at lease RequestLine + Host
                {
                    return(false);
                }

                // parse request line
                string requestLine = lines[0];
                // GET /pac?t=yyyyMMddHHmmssfff&secret=foobar HTTP/1.1
                string[] requestItems = requestLine.Split(' ');
                if (requestItems.Length == 3 && requestItems[0] == "GET")
                {
                    int index = requestItems[1].IndexOf('?');
                    if (index < 0)
                    {
                        index = requestItems[1].Length;
                    }
                    string resourceString = requestItems[1].Substring(0, index).Remove(0, 1);
                    if (string.Equals(resourceString, RESOURCE_NAME, StringComparison.OrdinalIgnoreCase))
                    {
                        pathMatch = true;
                        if (!secretMatch)
                        {
                            string queryString = requestItems[1].Substring(index);
                            if (queryString.Contains(PacSecret))
                            {
                                secretMatch = true;
                            }
                        }
                    }
                }

                // parse request header
                for (int i = 1; i < lines.Length; i++)
                {
                    if (string.IsNullOrEmpty(lines[i]))
                    {
                        continue;
                    }

                    string[] kv = lines[i].Split(new char[] { ':' }, 2);
                    if (kv.Length == 2)
                    {
                        if (kv[0] == "Host")
                        {
                            if (kv[1].Trim() == ((IPEndPoint)socket.LocalEndPoint).ToString())
                            {
                                hostMatch = true;
                            }
                        }
                        //else if (kv[0] == "User-Agent")
                        //{
                        //    // we need to drop connections when changing servers
                        //    if (kv[1].IndexOf("Chrome") >= 0)
                        //    {
                        //        useSocks = true;
                        //    }
                        //}
                    }
                }

                if (hostMatch && pathMatch)
                {
                    if (!secretMatch)
                    {
                        socket.Close(); // Close immediately
                    }
                    else
                    {
                        SendResponse(socket, useSocks);
                    }
                    return(true);
                }
                return(false);
            }
            catch (ArgumentException)
            {
                return(false);
            }
        }