private bool ProxyRemoteConnectionFilter(ProxyServer.Client client)
    {
        int    port     = client.ProxyDestinationPort;
        string host     = client.ProxyDestinationHost;
        bool   redirect = false;

        if (port == this.mSpecialProxyAuthPort && host.Equals(this.mSpecialProxyAuthHost, StringComparison.OrdinalIgnoreCase))
        {
            redirect = true;
        }
        else
        {
            bool sessionOK = (bool)client.ProxySessionTag;
            if (!sessionOK)
            {
                if (80 == port)
                {
                    redirect = true;
                }
                else
                {
                    client.ProxyDestinationHost = null;
                }
            }
            //
        }

        if (redirect)
        {
            client.ProxyDestinationHost             = IPAddress.Loopback.ToString();
            client.ProxyDestinationPort             = this.mLocalAuthServerPort;
            client.ProxyRemoteConnectionPostProcess = this.ProxyConnectionPostProcess;
        }
        return(true);
    }
 private void ProcessNewConn(Socket sock)
 {
     sock.NoDelay = true;
     ProxyServer.Client client = new ProxyServer.Client(sock, true);
     client.HttpRequestHeaderUserHandler = this.ProcessHttpRequestHeader;
     client.HttpRequestDataUserHandler   = this.ProcessHttpRequestData;
     client.Start();
 }
    private bool ProxyConnectionPostProcess(ProxyServer.Client client)
    {
        Socket sock          = client.ProxyRemoteSocket;
        string localEndPoint = sock.LocalEndPoint.ToString();

        ProxyInfo proxy = new ProxyInfo();

        proxy.realIP    = client.RemoteAddress;
        proxy.proxyType = client.ProxyTypeName;

        lock (this.mDicProxyInfoReverseLookup)
        {
            this.mDicProxyInfoReverseLookup[localEndPoint] = proxy;
        }
        return(true);
    }
    private bool ProxyClientConnectionFilter(ProxyServer.Client client)
    {
        DateTime now = DateTime.Now;

        TimeSpan    dt;
        SessionInfo session   = null;
        bool        sessionOK = false;
        string      clientIP  = client.RemoteAddress;

        if (!string.IsNullOrEmpty(clientIP))
        {
            lock (gDicIpSession)
            {
                if (!gDicIpSession.TryGetValue(clientIP, out session))
                {
                    session = null;
                }
                if (session != null)
                {
                    dt        = now - session.lastUpdatedTime;
                    sessionOK = ((int)dt.TotalMinutes < session.aliveTimeInMinute);
                    if (sessionOK)
                    {
                        session.lastUpdatedTime = now;
                    }
                    else
                    {
                        gDicIpSession.Remove(clientIP);
                    }
                    //
                }
                //
            }
            //
        }

        client.ProxyRemoteConnectionFilter = this.ProxyRemoteConnectionFilter;
        client.ProxySessionTag             = sessionOK;
        return(true);
    }
    private bool ProcessHttpRequestHeader(ProxyServer.Client client)
    {
        if (client.HttpRequestDataSize > 1024)
        {
            return(false);
        }

        string method = client.HttpRequestMethod;

        if (string.IsNullOrEmpty(method))
        {
            return(false);
        }

        method = method.ToUpper();
        if (!method.Equals("GET", StringComparison.Ordinal) && !method.Equals("POST", StringComparison.Ordinal))
        {
            return(false);
        }

        return(true);
    }
    private void PrepareLoginPageHTML(ProxyServer.Client client, StringBuilder sb, int currentSessionAliveTimeout)
    {
        string prefix = DateTime.Now.ToString(DateTimeSaltFormat);

        Socket    sock           = client.ProxyLocalSocket;
        ProxyInfo proxy          = null;
        string    remoteEndPoint = sock.RemoteEndPoint.ToString();

        lock (this.mDicProxyInfoReverseLookup)
        {
            if (!this.mDicProxyInfoReverseLookup.TryGetValue(remoteEndPoint, out proxy))
            {
                proxy = null;
            }
            this.mDicProxyInfoReverseLookup.Remove(remoteEndPoint);
        }

        string realIP    = null;
        string proxyType = null;

        if (proxy != null)
        {
            realIP    = proxy.realIP;
            proxyType = proxy.proxyType;
        }
        if (null == realIP)
        {
            realIP = string.Empty;
        }

        string title = string.Empty;

        if (!string.IsNullOrEmpty(proxyType))
        {
            title = (proxyType + " ");
        }
        title += "proxy version ";
        title += ProxyServerVersion.ToString();

        sb.AppendLine("<!DOCTYPE html>");
        sb.AppendLine("<html lang=\"en\">");
        sb.AppendLine("<head>");

        sb.Append("<title>");
        sb.Append(title);
        sb.AppendLine("</title>");

        sb.AppendLine("<meta charset=\"utf-8\" />");
        sb.AppendLine("<style>");

#if HTML_INPUT_STYLE_FOR_SINGLE_TYPE
        sb.AppendLine("input[type=text] { padding:0;margin:0;width:100%;height:40px;font-size:32px; }");
#endif
        sb.AppendLine("body { padding:0;margin:0;width:100%;font-size:32px; }");
        sb.AppendLine(".fullw { padding:0;margin:0;width:100%;height:40px;font-size:32px; }");
        sb.AppendLine(".sep1 { padding:0;margin:0;overflow:hidden;width:100%;height:8px; }");

        sb.Append("input { ");
        sb.Append("margin:0;padding:5px;");
        sb.Append("width:100%;height:40px;font-size:32px;");
        sb.Append("color:#999da0;background-color:white;");
        sb.Append("border-radius:10px;border:1px solid #999da0;");
        sb.AppendLine(" }");

        sb.AppendLine("</style>");
        sb.AppendLine("</head>");
        sb.AppendLine("<body style=\"color:#454545;background-color:white;font-family:Verdana;\" >");

        this.PrepareHeadJs(sb);

        sb.AppendLine("<div class=\"fullw\" >");
        sb.AppendLine("<div style=\"float:left;width:1%;overflow:hidden;\" >&nbsp;</div>");
        sb.AppendLine("<div style=\"float:left;width:97.8%;\" >");

        sb.AppendLine("<div class=\"fullw\" >Password</div>");
        sb.AppendLine("<div><input id=\"Passwd\" type=\"password\" /></div>");

        sb.AppendLine("<div style=\"display:none;\" ><iframe id=\"HdnLoginFrame\" name=\"HdnLoginFrame\" onload=\"LoginCompleted()\" ></iframe></div>");
        sb.Append("<div><form id=\"form1\" method=\"POST\" target=\"HdnLoginFrame\" ");
        sb.Append("action=\"/api/v1/sessions\"");
        sb.AppendLine(" >");

        sb.AppendLine("<div><input id=\"PasswdSALT\" name=\"PasswdSALT\" type=\"hidden\" value=\"" + prefix + "\" /></div>");
        sb.AppendLine("<div><input id=\"HashedPasswd\" name=\"HashedPasswd\" type=\"hidden\" /></div>");

        sb.AppendLine("<div class=\"fullw\" >IP address</div>");
        sb.AppendLine("<div><input name=\"IpAddress\" type=\"text\" value=\"" + realIP + "\" /></div>");

        sb.AppendLine("<div class=\"fullw\" >Session Alive Time ( minutes )</div>");
        sb.AppendLine("<div><input name=\"SessionAliveTime\" type=\"text\" value=\"" + currentSessionAliveTimeout.ToString() + "\" /></div>");

        sb.AppendLine("<div class=\"sep1\" >&nbsp;</div>");

        sb.Append("<div><input id=\"BtnLogin\" type=\"submit\" value=\"Login\" class=\"fullw\" style=\"");
        sb.Append("margin:5px;height:60px;color:white;background-color:#007aff;border-color:#007aff;\"");
        sb.AppendLine("onclick=\"BeforeSubmit();\" /></div>");

        sb.AppendLine("</form></div>");

        sb.AppendLine("<div class=\"sep1\" >&nbsp;</div>");
        sb.Append("<div id=\"DivErrMsg\" class=\"fullw\" style=\"color:#ff4555;\" ></div>");

        this.PrepareTailJS(sb);

        sb.AppendLine("</div>");
        sb.AppendLine("<div style=\"float:right;width:1%;overflow:hidden;\" >&nbsp;</div>");
        sb.AppendLine("</div>");

        sb.AppendLine("</body>");
        sb.AppendLine("</html>");
    }
    private bool ProcessHttpRequestData(ProxyServer.Client client)
    {
        StringBuilder sb       = new StringBuilder();
        string        clientIP = client.RemoteAddress;
        string        method   = client.HttpRequestMethod.ToUpper();
        string        host     = client.HttpRequestHost;

        SessionInfo session = null;
        int         currentSessionAliveTimeout = 0;

        if (method.Equals("GET", StringComparison.Ordinal))
        {
            int pos = host.IndexOf(':');
            if (pos >= 0)
            {
                host = host.Substring(0, pos);
            }
            if (host.Equals(this.mSpecialProxyAuthHost, StringComparison.OrdinalIgnoreCase))
            {
                if (!string.IsNullOrEmpty(clientIP))
                {
                    lock (gDicIpSession)
                    {
                        if (!gDicIpSession.TryGetValue(clientIP, out session))
                        {
                            session = null;
                        }
                        //
                    }
                    //
                }
                if (session != null)
                {
                    currentSessionAliveTimeout = session.aliveTimeInMinute;
                }
                else
                {
                    if (currentSessionAliveTimeout <= 0)
                    {
                        currentSessionAliveTimeout = 480;
                    }
                    //
                }

                this.PrepareLoginPageHTML(client, sb, currentSessionAliveTimeout);
            }
            else
            {
                this.PrepareWelcomePage(sb);
            }
        }
        else
        {
            byte[] postDataBuf = client.HttpRequestData;
            if (null == postDataBuf)
            {
                return(false);
            }

            string postData = Encoding.ASCII.GetString(postDataBuf);
            if (this.ProxyLogin(postData))
            {
                sb.AppendLine(GetJsonStringResponse(0, "Login OK !"));
            }
            else
            {
                sb.AppendLine(GetJsonStringResponse(5, "Login failed"));
            }
            //
        }

        string html = sb.ToString();

        byte[] htmlBuf = Encoding.UTF8.GetBytes(html);
        client.HttpResponseData = htmlBuf;
        return(true);
    }