Пример #1
0
        /// <summary>
        /// Parses a specific HTTP header field.
        /// </summary>
        /// <param name="KeyLower">Lower-case version of field name.</param>
        /// <param name="Key">Field name, as it appears in the header.</param>
        /// <param name="Value">Unparsed header field value</param>
        /// <returns>HTTP header field object, corresponding to the particular field.</returns>
        protected override HttpField ParseField(string KeyLower, string Key, string Value)
        {
            switch (KeyLower)
            {
            case "accept": return(this.accept = new HttpFieldAccept(Key, Value));

            case "accept-charset": return(this.acceptCharset = new HttpFieldAcceptCharset(Key, Value));

            case "accept-encoding": return(this.acceptEncoding = new HttpFieldAcceptEncoding(Key, Value));

            case "accept-language": return(this.acceptLanguage = new HttpFieldAcceptLanguage(Key, Value));

            case "authorization": return(this.authorization = new HttpFieldAuthorization(Key, Value));

            case "cookie": return(this.cookie = new HttpFieldCookie(Key, Value));

            case "expect": return(this.expect = new HttpFieldExpect(Key, Value));

            case "from": return(this.from = new HttpFieldFrom(Key, Value));

            case "host": return(this.host = new HttpFieldHost(Key, Value));

            case "if-match": return(this.ifMatch = new HttpFieldIfMatch(Key, Value));

            case "if-modified-since": return(this.ifModifiedSince = new HttpFieldIfModifiedSince(Key, Value));

            case "if-none-match": return(this.ifNoneMatch = new HttpFieldIfNoneMatch(Key, Value));

            case "if-range": return(this.ifRange = new HttpFieldIfRange(Key, Value));

            case "if-unmodified-since": return(this.ifUnmodifiedSince = new HttpFieldIfUnmodifiedSince(Key, Value));

            case "referer": return(this.referer = new HttpFieldReferer(Key, Value));

            case "range": return(this.range = new HttpFieldRange(Key, Value));

            case "user-agent": return(this.userAgent = new HttpFieldUserAgent(Key, Value));

            case "upgrade-insecure-requests": return(this.upgradeInsequreRequests = new HttpFieldUpgradeInsecureRequests(Key, Value));

            default: return(base.ParseField(KeyLower, Key, Value));
            }
        }
Пример #2
0
        /// <summary>
        /// Executes the POST method on the resource.
        /// </summary>
        /// <param name="Request">HTTP Request</param>
        /// <param name="Response">HTTP Response</param>
        /// <exception cref="HttpException">If an error occurred when processing the method.</exception>
        public void POST(HttpRequest Request, HttpResponse Response)
        {
            if (!Request.HasData || Request.Session == null)
            {
                throw new BadRequestException();
            }

            // TODO: Check User authenticated

            object Obj   = Request.DecodeData();
            string TabID = Request.Header["X-TabID"];

            if (!(Obj is string Location) || string.IsNullOrEmpty(TabID))
            {
                throw new BadRequestException();
            }

            Uri    Uri      = new Uri(Location);
            string Resource = Uri.LocalPath;
            List <KeyValuePair <string, string> > Query = null;
            string s;

            if (!string.IsNullOrEmpty(Uri.Query))
            {
                Query = new List <KeyValuePair <string, string> >();
                int i;

                s = Uri.Query;
                if (s.StartsWith("?"))
                {
                    s = s.Substring(1);
                }

                foreach (string Part in s.Split('&'))
                {
                    i = Part.IndexOf('=');
                    if (i < 0)
                    {
                        Query.Add(new KeyValuePair <string, string>(Part, string.Empty));
                    }
                    else
                    {
                        Query.Add(new KeyValuePair <string, string>(Part.Substring(0, i), Part.Substring(i + 1)));
                    }
                }
            }

            Response.ContentType = "application/json";

            if (!eventsByTabID.TryGetValue(TabID, out TabQueue Queue))
            {
                HttpFieldCookie Cookie        = Request.Header.Cookie;
                string          HttpSessionID = Cookie == null ? string.Empty : Cookie["HttpSessionID"];

                Queue = new TabQueue(TabID, HttpSessionID, Request.Session);
                eventsByTabID[TabID] = Queue;
            }

            lock (locationByTabID)
            {
                if (!locationByTabID.TryGetValue(TabID, out s) || s != Resource)
                {
                    locationByTabID[TabID] = Resource;
                }
            }

            lock (tabIdsByLocation)
            {
                if (!tabIdsByLocation.TryGetValue(Resource, out Dictionary <string, List <KeyValuePair <string, string> > > TabIds))
                {
                    TabIds = new Dictionary <string, List <KeyValuePair <string, string> > >();
                    tabIdsByLocation[Resource] = TabIds;
                }

                TabIds[TabID] = Query;
            }

            StringBuilder Json = null;

            lock (Queue)
            {
                if (Queue.Queue.First != null)
                {
                    foreach (string Event in Queue.Queue)
                    {
                        if (Json == null)
                        {
                            Json = new StringBuilder("[");
                        }
                        else
                        {
                            Json.Append(',');
                        }

                        Json.Append(Event);
                    }

                    Queue.Queue.Clear();
                    Queue.Response = null;
                }
                else
                {
                    Queue.Response = Response;
                }
            }

            if (Json != null)
            {
                timeoutByTabID.Remove(TabID);

                Json.Append(']');
                Response.Write(Json.ToString());
                Response.SendResponse();
                Response.Dispose();
            }
            else
            {
                timeoutByTabID[TabID] = Queue;
            }
        }
Пример #3
0
        internal static void RegisterWebSocket(WebSocket Socket, string Location, string TabID)
        {
            Uri    Uri      = new Uri(Location);
            string Resource = Uri.LocalPath;
            List <KeyValuePair <string, string> > Query = null;
            string s;

            if (!string.IsNullOrEmpty(Uri.Query))
            {
                Query = new List <KeyValuePair <string, string> >();
                int i;

                s = Uri.Query;
                if (s.StartsWith("?"))
                {
                    s = s.Substring(1);
                }

                foreach (string Part in s.Split('&'))
                {
                    i = Part.IndexOf('=');
                    if (i < 0)
                    {
                        Query.Add(new KeyValuePair <string, string>(Part, string.Empty));
                    }
                    else
                    {
                        Query.Add(new KeyValuePair <string, string>(Part.Substring(0, i), Part.Substring(i + 1)));
                    }
                }
            }

            if (eventsByTabID.TryGetValue(TabID, out TabQueue Queue))
            {
                Queue.WebSocket = Socket;
            }
            else
            {
                HttpFieldCookie Cookie        = Socket.HttpRequest.Header.Cookie;
                string          HttpSessionID = Cookie == null ? string.Empty : Cookie["HttpSessionID"];

                Queue = new TabQueue(TabID, HttpSessionID, Socket.HttpRequest.Session)
                {
                    WebSocket = Socket
                };

                eventsByTabID[TabID] = Queue;
            }

            lock (locationByTabID)
            {
                if (!locationByTabID.TryGetValue(TabID, out s) || s != Resource)
                {
                    locationByTabID[TabID] = Resource;
                }
            }

            lock (tabIdsByLocation)
            {
                if (!tabIdsByLocation.TryGetValue(Resource, out Dictionary <string, List <KeyValuePair <string, string> > > TabIds))
                {
                    TabIds = new Dictionary <string, List <KeyValuePair <string, string> > >();
                    tabIdsByLocation[Resource] = TabIds;
                }

                TabIds[TabID] = Query;
            }

            LinkedList <string> ToSend = null;

            lock (Queue)
            {
                if (Queue.Queue.First != null)
                {
                    ToSend = new LinkedList <string>();

                    foreach (string s2 in Queue.Queue)
                    {
                        ToSend.AddLast(s2);
                    }

                    Queue.Queue.Clear();
                }
            }

            if (ToSend != null)
            {
                foreach (string s2 in ToSend)
                {
                    Socket.Send(s2, 4096);
                }
            }
        }
Пример #4
0
        internal async Task Process(string Id, string From, string To, HttpRequest Request, IEndToEndEncryption E2e,
                                    string EndpointReference, int MaxChunkSize, string PostResource, bool Ibb, bool Socks5)
        {
            HttpAuthenticationScheme[] AuthenticationSchemes;
            bool Result;

            try
            {
                if (this.server.TryGetResource(Request.Header.Resource, out HttpResource Resource, out string SubPath))
                {
                    Request.Resource = Resource;

                    this.server.RequestReceived(Request, From, Resource, SubPath);

                    AuthenticationSchemes = Resource.GetAuthenticationSchemes(Request);
                    if (AuthenticationSchemes != null && AuthenticationSchemes.Length > 0)
                    {
                        foreach (HttpAuthenticationScheme Scheme in AuthenticationSchemes)
                        {
                            if (Scheme.UserSessions && Request.Session is null)
                            {
                                HttpFieldCookie Cookie = Request.Header.Cookie;
                                if (!(Cookie is null))
                                {
                                    string HttpSessionID = Cookie["HttpSessionID"];

                                    if (!string.IsNullOrEmpty(HttpSessionID))
                                    {
                                        Request.Session = this.server.GetSession(HttpSessionID);
                                    }
                                }
                            }

                            IUser User = await Scheme.IsAuthenticated(Request);

                            if (!(User is null))
                            {
                                Request.User = User;
                                break;
                            }
                        }

                        if (Request.User is null)
                        {
                            List <KeyValuePair <string, string> > Challenges = new List <KeyValuePair <string, string> >();

                            foreach (HttpAuthenticationScheme Scheme in AuthenticationSchemes)
                            {
                                string Challenge = Scheme.GetChallenge();
                                if (!string.IsNullOrEmpty(Challenge))
                                {
                                    Challenges.Add(new KeyValuePair <string, string>("WWW-Authenticate", Challenge));
                                }
                            }

                            await this.SendQuickResponse(Request, E2e, EndpointReference, Id, From, To, 401, "Unauthorized", false, MaxChunkSize, Challenges.ToArray());

                            Request.Dispose();
                            return;
                        }
                    }

                    Request.SubPath = SubPath;
                    Resource.Validate(Request);

                    if (Request.Header.Expect != null)
                    {
                        if (Request.Header.Expect.Continue100)
                        {
                            if (!Request.HasData)
                            {
                                await this.SendQuickResponse(Request, E2e, EndpointReference, Id, From, To, 100, "Continue", false, MaxChunkSize);

                                return;
                            }
                        }
                        else
                        {
                            await this.SendQuickResponse(Request, E2e, EndpointReference, Id, From, To, 417, "Expectation Failed", true, MaxChunkSize);

                            Request.Dispose();
                            return;
                        }
                    }

                    await this.ExecuteRequest(E2e, EndpointReference, Id, From, To, MaxChunkSize, PostResource, Ibb, Socks5, Request, Resource);

                    return;
                }
                else
                {
                    this.server.RequestReceived(Request, From, null, null);
                    await this.SendQuickResponse(Request, E2e, EndpointReference, Id, From, To, 404, "Not Found", false, MaxChunkSize);

                    Result = true;
                }
            }
        private async Task <bool?> QueueRequest(HttpRequest Request)
        {
            HttpAuthenticationScheme[] AuthenticationSchemes;
            bool Result;

            try
            {
                if (this.server.TryGetResource(Request.Header.Resource, out HttpResource Resource, out string SubPath))
                {
                    Request.Resource = Resource;
                    Request.SubPath  = SubPath;
#if WINDOWS_UWP
                    this.server.RequestReceived(Request, this.client.Client.Information.RemoteAddress.ToString() + ":" +
                                                this.client.Client.Information.RemotePort, Resource, SubPath);
#else
                    this.server.RequestReceived(Request, this.client.Client.Client.RemoteEndPoint.ToString(), Resource, SubPath);
#endif

                    AuthenticationSchemes = Resource.GetAuthenticationSchemes(Request);
                    if (AuthenticationSchemes != null && AuthenticationSchemes.Length > 0)
                    {
                        ILoginAuditor Auditor = this.server.LoginAuditor;

                        if (!(Auditor is null))
                        {
                            DateTime?Next = await Auditor.GetEarliestLoginOpportunity(Request.RemoteEndPoint, "HTTP");

                            if (Next.HasValue)
                            {
                                StringBuilder sb    = new StringBuilder();
                                DateTime      TP    = Next.Value;
                                DateTime      Today = DateTime.Today;
                                HttpException Error;

                                if (Next.Value == DateTime.MaxValue)
                                {
                                    sb.Append("This endpoint (");
                                    sb.Append(Request.RemoteEndPoint);
                                    sb.Append(") has been blocked from the system.");

                                    Error = new ForbiddenException(sb.ToString());
                                }
                                else
                                {
                                    sb.Append("Too many failed login attempts in a row registered. Try again in ");

                                    TimeSpan Span = TP - DateTime.Now;
                                    double   d;

                                    if ((d = Span.TotalDays) >= 1)
                                    {
                                        d = Math.Ceiling(d);
                                        sb.Append(d.ToString());
                                        sb.Append(" day");
                                    }
                                    else if ((d = Span.TotalHours) >= 1)
                                    {
                                        d = Math.Ceiling(d);
                                        sb.Append(d.ToString());
                                        sb.Append(" hour");
                                    }
                                    else
                                    {
                                        d = Math.Ceiling(Span.TotalMinutes);
                                        sb.Append(d.ToString());
                                        sb.Append(" minute");
                                    }

                                    if (d > 1)
                                    {
                                        sb.Append('s');
                                    }

                                    sb.Append('.');

                                    Error = new TooManyRequestsException(sb.ToString());
                                }

                                await this.SendResponse(Request, null, Error, true);

                                Request.Dispose();
                                return(true);
                            }
                        }

                        foreach (HttpAuthenticationScheme Scheme in AuthenticationSchemes)
                        {
                            if (Scheme.UserSessions && Request.Session is null)
                            {
                                HttpFieldCookie Cookie = Request.Header.Cookie;
                                if (!(Cookie is null))
                                {
                                    string HttpSessionID = Cookie["HttpSessionID"];

                                    if (!string.IsNullOrEmpty(HttpSessionID))
                                    {
                                        Request.Session = this.server.GetSession(HttpSessionID);
                                    }
                                }
                            }

                            IUser User = await Scheme.IsAuthenticated(Request);

                            if (!(User is null))
                            {
                                Request.User = User;
                                break;
                            }
                        }

                        if (Request.User is null)
                        {
                            List <KeyValuePair <string, string> > Challenges = new List <KeyValuePair <string, string> >();

                            foreach (HttpAuthenticationScheme Scheme in AuthenticationSchemes)
                            {
                                string Challenge = Scheme.GetChallenge();
                                if (!string.IsNullOrEmpty(Challenge))
                                {
                                    Challenges.Add(new KeyValuePair <string, string>("WWW-Authenticate", Challenge));
                                }
                            }

                            await this.SendResponse(Request, null, new HttpException(401, "Unauthorized", "Unauthorized access prohibited."), false, Challenges.ToArray());

                            Request.Dispose();
                            return(true);
                        }
                    }

                    Resource.Validate(Request);

                    if (Request.Header.Expect != null)
                    {
                        if (Request.Header.Expect.Continue100)
                        {
                            if (!Request.HasData)
                            {
                                await this.SendResponse(Request, null, new HttpException(100, "Continue", null), false);

                                return(null);
                            }
                        }
                        else
                        {
                            await this.SendResponse(Request, null, new HttpException(417, "Expectation Failed", "Unable to parse Expect header."), true);

                            Request.Dispose();
                            return(false);
                        }
                    }

                    Task _ = Task.Run(() => this.ProcessRequest(Request, Resource));
                    return(true);
                }
                else
                {
                    await this.SendResponse(Request, null, new NotFoundException("Resource not found: " + this.server.CheckResourceOverride(Request.Header.Resource)), false);

                    Result = true;
                }
            }